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)
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.
factory :user, :aliases => [:author]
@ -271,31 +271,31 @@ to any factory.
title "My awesome story"
author
attribute_group :published do
trait :published do
published true
end
attribute_group :unpublished do
trait :unpublished do
published false
end
attribute_group :week_long_publishing do
trait :week_long_publishing do
start_at { 1.week.ago }
end_at { Time.now }
end
attribute_group :month_long_publishing do
trait :month_long_publishing do
start_at { 1.month.ago }
end_at { Time.now }
end
factory :week_long_published_story, :attribute_groups => [:published, :week_long_publishing]
factory :month_long_published_story, :attribute_groups => [:published, :month_long_publishing]
factory :week_long_unpublished_story, :attribute_groups => [:unpublished, :week_long_publishing]
factory :month_long_unpublished_story, :attribute_groups => [:unpublished, :month_long_publishing]
factory :week_long_published_story, :traits => [:published, :week_long_publishing]
factory :month_long_published_story, :traits => [:published, :month_long_publishing]
factory :week_long_unpublished_story, :traits => [:unpublished, :week_long_publishing]
factory :month_long_unpublished_story, :traits => [:unpublished, :month_long_publishing]
end
Attribute groups can be used as attributes:
Traits can be used as attributes:
factory :week_long_published_story_with_title, :parent => :story do
published
@ -303,32 +303,32 @@ Attribute groups can be used as attributes:
title { "Publishing that was started at {start_at}" }
end
Attribute groups that define the same attributes won't raise AttributeDefinitionErrors;
the attribute group that defines the attribute latest in order gets precedence.
Traits that define the same attributes won't raise AttributeDefinitionErrors;
the trait that defines the attribute latest gets precedence.
factory :user do
name "Friendly User"
login { name }
attribute_group :male do
trait :male do
name "John Doe"
gender "Male"
login { "#{name} (M)" }
end
attribute_group :female do
trait :female do
name "Jane Doe"
gender "Female"
login { "#{name} (F)" }
end
attribute_group :admin do
trait :admin do
admin true
login { "admin-#{name}" }
end
factory :male_admin, :attribute_groups => [:male, :admin] # login will be "admin-John Doe"
factory :female_admin, :attribute_groups => [:admin, :female] # login will be "Jane Doe (F)"
factory :male_admin, :traits => [:male, :admin] # login will be "admin-John Doe"
factory :female_admin, :traits => [:admin, :female] # login will be "Jane Doe (F)"
end
Callbacks

View File

@ -12,10 +12,10 @@ require 'factory_girl/attribute/association'
require 'factory_girl/attribute/callback'
require 'factory_girl/attribute/sequence'
require 'factory_girl/attribute/implicit'
require 'factory_girl/attribute/attribute_group'
require 'factory_girl/attribute/trait'
require 'factory_girl/sequence'
require 'factory_girl/attribute_list'
require 'factory_girl/attribute_group'
require 'factory_girl/trait'
require 'factory_girl/aliases'
require 'factory_girl/definition_proxy'
require 'factory_girl/syntax/methods'
@ -54,15 +54,15 @@ module FactoryGirl
sequences.find(name)
end
def self.attribute_groups
@attribute_groups ||= Registry.new
def self.traits
@traits ||= Registry.new
end
def self.register_attribute_group(group)
attribute_groups.add(group)
def self.register_trait(trait)
traits.add(trait)
end
def self.attribute_group_by_name(name)
attribute_groups.find(name)
def self.trait_by_name(name)
traits.find(name)
end
end

View File

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

View File

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

View File

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

View File

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

View File

@ -17,8 +17,8 @@ module FactoryGirl
proxy = FactoryGirl::DefinitionProxy.new(factory)
proxy.instance_eval(&block) if block_given?
if groups = options.delete(:attribute_groups)
factory.apply_attribute_groups(groups)
if traits = options.delete(:traits)
factory.apply_traits(traits)
end
if parent = options.delete(:parent)
@ -35,8 +35,8 @@ module FactoryGirl
FactoryGirl.register_sequence(Sequence.new(name, start_value, &block))
end
def attribute_group(name, &block)
FactoryGirl.register_attribute_group(AttributeGroup.new(name, &block))
def trait(name, &block)
FactoryGirl.register_trait(Trait.new(name, &block))
end
end
end

View File

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

View File

@ -1,7 +1,7 @@
require "spec_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
define_model("User",
:name => :string,
@ -13,30 +13,30 @@ describe "an instance generated by a factory with multiple attribute groups" do
FactoryGirl.define do
factory :user_without_admin_scoping, :class => User do
admin_attribute_group
admin_trait
end
factory :user do
name "John"
attribute_group :great do
trait :great do
great "GREAT!!!"
end
attribute_group :admin do
trait :admin do
admin true
end
attribute_group :admin_attribute_group do
trait :admin_trait do
admin true
end
attribute_group :male do
trait :male do
name "Joe"
gender "Male"
end
attribute_group :female do
trait :female do
name "Jane"
gender "Female"
end
@ -45,7 +45,7 @@ describe "an instance generated by a factory with multiple attribute groups" do
great
end
factory :admin, :attribute_groups => [:admin]
factory :admin, :traits => [:admin]
factory :male_user do
male
@ -55,25 +55,25 @@ describe "an instance generated by a factory with multiple attribute groups" do
end
end
factory :female, :attribute_groups => [:female] do
attribute_group :admin do
factory :female, :traits => [:female] do
trait :admin do
admin true
name "Judy"
end
factory :female_admin_judy, :attribute_groups => [:admin]
factory :female_admin_judy, :traits => [:admin]
end
factory :female_admin, :attribute_groups => [:female, :admin]
factory :female_after_male_admin, :attribute_groups => [:male, :female, :admin]
factory :male_after_female_admin, :attribute_groups => [:female, :male, :admin]
factory :female_admin, :traits => [:female, :admin]
factory :female_after_male_admin, :traits => [:male, :female, :admin]
factory :male_after_female_admin, :traits => [:female, :male, :admin]
end
attribute_group :email do
trait :email do
email { "#{name}@example.com" }
end
factory :user_with_email, :class => User, :attribute_groups => [:email] do
factory :user_with_email, :class => User, :traits => [:email] do
name "Bill"
end
end
@ -86,35 +86,35 @@ describe "an instance generated by a factory with multiple attribute groups" do
it { should_not be_admin }
end
context "the child class with one attribute group" do
context "the child class with one trait" do
subject { FactoryGirl.create(:admin) }
its(:name) { should == "John" }
its(:gender) { should be_nil }
it { should be_admin }
end
context "the other child class with one attribute group" do
context "the other child class with one trait" do
subject { FactoryGirl.create(:female) }
its(:name) { should == "Jane" }
its(:gender) { should == "Female" }
it { should_not be_admin }
end
context "the child with multiple attribute groups" do
context "the child with multiple traits" do
subject { FactoryGirl.create(:female_admin) }
its(:name) { should == "Jane" }
its(:gender) { should == "Female" }
it { should be_admin }
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) }
its(:name) { should == "Jill" }
its(:gender) { should be_nil }
it { should be_admin }
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
subject { FactoryGirl.create(:male_after_female_admin) }
its(:name) { should == "Joe" }
@ -130,35 +130,35 @@ describe "an instance generated by a factory with multiple attribute groups" do
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) }
its(:name) { should == "Judy" }
its(:gender) { should == "Female" }
it { should be_admin }
end
context "factory using global attribute group" do
context "factory using global trait" do
subject { FactoryGirl.create(:user_with_email) }
its(:name) { should == "Bill" }
its(:email) { should == "Bill@example.com"}
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) }
its(:gender) { should == "Male" }
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) }
its(:great) { should == "GREAT!!!" }
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!!!") }
its(:great) { should == "SORT OF!!!" }
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) }
its(:gender) { should == "Male" }
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
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

View File

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