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/static'
|
||||||
require 'factory_girl/attribute/dynamic'
|
require 'factory_girl/attribute/dynamic'
|
||||||
require 'factory_girl/attribute/association'
|
require 'factory_girl/attribute/association'
|
||||||
require 'factory_girl/attribute/callback'
|
|
||||||
require 'factory_girl/attribute/sequence'
|
require 'factory_girl/attribute/sequence'
|
||||||
require 'factory_girl/attribute/implicit'
|
require 'factory_girl/attribute/implicit'
|
||||||
require 'factory_girl/attribute/trait'
|
require 'factory_girl/attribute/trait'
|
||||||
|
require 'factory_girl/callback'
|
||||||
require 'factory_girl/sequence'
|
require 'factory_girl/sequence'
|
||||||
require 'factory_girl/attribute_list'
|
require 'factory_girl/attribute_list'
|
||||||
require 'factory_girl/trait'
|
require 'factory_girl/trait'
|
||||||
|
|
|
@ -29,10 +29,6 @@ module FactoryGirl
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def callback?
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def priority
|
def priority
|
||||||
1
|
1
|
||||||
end
|
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
|
class AttributeList
|
||||||
include Enumerable
|
include Enumerable
|
||||||
|
|
||||||
|
attr_reader :callbacks
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@attributes = {}
|
@attributes = {}
|
||||||
@overridable = false
|
@overridable = false
|
||||||
|
@callbacks = []
|
||||||
end
|
end
|
||||||
|
|
||||||
def define_attribute(attribute)
|
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}"
|
raise InvalidCallbackNameError, "#{name} is not a valid callback name. Valid callback names are #{valid_callback_names.inspect}"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_attribute Attribute::Callback.new(name.to_sym, block)
|
@callbacks << Callback.new(name.to_sym, block)
|
||||||
end
|
end
|
||||||
|
|
||||||
def each(&block)
|
def each(&block)
|
||||||
|
@ -32,6 +35,7 @@ module FactoryGirl
|
||||||
end
|
end
|
||||||
|
|
||||||
def apply_attributes(attributes_to_apply)
|
def apply_attributes(attributes_to_apply)
|
||||||
|
attributes_to_apply.callbacks.each { |callback| add_callback(callback.name, &callback.block) }
|
||||||
new_attributes = []
|
new_attributes = []
|
||||||
|
|
||||||
attributes_to_apply.each do |attribute|
|
attributes_to_apply.each do |attribute|
|
||||||
|
@ -56,6 +60,10 @@ module FactoryGirl
|
||||||
@overridable
|
@overridable
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def size
|
||||||
|
to_a.size
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def valid_callback_names
|
def valid_callback_names
|
||||||
|
@ -85,7 +93,7 @@ module FactoryGirl
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_attribute(attribute_name)
|
def find_attribute(attribute_name)
|
||||||
@attributes.values.flatten.reject(&:callback?).detect do |attribute|
|
@attributes.values.flatten.detect do |attribute|
|
||||||
attribute.name == attribute_name
|
attribute.name == attribute_name
|
||||||
end
|
end
|
||||||
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|
|
AttributeList.new.tap do |list|
|
||||||
list.apply_attributes(@attribute_list)
|
list.apply_attributes(@attribute_list)
|
||||||
list.apply_attributes(@inherited_attribute_list)
|
list.apply_attributes(@inherited_attribute_list)
|
||||||
end.to_a
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(proxy_class, overrides) #:nodoc:
|
def run(proxy_class, overrides) #:nodoc:
|
||||||
proxy = proxy_class.new(build_class)
|
proxy = proxy_class.new(build_class)
|
||||||
|
callbacks.each { |callback| proxy.add_callback(callback.name, callback.block) }
|
||||||
overrides = symbolize_keys(overrides)
|
overrides = symbolize_keys(overrides)
|
||||||
|
|
||||||
attributes.each do |attribute|
|
attributes.each do |attribute|
|
||||||
|
@ -167,6 +168,10 @@ module FactoryGirl
|
||||||
@to_create_block = block
|
@to_create_block = block
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def callbacks
|
||||||
|
attributes.callbacks
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def update_children
|
def update_children
|
||||||
|
|
|
@ -19,7 +19,7 @@ module FactoryGirl
|
||||||
end
|
end
|
||||||
|
|
||||||
def attributes
|
def attributes
|
||||||
@attribute_list.to_a
|
@attribute_list
|
||||||
end
|
end
|
||||||
|
|
||||||
def names
|
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
|
describe FactoryGirl::AttributeList, "#attribute_defined?" do
|
||||||
let(:static_attribute) { FactoryGirl::Attribute::Static.new(:full_name, "value") }
|
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!") }
|
let(:static_attribute_named_after_create) { FactoryGirl::Attribute::Static.new(:after_create, "funky!") }
|
||||||
|
|
||||||
it "knows if an attribute has been defined" do
|
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?(static_attribute.name).should == true
|
||||||
subject.attribute_defined?(:undefined_attribute).should == false
|
subject.attribute_defined?(:undefined_attribute).should == false
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
describe FactoryGirl::AttributeList, "#add_callback" do
|
describe FactoryGirl::AttributeList, "#add_callback" do
|
||||||
|
@ -78,14 +69,8 @@ describe FactoryGirl::AttributeList, "#add_callback" do
|
||||||
it "allows for defining adding a callback" do
|
it "allows for defining adding a callback" do
|
||||||
subject.add_callback(:after_create) { "Called after_create" }
|
subject.add_callback(:after_create) { "Called after_create" }
|
||||||
|
|
||||||
subject.first.name.should == :after_create
|
subject.callbacks.first.name.should == :after_create
|
||||||
|
subject.callbacks.first.block.call.should == "Called 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)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows valid callback names to be assigned" do
|
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(: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}" }) }
|
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
|
it "prepends applied attributes" do
|
||||||
subject.define_attribute(full_name_attribute)
|
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]
|
subject.to_a.should == [city_attribute, full_name_attribute]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "moves non-static attributes to the end of the list" do
|
it "moves non-static attributes to the end of the list" do
|
||||||
subject.define_attribute(full_name_attribute)
|
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]
|
subject.to_a.should == [city_attribute, full_name_attribute, email_attribute]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "maintains order of non-static attributes" do
|
it "maintains order of non-static attributes" do
|
||||||
subject.define_attribute(full_name_attribute)
|
subject.define_attribute(full_name_attribute)
|
||||||
subject.define_attribute(login_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]
|
subject.to_a.should == [city_attribute, full_name_attribute, email_attribute, login_attribute]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -134,7 +125,7 @@ describe FactoryGirl::AttributeList, "#apply_attributes" do
|
||||||
subject.define_attribute(full_name_attribute)
|
subject.define_attribute(full_name_attribute)
|
||||||
attribute_with_same_name = FactoryGirl::Attribute::Static.new(:full_name, "Benjamin Franklin")
|
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]
|
subject.to_a.should == [full_name_attribute]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -143,20 +134,20 @@ describe FactoryGirl::AttributeList, "#apply_attributes" do
|
||||||
|
|
||||||
it "prepends applied attributes" do
|
it "prepends applied attributes" do
|
||||||
subject.define_attribute(full_name_attribute)
|
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]
|
subject.to_a.should == [city_attribute, full_name_attribute]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "moves non-static attributes to the end of the list" do
|
it "moves non-static attributes to the end of the list" do
|
||||||
subject.define_attribute(full_name_attribute)
|
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]
|
subject.to_a.should == [city_attribute, full_name_attribute, email_attribute]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "maintains order of non-static attributes" do
|
it "maintains order of non-static attributes" do
|
||||||
subject.define_attribute(full_name_attribute)
|
subject.define_attribute(full_name_attribute)
|
||||||
subject.define_attribute(login_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]
|
subject.to_a.should == [city_attribute, full_name_attribute, email_attribute, login_attribute]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -164,7 +155,7 @@ describe FactoryGirl::AttributeList, "#apply_attributes" do
|
||||||
subject.define_attribute(full_name_attribute)
|
subject.define_attribute(full_name_attribute)
|
||||||
attribute_with_same_name = FactoryGirl::Attribute::Static.new(:full_name, "Benjamin Franklin")
|
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]
|
subject.to_a.should == [attribute_with_same_name]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,6 @@ describe FactoryGirl::Attribute do
|
||||||
|
|
||||||
its(:name) { should == name.to_sym }
|
its(:name) { should == name.to_sym }
|
||||||
it { should_not be_association }
|
it { should_not be_association }
|
||||||
it { should_not be_callback }
|
|
||||||
|
|
||||||
it "doesn't set any attributes on a proxy when added" do
|
it "doesn't set any attributes on a proxy when added" do
|
||||||
proxy.stubs(:set)
|
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
|
it "should add a static attribute for type" do
|
||||||
subject.type 'value'
|
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
|
end
|
||||||
|
|
||||||
it "should add a static attribute for id" do
|
it "should add a static attribute for id" do
|
||||||
subject.id 'value'
|
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
|
end
|
||||||
|
|
||||||
it "should add a static attribute when an attribute is defined with a value" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
it "inherit all callbacks" do
|
it "inherits callbacks" do
|
||||||
@factory.add_callback(:after_stub) { |object| object.name = 'Stubby' }
|
@factory.add_callback(:after_stub) { |object| object.name = 'Stubby' }
|
||||||
child = FactoryGirl::Factory.new(:child)
|
child = FactoryGirl::Factory.new(:child)
|
||||||
child.inherit_from(@factory)
|
child.inherit_from(@factory)
|
||||||
child.attributes.last.should be_kind_of(FactoryGirl::Attribute::Callback)
|
child.callbacks.should_not be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -308,17 +308,16 @@ describe FactoryGirl::Factory, "human names" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe FactoryGirl::Factory, "running a factory" do
|
describe FactoryGirl::Factory, "running a factory" do
|
||||||
subject { FactoryGirl::Factory.new(:user) }
|
subject { FactoryGirl::Factory.new(:user) }
|
||||||
let(:attribute) { stub("attribute", :name => :name, :ignored => false, :add_to => nil, :aliases_for? => true) }
|
let(:attribute) { FactoryGirl::Attribute::Static.new(:name, "value") }
|
||||||
let(:attribute_list) { [attribute] }
|
let(:proxy) { stub("proxy", :result => "result", :set => nil) }
|
||||||
let(:proxy) { stub("proxy", :result => "result", :set => nil) }
|
|
||||||
|
|
||||||
before do
|
before do
|
||||||
define_model("User", :name => :string)
|
define_model("User", :name => :string)
|
||||||
FactoryGirl::Attribute::Static.stubs(:new => attribute)
|
FactoryGirl::Attribute::Static.stubs(:new => attribute)
|
||||||
FactoryGirl::Proxy::Build.stubs(:new => proxy)
|
FactoryGirl::Proxy::Build.stubs(:new => proxy)
|
||||||
attribute_list.stubs(:apply_attributes)
|
subject.define_attribute(attribute)
|
||||||
FactoryGirl::AttributeList.stubs(:new => attribute_list)
|
attribute.stubs(:add_to => nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates the right proxy using the build class when running" do
|
it "creates the right proxy using the build class when running" do
|
||||||
|
|
Loading…
Reference in a new issue