2011-08-09 18:00:24 -04:00
|
|
|
require "spec_helper"
|
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
describe "an instance generated by a factory with multiple traits" do
|
2011-08-09 18:00:24 -04:00
|
|
|
before do
|
2011-08-12 10:35:41 -04:00
|
|
|
define_model("User",
|
2012-03-09 17:20:38 -05:00
|
|
|
name: :string,
|
|
|
|
admin: :boolean,
|
|
|
|
gender: :string,
|
|
|
|
email: :string,
|
|
|
|
date_of_birth: :date,
|
|
|
|
great: :string)
|
2011-08-12 10:35:41 -04:00
|
|
|
|
|
|
|
FactoryGirl.define do
|
2012-03-09 17:20:38 -05:00
|
|
|
factory :user_without_admin_scoping, class: User do
|
2011-08-12 16:16:17 -04:00
|
|
|
admin_trait
|
2011-08-12 10:35:41 -04:00
|
|
|
end
|
2011-08-09 18:00:24 -04:00
|
|
|
|
|
|
|
factory :user do
|
|
|
|
name "John"
|
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
trait :great do
|
2011-08-12 15:05:38 -04:00
|
|
|
great "GREAT!!!"
|
|
|
|
end
|
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
trait :admin do
|
2011-08-09 18:00:24 -04:00
|
|
|
admin true
|
|
|
|
end
|
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
trait :admin_trait do
|
2011-08-12 10:35:41 -04:00
|
|
|
admin true
|
|
|
|
end
|
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
trait :male do
|
2011-08-09 20:29:02 -04:00
|
|
|
name "Joe"
|
2011-08-09 18:00:24 -04:00
|
|
|
gender "Male"
|
|
|
|
end
|
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
trait :female do
|
2011-08-09 18:00:24 -04:00
|
|
|
name "Jane"
|
|
|
|
gender "Female"
|
|
|
|
end
|
|
|
|
|
2011-08-12 15:05:38 -04:00
|
|
|
factory :great_user do
|
|
|
|
great
|
|
|
|
end
|
|
|
|
|
2012-03-09 17:20:38 -05:00
|
|
|
factory :admin, traits: [:admin]
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2011-08-10 23:33:50 -04:00
|
|
|
factory :male_user do
|
|
|
|
male
|
2011-08-12 15:05:38 -04:00
|
|
|
|
|
|
|
factory :child_male_user do
|
|
|
|
date_of_birth { Date.parse("1/1/2000") }
|
|
|
|
end
|
2011-08-10 23:33:50 -04:00
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2012-03-09 17:20:38 -05:00
|
|
|
factory :female, traits: [:female] do
|
2011-08-12 16:16:17 -04:00
|
|
|
trait :admin do
|
2011-08-10 14:11:53 -04:00
|
|
|
admin true
|
|
|
|
name "Judy"
|
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2012-03-04 14:28:09 -05:00
|
|
|
factory :female_great_user do
|
|
|
|
great
|
|
|
|
end
|
|
|
|
|
2012-03-09 17:20:38 -05:00
|
|
|
factory :female_admin_judy, traits: [:admin]
|
2011-08-10 14:11:53 -04:00
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2012-03-09 17:20:38 -05:00
|
|
|
factory :female_admin, traits: [:female, :admin]
|
|
|
|
factory :female_after_male_admin, traits: [:male, :female, :admin]
|
|
|
|
factory :male_after_female_admin, traits: [:female, :male, :admin]
|
2011-08-09 18:00:24 -04:00
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
trait :email do
|
2011-08-10 14:11:53 -04:00
|
|
|
email { "#{name}@example.com" }
|
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2012-03-09 17:20:38 -05:00
|
|
|
factory :user_with_email, class: User, traits: [:email] do
|
2011-08-10 14:11:53 -04:00
|
|
|
name "Bill"
|
|
|
|
end
|
2011-08-09 18:00:24 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "the parent class" do
|
|
|
|
subject { FactoryGirl.create(:user) }
|
|
|
|
its(:name) { should == "John" }
|
|
|
|
its(:gender) { should be_nil }
|
2011-08-12 10:35:41 -04:00
|
|
|
it { should_not be_admin }
|
2011-08-09 18:00:24 -04:00
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
context "the child class with one trait" do
|
2011-08-09 18:00:24 -04:00
|
|
|
subject { FactoryGirl.create(:admin) }
|
|
|
|
its(:name) { should == "John" }
|
|
|
|
its(:gender) { should be_nil }
|
2011-08-12 10:35:41 -04:00
|
|
|
it { should be_admin }
|
2011-08-09 18:00:24 -04:00
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
context "the other child class with one trait" do
|
2011-08-09 18:00:24 -04:00
|
|
|
subject { FactoryGirl.create(:female) }
|
|
|
|
its(:name) { should == "Jane" }
|
|
|
|
its(:gender) { should == "Female" }
|
2011-08-12 10:35:41 -04:00
|
|
|
it { should_not be_admin }
|
2011-08-09 18:00:24 -04:00
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
context "the child with multiple traits" do
|
2011-08-09 18:00:24 -04:00
|
|
|
subject { FactoryGirl.create(:female_admin) }
|
|
|
|
its(:name) { should == "Jane" }
|
|
|
|
its(:gender) { should == "Female" }
|
2011-08-12 10:35:41 -04:00
|
|
|
it { should be_admin }
|
2011-08-09 18:00:24 -04:00
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
context "the child with multiple traits and overridden attributes" do
|
2012-03-09 17:20:38 -05:00
|
|
|
subject { FactoryGirl.create(:female_admin, name: "Jill", gender: nil) }
|
2011-08-09 18:00:24 -04:00
|
|
|
its(:name) { should == "Jill" }
|
|
|
|
its(:gender) { should be_nil }
|
2011-08-12 10:35:41 -04:00
|
|
|
it { should be_admin }
|
2011-08-09 18:00:24 -04:00
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
context "the child with multiple traits who override the same attribute" do
|
2011-08-09 18:00:24 -04:00
|
|
|
context "when the male assigns name after female" do
|
|
|
|
subject { FactoryGirl.create(:male_after_female_admin) }
|
2011-08-09 20:29:02 -04:00
|
|
|
its(:name) { should == "Joe" }
|
2011-08-09 18:00:24 -04:00
|
|
|
its(:gender) { should == "Male" }
|
2011-08-12 10:35:41 -04:00
|
|
|
it { should be_admin }
|
2011-08-09 18:00:24 -04:00
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2011-08-09 18:00:24 -04:00
|
|
|
context "when the female assigns name after male" do
|
|
|
|
subject { FactoryGirl.create(:female_after_male_admin) }
|
|
|
|
its(:name) { should == "Jane" }
|
|
|
|
its(:gender) { should == "Female" }
|
2011-08-12 10:35:41 -04:00
|
|
|
it { should be_admin }
|
2011-08-09 18:00:24 -04:00
|
|
|
end
|
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
context "child class with scoped trait and inherited trait" do
|
2011-08-12 10:35:41 -04:00
|
|
|
subject { FactoryGirl.create(:female_admin_judy) }
|
|
|
|
its(:name) { should == "Judy" }
|
2011-08-10 14:11:53 -04:00
|
|
|
its(:gender) { should == "Female" }
|
2011-08-12 10:35:41 -04:00
|
|
|
it { should be_admin }
|
2011-08-10 14:11:53 -04:00
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
context "factory using global trait" do
|
2011-08-12 10:35:41 -04:00
|
|
|
subject { FactoryGirl.create(:user_with_email) }
|
|
|
|
its(:name) { should == "Bill" }
|
2011-08-10 14:11:53 -04:00
|
|
|
its(:email) { should == "Bill@example.com"}
|
|
|
|
end
|
2011-08-12 10:35:41 -04:00
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
context "factory created with alternate syntax for specifying trait" do
|
2011-08-12 10:35:41 -04:00
|
|
|
subject { FactoryGirl.create(:male_user) }
|
2011-08-10 23:33:50 -04:00
|
|
|
its(:gender) { should == "Male" }
|
|
|
|
end
|
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
context "factory created with alternate syntax where trait name and attribute are the same" do
|
2011-08-12 15:05:38 -04:00
|
|
|
subject { FactoryGirl.create(:great_user) }
|
|
|
|
its(:great) { should == "GREAT!!!" }
|
|
|
|
end
|
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
context "factory created with alternate syntax where trait name and attribute are the same and attribute is overridden" do
|
2012-03-09 17:20:38 -05:00
|
|
|
subject { FactoryGirl.create(:great_user, great: "SORT OF!!!") }
|
2011-08-12 15:05:38 -04:00
|
|
|
its(:great) { should == "SORT OF!!!" }
|
|
|
|
end
|
|
|
|
|
2011-08-12 16:16:17 -04:00
|
|
|
context "child factory created where trait attributes are inherited" do
|
2011-08-12 15:05:38 -04:00
|
|
|
subject { FactoryGirl.create(:child_male_user) }
|
|
|
|
its(:gender) { should == "Male" }
|
|
|
|
its(:date_of_birth) { should == Date.parse("1/1/2000") }
|
|
|
|
end
|
|
|
|
|
2011-08-12 10:35:41 -04:00
|
|
|
context "factory outside of scope" do
|
|
|
|
subject { FactoryGirl.create(:user_without_admin_scoping) }
|
2011-10-15 01:54:01 -04:00
|
|
|
it { expect { subject }.to raise_error(ArgumentError, "Trait not registered: admin_trait") }
|
2011-08-12 10:35:41 -04:00
|
|
|
end
|
2012-03-04 14:28:09 -05:00
|
|
|
|
|
|
|
context "child factory using grandparents' trait" do
|
|
|
|
subject { FactoryGirl.create(:female_great_user) }
|
|
|
|
its(:great) { should == "GREAT!!!" }
|
|
|
|
end
|
2011-08-09 18:00:24 -04:00
|
|
|
end
|
2011-10-28 17:01:27 -04:00
|
|
|
|
|
|
|
describe "traits with callbacks" do
|
|
|
|
before do
|
2012-03-09 17:20:38 -05:00
|
|
|
define_model("User", name: :string)
|
2011-10-28 17:01:27 -04:00
|
|
|
|
|
|
|
FactoryGirl.define do
|
|
|
|
factory :user do
|
|
|
|
name "John"
|
|
|
|
|
|
|
|
trait :great do
|
2012-05-04 16:48:46 -04:00
|
|
|
after(:create) {|user| user.name.upcase! }
|
2011-10-28 17:01:27 -04:00
|
|
|
end
|
|
|
|
|
2011-11-23 18:40:35 -05:00
|
|
|
trait :awesome do
|
2012-05-04 16:48:46 -04:00
|
|
|
after(:create) {|user| user.name = "awesome" }
|
2011-11-23 18:40:35 -05:00
|
|
|
end
|
|
|
|
|
2012-03-09 17:20:38 -05:00
|
|
|
factory :caps_user, traits: [:great]
|
|
|
|
factory :awesome_user, traits: [:great, :awesome]
|
2011-10-28 17:01:27 -04:00
|
|
|
|
|
|
|
factory :caps_user_implicit_trait do
|
|
|
|
great
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when the factory has a trait passed via arguments" do
|
|
|
|
subject { FactoryGirl.create(:caps_user) }
|
|
|
|
its(:name) { should == "JOHN" }
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when the factory has an implicit trait" do
|
|
|
|
subject { FactoryGirl.create(:caps_user_implicit_trait) }
|
2011-10-28 23:01:50 -04:00
|
|
|
its(:name) { should == "JOHN" }
|
2011-10-28 17:01:27 -04:00
|
|
|
end
|
2011-11-23 18:40:35 -05:00
|
|
|
|
|
|
|
it "executes callbacks in the order assigned" do
|
|
|
|
FactoryGirl.create(:awesome_user).name.should == "awesome"
|
|
|
|
end
|
2011-10-28 17:01:27 -04:00
|
|
|
end
|
Traits can be added to factories when the factory creates an instance
This allows for traits to be used with normal factories without having
to name every single factory that uses one (or many) traits.
So, instead of creating male_admin and female_admin factories:
FactoryGirl.define do
factory :user do
trait(:admin) { admin true }
trait(:male) { gender "Male" }
trait(:female) { gender "Female" }
factory :male_admin, :traits => [:male, :admin]
factory :female_admin, :traits => [:admin, :female]
end
end
FactoryGirl.create(:male_admin)
FactoryGirl.create(:female_admin)
You could just create a user with those traits assigned:
FactoryGirl.create(:user, :admin, :male)
FactoryGirl.create(:user, :admin, :female)
This can be combined with attribute overrides as expected.
FactoryGirl.create(:user, :admin, :male, :name => "John Doe")
FactoryGirl.create(:user, :admin, :female, :name => "Jane Doe")
2011-11-18 09:25:49 -05:00
|
|
|
|
2012-02-08 10:17:57 -05:00
|
|
|
describe "traits added via strategy" do
|
Traits can be added to factories when the factory creates an instance
This allows for traits to be used with normal factories without having
to name every single factory that uses one (or many) traits.
So, instead of creating male_admin and female_admin factories:
FactoryGirl.define do
factory :user do
trait(:admin) { admin true }
trait(:male) { gender "Male" }
trait(:female) { gender "Female" }
factory :male_admin, :traits => [:male, :admin]
factory :female_admin, :traits => [:admin, :female]
end
end
FactoryGirl.create(:male_admin)
FactoryGirl.create(:female_admin)
You could just create a user with those traits assigned:
FactoryGirl.create(:user, :admin, :male)
FactoryGirl.create(:user, :admin, :female)
This can be combined with attribute overrides as expected.
FactoryGirl.create(:user, :admin, :male, :name => "John Doe")
FactoryGirl.create(:user, :admin, :female, :name => "Jane Doe")
2011-11-18 09:25:49 -05:00
|
|
|
before do
|
2012-03-09 17:20:38 -05:00
|
|
|
define_model("User", name: :string, admin: :boolean)
|
Traits can be added to factories when the factory creates an instance
This allows for traits to be used with normal factories without having
to name every single factory that uses one (or many) traits.
So, instead of creating male_admin and female_admin factories:
FactoryGirl.define do
factory :user do
trait(:admin) { admin true }
trait(:male) { gender "Male" }
trait(:female) { gender "Female" }
factory :male_admin, :traits => [:male, :admin]
factory :female_admin, :traits => [:admin, :female]
end
end
FactoryGirl.create(:male_admin)
FactoryGirl.create(:female_admin)
You could just create a user with those traits assigned:
FactoryGirl.create(:user, :admin, :male)
FactoryGirl.create(:user, :admin, :female)
This can be combined with attribute overrides as expected.
FactoryGirl.create(:user, :admin, :male, :name => "John Doe")
FactoryGirl.create(:user, :admin, :female, :name => "Jane Doe")
2011-11-18 09:25:49 -05:00
|
|
|
|
|
|
|
FactoryGirl.define do
|
|
|
|
factory :user do
|
|
|
|
name "John"
|
|
|
|
|
|
|
|
trait :admin do
|
|
|
|
admin true
|
|
|
|
end
|
|
|
|
|
|
|
|
trait :great do
|
2012-05-04 16:48:46 -04:00
|
|
|
after(:create) {|user| user.name.upcase! }
|
Traits can be added to factories when the factory creates an instance
This allows for traits to be used with normal factories without having
to name every single factory that uses one (or many) traits.
So, instead of creating male_admin and female_admin factories:
FactoryGirl.define do
factory :user do
trait(:admin) { admin true }
trait(:male) { gender "Male" }
trait(:female) { gender "Female" }
factory :male_admin, :traits => [:male, :admin]
factory :female_admin, :traits => [:admin, :female]
end
end
FactoryGirl.create(:male_admin)
FactoryGirl.create(:female_admin)
You could just create a user with those traits assigned:
FactoryGirl.create(:user, :admin, :male)
FactoryGirl.create(:user, :admin, :female)
This can be combined with attribute overrides as expected.
FactoryGirl.create(:user, :admin, :male, :name => "John Doe")
FactoryGirl.create(:user, :admin, :female, :name => "Jane Doe")
2011-11-18 09:25:49 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "adding traits in create" do
|
2012-03-09 17:20:38 -05:00
|
|
|
subject { FactoryGirl.create(:user, :admin, :great, name: "Joe") }
|
Traits can be added to factories when the factory creates an instance
This allows for traits to be used with normal factories without having
to name every single factory that uses one (or many) traits.
So, instead of creating male_admin and female_admin factories:
FactoryGirl.define do
factory :user do
trait(:admin) { admin true }
trait(:male) { gender "Male" }
trait(:female) { gender "Female" }
factory :male_admin, :traits => [:male, :admin]
factory :female_admin, :traits => [:admin, :female]
end
end
FactoryGirl.create(:male_admin)
FactoryGirl.create(:female_admin)
You could just create a user with those traits assigned:
FactoryGirl.create(:user, :admin, :male)
FactoryGirl.create(:user, :admin, :female)
This can be combined with attribute overrides as expected.
FactoryGirl.create(:user, :admin, :male, :name => "John Doe")
FactoryGirl.create(:user, :admin, :female, :name => "Jane Doe")
2011-11-18 09:25:49 -05:00
|
|
|
|
|
|
|
its(:admin) { should be_true }
|
|
|
|
its(:name) { should == "JOE" }
|
|
|
|
|
|
|
|
it "doesn't modify the user factory" do
|
|
|
|
subject
|
|
|
|
FactoryGirl.create(:user).should_not be_admin
|
|
|
|
FactoryGirl.create(:user).name.should == "John"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "adding traits in build" do
|
2012-03-09 17:20:38 -05:00
|
|
|
subject { FactoryGirl.build(:user, :admin, :great, name: "Joe") }
|
Traits can be added to factories when the factory creates an instance
This allows for traits to be used with normal factories without having
to name every single factory that uses one (or many) traits.
So, instead of creating male_admin and female_admin factories:
FactoryGirl.define do
factory :user do
trait(:admin) { admin true }
trait(:male) { gender "Male" }
trait(:female) { gender "Female" }
factory :male_admin, :traits => [:male, :admin]
factory :female_admin, :traits => [:admin, :female]
end
end
FactoryGirl.create(:male_admin)
FactoryGirl.create(:female_admin)
You could just create a user with those traits assigned:
FactoryGirl.create(:user, :admin, :male)
FactoryGirl.create(:user, :admin, :female)
This can be combined with attribute overrides as expected.
FactoryGirl.create(:user, :admin, :male, :name => "John Doe")
FactoryGirl.create(:user, :admin, :female, :name => "Jane Doe")
2011-11-18 09:25:49 -05:00
|
|
|
|
|
|
|
its(:admin) { should be_true }
|
|
|
|
its(:name) { should == "Joe" }
|
|
|
|
end
|
|
|
|
|
|
|
|
context "adding traits in attributes_for" do
|
|
|
|
subject { FactoryGirl.attributes_for(:user, :admin, :great) }
|
|
|
|
|
|
|
|
its([:admin]) { should be_true }
|
|
|
|
its([:name]) { should == "John" }
|
|
|
|
end
|
|
|
|
|
|
|
|
context "adding traits in build_stubbed" do
|
2012-03-09 17:20:38 -05:00
|
|
|
subject { FactoryGirl.build_stubbed(:user, :admin, :great, name: "Jack") }
|
Traits can be added to factories when the factory creates an instance
This allows for traits to be used with normal factories without having
to name every single factory that uses one (or many) traits.
So, instead of creating male_admin and female_admin factories:
FactoryGirl.define do
factory :user do
trait(:admin) { admin true }
trait(:male) { gender "Male" }
trait(:female) { gender "Female" }
factory :male_admin, :traits => [:male, :admin]
factory :female_admin, :traits => [:admin, :female]
end
end
FactoryGirl.create(:male_admin)
FactoryGirl.create(:female_admin)
You could just create a user with those traits assigned:
FactoryGirl.create(:user, :admin, :male)
FactoryGirl.create(:user, :admin, :female)
This can be combined with attribute overrides as expected.
FactoryGirl.create(:user, :admin, :male, :name => "John Doe")
FactoryGirl.create(:user, :admin, :female, :name => "Jane Doe")
2011-11-18 09:25:49 -05:00
|
|
|
|
|
|
|
its(:admin) { should be_true }
|
|
|
|
its(:name) { should == "Jack" }
|
|
|
|
end
|
2012-02-07 10:13:27 -05:00
|
|
|
|
|
|
|
context "adding traits in create_list" do
|
2012-03-09 17:20:38 -05:00
|
|
|
subject { FactoryGirl.create_list(:user, 2, :admin, :great, name: "Joe") }
|
2012-02-07 10:13:27 -05:00
|
|
|
|
|
|
|
its(:length) { should == 2 }
|
|
|
|
|
|
|
|
it "creates all the records" do
|
|
|
|
subject.each do |record|
|
|
|
|
record.admin.should be_true
|
|
|
|
record.name.should == "JOE"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "adding traits in build_list" do
|
2012-03-09 17:20:38 -05:00
|
|
|
subject { FactoryGirl.build_list(:user, 2, :admin, :great, name: "Joe") }
|
2012-02-07 10:13:27 -05:00
|
|
|
|
|
|
|
its(:length) { should == 2 }
|
|
|
|
|
|
|
|
it "builds all the records" do
|
|
|
|
subject.each do |record|
|
|
|
|
record.admin.should be_true
|
|
|
|
record.name.should == "Joe"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
Traits can be added to factories when the factory creates an instance
This allows for traits to be used with normal factories without having
to name every single factory that uses one (or many) traits.
So, instead of creating male_admin and female_admin factories:
FactoryGirl.define do
factory :user do
trait(:admin) { admin true }
trait(:male) { gender "Male" }
trait(:female) { gender "Female" }
factory :male_admin, :traits => [:male, :admin]
factory :female_admin, :traits => [:admin, :female]
end
end
FactoryGirl.create(:male_admin)
FactoryGirl.create(:female_admin)
You could just create a user with those traits assigned:
FactoryGirl.create(:user, :admin, :male)
FactoryGirl.create(:user, :admin, :female)
This can be combined with attribute overrides as expected.
FactoryGirl.create(:user, :admin, :male, :name => "John Doe")
FactoryGirl.create(:user, :admin, :female, :name => "Jane Doe")
2011-11-18 09:25:49 -05:00
|
|
|
end
|
2011-11-23 18:56:07 -05:00
|
|
|
|
|
|
|
describe "traits and dynamic attributes that are applied simultaneously" do
|
|
|
|
before do
|
2012-03-09 17:20:38 -05:00
|
|
|
define_model("User", name: :string, email: :string, combined: :string)
|
2011-11-23 18:56:07 -05:00
|
|
|
|
|
|
|
FactoryGirl.define do
|
|
|
|
trait :email do
|
|
|
|
email { "#{name}@example.com" }
|
|
|
|
end
|
|
|
|
|
|
|
|
factory :user do
|
|
|
|
name "John"
|
|
|
|
email
|
|
|
|
combined { "#{name} <#{email}>" }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
subject { FactoryGirl.build(:user) }
|
|
|
|
its(:name) { should == "John" }
|
|
|
|
its(:email) { should == "John@example.com" }
|
|
|
|
its(:combined) { should == "John <John@example.com>" }
|
|
|
|
end
|
2012-01-16 12:29:43 -05:00
|
|
|
|
|
|
|
describe "applying inline traits" do
|
|
|
|
before do
|
|
|
|
define_model("User") do
|
|
|
|
has_many :posts
|
|
|
|
end
|
|
|
|
|
2012-03-09 17:20:38 -05:00
|
|
|
define_model("Post", user_id: :integer) do
|
2012-01-16 12:29:43 -05:00
|
|
|
belongs_to :user
|
|
|
|
end
|
|
|
|
|
|
|
|
FactoryGirl.define do
|
|
|
|
factory :user do
|
|
|
|
trait :with_post do
|
|
|
|
posts { [ Post.new ] }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "applies traits only to the instance generated for that call" do
|
|
|
|
FactoryGirl.create(:user, :with_post).posts.should_not be_empty
|
|
|
|
FactoryGirl.create(:user).posts.should be_empty
|
|
|
|
FactoryGirl.create(:user, :with_post).posts.should_not be_empty
|
|
|
|
end
|
|
|
|
end
|
2012-01-17 23:15:41 -05:00
|
|
|
|
|
|
|
describe "inline traits overriding existing attributes" do
|
|
|
|
before do
|
2012-03-09 17:20:38 -05:00
|
|
|
define_model("User", status: :string)
|
2012-01-17 23:15:41 -05:00
|
|
|
|
|
|
|
FactoryGirl.define do
|
|
|
|
factory :user do
|
|
|
|
status "pending"
|
|
|
|
|
|
|
|
trait(:accepted) { status "accepted" }
|
|
|
|
trait(:declined) { status "declined" }
|
|
|
|
|
2012-03-09 17:20:38 -05:00
|
|
|
factory :declined_user, traits: [:declined]
|
|
|
|
factory :extended_declined_user, traits: [:declined] do
|
2012-01-17 23:15:41 -05:00
|
|
|
status "extended_declined"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns the default status" do
|
|
|
|
FactoryGirl.build(:user).status.should == "pending"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "prefers inline trait attributes over default attributes" do
|
|
|
|
FactoryGirl.build(:user, :accepted).status.should == "accepted"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "prefers traits on a factory over default attributes" do
|
|
|
|
FactoryGirl.build(:declined_user).status.should == "declined"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "prefers inline trait attributes over traits on a factory" do
|
|
|
|
FactoryGirl.build(:declined_user, :accepted).status.should == "accepted"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "prefers attributes on factories over attributes from non-inline traits" do
|
|
|
|
FactoryGirl.build(:extended_declined_user).status.should == "extended_declined"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "prefers inline traits over attributes on factories" do
|
|
|
|
FactoryGirl.build(:extended_declined_user, :accepted).status.should == "accepted"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "prefers overridden attributes over attributes from traits, inline traits, or attributes on factories" do
|
2012-03-09 17:20:38 -05:00
|
|
|
FactoryGirl.build(:extended_declined_user, :accepted, status: "completely overridden").status.should == "completely overridden"
|
2012-01-17 23:15:41 -05:00
|
|
|
end
|
|
|
|
end
|
2012-03-09 14:05:05 -05:00
|
|
|
|
|
|
|
describe "making sure the factory is properly compiled the first time we want to instantiate it" do
|
|
|
|
before do
|
2012-03-09 17:20:38 -05:00
|
|
|
define_model("User", role: :string, gender: :string, age: :integer)
|
2012-03-09 14:05:05 -05:00
|
|
|
|
|
|
|
FactoryGirl.define do
|
|
|
|
factory :user do
|
|
|
|
trait(:female) { gender "female" }
|
|
|
|
trait(:admin) { role "admin" }
|
|
|
|
|
|
|
|
factory :female_user do
|
|
|
|
female
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "can honor traits on the very first call" do
|
2012-03-09 17:20:38 -05:00
|
|
|
user = FactoryGirl.build(:female_user, :admin, age: 30)
|
2012-03-09 14:05:05 -05:00
|
|
|
user.gender.should == 'female'
|
|
|
|
user.age.should == 30
|
|
|
|
user.role.should == 'admin'
|
|
|
|
end
|
|
|
|
end
|
2012-05-06 16:56:37 -04:00
|
|
|
|
2012-05-11 11:43:08 -04:00
|
|
|
describe "traits with to_create" do
|
2012-05-06 16:56:37 -04:00
|
|
|
before do
|
|
|
|
define_model("User", name: :string)
|
|
|
|
|
|
|
|
FactoryGirl.define do
|
|
|
|
factory :user do
|
|
|
|
trait :with_to_create do
|
|
|
|
to_create {|instance| instance.name = "to_create" }
|
|
|
|
end
|
|
|
|
|
|
|
|
factory :sub_user do
|
|
|
|
to_create {|instance| instance.name = "sub" }
|
|
|
|
|
|
|
|
factory :child_user
|
|
|
|
end
|
|
|
|
|
|
|
|
factory :sub_user_with_trait do
|
|
|
|
with_to_create
|
|
|
|
|
|
|
|
factory :child_user_with_trait
|
|
|
|
end
|
|
|
|
|
|
|
|
factory :sub_user_with_trait_and_override do
|
|
|
|
with_to_create
|
|
|
|
to_create {|instance| instance.name = "sub with trait and override" }
|
|
|
|
|
|
|
|
factory :child_user_with_trait_and_override
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "can apply to_create from traits" do
|
|
|
|
FactoryGirl.create(:user, :with_to_create).name.should == "to_create"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "can apply to_create from the definition" do
|
|
|
|
FactoryGirl.create(:sub_user).name.should == "sub"
|
|
|
|
FactoryGirl.create(:child_user).name.should == "sub"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "gives additional traits higher priority than to_create from the definition" do
|
|
|
|
FactoryGirl.create(:sub_user, :with_to_create).name.should == "to_create"
|
|
|
|
FactoryGirl.create(:child_user, :with_to_create).name.should == "to_create"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "gives base traits normal priority" do
|
|
|
|
FactoryGirl.create(:sub_user_with_trait).name.should == "to_create"
|
|
|
|
FactoryGirl.create(:child_user_with_trait).name.should == "to_create"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "gives base traits lower priority than overrides" do
|
|
|
|
FactoryGirl.create(:sub_user_with_trait_and_override).name.should == "sub with trait and override"
|
|
|
|
FactoryGirl.create(:child_user_with_trait_and_override).name.should == "sub with trait and override"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "gives additional traits higher priority than base traits and factory definition" do
|
|
|
|
FactoryGirl.define do
|
|
|
|
trait :overridden do
|
|
|
|
to_create {|instance| instance.name = "completely overridden" }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
FactoryGirl.create(:sub_user_with_trait_and_override, :overridden).name.should == "completely overridden"
|
|
|
|
FactoryGirl.create(:child_user_with_trait_and_override, :overridden).name.should == "completely overridden"
|
|
|
|
end
|
|
|
|
end
|
2012-05-11 11:43:08 -04:00
|
|
|
|
|
|
|
describe "traits with initialize_with" do
|
|
|
|
before do
|
2012-05-18 14:28:51 -04:00
|
|
|
ActiveSupport::Deprecation.silenced = true
|
|
|
|
|
2012-05-11 11:43:08 -04:00
|
|
|
define_class("User") do
|
|
|
|
attr_reader :name
|
|
|
|
|
|
|
|
def initialize(name)
|
|
|
|
@name = name
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
FactoryGirl.define do
|
|
|
|
factory :user do
|
|
|
|
trait :with_initialize_with do
|
|
|
|
initialize_with { new("initialize_with") }
|
|
|
|
end
|
|
|
|
|
|
|
|
factory :sub_user do
|
|
|
|
initialize_with { new("sub") }
|
|
|
|
|
|
|
|
factory :child_user
|
|
|
|
end
|
|
|
|
|
|
|
|
factory :sub_user_with_trait do
|
|
|
|
with_initialize_with
|
|
|
|
|
|
|
|
factory :child_user_with_trait
|
|
|
|
end
|
|
|
|
|
|
|
|
factory :sub_user_with_trait_and_override do
|
|
|
|
with_initialize_with
|
|
|
|
initialize_with { new("sub with trait and override") }
|
|
|
|
|
|
|
|
factory :child_user_with_trait_and_override
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "can apply initialize_with from traits" do
|
|
|
|
FactoryGirl.build(:user, :with_initialize_with).name.should == "initialize_with"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "can apply initialize_with from the definition" do
|
|
|
|
FactoryGirl.build(:sub_user).name.should == "sub"
|
|
|
|
FactoryGirl.build(:child_user).name.should == "sub"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "gives additional traits higher priority than initialize_with from the definition" do
|
|
|
|
FactoryGirl.build(:sub_user, :with_initialize_with).name.should == "initialize_with"
|
|
|
|
FactoryGirl.build(:child_user, :with_initialize_with).name.should == "initialize_with"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "gives base traits normal priority" do
|
|
|
|
FactoryGirl.build(:sub_user_with_trait).name.should == "initialize_with"
|
|
|
|
FactoryGirl.build(:child_user_with_trait).name.should == "initialize_with"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "gives base traits lower priority than overrides" do
|
|
|
|
FactoryGirl.build(:sub_user_with_trait_and_override).name.should == "sub with trait and override"
|
|
|
|
FactoryGirl.build(:child_user_with_trait_and_override).name.should == "sub with trait and override"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "gives additional traits higher priority than base traits and factory definition" do
|
|
|
|
FactoryGirl.define do
|
|
|
|
trait :overridden do
|
|
|
|
initialize_with { new("completely overridden") }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
FactoryGirl.build(:sub_user_with_trait_and_override, :overridden).name.should == "completely overridden"
|
|
|
|
FactoryGirl.build(:child_user_with_trait_and_override, :overridden).name.should == "completely overridden"
|
|
|
|
end
|
|
|
|
end
|
2012-06-12 23:11:55 -04:00
|
|
|
|
|
|
|
describe "nested implicit traits" do
|
|
|
|
before do
|
|
|
|
define_class("User") do
|
|
|
|
attr_accessor :gender, :role
|
|
|
|
attr_reader :name
|
|
|
|
|
|
|
|
def initialize(name)
|
|
|
|
@name = name
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples_for "assigning data from traits" do
|
|
|
|
it "assigns the correct values" do
|
|
|
|
user = FactoryGirl.create(:user, :female_admin)
|
|
|
|
user.gender.should == "FEMALE"
|
|
|
|
user.role.should == "ADMIN"
|
|
|
|
user.name.should == "Jane Doe"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "defined outside the factory" do
|
|
|
|
before do
|
|
|
|
FactoryGirl.define do
|
|
|
|
trait :female do
|
|
|
|
gender "female"
|
|
|
|
to_create {|instance| instance.gender = instance.gender.upcase }
|
|
|
|
end
|
|
|
|
|
|
|
|
trait :jane_doe do
|
|
|
|
initialize_with { new("Jane Doe") }
|
|
|
|
end
|
|
|
|
|
|
|
|
trait :admin do
|
|
|
|
role "admin"
|
|
|
|
after(:build) {|instance| instance.role = instance.role.upcase }
|
|
|
|
end
|
|
|
|
|
|
|
|
trait :female_admin do
|
|
|
|
female
|
|
|
|
admin
|
|
|
|
jane_doe
|
|
|
|
end
|
|
|
|
|
|
|
|
factory :user
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it_should_behave_like "assigning data from traits"
|
|
|
|
end
|
|
|
|
|
|
|
|
context "defined inside the factory" do
|
|
|
|
before do
|
|
|
|
FactoryGirl.define do
|
|
|
|
factory :user do
|
|
|
|
trait :female do
|
|
|
|
gender "female"
|
|
|
|
to_create {|instance| instance.gender = instance.gender.upcase }
|
|
|
|
end
|
|
|
|
|
|
|
|
trait :jane_doe do
|
|
|
|
initialize_with { new("Jane Doe") }
|
|
|
|
end
|
|
|
|
|
|
|
|
trait :admin do
|
|
|
|
role "admin"
|
|
|
|
after(:build) {|instance| instance.role = instance.role.upcase }
|
|
|
|
end
|
|
|
|
|
|
|
|
trait :female_admin do
|
|
|
|
female
|
|
|
|
admin
|
|
|
|
jane_doe
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it_should_behave_like "assigning data from traits"
|
|
|
|
end
|
|
|
|
end
|
2012-06-19 22:25:46 -04:00
|
|
|
|
|
|
|
describe "implicit traits containing callbacks" do
|
|
|
|
before do
|
|
|
|
define_model("User", value: :integer)
|
|
|
|
|
|
|
|
FactoryGirl.define do
|
|
|
|
factory :user do
|
|
|
|
value 0
|
|
|
|
|
|
|
|
trait :trait_with_callback do
|
|
|
|
after(:build) {|user| user.value += 1 }
|
|
|
|
end
|
|
|
|
|
|
|
|
factory :user_with_trait_with_callback do
|
|
|
|
trait_with_callback
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "only runs the callback once" do
|
|
|
|
FactoryGirl.build(:user_with_trait_with_callback).value.should == 1
|
|
|
|
end
|
|
|
|
end
|
2012-06-29 11:06:08 -04:00
|
|
|
|
|
|
|
describe "traits used in associations" do
|
|
|
|
before do
|
|
|
|
define_model("User", admin: :boolean, name: :string)
|
|
|
|
define_model("Post", author_id: :integer) do
|
|
|
|
belongs_to :author, class_name: 'User'
|
|
|
|
end
|
|
|
|
|
|
|
|
FactoryGirl.define do
|
|
|
|
factory :user do
|
|
|
|
admin false
|
|
|
|
|
|
|
|
trait :admin do
|
|
|
|
admin true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
factory :post do
|
|
|
|
association :author, factory: [:user, :admin], name: 'John Doe'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "allows assigning traits for the factory of an association" do
|
|
|
|
author = FactoryGirl.create(:post).author
|
|
|
|
author.should be_admin
|
|
|
|
author.name.should == 'John Doe'
|
|
|
|
end
|
|
|
|
end
|