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:
parent
da3af82510
commit
e28bdb8e63
5 changed files with 39 additions and 25 deletions
|
@ -58,15 +58,6 @@ module FactoryGirl
|
|||
@attribute_list.overridable?
|
||||
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)
|
||||
@children << factory unless @children.include?(factory)
|
||||
end
|
||||
|
@ -92,6 +83,7 @@ module FactoryGirl
|
|||
end
|
||||
|
||||
def run(proxy_class, overrides) #:nodoc:
|
||||
ensure_compiled
|
||||
proxy = proxy_class.new(build_class)
|
||||
callbacks.each { |callback| proxy.add_callback(callback) }
|
||||
overrides = overrides.symbolize_keys
|
||||
|
@ -164,13 +156,14 @@ module FactoryGirl
|
|||
end
|
||||
|
||||
def compile
|
||||
inherit_factory(FactoryGirl.factory_by_name(@parent)) if @parent
|
||||
|
||||
declarations.each do |declaration|
|
||||
declaration.to_attributes.each do |attribute|
|
||||
define_attribute(attribute)
|
||||
end
|
||||
end
|
||||
|
||||
update_children if allow_overrides?
|
||||
@compiled = true
|
||||
end
|
||||
|
||||
|
@ -178,16 +171,26 @@ module FactoryGirl
|
|||
@attribute_list.declare_attribute(declaration)
|
||||
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
|
||||
|
||||
def declarations
|
||||
@attribute_list.declarations
|
||||
end
|
||||
|
||||
def update_children
|
||||
@children.each { |child| child.inherit_factory(self) }
|
||||
end
|
||||
|
||||
def define_attribute(attribute)
|
||||
if attribute.respond_to?(:factory) && attribute.factory == self.name
|
||||
raise AssociationDefinitionError, "Self-referencing association '#{attribute.name}' in factory '#{self.name}'"
|
||||
|
@ -215,9 +218,5 @@ module FactoryGirl
|
|||
def trait_for(name)
|
||||
@defined_traits.detect {|trait| trait.name == name }
|
||||
end
|
||||
|
||||
def ensure_compiled
|
||||
compile unless @compiled
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,10 +21,6 @@ module FactoryGirl
|
|||
proxy = FactoryGirl::DefinitionProxy.new(factory)
|
||||
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)
|
||||
|
||||
proxy.child_factories.each do |(child_name, child_options, child_block)|
|
||||
|
|
|
@ -28,9 +28,6 @@ module FactoryGirl
|
|||
factory = FactoryGirl::Factory.new(name, options)
|
||||
proxy = FactoryGirl::DefinitionProxy.new(factory)
|
||||
yield(proxy)
|
||||
if parent = options.delete(:parent)
|
||||
factory.inherit_factory(FactoryGirl.factory_by_name(parent))
|
||||
end
|
||||
FactoryGirl.register_factory(factory)
|
||||
end
|
||||
|
||||
|
|
21
spec/acceptance/define_child_before_parent_spec.rb
Normal file
21
spec/acceptance/define_child_before_parent_spec.rb
Normal 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
|
|
@ -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
|
||||
lambda {
|
||||
Factory.define(:child, :parent => :nonexsitent) {}
|
||||
Factory.build(:child)
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue