diff --git a/Gemfile b/Gemfile index 9149e80..d8853c8 100644 --- a/Gemfile +++ b/Gemfile @@ -4,6 +4,7 @@ gem "rake" gem "rspec", "~> 2.0" gem "rcov" gem "activerecord", :require => false +gem "activesupport", :require => false gem "rr" gem "sqlite3-ruby", :require => false gem "appraisal", "~> 0.3.5" diff --git a/Gemfile.lock b/Gemfile.lock index f5107fc..9a5947c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -58,6 +58,7 @@ PLATFORMS DEPENDENCIES activerecord + activesupport appraisal (~> 0.3.5) bluecloth cucumber (~> 1.0.0) diff --git a/lib/factory_girl/attribute.rb b/lib/factory_girl/attribute.rb index 0a379d3..a9df000 100644 --- a/lib/factory_girl/attribute.rb +++ b/lib/factory_girl/attribute.rb @@ -34,6 +34,10 @@ module FactoryGirl 1 end + def aliases_for?(attr) + FactoryGirl.aliases_for(attr).include?(name) + end + def <=>(another) return nil unless another.is_a? Attribute self.priority <=> another.priority diff --git a/lib/factory_girl/factory.rb b/lib/factory_girl/factory.rb index a59a7ba..da6576a 100644 --- a/lib/factory_girl/factory.rb +++ b/lib/factory_girl/factory.rb @@ -76,13 +76,15 @@ module FactoryGirl def run(proxy_class, overrides) #:nodoc: proxy = proxy_class.new(build_class) overrides = symbolize_keys(overrides) - overrides.each {|attr, val| proxy.set(attr, val) } - passed_keys = overrides.keys.collect {|k| FactoryGirl.aliases_for(k) }.flatten @attributes.each do |attribute| - unless passed_keys.include?(attribute.name) + factory_overrides = overrides.select { |attr, val| attribute.aliases_for?(attr) } + if factory_overrides.empty? attribute.add_to(proxy) + else + factory_overrides.each { |attr, val| proxy.set(attr, val) } end end + overrides.each { |attr, val| proxy.set(attr, val) } proxy.result(@to_create_block) end diff --git a/spec/acceptance/overrides_spec.rb b/spec/acceptance/overrides_spec.rb new file mode 100644 index 0000000..d24aa2b --- /dev/null +++ b/spec/acceptance/overrides_spec.rb @@ -0,0 +1,65 @@ +require 'spec_helper' +require 'acceptance/acceptance_helper' +require 'active_support/ordered_hash' + +describe "attribute overrides" do + before do + define_model('User', :admin => :boolean) + define_model('Post', :title => :string, + :secure => :boolean, + :user_id => :integer) do + belongs_to :user + + def secure=(value) + return unless user && user.admin? + write_attribute(:secure, value) + end + end + + FactoryGirl.define do + factory :user do + factory :admin do + admin true + end + end + + factory :post do + user + title "default title" + end + end + end + + let(:admin) { FactoryGirl.create(:admin) } + + let(:post_attributes) do + attributes = ActiveSupport::OrderedHash.new + attributes[:secure] = false + attributes + end + + let(:non_admin_post_attributes) do + post_attributes[:user] = FactoryGirl.create(:user) + post_attributes + end + + let(:admin_post_attributes) do + post_attributes[:user] = admin + post_attributes + end + + context "with an admin posting" do + subject { FactoryGirl.create(:post, admin_post_attributes) } + its(:secure) { should == false } + end + + context "with a non-admin posting" do + subject { FactoryGirl.create(:post, non_admin_post_attributes) } + its(:secure) { should be_nil } + end + + context "with no user posting" do + subject { FactoryGirl.create(:post, post_attributes) } + its(:secure) { should be_nil } + end +end