diff --git a/lib/factory_girl.rb b/lib/factory_girl.rb index f026f17..ddf2b33 100644 --- a/lib/factory_girl.rb +++ b/lib/factory_girl.rb @@ -51,4 +51,17 @@ module FactoryGirl def self.sequence_by_name(name) sequences.find(name) end + + def self.attribute_groups + @attribute_groups ||= Registry.new + end + + def self.register_attribute_group(group) + attribute_groups.add(group) + end + + def self.attribute_group_by_name(name) + attribute_groups.find(name) + end + end diff --git a/lib/factory_girl/attribute_group.rb b/lib/factory_girl/attribute_group.rb index f6e6e57..03a01e7 100644 --- a/lib/factory_girl/attribute_group.rb +++ b/lib/factory_girl/attribute_group.rb @@ -19,6 +19,10 @@ module FactoryGirl @attributes << attribute end + def names + [@name] + end + private def attribute_defined? (name) diff --git a/lib/factory_girl/factory.rb b/lib/factory_girl/factory.rb index 34a871e..0e3a649 100644 --- a/lib/factory_girl/factory.rb +++ b/lib/factory_girl/factory.rb @@ -14,7 +14,6 @@ module FactoryGirl class Factory attr_reader :name #:nodoc: attr_reader :attributes #:nodoc: - attr_reader :attribute_groups #:nodoc: def factory_name puts "WARNING: factory.factory_name is deprecated. Use factory.name instead." @@ -38,7 +37,6 @@ module FactoryGirl @name = factory_name_for(name) @options = options @attributes = [] - @attribute_groups = {} end def inherit_from(parent) #:nodoc: @@ -90,7 +88,7 @@ module FactoryGirl end def define_attribute_group(group) - @attribute_groups[group.name.to_sym] = group + attribute_groups.add group end def add_callback(name, &block) @@ -124,13 +122,16 @@ module FactoryGirl end def attribute_group_by_name(name) - name=name.to_sym - group = @attribute_groups[name] - unless @options[:parent].nil? - group ||= FactoryGirl.factory_by_name(@options[:parent]).attribute_group_by_name(name) + return attribute_groups.find(name) if attribute_groups.registered?(name) + + parent=@options[:parent] + if parent.nil? + FactoryGirl::attribute_group_by_name(name) + else + FactoryGirl.factory_by_name(parent).attribute_group_by_name(name) end - group end + # Names for this factory, including aliases. # # Example: @@ -230,6 +231,9 @@ module FactoryGirl options end end - + + def attribute_groups + @attribute_groups ||= Registry.new + end end end diff --git a/lib/factory_girl/syntax/default.rb b/lib/factory_girl/syntax/default.rb index 03d20eb..bff3eba 100644 --- a/lib/factory_girl/syntax/default.rb +++ b/lib/factory_girl/syntax/default.rb @@ -34,6 +34,10 @@ module FactoryGirl def sequence(name, start_value = 1, &block) FactoryGirl.register_sequence(Sequence.new(name, start_value, &block)) end + + def attr_group(name, &block) + FactoryGirl.register_attribute_group(AttributeGroup.new(name, &block)) + end end end end diff --git a/spec/acceptance/attribute_groups_spec.rb b/spec/acceptance/attribute_groups_spec.rb index 2e49177..f2cf407 100644 --- a/spec/acceptance/attribute_groups_spec.rb +++ b/spec/acceptance/attribute_groups_spec.rb @@ -3,9 +3,9 @@ require "acceptance/acceptance_helper" describe "an instance generated by a factory with multiple attribute groups" do before do - define_model("User", :name => :string, :admin => :boolean, :gender => :string) + define_model("User", :name => :string, :admin => :boolean, :gender => :string, :email => :string) - FactoryGirl.define do + FactoryGirl.define do factory :user do name "John" @@ -25,11 +25,26 @@ describe "an instance generated by a factory with multiple attribute groups" do factory :admin, :attr_groups => [:admin] factory :male, :attr_groups => [:male] - factory :female, :attr_groups => [:female] + factory :female, :attr_groups => [:female] do + attr_group :admin do + admin true + name "Judy" + end + factory :female_admin_judy, :attr_groups=>[:admin] + end factory :female_admin, :attr_groups => [:female, :admin] factory :female_after_male_admin, :attr_groups => [:male, :female, :admin] factory :male_after_female_admin, :attr_groups => [:female, :male, :admin] end + + attr_group :email do + email { "#{name}@example.com" } + end + + factory :user_with_email, :class=>User, :attr_groups=>[:email] do + name "Bill" + end + end end @@ -85,4 +100,17 @@ describe "an instance generated by a factory with multiple attribute groups" do it { should be_admin } end end + + context "child class with scoped attribute group and inherited attribute group" do + subject { FactoryGirl.create(:female_admin_judy) } + its(:name) { should == "Judy" } + its(:gender) { should == "Female" } + it { should be_admin } + end + + context "factory using global attribute group" do + subject { FactoryGirl.create(:user_with_email) } + its(:name) { should == "Bill" } + its(:email) { should == "Bill@example.com"} + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4354ef4..ce30de9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -24,6 +24,7 @@ RSpec.configure do |config| config.after do FactoryGirl.factories.clear FactoryGirl.sequences.clear + FactoryGirl.attribute_groups.clear end end