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?
|
@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
|
||||||
|
|
|
@ -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)|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
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
|
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
|
||||||
|
|
Loading…
Reference in a new issue