This allows callbacks (after :build, :create, etc.) to be defined at the
FactoryGirl level; this means that the callback will be invoked for all
factories. This is primarily to maintain consistency and follow the
principle of least surprise.
As usual, callbacks are applied from the lowest component to the
highest, meaning that global callbacks will be run after factory and
trait callbacks are run.
FactoryGirl.define do
after(:build) {|object| puts "Built #{object}" }
factory :user
# ...
end
Closes#481Closes#486
The previous implementation of trait handling within the Definition
didn't account for when implicit traits were used within other traits.
This is useful if you have two different traits, but one depends on
another; for example, a refunded order and a completed order could both
have the attribute `completed_at` set, but refunded would additionally
have `refunded_at` set:
FactoryGirl.define do
factory :order do
trait :completed do
completed_at { 3.days.ago }
end
trait :refunded do
completed
refunded_at { 1.day.ago }
end
end
end
This also tests to make sure that callbacks, custom constructors, and
creation overrides work correctly when implicit traits are used within
other traits.
Fixes#360
This allows users to define to_create for every factory run through
factory_girl.
FactoryGirl.define do
to_create {|instance| instance.persist! }
end
If you want to override this default, set it per factory or in a trait
(and include the trait).
Closes#341
Factory Girl now allows factories to override object instantiation. This
means factories can use factory methods (e.g. methods other than new) as
well as pass arguments explicitly.
factory :user do
ignore do
things { ["thing 1", "thing 2"] }
end
initialize_with { User.construct_with_things(things) }
end
factory :report_generator do
ignore do
name { "Generic Report" }
data { {:foo => "bar", :baz => "buzz"} }
end
initialize_with { ReportGenerator.new(name, data) }
end
Whitespace
Code recommendations
DeclarationList knows how to generate an attribute
list, which never really made sense outside of being generated from
declarations. Now, the declaration list builds a list of attributes
which is combined in Factory#attributes with attributes from traits and
its parents.
Both Factory and Trait have similar methods and interact with a
DefinitionProxy. The idea here is to move the interface DefinitionProxy
expects to a separate class and both Factory and Trait can delegate to
an instance of Definition.