mirror of
https://github.com/thoughtbot/factory_bot.git
synced 2022-11-09 11:43:51 -05:00
Callbacks aren't attributes
This commit is contained in:
parent
67fc3bc8a9
commit
4d30663a5b
13 changed files with 70 additions and 88 deletions
|
@ -9,10 +9,10 @@ require 'factory_girl/attribute'
|
|||
require 'factory_girl/attribute/static'
|
||||
require 'factory_girl/attribute/dynamic'
|
||||
require 'factory_girl/attribute/association'
|
||||
require 'factory_girl/attribute/callback'
|
||||
require 'factory_girl/attribute/sequence'
|
||||
require 'factory_girl/attribute/implicit'
|
||||
require 'factory_girl/attribute/trait'
|
||||
require 'factory_girl/callback'
|
||||
require 'factory_girl/sequence'
|
||||
require 'factory_girl/attribute_list'
|
||||
require 'factory_girl/trait'
|
||||
|
|
|
@ -29,10 +29,6 @@ module FactoryGirl
|
|||
false
|
||||
end
|
||||
|
||||
def callback?
|
||||
false
|
||||
end
|
||||
|
||||
def priority
|
||||
1
|
||||
end
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
module FactoryGirl
|
||||
class Attribute #:nodoc:
|
||||
class Callback < Attribute #:nodoc:
|
||||
def initialize(name, block)
|
||||
@name = name.to_sym
|
||||
@block = block
|
||||
end
|
||||
|
||||
def add_to(proxy)
|
||||
proxy.add_callback(name, @block)
|
||||
end
|
||||
|
||||
def callback?
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,9 +2,12 @@ module FactoryGirl
|
|||
class AttributeList
|
||||
include Enumerable
|
||||
|
||||
attr_reader :callbacks
|
||||
|
||||
def initialize
|
||||
@attributes = {}
|
||||
@overridable = false
|
||||
@callbacks = []
|
||||
end
|
||||
|
||||
def define_attribute(attribute)
|
||||
|
@ -20,7 +23,7 @@ module FactoryGirl
|
|||
raise InvalidCallbackNameError, "#{name} is not a valid callback name. Valid callback names are #{valid_callback_names.inspect}"
|
||||
end
|
||||
|
||||
add_attribute Attribute::Callback.new(name.to_sym, block)
|
||||
@callbacks << Callback.new(name.to_sym, block)
|
||||
end
|
||||
|
||||
def each(&block)
|
||||
|
@ -32,6 +35,7 @@ module FactoryGirl
|
|||
end
|
||||
|
||||
def apply_attributes(attributes_to_apply)
|
||||
attributes_to_apply.callbacks.each { |callback| add_callback(callback.name, &callback.block) }
|
||||
new_attributes = []
|
||||
|
||||
attributes_to_apply.each do |attribute|
|
||||
|
@ -56,6 +60,10 @@ module FactoryGirl
|
|||
@overridable
|
||||
end
|
||||
|
||||
def size
|
||||
to_a.size
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valid_callback_names
|
||||
|
@ -85,7 +93,7 @@ module FactoryGirl
|
|||
end
|
||||
|
||||
def find_attribute(attribute_name)
|
||||
@attributes.values.flatten.reject(&:callback?).detect do |attribute|
|
||||
@attributes.values.flatten.detect do |attribute|
|
||||
attribute.name == attribute_name
|
||||
end
|
||||
end
|
||||
|
|
10
lib/factory_girl/callback.rb
Normal file
10
lib/factory_girl/callback.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
module FactoryGirl
|
||||
class Callback
|
||||
attr_reader :name, :block
|
||||
|
||||
def initialize(name, block)
|
||||
@name = name.to_sym
|
||||
@block = block
|
||||
end
|
||||
end
|
||||
end
|
|
@ -97,11 +97,12 @@ module FactoryGirl
|
|||
AttributeList.new.tap do |list|
|
||||
list.apply_attributes(@attribute_list)
|
||||
list.apply_attributes(@inherited_attribute_list)
|
||||
end.to_a
|
||||
end
|
||||
end
|
||||
|
||||
def run(proxy_class, overrides) #:nodoc:
|
||||
proxy = proxy_class.new(build_class)
|
||||
callbacks.each { |callback| proxy.add_callback(callback.name, callback.block) }
|
||||
overrides = symbolize_keys(overrides)
|
||||
|
||||
attributes.each do |attribute|
|
||||
|
@ -167,6 +168,10 @@ module FactoryGirl
|
|||
@to_create_block = block
|
||||
end
|
||||
|
||||
def callbacks
|
||||
attributes.callbacks
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_children
|
||||
|
|
|
@ -19,7 +19,7 @@ module FactoryGirl
|
|||
end
|
||||
|
||||
def attributes
|
||||
@attribute_list.to_a
|
||||
@attribute_list
|
||||
end
|
||||
|
||||
def names
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe FactoryGirl::Attribute::Callback do
|
||||
let(:name) { :after_create }
|
||||
let(:block) { proc { "block" } }
|
||||
let(:proxy) { stub("proxy") }
|
||||
|
||||
subject { FactoryGirl::Attribute::Callback.new(name, block) }
|
||||
|
||||
its(:name) { should == name }
|
||||
|
||||
it { should be_callback }
|
||||
|
||||
it "set its callback on a proxy" do
|
||||
proxy.stubs(:add_callback)
|
||||
subject.add_to(proxy)
|
||||
proxy.should have_received(:add_callback).with(name, block)
|
||||
end
|
||||
end
|
||||
|
||||
describe FactoryGirl::Attribute::Callback, "with a string name" do
|
||||
subject { FactoryGirl::Attribute::Callback.new("name", nil) }
|
||||
its(:name) { should == :name }
|
||||
end
|
|
@ -47,7 +47,7 @@ end
|
|||
|
||||
describe FactoryGirl::AttributeList, "#attribute_defined?" do
|
||||
let(:static_attribute) { FactoryGirl::Attribute::Static.new(:full_name, "value") }
|
||||
let(:callback_attribute) { FactoryGirl::Attribute::Callback.new(:after_create, lambda { }) }
|
||||
let(:callback_attribute) { FactoryGirl::Callback.new(:after_create, lambda { }) }
|
||||
let(:static_attribute_named_after_create) { FactoryGirl::Attribute::Static.new(:after_create, "funky!") }
|
||||
|
||||
it "knows if an attribute has been defined" do
|
||||
|
@ -58,15 +58,6 @@ describe FactoryGirl::AttributeList, "#attribute_defined?" do
|
|||
subject.attribute_defined?(static_attribute.name).should == true
|
||||
subject.attribute_defined?(:undefined_attribute).should == false
|
||||
end
|
||||
|
||||
it "doesn't reference callbacks" do
|
||||
subject.define_attribute(callback_attribute)
|
||||
|
||||
subject.attribute_defined?(:after_create).should == false
|
||||
|
||||
subject.define_attribute(static_attribute_named_after_create)
|
||||
subject.attribute_defined?(:after_create).should == true
|
||||
end
|
||||
end
|
||||
|
||||
describe FactoryGirl::AttributeList, "#add_callback" do
|
||||
|
@ -78,14 +69,8 @@ describe FactoryGirl::AttributeList, "#add_callback" do
|
|||
it "allows for defining adding a callback" do
|
||||
subject.add_callback(:after_create) { "Called after_create" }
|
||||
|
||||
subject.first.name.should == :after_create
|
||||
|
||||
subject.first.add_to(proxy)
|
||||
proxy.callbacks[:after_create].first.call.should == "Called after_create"
|
||||
end
|
||||
|
||||
it "returns the callback" do
|
||||
subject.add_callback(:after_create) { "Called after_create" }.should be_a(FactoryGirl::Attribute::Callback)
|
||||
subject.callbacks.first.name.should == :after_create
|
||||
subject.callbacks.first.block.call.should == "Called after_create"
|
||||
end
|
||||
|
||||
it "allows valid callback names to be assigned" do
|
||||
|
@ -111,22 +96,28 @@ describe FactoryGirl::AttributeList, "#apply_attributes" do
|
|||
let(:email_attribute) { FactoryGirl::Attribute::Dynamic.new(:email, lambda {|model| "#{model.full_name}@example.com" }) }
|
||||
let(:login_attribute) { FactoryGirl::Attribute::Dynamic.new(:login, lambda {|model| "username-#{model.full_name}" }) }
|
||||
|
||||
def list(*attributes)
|
||||
FactoryGirl::AttributeList.new.tap do |list|
|
||||
attributes.each { |attribute| list.define_attribute(attribute) }
|
||||
end
|
||||
end
|
||||
|
||||
it "prepends applied attributes" do
|
||||
subject.define_attribute(full_name_attribute)
|
||||
subject.apply_attributes([city_attribute])
|
||||
subject.apply_attributes(list(city_attribute))
|
||||
subject.to_a.should == [city_attribute, full_name_attribute]
|
||||
end
|
||||
|
||||
it "moves non-static attributes to the end of the list" do
|
||||
subject.define_attribute(full_name_attribute)
|
||||
subject.apply_attributes([city_attribute, email_attribute])
|
||||
subject.apply_attributes(list(city_attribute, email_attribute))
|
||||
subject.to_a.should == [city_attribute, full_name_attribute, email_attribute]
|
||||
end
|
||||
|
||||
it "maintains order of non-static attributes" do
|
||||
subject.define_attribute(full_name_attribute)
|
||||
subject.define_attribute(login_attribute)
|
||||
subject.apply_attributes([city_attribute, email_attribute])
|
||||
subject.apply_attributes(list(city_attribute, email_attribute))
|
||||
subject.to_a.should == [city_attribute, full_name_attribute, email_attribute, login_attribute]
|
||||
end
|
||||
|
||||
|
@ -134,7 +125,7 @@ describe FactoryGirl::AttributeList, "#apply_attributes" do
|
|||
subject.define_attribute(full_name_attribute)
|
||||
attribute_with_same_name = FactoryGirl::Attribute::Static.new(:full_name, "Benjamin Franklin")
|
||||
|
||||
subject.apply_attributes([attribute_with_same_name])
|
||||
subject.apply_attributes(list(attribute_with_same_name))
|
||||
subject.to_a.should == [full_name_attribute]
|
||||
end
|
||||
|
||||
|
@ -143,20 +134,20 @@ describe FactoryGirl::AttributeList, "#apply_attributes" do
|
|||
|
||||
it "prepends applied attributes" do
|
||||
subject.define_attribute(full_name_attribute)
|
||||
subject.apply_attributes([city_attribute])
|
||||
subject.apply_attributes(list(city_attribute))
|
||||
subject.to_a.should == [city_attribute, full_name_attribute]
|
||||
end
|
||||
|
||||
it "moves non-static attributes to the end of the list" do
|
||||
subject.define_attribute(full_name_attribute)
|
||||
subject.apply_attributes([city_attribute, email_attribute])
|
||||
subject.apply_attributes(list(city_attribute, email_attribute))
|
||||
subject.to_a.should == [city_attribute, full_name_attribute, email_attribute]
|
||||
end
|
||||
|
||||
it "maintains order of non-static attributes" do
|
||||
subject.define_attribute(full_name_attribute)
|
||||
subject.define_attribute(login_attribute)
|
||||
subject.apply_attributes([city_attribute, email_attribute])
|
||||
subject.apply_attributes(list(city_attribute, email_attribute))
|
||||
subject.to_a.should == [city_attribute, full_name_attribute, email_attribute, login_attribute]
|
||||
end
|
||||
|
||||
|
@ -164,7 +155,7 @@ describe FactoryGirl::AttributeList, "#apply_attributes" do
|
|||
subject.define_attribute(full_name_attribute)
|
||||
attribute_with_same_name = FactoryGirl::Attribute::Static.new(:full_name, "Benjamin Franklin")
|
||||
|
||||
subject.apply_attributes([attribute_with_same_name])
|
||||
subject.apply_attributes(list(attribute_with_same_name))
|
||||
subject.to_a.should == [attribute_with_same_name]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,7 +7,6 @@ describe FactoryGirl::Attribute do
|
|||
|
||||
its(:name) { should == name.to_sym }
|
||||
it { should_not be_association }
|
||||
it { should_not be_callback }
|
||||
|
||||
it "doesn't set any attributes on a proxy when added" do
|
||||
proxy.stubs(:set)
|
||||
|
|
16
spec/factory_girl/callback_spec.rb
Normal file
16
spec/factory_girl/callback_spec.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe FactoryGirl::Callback do
|
||||
let(:name) { :after_create }
|
||||
let(:block) { proc { "block" } }
|
||||
let(:proxy) { stub("proxy") }
|
||||
|
||||
subject { FactoryGirl::Callback.new(name, block) }
|
||||
|
||||
its(:name) { should == name }
|
||||
end
|
||||
|
||||
describe FactoryGirl::Callback, "with a string name" do
|
||||
subject { FactoryGirl::Callback.new("name", nil) }
|
||||
its(:name) { should == :name }
|
||||
end
|
|
@ -6,12 +6,12 @@ describe FactoryGirl::DefinitionProxy do
|
|||
|
||||
it "should add a static attribute for type" do
|
||||
subject.type 'value'
|
||||
factory.attributes.last.should be_kind_of(FactoryGirl::Attribute::Static)
|
||||
factory.attributes.to_a.last.should be_kind_of(FactoryGirl::Attribute::Static)
|
||||
end
|
||||
|
||||
it "should add a static attribute for id" do
|
||||
subject.id 'value'
|
||||
factory.attributes.last.should be_kind_of(FactoryGirl::Attribute::Static)
|
||||
factory.attributes.to_a.last.should be_kind_of(FactoryGirl::Attribute::Static)
|
||||
end
|
||||
|
||||
it "should add a static attribute when an attribute is defined with a value" do
|
||||
|
|
|
@ -159,11 +159,11 @@ describe FactoryGirl::Factory do
|
|||
end
|
||||
end
|
||||
|
||||
it "inherit all callbacks" do
|
||||
it "inherits callbacks" do
|
||||
@factory.add_callback(:after_stub) { |object| object.name = 'Stubby' }
|
||||
child = FactoryGirl::Factory.new(:child)
|
||||
child.inherit_from(@factory)
|
||||
child.attributes.last.should be_kind_of(FactoryGirl::Attribute::Callback)
|
||||
child.callbacks.should_not be_empty
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -308,17 +308,16 @@ describe FactoryGirl::Factory, "human names" do
|
|||
end
|
||||
|
||||
describe FactoryGirl::Factory, "running a factory" do
|
||||
subject { FactoryGirl::Factory.new(:user) }
|
||||
let(:attribute) { stub("attribute", :name => :name, :ignored => false, :add_to => nil, :aliases_for? => true) }
|
||||
let(:attribute_list) { [attribute] }
|
||||
let(:proxy) { stub("proxy", :result => "result", :set => nil) }
|
||||
subject { FactoryGirl::Factory.new(:user) }
|
||||
let(:attribute) { FactoryGirl::Attribute::Static.new(:name, "value") }
|
||||
let(:proxy) { stub("proxy", :result => "result", :set => nil) }
|
||||
|
||||
before do
|
||||
define_model("User", :name => :string)
|
||||
FactoryGirl::Attribute::Static.stubs(:new => attribute)
|
||||
FactoryGirl::Proxy::Build.stubs(:new => proxy)
|
||||
attribute_list.stubs(:apply_attributes)
|
||||
FactoryGirl::AttributeList.stubs(:new => attribute_list)
|
||||
subject.define_attribute(attribute)
|
||||
attribute.stubs(:add_to => nil)
|
||||
end
|
||||
|
||||
it "creates the right proxy using the build class when running" do
|
||||
|
|
Loading…
Reference in a new issue