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:
parent
e39d6e6897
commit
36fb3fbe88
6 changed files with 84 additions and 14 deletions
|
@ -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'
|
||||||
|
|
29
lib/factory_girl/attribute_group.rb
Normal file
29
lib/factory_girl/attribute_group.rb
Normal 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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
Loading…
Reference in a new issue