Rename attribute groups to traits

This commit is contained in:
Joshua Clayton 2011-08-12 16:16:17 -04:00
parent 86125a4448
commit 1c74d9d6ec
10 changed files with 86 additions and 86 deletions

View File

@ -259,10 +259,10 @@ Without a block, the value will increment itself, starting at its initial value:
sequence(:position) sequence(:position)
end end
Attribute Groups Traits
---------------- ------
Attribute groups allow you to group attributes together and then apply them Traits allow you to group attributes together and then apply them
to any factory. to any factory.
factory :user, :aliases => [:author] factory :user, :aliases => [:author]
@ -271,31 +271,31 @@ to any factory.
title "My awesome story" title "My awesome story"
author author
attribute_group :published do trait :published do
published true published true
end end
attribute_group :unpublished do trait :unpublished do
published false published false
end end
attribute_group :week_long_publishing do trait :week_long_publishing do
start_at { 1.week.ago } start_at { 1.week.ago }
end_at { Time.now } end_at { Time.now }
end end
attribute_group :month_long_publishing do trait :month_long_publishing do
start_at { 1.month.ago } start_at { 1.month.ago }
end_at { Time.now } end_at { Time.now }
end end
factory :week_long_published_story, :attribute_groups => [:published, :week_long_publishing] factory :week_long_published_story, :traits => [:published, :week_long_publishing]
factory :month_long_published_story, :attribute_groups => [:published, :month_long_publishing] factory :month_long_published_story, :traits => [:published, :month_long_publishing]
factory :week_long_unpublished_story, :attribute_groups => [:unpublished, :week_long_publishing] factory :week_long_unpublished_story, :traits => [:unpublished, :week_long_publishing]
factory :month_long_unpublished_story, :attribute_groups => [:unpublished, :month_long_publishing] factory :month_long_unpublished_story, :traits => [:unpublished, :month_long_publishing]
end end
Attribute groups can be used as attributes: Traits can be used as attributes:
factory :week_long_published_story_with_title, :parent => :story do factory :week_long_published_story_with_title, :parent => :story do
published published
@ -303,32 +303,32 @@ Attribute groups can be used as attributes:
title { "Publishing that was started at {start_at}" } title { "Publishing that was started at {start_at}" }
end end
Attribute groups that define the same attributes won't raise AttributeDefinitionErrors; Traits that define the same attributes won't raise AttributeDefinitionErrors;
the attribute group that defines the attribute latest in order gets precedence. the trait that defines the attribute latest gets precedence.
factory :user do factory :user do
name "Friendly User" name "Friendly User"
login { name } login { name }
attribute_group :male do trait :male do
name "John Doe" name "John Doe"
gender "Male" gender "Male"
login { "#{name} (M)" } login { "#{name} (M)" }
end end
attribute_group :female do trait :female do
name "Jane Doe" name "Jane Doe"
gender "Female" gender "Female"
login { "#{name} (F)" } login { "#{name} (F)" }
end end
attribute_group :admin do trait :admin do
admin true admin true
login { "admin-#{name}" } login { "admin-#{name}" }
end end
factory :male_admin, :attribute_groups => [:male, :admin] # login will be "admin-John Doe" factory :male_admin, :traits => [:male, :admin] # login will be "admin-John Doe"
factory :female_admin, :attribute_groups => [:admin, :female] # login will be "Jane Doe (F)" factory :female_admin, :traits => [:admin, :female] # login will be "Jane Doe (F)"
end end
Callbacks Callbacks

View File

@ -12,10 +12,10 @@ require 'factory_girl/attribute/association'
require 'factory_girl/attribute/callback' 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/attribute/attribute_group' require 'factory_girl/attribute/trait'
require 'factory_girl/sequence' require 'factory_girl/sequence'
require 'factory_girl/attribute_list' require 'factory_girl/attribute_list'
require 'factory_girl/attribute_group' require 'factory_girl/trait'
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'
@ -54,15 +54,15 @@ module FactoryGirl
sequences.find(name) sequences.find(name)
end end
def self.attribute_groups def self.traits
@attribute_groups ||= Registry.new @traits ||= Registry.new
end end
def self.register_attribute_group(group) def self.register_trait(trait)
attribute_groups.add(group) traits.add(trait)
end end
def self.attribute_group_by_name(name) def self.trait_by_name(name)
attribute_groups.find(name) traits.find(name)
end end
end end

View File

@ -31,7 +31,7 @@ module FactoryGirl
elsif FactoryGirl.sequences.registered?(name) elsif FactoryGirl.sequences.registered?(name)
Attribute::Sequence.new(name, name) Attribute::Sequence.new(name, name)
else else
Attribute::AttributeGroup.new(name, @factory) Attribute::Trait.new(name, @factory)
end end
end end
end end

View File

@ -1,20 +1,20 @@
module FactoryGirl module FactoryGirl
class Attribute #:nodoc: class Attribute #:nodoc:
class AttributeGroup < Attribute #:nodoc: class Trait < Attribute #:nodoc:
def initialize(name, factory) def initialize(name, factory)
super(name) super(name)
@factory = factory @factory = factory
end end
def add_to(proxy) def add_to(proxy)
attribute_group.attributes.each { |attr| attr.add_to(proxy) } trait.attributes.each { |attr| attr.add_to(proxy) }
end end
private private
def attribute_group def trait
(@factory || FactoryGirl).attribute_group_by_name(name) (@factory || FactoryGirl).trait_by_name(name)
end end
end end

View File

@ -155,8 +155,8 @@ module FactoryGirl
@child_factories << [name, options, block] @child_factories << [name, options, block]
end end
def attribute_group(name, &block) def trait(name, &block)
@factory.define_attribute_group(AttributeGroup.new(name, &block)) @factory.define_trait(Trait.new(name, &block))
end end
end end
end end

View File

@ -13,7 +13,7 @@ module FactoryGirl
class Factory class Factory
attr_reader :name #:nodoc: attr_reader :name #:nodoc:
attr_reader :attribute_groups #:nodoc: attr_reader :traits #: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."
@ -34,11 +34,11 @@ module FactoryGirl
def initialize(name, options = {}) #:nodoc: def initialize(name, options = {}) #:nodoc:
assert_valid_options(options) assert_valid_options(options)
@name = factory_name_for(name) @name = factory_name_for(name)
@parent = options[:parent] @parent = options[:parent]
@options = options @options = options
@attribute_list = AttributeList.new @attribute_list = AttributeList.new
@attribute_groups = [] @traits = []
end end
def inherit_from(parent) #:nodoc: def inherit_from(parent) #:nodoc:
@ -48,9 +48,9 @@ module FactoryGirl
apply_attributes(parent.attributes) apply_attributes(parent.attributes)
end end
def apply_attribute_groups(groups) #:nodoc: def apply_traits(traits) #:nodoc:
groups.reverse.map { |name| attribute_group_by_name(name) }.each do |group| traits.reverse.map { |name| trait_by_name(name) }.each do |trait|
apply_attributes(group.attributes) apply_attributes(trait.attributes)
end end
end end
@ -66,8 +66,8 @@ module FactoryGirl
@attribute_list.define_attribute(attribute) @attribute_list.define_attribute(attribute)
end end
def define_attribute_group(group) def define_trait(trait)
@attribute_groups << group @traits << trait
end end
def add_callback(name, &block) def add_callback(name, &block)
@ -102,13 +102,13 @@ module FactoryGirl
attributes.select {|attribute| attribute.association? } attributes.select {|attribute| attribute.association? }
end end
def attribute_group_by_name(name) def trait_by_name(name)
if existing_attribute = attribute_group_for(name) if existing_attribute = trait_for(name)
existing_attribute existing_attribute
elsif @parent elsif @parent
FactoryGirl.factory_by_name(@parent).attribute_group_by_name(name) FactoryGirl.factory_by_name(@parent).trait_by_name(name)
else else
FactoryGirl.attribute_group_by_name(name) FactoryGirl.trait_by_name(name)
end end
end end
@ -167,7 +167,7 @@ module FactoryGirl
end end
def assert_valid_options(options) def assert_valid_options(options)
invalid_keys = options.keys - [:class, :parent, :default_strategy, :aliases, :attribute_groups] invalid_keys = options.keys - [:class, :parent, :default_strategy, :aliases, :traits]
unless invalid_keys == [] unless invalid_keys == []
raise ArgumentError, "Unknown arguments: #{invalid_keys.inspect}" raise ArgumentError, "Unknown arguments: #{invalid_keys.inspect}"
end end
@ -208,8 +208,8 @@ module FactoryGirl
end end
end end
def attribute_group_for(name) def trait_for(name)
attribute_groups.detect {|attribute_group| attribute_group.name == name } traits.detect {|trait| trait.name == name }
end end
end end
end end

View File

@ -17,8 +17,8 @@ module FactoryGirl
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(:attribute_groups) if traits = options.delete(:traits)
factory.apply_attribute_groups(groups) factory.apply_traits(traits)
end end
if parent = options.delete(:parent) if parent = options.delete(:parent)
@ -35,8 +35,8 @@ module FactoryGirl
FactoryGirl.register_sequence(Sequence.new(name, start_value, &block)) FactoryGirl.register_sequence(Sequence.new(name, start_value, &block))
end end
def attribute_group(name, &block) def trait(name, &block)
FactoryGirl.register_attribute_group(AttributeGroup.new(name, &block)) FactoryGirl.register_trait(Trait.new(name, &block))
end end
end end
end end

View File

@ -1,5 +1,5 @@
module FactoryGirl module FactoryGirl
class AttributeGroup class Trait
attr_reader :name attr_reader :name
def initialize(name, &block) #:nodoc: def initialize(name, &block) #:nodoc:

View File

@ -1,7 +1,7 @@
require "spec_helper" require "spec_helper"
require "acceptance/acceptance_helper" require "acceptance/acceptance_helper"
describe "an instance generated by a factory with multiple attribute groups" do describe "an instance generated by a factory with multiple traits" do
before do before do
define_model("User", define_model("User",
:name => :string, :name => :string,
@ -13,30 +13,30 @@ describe "an instance generated by a factory with multiple attribute groups" do
FactoryGirl.define do FactoryGirl.define do
factory :user_without_admin_scoping, :class => User do factory :user_without_admin_scoping, :class => User do
admin_attribute_group admin_trait
end end
factory :user do factory :user do
name "John" name "John"
attribute_group :great do trait :great do
great "GREAT!!!" great "GREAT!!!"
end end
attribute_group :admin do trait :admin do
admin true admin true
end end
attribute_group :admin_attribute_group do trait :admin_trait do
admin true admin true
end end
attribute_group :male do trait :male do
name "Joe" name "Joe"
gender "Male" gender "Male"
end end
attribute_group :female do trait :female do
name "Jane" name "Jane"
gender "Female" gender "Female"
end end
@ -45,7 +45,7 @@ describe "an instance generated by a factory with multiple attribute groups" do
great great
end end
factory :admin, :attribute_groups => [:admin] factory :admin, :traits => [:admin]
factory :male_user do factory :male_user do
male male
@ -55,25 +55,25 @@ describe "an instance generated by a factory with multiple attribute groups" do
end end
end end
factory :female, :attribute_groups => [:female] do factory :female, :traits => [:female] do
attribute_group :admin do trait :admin do
admin true admin true
name "Judy" name "Judy"
end end
factory :female_admin_judy, :attribute_groups => [:admin] factory :female_admin_judy, :traits => [:admin]
end end
factory :female_admin, :attribute_groups => [:female, :admin] factory :female_admin, :traits => [:female, :admin]
factory :female_after_male_admin, :attribute_groups => [:male, :female, :admin] factory :female_after_male_admin, :traits => [:male, :female, :admin]
factory :male_after_female_admin, :attribute_groups => [:female, :male, :admin] factory :male_after_female_admin, :traits => [:female, :male, :admin]
end end
attribute_group :email do trait :email do
email { "#{name}@example.com" } email { "#{name}@example.com" }
end end
factory :user_with_email, :class => User, :attribute_groups => [:email] do factory :user_with_email, :class => User, :traits => [:email] do
name "Bill" name "Bill"
end end
end end
@ -86,35 +86,35 @@ describe "an instance generated by a factory with multiple attribute groups" do
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 trait" 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 trait" 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 traits" 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 traits 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 traits 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 == "Joe" } its(:name) { should == "Joe" }
@ -130,35 +130,35 @@ describe "an instance generated by a factory with multiple attribute groups" do
end end
end end
context "child class with scoped attribute group and inherited attribute group" do context "child class with scoped trait and inherited trait" do
subject { FactoryGirl.create(:female_admin_judy) } subject { FactoryGirl.create(:female_admin_judy) }
its(:name) { should == "Judy" } its(:name) { should == "Judy" }
its(:gender) { should == "Female" } its(:gender) { should == "Female" }
it { should be_admin } it { should be_admin }
end end
context "factory using global attribute group" do context "factory using global trait" do
subject { FactoryGirl.create(:user_with_email) } subject { FactoryGirl.create(:user_with_email) }
its(:name) { should == "Bill" } its(:name) { should == "Bill" }
its(:email) { should == "Bill@example.com"} its(:email) { should == "Bill@example.com"}
end end
context "factory created with alternate syntax for specifying attribute group" do context "factory created with alternate syntax for specifying trait" do
subject { FactoryGirl.create(:male_user) } subject { FactoryGirl.create(:male_user) }
its(:gender) { should == "Male" } its(:gender) { should == "Male" }
end end
context "factory created with alternate syntax where attribute group and attribute are the same" do context "factory created with alternate syntax where trait name and attribute are the same" do
subject { FactoryGirl.create(:great_user) } subject { FactoryGirl.create(:great_user) }
its(:great) { should == "GREAT!!!" } its(:great) { should == "GREAT!!!" }
end end
context "factory created with alternate syntax where attribute group and attribute are the same and attribute is overridden" do context "factory created with alternate syntax where trait name and attribute are the same and attribute is overridden" do
subject { FactoryGirl.create(:great_user, :great => "SORT OF!!!") } subject { FactoryGirl.create(:great_user, :great => "SORT OF!!!") }
its(:great) { should == "SORT OF!!!" } its(:great) { should == "SORT OF!!!" }
end end
context "child factory created where attribute group attributes are inherited" do context "child factory created where trait attributes are inherited" do
subject { FactoryGirl.create(:child_male_user) } subject { FactoryGirl.create(:child_male_user) }
its(:gender) { should == "Male" } its(:gender) { should == "Male" }
its(:date_of_birth) { should == Date.parse("1/1/2000") } its(:date_of_birth) { should == Date.parse("1/1/2000") }
@ -166,6 +166,6 @@ describe "an instance generated by a factory with multiple attribute groups" do
context "factory outside of scope" do context "factory outside of scope" do
subject { FactoryGirl.create(:user_without_admin_scoping) } subject { FactoryGirl.create(:user_without_admin_scoping) }
it { expect { subject }.to raise_error(ArgumentError, "Not registered: admin_attribute_group") } it { expect { subject }.to raise_error(ArgumentError, "Not registered: admin_trait") }
end end
end end

View File

@ -24,7 +24,7 @@ RSpec.configure do |config|
config.after do config.after do
FactoryGirl.factories.clear FactoryGirl.factories.clear
FactoryGirl.sequences.clear FactoryGirl.sequences.clear
FactoryGirl.attribute_groups.clear FactoryGirl.traits.clear
end end
end end