diff --git a/lib/factory_girl/factory.rb b/lib/factory_girl/factory.rb index c679fa7..babfd50 100644 --- a/lib/factory_girl/factory.rb +++ b/lib/factory_girl/factory.rb @@ -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 diff --git a/lib/factory_girl/syntax/default.rb b/lib/factory_girl/syntax/default.rb index b7277fe..adde931 100644 --- a/lib/factory_girl/syntax/default.rb +++ b/lib/factory_girl/syntax/default.rb @@ -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)| diff --git a/lib/factory_girl/syntax/vintage.rb b/lib/factory_girl/syntax/vintage.rb index 78a0630..8b14848 100644 --- a/lib/factory_girl/syntax/vintage.rb +++ b/lib/factory_girl/syntax/vintage.rb @@ -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 diff --git a/spec/acceptance/define_child_before_parent_spec.rb b/spec/acceptance/define_child_before_parent_spec.rb new file mode 100644 index 0000000..fe1d67f --- /dev/null +++ b/spec/acceptance/define_child_before_parent_spec.rb @@ -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 diff --git a/spec/acceptance/syntax/vintage_spec.rb b/spec/acceptance/syntax/vintage_spec.rb index 47e420d..f2da597 100644 --- a/spec/acceptance/syntax/vintage_spec.rb +++ b/spec/acceptance/syntax/vintage_spec.rb @@ -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