Skip to content

Commit

Permalink
Support binding a block to multiple callbacks
Browse files Browse the repository at this point in the history
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
  • Loading branch information
joshuaclayton committed Sep 11, 2012
1 parent 4bc2bb1 commit f92195f
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 7 deletions.
10 changes: 10 additions & 0 deletions GETTING_STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------------------

Expand Down
16 changes: 9 additions & 7 deletions lib/factory_girl/definition_proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,17 +158,19 @@ def initialize_with(&block)
@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
26 changes: 26 additions & 0 deletions spec/acceptance/callbacks_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,29 @@ def name
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
18 changes: 18 additions & 0 deletions spec/factory_girl/definition_proxy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,24 @@
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
Expand Down

0 comments on commit f92195f

Please sign in to comment.