1
0
Fork 0
mirror of https://github.com/thoughtbot/factory_bot.git synced 2022-11-09 11:43:51 -05:00

first attribute groups specs passing

This commit is contained in:
Thomas Walpole 2011-08-09 17:29:02 -07:00 committed by Joshua Clayton
parent e39d6e6897
commit 36fb3fbe88
6 changed files with 84 additions and 14 deletions

View file

@ -13,6 +13,7 @@ require 'factory_girl/attribute/callback'
require 'factory_girl/attribute/sequence' require 'factory_girl/attribute/sequence'
require 'factory_girl/attribute/implicit' require 'factory_girl/attribute/implicit'
require 'factory_girl/sequence' require 'factory_girl/sequence'
require 'factory_girl/attribute_group'
require 'factory_girl/aliases' require 'factory_girl/aliases'
require 'factory_girl/definition_proxy' require 'factory_girl/definition_proxy'
require 'factory_girl/syntax/methods' require 'factory_girl/syntax/methods'

View file

@ -0,0 +1,29 @@
module FactoryGirl
class AttributeGroup
attr_reader :name
attr_reader :attributes
def initialize(name, &block) #:nodoc:
@name = name
@attributes = []
proxy = FactoryGirl::DefinitionProxy.new(self)
proxy.instance_eval(&block) if block_given?
end
def define_attribute(attribute)
name = attribute.name
if attribute_defined?(name)
raise AttributeDefinitionError, "Attribute already defined: #{name}"
end
@attributes << attribute
end
private
def attribute_defined? (name)
!@attributes.detect {|attr| attr.name == name && !attr.is_a?(Attribute::Callback) }.nil?
end
end
end

View file

@ -7,7 +7,6 @@ module FactoryGirl
end end
attr_reader :child_factories attr_reader :child_factories
def initialize(factory) def initialize(factory)
@factory = factory @factory = factory
@child_factories = [] @child_factories = []
@ -154,5 +153,9 @@ module FactoryGirl
def factory(name, options = {}, &block) def factory(name, options = {}, &block)
@child_factories << [name, options, block] @child_factories << [name, options, block]
end end
def attr_group(name, &block)
@factory.define_attribute_group(AttributeGroup.new(name, &block))
end
end end
end end

View file

@ -14,7 +14,8 @@ module FactoryGirl
class Factory class Factory
attr_reader :name #:nodoc: attr_reader :name #:nodoc:
attr_reader :attributes #:nodoc: attr_reader :attributes #:nodoc:
attr_reader :attribute_groups #:nodoc:
def factory_name def factory_name
puts "WARNING: factory.factory_name is deprecated. Use factory.name instead." puts "WARNING: factory.factory_name is deprecated. Use factory.name instead."
name name
@ -37,6 +38,7 @@ module FactoryGirl
@name = factory_name_for(name) @name = factory_name_for(name)
@options = options @options = options
@attributes = [] @attributes = []
@attribute_groups = {}
end end
def inherit_from(parent) #:nodoc: def inherit_from(parent) #:nodoc:
@ -55,7 +57,24 @@ module FactoryGirl
end end
@attributes.unshift *new_attributes @attributes.unshift *new_attributes
@attributes = @attributes.partition {|attr| attr.priority.zero? }.flatten @attributes = @attributes.partition{|attr| attr.priority.zero? }.flatten
end
def apply_attribute_groups(groups)
groups.reverse.map{ |name| attribute_group_by_name(name) }.each do |group|
new_attributes=[]
group.attributes.each do |attribute|
if attribute_defined?(attribute.name)
@attributes.delete_if do |attrib|
new_attributes << attrib.clone if attrib.name == attribute.name
end
else
new_attributes << attribute.clone
end
end
@attributes.unshift *new_attributes
@attributes = @attributes.partition{|attr| attr.priority.zero?}.flatten
end
end end
def define_attribute(attribute) def define_attribute(attribute)
@ -69,6 +88,10 @@ module FactoryGirl
end end
@attributes << attribute @attributes << attribute
end end
def define_attribute_group(group)
@attribute_groups[group.name.to_sym] = group
end
def add_callback(name, &block) def add_callback(name, &block)
unless [:after_build, :after_create, :after_stub].include?(name.to_sym) unless [:after_build, :after_create, :after_stub].include?(name.to_sym)
@ -100,6 +123,14 @@ module FactoryGirl
attributes.select {|attribute| attribute.association? } attributes.select {|attribute| attribute.association? }
end 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)
end
group
end
# Names for this factory, including aliases. # Names for this factory, including aliases.
# #
# Example: # Example:
@ -159,7 +190,7 @@ module FactoryGirl
end end
def assert_valid_options(options) def assert_valid_options(options)
invalid_keys = options.keys - [:class, :parent, :default_strategy, :aliases] invalid_keys = options.keys - [:class, :parent, :default_strategy, :aliases, :attr_groups]
unless invalid_keys == [] unless invalid_keys == []
raise ArgumentError, "Unknown arguments: #{invalid_keys.inspect}" raise ArgumentError, "Unknown arguments: #{invalid_keys.inspect}"
end end

View file

@ -16,6 +16,11 @@ module FactoryGirl
factory = Factory.new(name, options) factory = Factory.new(name, options)
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 groups = options.delete(:attr_groups)
factory.apply_attribute_groups(groups)
end
if parent = options.delete(:parent) if parent = options.delete(:parent)
factory.inherit_from(FactoryGirl.factory_by_name(parent)) factory.inherit_from(FactoryGirl.factory_by_name(parent))
end end
@ -25,7 +30,7 @@ module FactoryGirl
factory(child_name, child_options.merge(:parent => name), &child_block) factory(child_name, child_options.merge(:parent => name), &child_block)
end end
end end
def sequence(name, start_value = 1, &block) def sequence(name, start_value = 1, &block)
FactoryGirl.register_sequence(Sequence.new(name, start_value, &block)) FactoryGirl.register_sequence(Sequence.new(name, start_value, &block))
end end

View file

@ -14,6 +14,7 @@ describe "an instance generated by a factory with multiple attribute groups" do
end end
attr_group :male do attr_group :male do
name "Joe"
gender "Male" gender "Male"
end end
@ -38,47 +39,47 @@ describe "an instance generated by a factory with multiple attribute groups" do
its(:gender) { should be_nil } its(:gender) { should be_nil }
it { should_not be_admin } it { should_not be_admin }
end end
context "the child class with one attribute group" do context "the child class with one attribute group" do
subject { FactoryGirl.create(:admin) } subject { FactoryGirl.create(:admin) }
its(:name) { should == "John" } its(:name) { should == "John" }
its(:gender) { should be_nil } its(:gender) { should be_nil }
it { should be_admin } it { should be_admin }
end end
context "the other child class with one attribute group" do context "the other child class with one attribute group" do
subject { FactoryGirl.create(:female) } subject { FactoryGirl.create(:female) }
its(:name) { should == "Jane" } its(:name) { should == "Jane" }
its(:gender) { should == "Female" } its(:gender) { should == "Female" }
it { should_not be_admin } it { should_not be_admin }
end end
context "the child with multiple attribute groups" do context "the child with multiple attribute groups" do
subject { FactoryGirl.create(:female_admin) } subject { FactoryGirl.create(:female_admin) }
its(:name) { should == "Jane" } its(:name) { should == "Jane" }
its(:gender) { should == "Female" } its(:gender) { should == "Female" }
it { should be_admin } it { should be_admin }
end end
context "the child with multiple attribute groups and overridden attributes" do context "the child with multiple attribute groups and overridden attributes" do
subject { FactoryGirl.create(:female_admin, :name => "Jill", :gender => nil) } subject { FactoryGirl.create(:female_admin, :name => "Jill", :gender => nil) }
its(:name) { should == "Jill" } its(:name) { should == "Jill" }
its(:gender) { should be_nil } its(:gender) { should be_nil }
it { should be_admin } it { should be_admin }
end end
context "the child with multiple attribute groups who override the same attribute" do context "the child with multiple attribute groups who override the same attribute" do
context "when the male assigns name after female" do context "when the male assigns name after female" do
subject { FactoryGirl.create(:male_after_female_admin) } subject { FactoryGirl.create(:male_after_female_admin) }
its(:name) { should == "John" } its(:name) { should == "Joe" }
its(:gender) { should == "Male" } its(:gender) { should == "Male" }
it { should be_admin } it { should be_admin }
end end
context "when the female assigns name after male" do context "when the female assigns name after male" do
subject { FactoryGirl.create(:female_after_male_admin) } subject { FactoryGirl.create(:female_after_male_admin) }
its(:name) { should == "Jane" } its(:name) { should == "Jane" }
its(:gender) { should == "Female" } its(:gender) { should == "Female" }
it { should be_admin } it { should be_admin }