1
0
Fork 0
mirror of https://github.com/thoughtbot/factory_bot.git synced 2022-11-09 11:43:51 -05:00

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. 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 Modifying factories
------------------- -------------------

View file

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

View file

@ -149,3 +149,29 @@ describe "custom callbacks" do
FactoryGirl.totally_custom(:user).name.should == "Totally Custom" FactoryGirl.totally_custom(:user).name.should == "Totally Custom"
end end
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) } before { proxy.after(:stub, &callback) }
it { should have_callback(:after_stub).with_block(callback) } it { should have_callback(:after_stub).with_block(callback) }
end 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 end
describe FactoryGirl::DefinitionProxy, "#to_create" do describe FactoryGirl::DefinitionProxy, "#to_create" do