Skip to content

Commit

Permalink
Proxies are always instantiated with callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuaclayton committed Oct 20, 2011
1 parent 369b4b9 commit 8f4e052
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 81 deletions.
9 changes: 1 addition & 8 deletions lib/factory_girl/factory.rb
Expand Up @@ -203,7 +203,6 @@ def initialize(options = {})
def run(overrides = {})
@overrides = overrides.symbolize_keys

apply_callbacks
apply_attributes
apply_remaining_overrides

Expand All @@ -212,12 +211,6 @@ def run(overrides = {})

private

def apply_callbacks
@callbacks.each do |callback|
proxy.add_callback(callback)
end
end

def apply_attributes
@attributes.each do |attribute|
if overrides_for_attribute(attribute).any?
Expand Down Expand Up @@ -253,7 +246,7 @@ def handle_attribute_without_overrides(attribute)
end

def proxy
@proxy ||= @proxy_class.new(@build_class)
@proxy ||= @proxy_class.new(@build_class, @callbacks)
end
end
end
Expand Down
15 changes: 6 additions & 9 deletions lib/factory_girl/proxy.rb
@@ -1,10 +1,12 @@
module FactoryGirl
class Proxy #:nodoc:
def initialize(klass, callbacks = [])
@callbacks = callbacks.inject({}) do |result, callback|
result[callback.name] ||= []
result[callback.name] << callback
result
end

attr_reader :callbacks

def initialize(klass)
@callbacks = {}
@ignored_attributes = {}
end

Expand All @@ -21,11 +23,6 @@ def set_ignored(attribute, value)
def associate(name, factory, attributes)
end

def add_callback(callback)
@callbacks[callback.name] ||= []
@callbacks[callback.name] << callback
end

def run_callbacks(name)
if @callbacks[name]
@callbacks[name].each do |callback|
Expand Down
4 changes: 2 additions & 2 deletions lib/factory_girl/proxy/attributes_for.rb
@@ -1,8 +1,8 @@
module FactoryGirl
class Proxy #:nodoc:
class AttributesFor < Proxy #:nodoc:
def initialize(klass)
super(klass)
def initialize(klass, callbacks = [])
super
@hash = {}
@ignored_attributes = {}
end
Expand Down
4 changes: 2 additions & 2 deletions lib/factory_girl/proxy/build.rb
@@ -1,8 +1,8 @@
module FactoryGirl
class Proxy #:nodoc:
class Build < Proxy #:nodoc:
def initialize(klass)
super(klass)
def initialize(klass, callbacks = [])
super
@instance = klass.new
end

Expand Down
4 changes: 2 additions & 2 deletions lib/factory_girl/proxy/stub.rb
Expand Up @@ -3,8 +3,8 @@ class Proxy
class Stub < Proxy #:nodoc:
@@next_id = 1000

def initialize(klass)
super(klass)
def initialize(klass, callbacks = [])
super
@instance = klass.new
@ignored_attributes = {}
@instance.id = next_id
Expand Down
2 changes: 1 addition & 1 deletion spec/factory_girl/factory_spec.rb
Expand Up @@ -263,7 +263,7 @@

it "creates the right proxy using the build class when running" do
subject.run(FactoryGirl::Proxy::Build, {})
FactoryGirl::Proxy::Build.should have_received(:new).with(subject.build_class)
FactoryGirl::Proxy::Build.should have_received(:new).with(subject.build_class, [])
end

it "adds the attribute to the proxy when running" do
Expand Down
25 changes: 14 additions & 11 deletions spec/factory_girl/proxy/create_spec.rb
@@ -1,7 +1,6 @@
require 'spec_helper'

describe FactoryGirl::Proxy::Create do

let(:instance) { stub("created-instance", :save! => true) }
let(:proxy_class) { stub("class", :new => instance) }

Expand All @@ -24,17 +23,21 @@
instance.should have_received(:save!).never
end

context "callback execution order" do
it "runs after_build callbacks before after_create callbacks" do
ran = []
after_create = FactoryGirl::Callback.new(:after_create, lambda { ran << :after_create })
after_build = FactoryGirl::Callback.new(:after_build, lambda { ran << :after_build })
subject.add_callback(after_create)
subject.add_callback(after_build)
end

describe FactoryGirl::Proxy::Create, "when running callbacks" do
let(:instance) { stub("created-instance", :save! => true) }
let(:proxy_class) { stub("class", :new => instance) }
let!(:callback_result) { [] }

subject.result(nil)
let(:after_create_one) { FactoryGirl::Callback.new(:after_create, lambda { callback_result << :after_create_one }) }
let(:after_create_two) { FactoryGirl::Callback.new(:after_create, lambda { callback_result << :after_create_two }) }
let(:after_build_one) { FactoryGirl::Callback.new(:after_build, lambda { callback_result << :after_build_one }) }

ran.should == [:after_build, :after_create]
end
subject { FactoryGirl::Proxy::Create.new(proxy_class, [after_create_one, after_create_two, after_build_one]) }

it "runs callbacks in the correct order" do
subject.result(nil)
callback_result.should == [:after_build_one, :after_create_one, :after_create_two]
end
end
55 changes: 14 additions & 41 deletions spec/factory_girl/proxy_spec.rb
Expand Up @@ -21,51 +21,24 @@
it "raises an error when asking for the result" do
expect { subject.result(nil) }.to raise_error(NotImplementedError)
end
end

describe "when adding callbacks" do
it "adds a callback" do
callback = FactoryGirl::Callback.new(:after_create, lambda {})
subject.add_callback(callback)
subject.callbacks[:after_create].should == [callback]
end
describe FactoryGirl::Proxy, "when running callbacks" do
let!(:callback_result) { [] }

it "adds multiple callbacks of the same name" do
one = FactoryGirl::Callback.new(:after_create, lambda {})
two = FactoryGirl::Callback.new(:after_create, lambda {})
subject.add_callback(one)
subject.add_callback(two)
subject.callbacks[:after_create].should == [one, two]
end
let(:after_create_one) { FactoryGirl::Callback.new(:after_create, lambda { callback_result << :after_create_one }) }
let(:after_create_two) { FactoryGirl::Callback.new(:after_create, lambda { callback_result << :after_create_two }) }
let(:after_build_one) { FactoryGirl::Callback.new(:after_build, lambda { callback_result << :after_build_one }) }

it "adds multiple callbacks with different names" do
after_create = FactoryGirl::Callback.new(:after_create, lambda {})
after_build = FactoryGirl::Callback.new(:after_build, lambda {})
subject.add_callback(after_create)
subject.add_callback(after_build)
subject.callbacks[:after_create].should == [after_create]
subject.callbacks[:after_build].should == [after_build]
end
end
subject { FactoryGirl::Proxy.new(Class.new, [after_create_one, after_create_two, after_build_one]) }

describe "when running callbacks" do
it "runs all callbacks with a given name" do
ran = []
one = FactoryGirl::Callback.new(:after_create, lambda { ran << :one })
two = FactoryGirl::Callback.new(:after_create, lambda { ran << :two })
subject.add_callback(one)
subject.add_callback(two)
subject.run_callbacks(:after_create)
ran.should == [:one, :two]
end
it "runs callbacks in the correct order" do
subject.run_callbacks(:after_create)
callback_result.should == [:after_create_one, :after_create_two]
end

it "only runs callbacks with a given name" do
ran = []
after_create = FactoryGirl::Callback.new(:after_create, lambda { ran << :after_create })
after_build = FactoryGirl::Callback.new(:after_build, lambda { ran << :after_build })
subject.add_callback(after_create)
subject.add_callback(after_build)
subject.run_callbacks(:after_create)
ran.should == [:after_create]
end
it "runs the correct callbacks based on name" do
subject.run_callbacks(:after_build)
callback_result.should == [:after_build_one]
end
end
9 changes: 4 additions & 5 deletions spec/support/shared_examples/proxy.rb
Expand Up @@ -111,15 +111,14 @@
end

shared_examples_for "proxy with callbacks" do |callback_name|
let(:callback) { stub("#{callback_name} callback", :foo => nil) }
let(:callback_instance) { stub("#{callback_name} callback", :foo => nil) }
let(:callback) { FactoryGirl::Callback.new(callback_name, proc { callback_instance.foo }) }

before do
subject.add_callback(FactoryGirl::Callback.new(callback_name, proc { callback.foo }))
end
subject { described_class.new(proxy_class, [callback]) }

it "runs the #{callback_name} callback" do
subject.result(nil)
callback.should have_received(:foo).once
callback_instance.should have_received(:foo).once
end

it "returns the proxy instance" do
Expand Down

0 comments on commit 8f4e052

Please sign in to comment.