factory_girl 2.0.5 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|