Support binding a block to multiple callbacks

This allows for binding multiple callbacks (after_stub, before_create,
etc.) to a single block. This is useful if you want a block to be called
across all build strategies (since build_stubbed doesn't share any
callbacks with build/create).

Examples:

    factory :user do
      callback(:after_stub, :before_create) { do_something }
      after(:stub, :create) { do_something_else }
      before(:create, :custom) { do_a_third_thing }
    end
This commit is contained in:
Joshua Clayton 2012-09-11 11:08:44 -04:00
parent 4bc2bb1d92
commit f92195f35a
4 changed files with 63 additions and 7 deletions

View File

@ -714,6 +714,16 @@ Calling FactoryGirl.create will invoke both `after_build` and `after_create` cal
Also, like standard attributes, child factories will inherit (and can also define) callbacks from their parent factory.
Multiple callbacks can be assigned to run a block; this is useful when building various strategies that run the same code (since there are no callbacks that are shared across all strategies).
```ruby
factory :user do
callback(:after_stub, :before_create) { do_something }
after(:stub, :create) { do_something_else }
before(:create, :custom) { do_a_third_thing }
end
```
Modifying factories
-------------------

View File

@ -158,17 +158,19 @@ module FactoryGirl
@definition.define_constructor(&block)
end
def before(name, &block)
callback("before_#{name}", &block)
def before(*names, &block)
callback(*names.map {|name| "before_#{name}" }, &block)
end
def after(name, &block)
callback("after_#{name}", &block)
def after(*names, &block)
callback(*names.map {|name| "after_#{name}" }, &block)
end
def callback(name, &block)
FactoryGirl.register_callback(name)
@definition.add_callback(Callback.new(name, block))
def callback(*names, &block)
names.each do |name|
FactoryGirl.register_callback(name)
@definition.add_callback(Callback.new(name, block))
end
end
end
end

View File

@ -149,3 +149,29 @@ describe "custom callbacks" do
FactoryGirl.totally_custom(:user).name.should == "Totally Custom"
end
end
describe 'binding a callback to multiple callbacks' do
before do
define_model('User', name: :string)
FactoryGirl.define do
factory :user do
callback(:before_create, :after_stub) do |instance|
instance.name = instance.name.upcase
end
end
end
end
it 'binds the callback to creation' do
FactoryGirl.create(:user, name: 'John Doe').name.should == 'JOHN DOE'
end
it 'does not bind the callback to building' do
FactoryGirl.build(:user, name: 'John Doe').name.should == 'John Doe'
end
it 'binds the callback to stubbing' do
FactoryGirl.build_stubbed(:user, name: 'John Doe').name.should == 'JOHN DOE'
end
end

View File

@ -140,6 +140,24 @@ describe FactoryGirl::DefinitionProxy, "adding callbacks" do
before { proxy.after(:stub, &callback) }
it { should have_callback(:after_stub).with_block(callback) }
end
context "#after(:stub, :create)" do
before { proxy.after(:stub, :create, &callback) }
it { should have_callback(:after_stub).with_block(callback) }
it { should have_callback(:after_create).with_block(callback) }
end
context "#before(:stub, :create)" do
before { proxy.before(:stub, :create, &callback) }
it { should have_callback(:before_stub).with_block(callback) }
it { should have_callback(:before_create).with_block(callback) }
end
context "#callback(:after_stub, :before_create)" do
before { proxy.callback(:after_stub, :before_create, &callback) }
it { should have_callback(:after_stub).with_block(callback) }
it { should have_callback(:before_create).with_block(callback) }
end
end
describe FactoryGirl::DefinitionProxy, "#to_create" do