mirror of
https://github.com/thoughtbot/factory_bot.git
synced 2022-11-09 11:43:51 -05:00
Use objects, not structs
This commit is contained in:
parent
ede051f81f
commit
0f87ca3aa9
13 changed files with 78 additions and 68 deletions
|
@ -18,8 +18,8 @@ module FactoryGirl
|
|||
add_attribute attribute
|
||||
end
|
||||
|
||||
def add_callback(name, &block)
|
||||
@callbacks << Callback.new(name.to_sym, block)
|
||||
def add_callback(callback)
|
||||
@callbacks << callback
|
||||
end
|
||||
|
||||
def each(&block)
|
||||
|
@ -31,7 +31,7 @@ module FactoryGirl
|
|||
end
|
||||
|
||||
def apply_attributes(attributes_to_apply)
|
||||
attributes_to_apply.callbacks.each { |callback| add_callback(callback.name, &callback.block) }
|
||||
attributes_to_apply.callbacks.each { |callback| add_callback(callback) }
|
||||
new_attributes = []
|
||||
|
||||
attributes_to_apply.each do |attribute|
|
||||
|
|
|
@ -10,6 +10,14 @@ module FactoryGirl
|
|||
check_name
|
||||
end
|
||||
|
||||
def run(instance, proxy)
|
||||
case block.arity
|
||||
when 1 then block.call(instance)
|
||||
when 2 then block.call(instance, proxy)
|
||||
else block.call
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_name
|
||||
|
|
|
@ -90,7 +90,7 @@ module FactoryGirl
|
|||
end
|
||||
|
||||
def add_callback(name, &block)
|
||||
@attribute_list.add_callback(name, &block)
|
||||
@attribute_list.add_callback(Callback.new(name, block))
|
||||
end
|
||||
|
||||
def attributes
|
||||
|
@ -102,7 +102,7 @@ module FactoryGirl
|
|||
|
||||
def run(proxy_class, overrides) #:nodoc:
|
||||
proxy = proxy_class.new(build_class)
|
||||
callbacks.each { |callback| proxy.add_callback(callback.name, callback.block) }
|
||||
callbacks.each { |callback| proxy.add_callback(callback) }
|
||||
overrides = symbolize_keys(overrides)
|
||||
|
||||
attributes.each do |attribute|
|
||||
|
|
|
@ -4,6 +4,7 @@ module FactoryGirl
|
|||
attr_reader :callbacks
|
||||
|
||||
def initialize(klass)
|
||||
@callbacks = {}
|
||||
end
|
||||
|
||||
def get(attribute)
|
||||
|
@ -15,20 +16,15 @@ module FactoryGirl
|
|||
def associate(name, factory, attributes)
|
||||
end
|
||||
|
||||
def add_callback(name, block)
|
||||
@callbacks ||= {}
|
||||
@callbacks[name] ||= []
|
||||
@callbacks[name] << block
|
||||
def add_callback(callback)
|
||||
@callbacks[callback.name] ||= []
|
||||
@callbacks[callback.name] << callback
|
||||
end
|
||||
|
||||
def run_callbacks(name)
|
||||
if @callbacks && @callbacks[name]
|
||||
@callbacks[name].each do |block|
|
||||
case block.arity
|
||||
when 0 then block.call
|
||||
when 2 then block.call(@instance, self)
|
||||
else block.call(@instance)
|
||||
end
|
||||
if @callbacks[name]
|
||||
@callbacks[name].each do |callback|
|
||||
callback.run(@instance, self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@ module FactoryGirl
|
|||
class Proxy #:nodoc:
|
||||
class AttributesFor < Proxy #:nodoc:
|
||||
def initialize(klass)
|
||||
super(klass)
|
||||
@hash = {}
|
||||
@ignored_attributes = {}
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@ module FactoryGirl
|
|||
class Proxy #:nodoc:
|
||||
class Build < Proxy #:nodoc:
|
||||
def initialize(klass)
|
||||
super(klass)
|
||||
@instance = klass.new
|
||||
@ignored_attributes = {}
|
||||
end
|
||||
|
|
|
@ -4,6 +4,7 @@ module FactoryGirl
|
|||
@@next_id = 1000
|
||||
|
||||
def initialize(klass)
|
||||
super(klass)
|
||||
@instance = klass.new
|
||||
@ignored_attributes = {}
|
||||
@instance.id = next_id
|
||||
|
|
|
@ -15,7 +15,7 @@ module FactoryGirl
|
|||
end
|
||||
|
||||
def add_callback(name, &block)
|
||||
@attribute_list.add_callback(name, &block)
|
||||
@attribute_list.add_callback(Callback.new(name, block))
|
||||
end
|
||||
|
||||
def attributes
|
||||
|
|
|
@ -65,10 +65,10 @@ describe FactoryGirl::AttributeList, "#add_callback" do
|
|||
let(:proxy) { FactoryGirl::Proxy.new(proxy_class) }
|
||||
|
||||
it "allows for defining adding a callback" do
|
||||
subject.add_callback(:after_create) { "Called after_create" }
|
||||
subject.add_callback(FactoryGirl::Callback.new(:after_create, lambda { "Called after_create" }))
|
||||
|
||||
subject.callbacks.first.name.should == :after_create
|
||||
subject.callbacks.first.block.call.should == "Called after_create"
|
||||
subject.callbacks.first.run(nil, nil).should == "Called after_create"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -9,6 +9,24 @@ describe FactoryGirl::Callback do
|
|||
FactoryGirl::Callback.new("after_create", lambda {}).name.should == :after_create
|
||||
end
|
||||
|
||||
it "runs its block with no parameters" do
|
||||
ran_with = nil
|
||||
FactoryGirl::Callback.new(:after_create, lambda { ran_with = [] }).run(:one, :two)
|
||||
ran_with.should == []
|
||||
end
|
||||
|
||||
it "runs its block with one parameter" do
|
||||
ran_with = nil
|
||||
FactoryGirl::Callback.new(:after_create, lambda { |one| ran_with = [one] }).run(:one, :two)
|
||||
ran_with.should == [:one]
|
||||
end
|
||||
|
||||
it "runs its block with two parameters" do
|
||||
ran_with = nil
|
||||
FactoryGirl::Callback.new(:after_create, lambda { |one, two| ran_with = [one, two] }).run(:one, :two)
|
||||
ran_with.should == [:one, :two]
|
||||
end
|
||||
|
||||
it "allows valid callback names to be assigned" do
|
||||
FactoryGirl::Callback::VALID_NAMES.each do |callback_name|
|
||||
expect { FactoryGirl::Callback.new(callback_name, lambda {}) }.
|
||||
|
|
|
@ -25,18 +25,16 @@ describe FactoryGirl::Proxy::Create do
|
|||
end
|
||||
|
||||
context "callback execution order" do
|
||||
let(:after_build_callback) { stub("after_build callback", :foo => nil) }
|
||||
let(:after_create_callback) { stub("after_create callback", :foo => nil) }
|
||||
let(:callback_sequence) { sequence("after_* callbacks") }
|
||||
|
||||
it "runs after_build callbacks before after_create callbacks" do
|
||||
subject.add_callback(:after_build, proc { after_build_callback.foo })
|
||||
subject.add_callback(:after_create, proc { after_create_callback.foo })
|
||||
|
||||
after_build_callback.expects(:foo).once.in_sequence(callback_sequence)
|
||||
after_create_callback.expects(:foo).once.in_sequence(callback_sequence)
|
||||
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.result(nil)
|
||||
|
||||
ran.should == [:after_build, :after_create]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,62 +23,49 @@ describe FactoryGirl::Proxy do
|
|||
end
|
||||
|
||||
describe "when adding callbacks" do
|
||||
let(:block_1) { proc { "block 1" } }
|
||||
let(:block_2) { proc { "block 2" } }
|
||||
|
||||
it "adds a callback" do
|
||||
subject.add_callback(:after_create, block_1)
|
||||
subject.callbacks[:after_create].should be_eql([block_1])
|
||||
callback = FactoryGirl::Callback.new(:after_create, lambda {})
|
||||
subject.add_callback(callback)
|
||||
subject.callbacks[:after_create].should == [callback]
|
||||
end
|
||||
|
||||
it "adds multiple callbacks of the same name" do
|
||||
subject.add_callback(:after_create, block_1)
|
||||
subject.add_callback(:after_create, block_2)
|
||||
subject.callbacks[:after_create].should be_eql([block_1, block_2])
|
||||
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
|
||||
|
||||
it "adds multiple callbacks with different names" do
|
||||
subject.add_callback(:after_create, block_1)
|
||||
subject.add_callback(:after_build, block_2)
|
||||
subject.callbacks[:after_create].should be_eql([block_1])
|
||||
subject.callbacks[:after_build].should be_eql([block_2])
|
||||
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
|
||||
|
||||
describe "when running callbacks" do
|
||||
let(:object_1_within_callback) { stub("call_in_create", :foo => true) }
|
||||
let(:object_2_within_callback) { stub("call_in_create", :foo => true) }
|
||||
|
||||
it "runs all callbacks with a given name" do
|
||||
subject.add_callback(:after_create, proc { object_1_within_callback.foo })
|
||||
subject.add_callback(:after_create, proc { object_2_within_callback.foo })
|
||||
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)
|
||||
object_1_within_callback.should have_received(:foo).once
|
||||
object_2_within_callback.should have_received(:foo).once
|
||||
ran.should == [:one, :two]
|
||||
end
|
||||
|
||||
it "only runs callbacks with a given name" do
|
||||
subject.add_callback(:after_create, proc { object_1_within_callback.foo })
|
||||
subject.add_callback(:after_build, proc { object_2_within_callback.foo })
|
||||
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)
|
||||
object_1_within_callback.should have_received(:foo).once
|
||||
object_2_within_callback.should have_received(:foo).never
|
||||
end
|
||||
|
||||
it "passes in the instance if the block takes an argument" do
|
||||
subject.instance_variable_set("@instance", object_1_within_callback)
|
||||
subject.add_callback(:after_create, proc {|spy| spy.foo })
|
||||
subject.run_callbacks(:after_create)
|
||||
object_1_within_callback.should have_received(:foo).once
|
||||
end
|
||||
|
||||
it "passes in the instance and the proxy if the block takes two arguments" do
|
||||
subject.instance_variable_set("@instance", object_1_within_callback)
|
||||
proxy_instance = nil
|
||||
subject.add_callback(:after_create, proc {|spy, proxy| spy.foo; proxy_instance = proxy })
|
||||
subject.run_callbacks(:after_create)
|
||||
object_1_within_callback.should have_received(:foo).once
|
||||
proxy_instance.should == subject
|
||||
ran.should == [:after_create]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -114,7 +114,7 @@ shared_examples_for "proxy with callbacks" do |callback_name|
|
|||
let(:callback) { stub("#{callback_name} callback", :foo => nil) }
|
||||
|
||||
before do
|
||||
subject.add_callback(callback_name, proc { callback.foo })
|
||||
subject.add_callback(FactoryGirl::Callback.new(callback_name, proc { callback.foo }))
|
||||
end
|
||||
|
||||
it "runs the #{callback_name} callback" do
|
||||
|
|
Loading…
Reference in a new issue