mirror of
https://github.com/thoughtbot/factory_bot.git
synced 2022-11-09 11:43:51 -05:00
Fix initialize_with in the context of traits
This commit is contained in:
parent
645afa9689
commit
0d4b5cb34e
6 changed files with 96 additions and 21 deletions
|
@ -10,7 +10,7 @@ module FactoryGirl
|
|||
@to_create = nil
|
||||
@base_traits = base_traits
|
||||
@additional_traits = []
|
||||
@constructor = default_constructor
|
||||
@constructor = nil
|
||||
end
|
||||
|
||||
delegate :declare_attribute, to: :declarations
|
||||
|
@ -50,6 +50,10 @@ module FactoryGirl
|
|||
definition_list.to_create
|
||||
end
|
||||
|
||||
def compiled_constructor
|
||||
definition_list.constructor
|
||||
end
|
||||
|
||||
def to_create(&block)
|
||||
if block_given?
|
||||
@to_create = block
|
||||
|
@ -66,16 +70,8 @@ module FactoryGirl
|
|||
@constructor = block
|
||||
end
|
||||
|
||||
def custom_constructor?
|
||||
@constructor != default_constructor
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def default_constructor
|
||||
@default_constructor ||= -> { new }
|
||||
end
|
||||
|
||||
def base_traits
|
||||
@base_traits.map { |name| trait_by_name(name) }
|
||||
end
|
||||
|
|
|
@ -22,6 +22,10 @@ module FactoryGirl
|
|||
map(&:to_create).compact.last
|
||||
end
|
||||
|
||||
def constructor
|
||||
map(&:constructor).compact.last
|
||||
end
|
||||
|
||||
delegate :[], :==, to: :@definitions
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@ module FactoryGirl
|
|||
@compiled = false
|
||||
end
|
||||
|
||||
delegate :add_callback, :declare_attribute, :to_create, :define_trait,
|
||||
delegate :add_callback, :declare_attribute, :to_create, :define_trait, :constructor,
|
||||
:defined_traits, :inherit_traits, :append_traits, :definition_list, to: :@definition
|
||||
|
||||
def build_class
|
||||
|
@ -34,6 +34,7 @@ module FactoryGirl
|
|||
strategy = StrategyCalculator.new(build_strategy).strategy.new
|
||||
|
||||
evaluator = evaluator_class.new(build_class, strategy, overrides.symbolize_keys)
|
||||
constructor = compiled_constructor || -> { new }
|
||||
attribute_assigner = AttributeAssigner.new(evaluator, build_class, &constructor)
|
||||
|
||||
evaluation = Evaluation.new(attribute_assigner, compiled_to_create)
|
||||
|
@ -119,13 +120,12 @@ module FactoryGirl
|
|||
parent.callbacks + definition_list.callbacks
|
||||
end
|
||||
|
||||
def constructor
|
||||
@constructor ||=
|
||||
if @definition.custom_constructor?
|
||||
@definition.constructor
|
||||
else
|
||||
parent.constructor
|
||||
end
|
||||
def compiled_to_create
|
||||
@definition.compiled_to_create || parent.compiled_to_create
|
||||
end
|
||||
|
||||
def compiled_constructor
|
||||
@definition.compiled_constructor || parent.compiled_constructor
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -7,7 +7,8 @@ module FactoryGirl
|
|||
@definition = Definition.new
|
||||
end
|
||||
|
||||
delegate :defined_traits, :callbacks, :attributes, :constructor, :compiled_to_create, to: :definition
|
||||
delegate :defined_traits, :callbacks, :attributes, :constructor,
|
||||
:compiled_to_create, :compiled_constructor, to: :definition
|
||||
|
||||
def compile; end
|
||||
def class_name; end
|
||||
|
|
|
@ -6,13 +6,13 @@ module FactoryGirl
|
|||
def initialize(name, &block)
|
||||
@name = name
|
||||
@block = block
|
||||
@definition = Definition.new
|
||||
@definition = Definition.new(@name)
|
||||
|
||||
proxy = FactoryGirl::DefinitionProxy.new(@definition)
|
||||
proxy.instance_eval(&@block) if block_given?
|
||||
end
|
||||
|
||||
delegate :add_callback, :declare_attribute, :to_create, :define_trait,
|
||||
delegate :add_callback, :declare_attribute, :to_create, :define_trait, :constructor,
|
||||
:callbacks, :attributes, to: :@definition
|
||||
|
||||
def names
|
||||
|
|
|
@ -420,7 +420,7 @@ describe "making sure the factory is properly compiled the first time we want to
|
|||
end
|
||||
end
|
||||
|
||||
describe "traits with other than attributes or callbacks defined" do
|
||||
describe "traits with to_create" do
|
||||
before do
|
||||
define_model("User", name: :string)
|
||||
|
||||
|
@ -487,3 +487,77 @@ describe "traits with other than attributes or callbacks defined" do
|
|||
FactoryGirl.create(:child_user_with_trait_and_override, :overridden).name.should == "completely overridden"
|
||||
end
|
||||
end
|
||||
|
||||
describe "traits with initialize_with" do
|
||||
before do
|
||||
define_class("User") do
|
||||
attr_reader :name
|
||||
|
||||
def initialize(name)
|
||||
@name = name
|
||||
end
|
||||
end
|
||||
|
||||
FactoryGirl.define do
|
||||
factory :user do
|
||||
trait :with_initialize_with do
|
||||
initialize_with { new("initialize_with") }
|
||||
end
|
||||
|
||||
factory :sub_user do
|
||||
initialize_with { new("sub") }
|
||||
|
||||
factory :child_user
|
||||
end
|
||||
|
||||
factory :sub_user_with_trait do
|
||||
with_initialize_with
|
||||
|
||||
factory :child_user_with_trait
|
||||
end
|
||||
|
||||
factory :sub_user_with_trait_and_override do
|
||||
with_initialize_with
|
||||
initialize_with { new("sub with trait and override") }
|
||||
|
||||
factory :child_user_with_trait_and_override
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "can apply initialize_with from traits" do
|
||||
FactoryGirl.build(:user, :with_initialize_with).name.should == "initialize_with"
|
||||
end
|
||||
|
||||
it "can apply initialize_with from the definition" do
|
||||
FactoryGirl.build(:sub_user).name.should == "sub"
|
||||
FactoryGirl.build(:child_user).name.should == "sub"
|
||||
end
|
||||
|
||||
it "gives additional traits higher priority than initialize_with from the definition" do
|
||||
FactoryGirl.build(:sub_user, :with_initialize_with).name.should == "initialize_with"
|
||||
FactoryGirl.build(:child_user, :with_initialize_with).name.should == "initialize_with"
|
||||
end
|
||||
|
||||
it "gives base traits normal priority" do
|
||||
FactoryGirl.build(:sub_user_with_trait).name.should == "initialize_with"
|
||||
FactoryGirl.build(:child_user_with_trait).name.should == "initialize_with"
|
||||
end
|
||||
|
||||
it "gives base traits lower priority than overrides" do
|
||||
FactoryGirl.build(:sub_user_with_trait_and_override).name.should == "sub with trait and override"
|
||||
FactoryGirl.build(:child_user_with_trait_and_override).name.should == "sub with trait and override"
|
||||
end
|
||||
|
||||
it "gives additional traits higher priority than base traits and factory definition" do
|
||||
FactoryGirl.define do
|
||||
trait :overridden do
|
||||
initialize_with { new("completely overridden") }
|
||||
end
|
||||
end
|
||||
|
||||
FactoryGirl.build(:sub_user_with_trait_and_override, :overridden).name.should == "completely overridden"
|
||||
FactoryGirl.build(:child_user_with_trait_and_override, :overridden).name.should == "completely overridden"
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue