Allow initialize_with defined for all factories

This allows users to define initialize_with for every factory run through
factory_girl.

    FactoryGirl.define do
      initialize_with { new("John Doe") }
    end

If you want to override this default, set it per factory or in a trait
(and include the trait).

Closes #342
This commit is contained in:
Joshua Clayton 2012-05-12 18:53:17 -04:00
parent f7efc610fd
commit 2f8731dd7e
6 changed files with 104 additions and 5 deletions

View File

@ -762,6 +762,15 @@ factory :user do
end
```
You can define `initialize_with` for all factories by including it in the
`FactoryGirl.define` block:
```ruby
FactoryGirl.define do
initialize_with { new("Awesome first argument") }
end
```
Custom Strategies
-----------------

View File

@ -50,7 +50,7 @@ module FactoryGirl
class << self
delegate :factories, :sequences, :traits, :strategies, :callback_names,
:to_create, :skip_create, to: :configuration
:to_create, :skip_create, :initialize_with, :constructor, to: :configuration
end
def self.register_factory(factory)

View File

@ -12,8 +12,13 @@ module FactoryGirl
@definition = Definition.new
to_create {|instance| instance.save! }
initialize_with { new }
end
delegate :to_create, :skip_create, to: :@definition
delegate :to_create, :skip_create, :constructor, to: :@definition
def initialize_with(&block)
@definition.define_constructor(&block)
end
end
end

View File

@ -34,8 +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)
attribute_assigner = AttributeAssigner.new(evaluator, build_class, &compiled_constructor)
evaluation = Evaluation.new(attribute_assigner, compiled_to_create)
evaluation.add_observer(CallbacksObserver.new(callbacks, evaluator))
@ -121,7 +120,7 @@ module FactoryGirl
end
def compiled_constructor
@definition.compiled_constructor || parent.compiled_constructor
@definition.compiled_constructor || parent.compiled_constructor || FactoryGirl.constructor
end
private

View File

@ -41,6 +41,10 @@ module FactoryGirl
FactoryGirl.skip_create
end
def initialize_with(&block)
FactoryGirl.initialize_with(&block)
end
def self.run(block)
new.instance_eval(&block)
end

View File

@ -0,0 +1,82 @@
require 'spec_helper'
describe 'global initialize_with' do
before do
define_class('User') do
attr_accessor:name
def initialize(name)
@name = name
end
end
define_class('Post') do
attr_reader :name
def initialize(name)
@name = name
end
end
FactoryGirl.define do
initialize_with { new("initialize_with") }
trait :with_initialize_with do
initialize_with { new("trait initialize_with") }
end
factory :user do
factory :child_user
factory :child_user_with_trait do
with_initialize_with
end
end
factory :post do
factory :child_post
factory :child_post_with_trait do
with_initialize_with
end
end
end
end
it 'handles base initialize_with' do
FactoryGirl.build(:user).name.should == 'initialize_with'
FactoryGirl.build(:post).name.should == 'initialize_with'
end
it 'handles child initialize_with' do
FactoryGirl.build(:child_user).name.should == 'initialize_with'
FactoryGirl.build(:child_post).name.should == 'initialize_with'
end
it 'handles child initialize_with with trait' do
FactoryGirl.build(:child_user_with_trait).name.should == 'trait initialize_with'
FactoryGirl.build(:child_post_with_trait).name.should == 'trait initialize_with'
end
it 'handles inline trait override' do
FactoryGirl.build(:child_user, :with_initialize_with).name.should == 'trait initialize_with'
FactoryGirl.build(:child_post, :with_initialize_with).name.should == 'trait initialize_with'
end
it 'uses initialize_with globally across FactoryGirl.define' do
define_class('Company') do
attr_reader :name
def initialize(name)
@name = name
end
end
FactoryGirl.define do
factory :company
end
FactoryGirl.build(:company).name.should == 'initialize_with'
FactoryGirl.build(:company, :with_initialize_with).name.should == 'trait initialize_with'
end
end