1
0
Fork 0
mirror of https://github.com/thoughtbot/factory_bot.git synced 2022-11-09 11:43:51 -05:00

Fix factory definitions so parents can be defined AFTER child factories

This commit is contained in:
Joshua Clayton 2011-09-23 17:57:20 -04:00
parent da3af82510
commit e28bdb8e63
5 changed files with 39 additions and 25 deletions

View file

@ -58,15 +58,6 @@ module FactoryGirl
@attribute_list.overridable? @attribute_list.overridable?
end end
def inherit_factory(parent) #:nodoc:
@class_name ||= parent.class_name
@default_strategy ||= parent.default_strategy
@parent_factory = parent
allow_overrides if parent.allow_overrides?
parent.add_child(self)
end
def add_child(factory) def add_child(factory)
@children << factory unless @children.include?(factory) @children << factory unless @children.include?(factory)
end end
@ -92,6 +83,7 @@ module FactoryGirl
end end
def run(proxy_class, overrides) #:nodoc: def run(proxy_class, overrides) #:nodoc:
ensure_compiled
proxy = proxy_class.new(build_class) proxy = proxy_class.new(build_class)
callbacks.each { |callback| proxy.add_callback(callback) } callbacks.each { |callback| proxy.add_callback(callback) }
overrides = overrides.symbolize_keys overrides = overrides.symbolize_keys
@ -164,13 +156,14 @@ module FactoryGirl
end end
def compile def compile
inherit_factory(FactoryGirl.factory_by_name(@parent)) if @parent
declarations.each do |declaration| declarations.each do |declaration|
declaration.to_attributes.each do |attribute| declaration.to_attributes.each do |attribute|
define_attribute(attribute) define_attribute(attribute)
end end
end end
update_children if allow_overrides?
@compiled = true @compiled = true
end end
@ -178,16 +171,26 @@ module FactoryGirl
@attribute_list.declare_attribute(declaration) @attribute_list.declare_attribute(declaration)
end end
def ensure_compiled
compile unless @compiled
end
def inherit_factory(parent) #:nodoc:
parent.ensure_compiled
@class_name ||= parent.class_name
@default_strategy ||= parent.default_strategy
@parent_factory = parent
allow_overrides if parent.allow_overrides?
parent.add_child(self)
end
private private
def declarations def declarations
@attribute_list.declarations @attribute_list.declarations
end end
def update_children
@children.each { |child| child.inherit_factory(self) }
end
def define_attribute(attribute) def define_attribute(attribute)
if attribute.respond_to?(:factory) && attribute.factory == self.name if attribute.respond_to?(:factory) && attribute.factory == self.name
raise AssociationDefinitionError, "Self-referencing association '#{attribute.name}' in factory '#{self.name}'" raise AssociationDefinitionError, "Self-referencing association '#{attribute.name}' in factory '#{self.name}'"
@ -215,9 +218,5 @@ module FactoryGirl
def trait_for(name) def trait_for(name)
@defined_traits.detect {|trait| trait.name == name } @defined_traits.detect {|trait| trait.name == name }
end end
def ensure_compiled
compile unless @compiled
end
end end
end end

View file

@ -21,10 +21,6 @@ module FactoryGirl
proxy = FactoryGirl::DefinitionProxy.new(factory) proxy = FactoryGirl::DefinitionProxy.new(factory)
proxy.instance_eval(&block) if block_given? proxy.instance_eval(&block) if block_given?
if parent = options.delete(:parent)
factory.inherit_factory(FactoryGirl.factory_by_name(parent))
end
FactoryGirl.register_factory(factory) FactoryGirl.register_factory(factory)
proxy.child_factories.each do |(child_name, child_options, child_block)| proxy.child_factories.each do |(child_name, child_options, child_block)|

View file

@ -28,9 +28,6 @@ module FactoryGirl
factory = FactoryGirl::Factory.new(name, options) factory = FactoryGirl::Factory.new(name, options)
proxy = FactoryGirl::DefinitionProxy.new(factory) proxy = FactoryGirl::DefinitionProxy.new(factory)
yield(proxy) yield(proxy)
if parent = options.delete(:parent)
factory.inherit_factory(FactoryGirl.factory_by_name(parent))
end
FactoryGirl.register_factory(factory) FactoryGirl.register_factory(factory)
end end

View file

@ -0,0 +1,21 @@
require "spec_helper"
describe "defining a child factory before a parent" do
before do
define_model("User", :name => :string, :admin => :boolean, :email => :string, :upper_email => :string, :login => :string)
FactoryGirl.define do
factory :admin, :parent => :user do
admin true
end
factory :user do
name "awesome"
end
end
end
it "creates admin factories correctly" do
FactoryGirl.create(:admin).should be_admin
end
end

View file

@ -50,6 +50,7 @@ describe Factory, "referencing a nonexistent factory as a parent" do
it "should raise an ArgumentError when trying to use a non-existent factory as parent" do it "should raise an ArgumentError when trying to use a non-existent factory as parent" do
lambda { lambda {
Factory.define(:child, :parent => :nonexsitent) {} Factory.define(:child, :parent => :nonexsitent) {}
Factory.build(:child)
}.should raise_error(ArgumentError) }.should raise_error(ArgumentError)
end end
end end