1
0
Fork 0
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:
Joshua Clayton 2012-05-11 11:43:08 -04:00
parent 645afa9689
commit 0d4b5cb34e
6 changed files with 96 additions and 21 deletions

View file

@ -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

View file

@ -22,6 +22,10 @@ module FactoryGirl
map(&:to_create).compact.last
end
def constructor
map(&:constructor).compact.last
end
delegate :[], :==, to: :@definitions
end
end

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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