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,6 +14,7 @@ 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."
@ -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:
@ -58,6 +60,23 @@ module FactoryGirl
@attributes = @attributes.partition{|attr| attr.priority.zero? }.flatten @attributes = @attributes.partition{|attr| attr.priority.zero? }.flatten
end 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
def define_attribute(attribute) def define_attribute(attribute)
name = attribute.name name = attribute.name
# TODO: move these checks into Attribute # TODO: move these checks into Attribute
@ -70,6 +89,10 @@ module FactoryGirl
@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)
raise InvalidCallbackNameError, "#{name} is not a valid callback name. Valid callback names are :after_build, :after_create, and :after_stub" raise InvalidCallbackNameError, "#{name} is not a valid callback name. Valid callback names are :after_build, :after_create, and :after_stub"
@ -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

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
@ -71,7 +72,7 @@ describe "an instance generated by a factory with multiple attribute groups" 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