factory_girl 2.0.5 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +9 -0
- data/.gitignore +8 -0
- data/.rspec +2 -0
- data/.travis.yml +10 -0
- data/.yardopts +5 -0
- data/Appraisals +3 -0
- data/GETTING_STARTED.md +67 -8
- data/Gemfile +2 -11
- data/Gemfile.lock +51 -34
- data/README.md +3 -1
- data/cucumber.yml +1 -0
- data/features/find_definitions.feature +21 -8
- data/features/step_definitions/factory_girl_steps.rb +4 -4
- data/gemfiles/2.1.gemfile +8 -0
- data/gemfiles/2.1.gemfile.lock +73 -0
- data/gemfiles/2.3.gemfile +7 -0
- data/gemfiles/2.3.gemfile.lock +71 -0
- data/gemfiles/3.0.gemfile +7 -0
- data/gemfiles/3.0.gemfile.lock +81 -0
- data/gemfiles/3.1.gemfile +7 -0
- data/gemfiles/3.1.gemfile.lock +91 -0
- data/lib/factory_girl.rb +1 -0
- data/lib/factory_girl/attribute.rb +4 -0
- data/lib/factory_girl/attribute_list.rb +35 -13
- data/lib/factory_girl/factory.rb +36 -9
- data/lib/factory_girl/proxy/build.rb +21 -2
- data/lib/factory_girl/proxy/create.rb +6 -0
- data/lib/factory_girl/proxy/stub.rb +10 -2
- data/lib/factory_girl/rails2.rb +1 -0
- data/lib/factory_girl/reload.rb +8 -0
- data/lib/factory_girl/syntax/default.rb +16 -0
- data/lib/factory_girl/version.rb +1 -1
- data/spec/acceptance/build_spec.rb +31 -0
- data/spec/acceptance/create_spec.rb +27 -1
- data/spec/acceptance/modify_factories_spec.rb +184 -0
- data/spec/acceptance/stub_spec.rb +64 -0
- data/spec/factory_girl/attribute_list_spec.rb +54 -2
- data/spec/factory_girl/factory_spec.rb +6 -4
- data/spec/factory_girl/proxy/build_spec.rb +24 -0
- data/spec/factory_girl/proxy/stub_spec.rb +14 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/shared_examples/proxy.rb +29 -0
- metadata +109 -57
- data/features/support/test.db +0 -0
@@ -23,19 +23,38 @@ module FactoryGirl
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def associate(name, factory_name, overrides)
|
26
|
+
method = get_method(overrides[:method])
|
26
27
|
factory = FactoryGirl.factory_by_name(factory_name)
|
27
|
-
set(name, factory.run(
|
28
|
+
set(name, factory.run(method, remove_method(overrides)))
|
28
29
|
end
|
29
30
|
|
30
31
|
def association(factory_name, overrides = {})
|
32
|
+
method = get_method(overrides[:method])
|
31
33
|
factory = FactoryGirl.factory_by_name(factory_name)
|
32
|
-
factory.run(
|
34
|
+
factory.run(method, remove_method(overrides))
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove_method(overrides)
|
38
|
+
overrides.dup.delete_if {|key, value| key == :method}
|
33
39
|
end
|
34
40
|
|
35
41
|
def result(to_create)
|
36
42
|
run_callbacks(:after_build)
|
37
43
|
@instance
|
38
44
|
end
|
45
|
+
|
46
|
+
def parse_method(method)
|
47
|
+
method ||= :create
|
48
|
+
if :build == method
|
49
|
+
return Proxy::Build
|
50
|
+
elsif :create == method
|
51
|
+
return Proxy::Create
|
52
|
+
else
|
53
|
+
raise "unrecognized method #{method}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
alias_method :get_method, :parse_method
|
39
58
|
end
|
40
59
|
end
|
41
60
|
end
|
@@ -11,6 +11,12 @@ module FactoryGirl
|
|
11
11
|
run_callbacks(:after_create)
|
12
12
|
@instance
|
13
13
|
end
|
14
|
+
|
15
|
+
def get_method(method_string)
|
16
|
+
# Leaving this as Proxy::Build in the :method => :build case
|
17
|
+
# is a bit strange, but does it have any user-visible behaviors?
|
18
|
+
parse_method(method_string)
|
19
|
+
end
|
14
20
|
end
|
15
21
|
end
|
16
22
|
end
|
@@ -12,6 +12,10 @@ module FactoryGirl
|
|
12
12
|
!new_record?
|
13
13
|
end
|
14
14
|
|
15
|
+
def created_at
|
16
|
+
@created_at ||= Time.now
|
17
|
+
end
|
18
|
+
|
15
19
|
def new_record?
|
16
20
|
id.nil?
|
17
21
|
end
|
@@ -60,12 +64,16 @@ module FactoryGirl
|
|
60
64
|
|
61
65
|
def associate(name, factory_name, overrides)
|
62
66
|
factory = FactoryGirl.factory_by_name(factory_name)
|
63
|
-
set(name, factory.run(Proxy::Stub, overrides))
|
67
|
+
set(name, factory.run(Proxy::Stub, remove_method(overrides)))
|
64
68
|
end
|
65
69
|
|
66
70
|
def association(factory_name, overrides = {})
|
67
71
|
factory = FactoryGirl.factory_by_name(factory_name)
|
68
|
-
factory.run(Proxy::Stub, overrides)
|
72
|
+
factory.run(Proxy::Stub, remove_method(overrides))
|
73
|
+
end
|
74
|
+
|
75
|
+
def remove_method(overrides)
|
76
|
+
overrides.dup.delete_if {|key, value| key == :method}
|
69
77
|
end
|
70
78
|
|
71
79
|
def result(to_create)
|
data/lib/factory_girl/rails2.rb
CHANGED
@@ -7,6 +7,10 @@ module FactoryGirl
|
|
7
7
|
DSL.run(block)
|
8
8
|
end
|
9
9
|
|
10
|
+
def modify(&block)
|
11
|
+
ModifyDSL.run(block)
|
12
|
+
end
|
13
|
+
|
10
14
|
class DSL
|
11
15
|
def self.run(block)
|
12
16
|
new.instance_eval(&block)
|
@@ -39,6 +43,18 @@ module FactoryGirl
|
|
39
43
|
FactoryGirl.register_trait(Trait.new(name, &block))
|
40
44
|
end
|
41
45
|
end
|
46
|
+
|
47
|
+
class ModifyDSL
|
48
|
+
def self.run(block)
|
49
|
+
new.instance_eval(&block)
|
50
|
+
end
|
51
|
+
|
52
|
+
def factory(name, options = {}, &block)
|
53
|
+
factory = FactoryGirl.factory_by_name(name).allow_overrides
|
54
|
+
proxy = FactoryGirl::DefinitionProxy.new(factory)
|
55
|
+
proxy.instance_eval(&block)
|
56
|
+
end
|
57
|
+
end
|
42
58
|
end
|
43
59
|
end
|
44
60
|
|
data/lib/factory_girl/version.rb
CHANGED
@@ -31,3 +31,34 @@ describe "a built instance" do
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
describe "a built instance with :method => :build" do
|
35
|
+
include FactoryGirl::Syntax::Methods
|
36
|
+
|
37
|
+
before do
|
38
|
+
define_model('User')
|
39
|
+
|
40
|
+
define_model('Post', :user_id => :integer) do
|
41
|
+
belongs_to :user
|
42
|
+
end
|
43
|
+
|
44
|
+
FactoryGirl.define do
|
45
|
+
factory :user
|
46
|
+
|
47
|
+
factory :post do
|
48
|
+
association(:user, :method => :build)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
subject { build(:post) }
|
54
|
+
|
55
|
+
it "isn't saved" do
|
56
|
+
should be_new_record
|
57
|
+
end
|
58
|
+
|
59
|
+
it "assigns but does not save associations" do
|
60
|
+
subject.user.should be_kind_of(User)
|
61
|
+
subject.user.should be_new_record
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -31,6 +31,33 @@ describe "a created instance" do
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
describe "a created instance, specifying :method => build" do
|
35
|
+
include FactoryGirl::Syntax::Methods
|
36
|
+
|
37
|
+
before do
|
38
|
+
define_model('User')
|
39
|
+
|
40
|
+
define_model('Post', :user_id => :integer) do
|
41
|
+
belongs_to :user
|
42
|
+
end
|
43
|
+
|
44
|
+
FactoryGirl.define do
|
45
|
+
factory :user
|
46
|
+
|
47
|
+
factory :post do
|
48
|
+
association(:user, :method => :build)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
subject { create('post') }
|
54
|
+
|
55
|
+
it "still saves associations (:method => :build only affects build, not create)" do
|
56
|
+
subject.user.should be_kind_of(User)
|
57
|
+
subject.user.should_not be_new_record
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
34
61
|
describe "a custom create" do
|
35
62
|
include FactoryGirl::Syntax::Methods
|
36
63
|
|
@@ -62,4 +89,3 @@ describe "a custom create" do
|
|
62
89
|
FactoryGirl.create(:user).should be_persisted
|
63
90
|
end
|
64
91
|
end
|
65
|
-
|
@@ -0,0 +1,184 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "modifying factories" do
|
4
|
+
include FactoryGirl::Syntax::Methods
|
5
|
+
|
6
|
+
before do
|
7
|
+
define_model('User', :name => :string, :admin => :boolean, :email => :string, :login => :string)
|
8
|
+
|
9
|
+
FactoryGirl.define do
|
10
|
+
sequence(:email) {|n| "user#{n}@example.com" }
|
11
|
+
|
12
|
+
factory :user do
|
13
|
+
email
|
14
|
+
|
15
|
+
after_create do |user|
|
16
|
+
user.login = user.name.upcase if user.name
|
17
|
+
end
|
18
|
+
|
19
|
+
factory :admin do
|
20
|
+
admin true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "simple modification" do
|
27
|
+
before do
|
28
|
+
FactoryGirl.modify do
|
29
|
+
factory :user do
|
30
|
+
name "Great User"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
subject { create(:user) }
|
36
|
+
its(:name) { should == "Great User" }
|
37
|
+
its(:login) { should == "GREAT USER" }
|
38
|
+
|
39
|
+
it "doesn't allow the factory to be subsequently defined" do
|
40
|
+
expect do
|
41
|
+
FactoryGirl.define { factory :user }
|
42
|
+
end.to raise_error(FactoryGirl::DuplicateDefinitionError)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "does allow the factory to be subsequently modified" do
|
46
|
+
FactoryGirl.modify do
|
47
|
+
factory :user do
|
48
|
+
name "Overridden again!"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
create(:user).name.should == "Overridden again!"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "adding callbacks" do
|
57
|
+
before do
|
58
|
+
FactoryGirl.modify do
|
59
|
+
factory :user do
|
60
|
+
name "Great User"
|
61
|
+
after_create do |user|
|
62
|
+
user.name = user.name.downcase
|
63
|
+
user.login = nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
subject { create(:user) }
|
70
|
+
|
71
|
+
its(:name) { should == "great user" }
|
72
|
+
its(:login) { should be_nil }
|
73
|
+
end
|
74
|
+
|
75
|
+
context "reusing traits" do
|
76
|
+
before do
|
77
|
+
FactoryGirl.define do
|
78
|
+
trait :rockstar do
|
79
|
+
name "Johnny Rockstar!!!"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
FactoryGirl.modify do
|
84
|
+
factory :user do
|
85
|
+
rockstar
|
86
|
+
email { "#{name}@example.com" }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
subject { create(:user) }
|
92
|
+
|
93
|
+
its(:name) { should == "Johnny Rockstar!!!" }
|
94
|
+
its(:email) { should == "Johnny Rockstar!!!@example.com" }
|
95
|
+
its(:login) { should == "JOHNNY ROCKSTAR!!!" }
|
96
|
+
end
|
97
|
+
|
98
|
+
context "redefining attributes" do
|
99
|
+
before do
|
100
|
+
FactoryGirl.modify do
|
101
|
+
factory :user do
|
102
|
+
email { "#{name}-modified@example.com" }
|
103
|
+
name "Great User"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "creating user" do
|
109
|
+
context "without overrides" do
|
110
|
+
subject { create(:user) }
|
111
|
+
|
112
|
+
its(:name) { should == "Great User" }
|
113
|
+
its(:email) { should == "Great User-modified@example.com" }
|
114
|
+
end
|
115
|
+
|
116
|
+
context "overriding dynamic attributes" do
|
117
|
+
subject { create(:user, :email => "perfect@example.com") }
|
118
|
+
|
119
|
+
its(:name) { should == "Great User" }
|
120
|
+
its(:email) { should == "perfect@example.com" }
|
121
|
+
end
|
122
|
+
|
123
|
+
context "overriding static attributes" do
|
124
|
+
subject { create(:user, :name => "wonderful") }
|
125
|
+
|
126
|
+
its(:name) { should == "wonderful" }
|
127
|
+
its(:email) { should == "wonderful-modified@example.com" }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "creating admin" do
|
132
|
+
context "without overrides" do
|
133
|
+
subject { create(:admin) }
|
134
|
+
|
135
|
+
its(:name) { should == "Great User" }
|
136
|
+
its(:email) { should == "Great User-modified@example.com" }
|
137
|
+
its(:admin) { should be_true }
|
138
|
+
end
|
139
|
+
|
140
|
+
context "overriding dynamic attributes" do
|
141
|
+
subject { create(:admin, :email => "perfect@example.com") }
|
142
|
+
|
143
|
+
its(:name) { should == "Great User" }
|
144
|
+
its(:email) { should == "perfect@example.com" }
|
145
|
+
its(:admin) { should be_true }
|
146
|
+
end
|
147
|
+
|
148
|
+
context "overriding static attributes" do
|
149
|
+
subject { create(:admin, :name => "wonderful") }
|
150
|
+
|
151
|
+
its(:name) { should == "wonderful" }
|
152
|
+
its(:email) { should == "wonderful-modified@example.com" }
|
153
|
+
its(:admin) { should be_true }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it "doesn't overwrite already defined child's attributes" do
|
159
|
+
FactoryGirl.modify do
|
160
|
+
factory :user do
|
161
|
+
admin false
|
162
|
+
end
|
163
|
+
end
|
164
|
+
create(:admin).should be_admin
|
165
|
+
end
|
166
|
+
|
167
|
+
it "allows for overriding child classes" do
|
168
|
+
FactoryGirl.modify do
|
169
|
+
factory :admin do
|
170
|
+
admin false
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
create(:admin).should_not be_admin
|
175
|
+
end
|
176
|
+
|
177
|
+
it "raises an exception if the factory was not defined before" do
|
178
|
+
lambda {
|
179
|
+
FactoryGirl.modify do
|
180
|
+
factory :unknown_factory
|
181
|
+
end
|
182
|
+
}.should raise_error(ArgumentError)
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "a stubbed instance" do
|
4
|
+
include FactoryGirl::Syntax::Methods
|
5
|
+
|
6
|
+
before do
|
7
|
+
define_model('User')
|
8
|
+
|
9
|
+
define_model('Post', :user_id => :integer) do
|
10
|
+
belongs_to :user
|
11
|
+
end
|
12
|
+
|
13
|
+
FactoryGirl.define do
|
14
|
+
factory :user
|
15
|
+
|
16
|
+
factory :post do
|
17
|
+
user
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
subject { build_stubbed(:post) }
|
23
|
+
|
24
|
+
it "acts as if it came from the database" do
|
25
|
+
should_not be_new_record
|
26
|
+
end
|
27
|
+
|
28
|
+
it "assigns associations and acts as if it is saved" do
|
29
|
+
subject.user.should be_kind_of(User)
|
30
|
+
subject.user.should_not be_new_record
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "a stubbed instance with :method => :build" do
|
35
|
+
include FactoryGirl::Syntax::Methods
|
36
|
+
|
37
|
+
before do
|
38
|
+
define_model('User')
|
39
|
+
|
40
|
+
define_model('Post', :user_id => :integer) do
|
41
|
+
belongs_to :user
|
42
|
+
end
|
43
|
+
|
44
|
+
FactoryGirl.define do
|
45
|
+
factory :user
|
46
|
+
|
47
|
+
factory :post do
|
48
|
+
association(:user, :method => :build)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
subject { build_stubbed(:post) }
|
54
|
+
|
55
|
+
it "acts as if it is saved in the database" do
|
56
|
+
should_not be_new_record
|
57
|
+
end
|
58
|
+
|
59
|
+
it "assigns associations and acts as if it is saved" do
|
60
|
+
subject.user.should be_kind_of(User)
|
61
|
+
subject.user.should_not be_new_record
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|