factory_girl 4.5.0 → 4.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +25 -5
  3. data/Appraisals +11 -7
  4. data/CONTRIBUTING.md +44 -6
  5. data/GETTING_STARTED.md +175 -59
  6. data/Gemfile +5 -0
  7. data/Gemfile.lock +86 -63
  8. data/LICENSE +1 -1
  9. data/NEWS +12 -1
  10. data/README.md +21 -10
  11. data/Rakefile +1 -3
  12. data/factory_girl.gemspec +6 -14
  13. data/gemfiles/3.2.gemfile +4 -1
  14. data/gemfiles/3.2.gemfile.lock +84 -52
  15. data/gemfiles/4.0.gemfile +4 -1
  16. data/gemfiles/4.0.gemfile.lock +75 -49
  17. data/gemfiles/4.1.gemfile +4 -1
  18. data/gemfiles/4.1.gemfile.lock +78 -48
  19. data/gemfiles/4.2.gemfile +10 -0
  20. data/gemfiles/4.2.gemfile.lock +123 -0
  21. data/gemfiles/5.0.gemfile +10 -0
  22. data/gemfiles/5.0.gemfile.lock +126 -0
  23. data/lib/factory_girl.rb +13 -4
  24. data/lib/factory_girl/attribute/dynamic.rb +4 -1
  25. data/lib/factory_girl/attribute_assigner.rb +2 -2
  26. data/lib/factory_girl/configuration.rb +4 -0
  27. data/lib/factory_girl/decorator.rb +2 -2
  28. data/lib/factory_girl/decorator/class_key_hash.rb +2 -1
  29. data/lib/factory_girl/definition_proxy.rb +2 -2
  30. data/lib/factory_girl/evaluator.rb +4 -0
  31. data/lib/factory_girl/factory_runner.rb +7 -1
  32. data/lib/factory_girl/find_definitions.rb +1 -1
  33. data/lib/factory_girl/linter.rb +65 -14
  34. data/lib/factory_girl/strategy/stub.rb +25 -1
  35. data/lib/factory_girl/strategy_syntax_method_registrar.rb +4 -0
  36. data/lib/factory_girl/version.rb +1 -1
  37. metadata +26 -185
  38. data/features/find_definitions.feature +0 -75
  39. data/features/step_definitions/database_steps.rb +0 -9
  40. data/features/step_definitions/factory_girl_steps.rb +0 -36
  41. data/features/support/env.rb +0 -10
  42. data/features/support/factories.rb +0 -16
  43. data/gemfiles/3.1.gemfile +0 -7
  44. data/gemfiles/3.1.gemfile.lock +0 -91
  45. data/spec/acceptance/activesupport_instrumentation_spec.rb +0 -62
  46. data/spec/acceptance/aliases_spec.rb +0 -19
  47. data/spec/acceptance/attribute_aliases_spec.rb +0 -45
  48. data/spec/acceptance/attribute_existing_on_object_spec.rb +0 -68
  49. data/spec/acceptance/attributes_for_spec.rb +0 -97
  50. data/spec/acceptance/attributes_from_instance_spec.rb +0 -53
  51. data/spec/acceptance/attributes_ordered_spec.rb +0 -51
  52. data/spec/acceptance/build_list_spec.rb +0 -56
  53. data/spec/acceptance/build_spec.rb +0 -86
  54. data/spec/acceptance/build_stubbed_spec.rb +0 -161
  55. data/spec/acceptance/callbacks_spec.rb +0 -253
  56. data/spec/acceptance/create_list_spec.rb +0 -97
  57. data/spec/acceptance/create_pair_spec.rb +0 -32
  58. data/spec/acceptance/create_spec.rb +0 -116
  59. data/spec/acceptance/define_child_before_parent_spec.rb +0 -21
  60. data/spec/acceptance/defining_methods_inside_a_factory_spec.rb +0 -17
  61. data/spec/acceptance/definition_camel_string_spec.rb +0 -15
  62. data/spec/acceptance/definition_spec.rb +0 -21
  63. data/spec/acceptance/definition_without_block_spec.rb +0 -15
  64. data/spec/acceptance/global_initialize_with_spec.rb +0 -82
  65. data/spec/acceptance/global_to_create_spec.rb +0 -122
  66. data/spec/acceptance/initialize_with_spec.rb +0 -217
  67. data/spec/acceptance/keyed_by_class_spec.rb +0 -22
  68. data/spec/acceptance/lint_spec.rb +0 -65
  69. data/spec/acceptance/modify_factories_spec.rb +0 -184
  70. data/spec/acceptance/modify_inherited_spec.rb +0 -52
  71. data/spec/acceptance/nested_attributes_spec.rb +0 -32
  72. data/spec/acceptance/overrides_spec.rb +0 -61
  73. data/spec/acceptance/parent_spec.rb +0 -90
  74. data/spec/acceptance/private_attributes_spec.rb +0 -20
  75. data/spec/acceptance/register_strategies_spec.rb +0 -136
  76. data/spec/acceptance/sequence_context_spec.rb +0 -52
  77. data/spec/acceptance/sequence_spec.rb +0 -61
  78. data/spec/acceptance/skip_create_spec.rb +0 -19
  79. data/spec/acceptance/stub_spec.rb +0 -62
  80. data/spec/acceptance/syntax_methods_within_dynamic_attributes_spec.rb +0 -51
  81. data/spec/acceptance/traits_spec.rb +0 -727
  82. data/spec/acceptance/transient_attributes_spec.rb +0 -151
  83. data/spec/factory_girl/aliases_spec.rb +0 -31
  84. data/spec/factory_girl/attribute/association_spec.rb +0 -28
  85. data/spec/factory_girl/attribute/dynamic_spec.rb +0 -52
  86. data/spec/factory_girl/attribute/sequence_spec.rb +0 -16
  87. data/spec/factory_girl/attribute/static_spec.rb +0 -19
  88. data/spec/factory_girl/attribute_list_spec.rb +0 -143
  89. data/spec/factory_girl/attribute_spec.rb +0 -16
  90. data/spec/factory_girl/callback_spec.rb +0 -41
  91. data/spec/factory_girl/declaration/implicit_spec.rb +0 -25
  92. data/spec/factory_girl/declaration_list_spec.rb +0 -67
  93. data/spec/factory_girl/definition_proxy_spec.rb +0 -215
  94. data/spec/factory_girl/definition_spec.rb +0 -64
  95. data/spec/factory_girl/disallows_duplicates_registry_spec.rb +0 -19
  96. data/spec/factory_girl/evaluator_class_definer_spec.rb +0 -77
  97. data/spec/factory_girl/factory_spec.rb +0 -259
  98. data/spec/factory_girl/find_definitions_spec.rb +0 -110
  99. data/spec/factory_girl/null_factory_spec.rb +0 -13
  100. data/spec/factory_girl/null_object_spec.rb +0 -22
  101. data/spec/factory_girl/registry_spec.rb +0 -68
  102. data/spec/factory_girl/sequence_spec.rb +0 -95
  103. data/spec/factory_girl/strategy/attributes_for_spec.rb +0 -18
  104. data/spec/factory_girl/strategy/build_spec.rb +0 -7
  105. data/spec/factory_girl/strategy/create_spec.rb +0 -25
  106. data/spec/factory_girl/strategy/stub_spec.rb +0 -38
  107. data/spec/factory_girl/strategy_calculator_spec.rb +0 -29
  108. data/spec/factory_girl_spec.rb +0 -22
  109. data/spec/spec_helper.rb +0 -26
  110. data/spec/support/macros/define_constant.rb +0 -86
  111. data/spec/support/matchers/callback.rb +0 -9
  112. data/spec/support/matchers/declaration.rb +0 -83
  113. data/spec/support/matchers/delegate.rb +0 -44
  114. data/spec/support/matchers/trait.rb +0 -11
  115. data/spec/support/shared_examples/strategy.rb +0 -90
@@ -1,61 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "sequences" do
4
- include FactoryGirl::Syntax::Methods
5
-
6
- it "generates several values in the correct format" do
7
- FactoryGirl.define do
8
- sequence :email do |n|
9
- "somebody#{n}@example.com"
10
- end
11
- end
12
-
13
- first_value = generate(:email)
14
- another_value = generate(:email)
15
-
16
- expect(first_value).to match /^somebody\d+@example\.com$/
17
- expect(another_value).to match /^somebody\d+@example\.com$/
18
- expect(first_value).not_to eq another_value
19
- end
20
-
21
- it "generates sequential numbers if no block is given" do
22
- FactoryGirl.define do
23
- sequence :order
24
- end
25
-
26
- first_value = generate(:order)
27
- another_value = generate(:order)
28
-
29
- expect(first_value).to eq 1
30
- expect(another_value).to eq 2
31
- expect(first_value).not_to eq another_value
32
- end
33
-
34
- it "generates aliases for the sequence that reference the same block" do
35
- FactoryGirl.define do
36
- sequence(:size, aliases: [:count, :length]) { |n| "called-#{n}" }
37
- end
38
-
39
- first_value = generate(:size)
40
- second_value = generate(:count)
41
- third_value = generate(:length)
42
-
43
- expect(first_value).to eq "called-1"
44
- expect(second_value).to eq "called-2"
45
- expect(third_value).to eq "called-3"
46
- end
47
-
48
- it "generates aliases for the sequence that reference the same block and retains value" do
49
- FactoryGirl.define do
50
- sequence(:size, "a", aliases: [:count, :length]) { |n| "called-#{n}" }
51
- end
52
-
53
- first_value = generate(:size)
54
- second_value = generate(:count)
55
- third_value = generate(:length)
56
-
57
- expect(first_value).to eq "called-a"
58
- expect(second_value).to eq "called-b"
59
- expect(third_value).to eq "called-c"
60
- end
61
- end
@@ -1,19 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "skipping the default create" do
4
- before do
5
- define_model("User", email: :string)
6
-
7
- FactoryGirl.define do
8
- factory :user do
9
- skip_create
10
-
11
- email "john@example.com"
12
- end
13
- end
14
- end
15
-
16
- it "doesn't execute anything when creating the instance" do
17
- expect(FactoryGirl.create(:user)).not_to be_persisted
18
- end
19
- end
@@ -1,62 +0,0 @@
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
- expect(subject.user).to be_kind_of(User)
30
- expect(subject.user).not_to be_new_record
31
- end
32
- end
33
-
34
- describe "a stubbed instance overriding strategy" do
35
- include FactoryGirl::Syntax::Methods
36
-
37
- before do
38
- define_model('User')
39
- define_model('Post', user_id: :integer) do
40
- belongs_to :user
41
- end
42
-
43
- FactoryGirl.define do
44
- factory :user
45
-
46
- factory :post do
47
- association(:user, strategy: :build)
48
- end
49
- end
50
- end
51
-
52
- subject { build_stubbed(:post) }
53
-
54
- it "acts as if it is saved in the database" do
55
- should_not be_new_record
56
- end
57
-
58
- it "assigns associations and acts as if it is saved" do
59
- expect(subject.user).to be_kind_of(User)
60
- expect(subject.user).not_to be_new_record
61
- end
62
- end
@@ -1,51 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "syntax methods within dynamic attributes" do
4
- before do
5
- define_model("Post", title: :string, user_id: :integer) do
6
- belongs_to :user
7
-
8
- def generate
9
- "generate result"
10
- end
11
- end
12
- define_model("User", email: :string)
13
-
14
- FactoryGirl.define do
15
- sequence(:email_address) { |n| "person-#{n}@example.com" }
16
-
17
- factory :user do
18
- email { generate(:email_address) }
19
- end
20
-
21
- factory :post do
22
- title { generate }
23
- user { build(:user) }
24
- end
25
- end
26
- end
27
-
28
- it "can access syntax methods from dynamic attributes" do
29
- expect(FactoryGirl.build(:user).email).to eq "person-1@example.com"
30
- expect(FactoryGirl.attributes_for(:user)[:email]).to eq "person-2@example.com"
31
- end
32
-
33
- it "can access syntax methods from dynamic attributes" do
34
- expect(FactoryGirl.build(:post).user).to be_instance_of(User)
35
- end
36
-
37
- it "can access methods already existing on the class" do
38
- expect(FactoryGirl.build(:post).title).to eq "generate result"
39
- expect(FactoryGirl.attributes_for(:post)[:title]).to be_nil
40
- end
41
-
42
- it 'allows syntax methods to be used when the block has an arity of 1' do
43
- FactoryGirl.define do
44
- factory :post_using_block_with_variable, parent: :post do
45
- user { |_| build(:user) }
46
- end
47
- end
48
-
49
- expect(FactoryGirl.build(:post_using_block_with_variable).user).to be_instance_of(User)
50
- end
51
- end
@@ -1,727 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "an instance generated by a factory with multiple traits" do
4
- before do
5
- define_model("User",
6
- name: :string,
7
- admin: :boolean,
8
- gender: :string,
9
- email: :string,
10
- date_of_birth: :date,
11
- great: :string)
12
-
13
- FactoryGirl.define do
14
- factory :user_without_admin_scoping, class: User do
15
- admin_trait
16
- end
17
-
18
- factory :user do
19
- name "John"
20
-
21
- trait :great do
22
- great "GREAT!!!"
23
- end
24
-
25
- trait :admin do
26
- admin true
27
- end
28
-
29
- trait :admin_trait do
30
- admin true
31
- end
32
-
33
- trait :male do
34
- name "Joe"
35
- gender "Male"
36
- end
37
-
38
- trait :female do
39
- name "Jane"
40
- gender "Female"
41
- end
42
-
43
- factory :great_user do
44
- great
45
- end
46
-
47
- factory :admin, traits: [:admin]
48
-
49
- factory :male_user do
50
- male
51
-
52
- factory :child_male_user do
53
- date_of_birth { Date.parse("1/1/2000") }
54
- end
55
- end
56
-
57
- factory :female, traits: [:female] do
58
- trait :admin do
59
- admin true
60
- name "Judy"
61
- end
62
-
63
- factory :female_great_user do
64
- great
65
- end
66
-
67
- factory :female_admin_judy, traits: [:admin]
68
- end
69
-
70
- factory :female_admin, traits: [:female, :admin]
71
- factory :female_after_male_admin, traits: [:male, :female, :admin]
72
- factory :male_after_female_admin, traits: [:female, :male, :admin]
73
- end
74
-
75
- trait :email do
76
- email { "#{name}@example.com" }
77
- end
78
-
79
- factory :user_with_email, class: User, traits: [:email] do
80
- name "Bill"
81
- end
82
- end
83
- end
84
-
85
- context "the parent class" do
86
- subject { FactoryGirl.create(:user) }
87
- its(:name) { should eq "John" }
88
- its(:gender) { should be_nil }
89
- it { should_not be_admin }
90
- end
91
-
92
- context "the child class with one trait" do
93
- subject { FactoryGirl.create(:admin) }
94
- its(:name) { should eq "John" }
95
- its(:gender) { should be_nil }
96
- it { should be_admin }
97
- end
98
-
99
- context "the other child class with one trait" do
100
- subject { FactoryGirl.create(:female) }
101
- its(:name) { should eq "Jane" }
102
- its(:gender) { should eq "Female" }
103
- it { should_not be_admin }
104
- end
105
-
106
- context "the child with multiple traits" do
107
- subject { FactoryGirl.create(:female_admin) }
108
- its(:name) { should eq "Jane" }
109
- its(:gender) { should eq "Female" }
110
- it { should be_admin }
111
- end
112
-
113
- context "the child with multiple traits and overridden attributes" do
114
- subject { FactoryGirl.create(:female_admin, name: "Jill", gender: nil) }
115
- its(:name) { should eq "Jill" }
116
- its(:gender) { should be_nil }
117
- it { should be_admin }
118
- end
119
-
120
- context "the child with multiple traits who override the same attribute" do
121
- context "when the male assigns name after female" do
122
- subject { FactoryGirl.create(:male_after_female_admin) }
123
- its(:name) { should eq "Joe" }
124
- its(:gender) { should eq "Male" }
125
- it { should be_admin }
126
- end
127
-
128
- context "when the female assigns name after male" do
129
- subject { FactoryGirl.create(:female_after_male_admin) }
130
- its(:name) { should eq "Jane" }
131
- its(:gender) { should eq "Female" }
132
- it { should be_admin }
133
- end
134
- end
135
-
136
- context "child class with scoped trait and inherited trait" do
137
- subject { FactoryGirl.create(:female_admin_judy) }
138
- its(:name) { should eq "Judy" }
139
- its(:gender) { should eq "Female" }
140
- it { should be_admin }
141
- end
142
-
143
- context "factory using global trait" do
144
- subject { FactoryGirl.create(:user_with_email) }
145
- its(:name) { should eq "Bill" }
146
- its(:email) { should eq "Bill@example.com"}
147
- end
148
-
149
- context "factory created with alternate syntax for specifying trait" do
150
- subject { FactoryGirl.create(:male_user) }
151
- its(:gender) { should eq "Male" }
152
- end
153
-
154
- context "factory created with alternate syntax where trait name and attribute are the same" do
155
- subject { FactoryGirl.create(:great_user) }
156
- its(:great) { should eq "GREAT!!!" }
157
- end
158
-
159
- context "factory created with alternate syntax where trait name and attribute are the same and attribute is overridden" do
160
- subject { FactoryGirl.create(:great_user, great: "SORT OF!!!") }
161
- its(:great) { should eq "SORT OF!!!" }
162
- end
163
-
164
- context "child factory created where trait attributes are inherited" do
165
- subject { FactoryGirl.create(:child_male_user) }
166
- its(:gender) { should eq "Male" }
167
- its(:date_of_birth) { should eq Date.parse("1/1/2000") }
168
- end
169
-
170
- context "factory outside of scope" do
171
- subject { FactoryGirl.create(:user_without_admin_scoping) }
172
- it { expect { subject }.to raise_error(ArgumentError, "Trait not registered: admin_trait") }
173
- end
174
-
175
- context "child factory using grandparents' trait" do
176
- subject { FactoryGirl.create(:female_great_user) }
177
- its(:great) { should eq "GREAT!!!" }
178
- end
179
- end
180
-
181
- describe "traits with callbacks" do
182
- before do
183
- define_model("User", name: :string)
184
-
185
- FactoryGirl.define do
186
- factory :user do
187
- name "John"
188
-
189
- trait :great do
190
- after(:create) { |user| user.name.upcase! }
191
- end
192
-
193
- trait :awesome do
194
- after(:create) { |user| user.name = "awesome" }
195
- end
196
-
197
- factory :caps_user, traits: [:great]
198
- factory :awesome_user, traits: [:great, :awesome]
199
-
200
- factory :caps_user_implicit_trait do
201
- great
202
- end
203
- end
204
- end
205
- end
206
-
207
- context "when the factory has a trait passed via arguments" do
208
- subject { FactoryGirl.create(:caps_user) }
209
- its(:name) { should eq "JOHN" }
210
- end
211
-
212
- context "when the factory has an implicit trait" do
213
- subject { FactoryGirl.create(:caps_user_implicit_trait) }
214
- its(:name) { should eq "JOHN" }
215
- end
216
-
217
- it "executes callbacks in the order assigned" do
218
- expect(FactoryGirl.create(:awesome_user).name).to eq "awesome"
219
- end
220
- end
221
-
222
- describe "traits added via strategy" do
223
- before do
224
- define_model("User", name: :string, admin: :boolean)
225
-
226
- FactoryGirl.define do
227
- factory :user do
228
- name "John"
229
-
230
- trait :admin do
231
- admin true
232
- end
233
-
234
- trait :great do
235
- after(:create) { |user| user.name.upcase! }
236
- end
237
- end
238
- end
239
- end
240
-
241
- context "adding traits in create" do
242
- subject { FactoryGirl.create(:user, :admin, :great, name: "Joe") }
243
-
244
- its(:admin) { should be_true }
245
- its(:name) { should eq "JOE" }
246
-
247
- it "doesn't modify the user factory" do
248
- subject
249
- expect(FactoryGirl.create(:user)).not_to be_admin
250
- expect(FactoryGirl.create(:user).name).to eq "John"
251
- end
252
- end
253
-
254
- context "adding traits in build" do
255
- subject { FactoryGirl.build(:user, :admin, :great, name: "Joe") }
256
-
257
- its(:admin) { should be_true }
258
- its(:name) { should eq "Joe" }
259
- end
260
-
261
- context "adding traits in attributes_for" do
262
- subject { FactoryGirl.attributes_for(:user, :admin, :great) }
263
-
264
- its([:admin]) { should be_true }
265
- its([:name]) { should eq "John" }
266
- end
267
-
268
- context "adding traits in build_stubbed" do
269
- subject { FactoryGirl.build_stubbed(:user, :admin, :great, name: "Jack") }
270
-
271
- its(:admin) { should be_true }
272
- its(:name) { should eq "Jack" }
273
- end
274
-
275
- context "adding traits in create_list" do
276
- subject { FactoryGirl.create_list(:user, 2, :admin, :great, name: "Joe") }
277
-
278
- its(:length) { should eq 2 }
279
-
280
- it "creates all the records" do
281
- subject.each do |record|
282
- expect(record.admin).to be_true
283
- expect(record.name).to eq "JOE"
284
- end
285
- end
286
- end
287
-
288
- context "adding traits in build_list" do
289
- subject { FactoryGirl.build_list(:user, 2, :admin, :great, name: "Joe") }
290
-
291
- its(:length) { should eq 2 }
292
-
293
- it "builds all the records" do
294
- subject.each do |record|
295
- expect(record.admin).to be_true
296
- expect(record.name).to eq "Joe"
297
- end
298
- end
299
- end
300
- end
301
-
302
- describe "traits and dynamic attributes that are applied simultaneously" do
303
- before do
304
- define_model("User", name: :string, email: :string, combined: :string)
305
-
306
- FactoryGirl.define do
307
- trait :email do
308
- email { "#{name}@example.com" }
309
- end
310
-
311
- factory :user do
312
- name "John"
313
- email
314
- combined { "#{name} <#{email}>" }
315
- end
316
- end
317
- end
318
-
319
- subject { FactoryGirl.build(:user) }
320
- its(:name) { should eq "John" }
321
- its(:email) { should eq "John@example.com" }
322
- its(:combined) { should eq "John <John@example.com>" }
323
- end
324
-
325
- describe "applying inline traits" do
326
- before do
327
- define_model("User") do
328
- has_many :posts
329
- end
330
-
331
- define_model("Post", user_id: :integer) do
332
- belongs_to :user
333
- end
334
-
335
- FactoryGirl.define do
336
- factory :user do
337
- trait :with_post do
338
- posts { [ Post.new ] }
339
- end
340
- end
341
- end
342
- end
343
-
344
- it "applies traits only to the instance generated for that call" do
345
- expect(FactoryGirl.create(:user, :with_post).posts).not_to be_empty
346
- expect(FactoryGirl.create(:user).posts).to be_empty
347
- expect(FactoryGirl.create(:user, :with_post).posts).not_to be_empty
348
- end
349
- end
350
-
351
- describe "inline traits overriding existing attributes" do
352
- before do
353
- define_model("User", status: :string)
354
-
355
- FactoryGirl.define do
356
- factory :user do
357
- status "pending"
358
-
359
- trait(:accepted) { status "accepted" }
360
- trait(:declined) { status "declined" }
361
-
362
- factory :declined_user, traits: [:declined]
363
- factory :extended_declined_user, traits: [:declined] do
364
- status "extended_declined"
365
- end
366
- end
367
- end
368
- end
369
-
370
- it "returns the default status" do
371
- expect(FactoryGirl.build(:user).status).to eq "pending"
372
- end
373
-
374
- it "prefers inline trait attributes over default attributes" do
375
- expect(FactoryGirl.build(:user, :accepted).status).to eq "accepted"
376
- end
377
-
378
- it "prefers traits on a factory over default attributes" do
379
- expect(FactoryGirl.build(:declined_user).status).to eq "declined"
380
- end
381
-
382
- it "prefers inline trait attributes over traits on a factory" do
383
- expect(FactoryGirl.build(:declined_user, :accepted).status).to eq "accepted"
384
- end
385
-
386
- it "prefers attributes on factories over attributes from non-inline traits" do
387
- expect(FactoryGirl.build(:extended_declined_user).status).to eq "extended_declined"
388
- end
389
-
390
- it "prefers inline traits over attributes on factories" do
391
- expect(FactoryGirl.build(:extended_declined_user, :accepted).status).to eq "accepted"
392
- end
393
-
394
- it "prefers overridden attributes over attributes from traits, inline traits, or attributes on factories" do
395
- expect(FactoryGirl.build(:extended_declined_user, :accepted, status: "completely overridden").status).to eq "completely overridden"
396
- end
397
- end
398
-
399
- describe "making sure the factory is properly compiled the first time we want to instantiate it" do
400
- before do
401
- define_model("User", role: :string, gender: :string, age: :integer)
402
-
403
- FactoryGirl.define do
404
- factory :user do
405
- trait(:female) { gender "female" }
406
- trait(:admin) { role "admin" }
407
-
408
- factory :female_user do
409
- female
410
- end
411
- end
412
- end
413
- end
414
-
415
- it "can honor traits on the very first call" do
416
- user = FactoryGirl.build(:female_user, :admin, age: 30)
417
- expect(user.gender).to eq 'female'
418
- expect(user.age).to eq 30
419
- expect(user.role).to eq 'admin'
420
- end
421
- end
422
-
423
- describe "traits with to_create" do
424
- before do
425
- define_model("User", name: :string)
426
-
427
- FactoryGirl.define do
428
- factory :user do
429
- trait :with_to_create do
430
- to_create { |instance| instance.name = "to_create" }
431
- end
432
-
433
- factory :sub_user do
434
- to_create { |instance| instance.name = "sub" }
435
-
436
- factory :child_user
437
- end
438
-
439
- factory :sub_user_with_trait do
440
- with_to_create
441
-
442
- factory :child_user_with_trait
443
- end
444
-
445
- factory :sub_user_with_trait_and_override do
446
- with_to_create
447
- to_create { |instance| instance.name = "sub with trait and override" }
448
-
449
- factory :child_user_with_trait_and_override
450
- end
451
- end
452
- end
453
- end
454
-
455
- it "can apply to_create from traits" do
456
- expect(FactoryGirl.create(:user, :with_to_create).name).to eq "to_create"
457
- end
458
-
459
- it "can apply to_create from the definition" do
460
- expect(FactoryGirl.create(:sub_user).name).to eq "sub"
461
- expect(FactoryGirl.create(:child_user).name).to eq "sub"
462
- end
463
-
464
- it "gives additional traits higher priority than to_create from the definition" do
465
- expect(FactoryGirl.create(:sub_user, :with_to_create).name).to eq "to_create"
466
- expect(FactoryGirl.create(:child_user, :with_to_create).name).to eq "to_create"
467
- end
468
-
469
- it "gives base traits normal priority" do
470
- expect(FactoryGirl.create(:sub_user_with_trait).name).to eq "to_create"
471
- expect(FactoryGirl.create(:child_user_with_trait).name).to eq "to_create"
472
- end
473
-
474
- it "gives base traits lower priority than overrides" do
475
- expect(FactoryGirl.create(:sub_user_with_trait_and_override).name).to eq "sub with trait and override"
476
- expect(FactoryGirl.create(:child_user_with_trait_and_override).name).to eq "sub with trait and override"
477
- end
478
-
479
- it "gives additional traits higher priority than base traits and factory definition" do
480
- FactoryGirl.define do
481
- trait :overridden do
482
- to_create { |instance| instance.name = "completely overridden" }
483
- end
484
- end
485
-
486
- expect(FactoryGirl.create(:sub_user_with_trait_and_override, :overridden).name).to eq "completely overridden"
487
- expect(FactoryGirl.create(:child_user_with_trait_and_override, :overridden).name).to eq "completely overridden"
488
- end
489
- end
490
-
491
- describe "traits with initialize_with" do
492
- before do
493
- define_class("User") do
494
- attr_reader :name
495
-
496
- def initialize(name)
497
- @name = name
498
- end
499
- end
500
-
501
- FactoryGirl.define do
502
- factory :user do
503
- trait :with_initialize_with do
504
- initialize_with { new("initialize_with") }
505
- end
506
-
507
- factory :sub_user do
508
- initialize_with { new("sub") }
509
-
510
- factory :child_user
511
- end
512
-
513
- factory :sub_user_with_trait do
514
- with_initialize_with
515
-
516
- factory :child_user_with_trait
517
- end
518
-
519
- factory :sub_user_with_trait_and_override do
520
- with_initialize_with
521
- initialize_with { new("sub with trait and override") }
522
-
523
- factory :child_user_with_trait_and_override
524
- end
525
- end
526
- end
527
- end
528
-
529
- it "can apply initialize_with from traits" do
530
- expect(FactoryGirl.build(:user, :with_initialize_with).name).to eq "initialize_with"
531
- end
532
-
533
- it "can apply initialize_with from the definition" do
534
- expect(FactoryGirl.build(:sub_user).name).to eq "sub"
535
- expect(FactoryGirl.build(:child_user).name).to eq "sub"
536
- end
537
-
538
- it "gives additional traits higher priority than initialize_with from the definition" do
539
- expect(FactoryGirl.build(:sub_user, :with_initialize_with).name).to eq "initialize_with"
540
- expect(FactoryGirl.build(:child_user, :with_initialize_with).name).to eq "initialize_with"
541
- end
542
-
543
- it "gives base traits normal priority" do
544
- expect(FactoryGirl.build(:sub_user_with_trait).name).to eq "initialize_with"
545
- expect(FactoryGirl.build(:child_user_with_trait).name).to eq "initialize_with"
546
- end
547
-
548
- it "gives base traits lower priority than overrides" do
549
- expect(FactoryGirl.build(:sub_user_with_trait_and_override).name).to eq "sub with trait and override"
550
- expect(FactoryGirl.build(:child_user_with_trait_and_override).name).to eq "sub with trait and override"
551
- end
552
-
553
- it "gives additional traits higher priority than base traits and factory definition" do
554
- FactoryGirl.define do
555
- trait :overridden do
556
- initialize_with { new("completely overridden") }
557
- end
558
- end
559
-
560
- expect(FactoryGirl.build(:sub_user_with_trait_and_override, :overridden).name).to eq "completely overridden"
561
- expect(FactoryGirl.build(:child_user_with_trait_and_override, :overridden).name).to eq "completely overridden"
562
- end
563
- end
564
-
565
- describe "nested implicit traits" do
566
- before do
567
- define_class("User") do
568
- attr_accessor :gender, :role
569
- attr_reader :name
570
-
571
- def initialize(name)
572
- @name = name
573
- end
574
- end
575
- end
576
-
577
- shared_examples_for "assigning data from traits" do
578
- it "assigns the correct values" do
579
- user = FactoryGirl.create(:user, :female_admin)
580
- expect(user.gender).to eq "FEMALE"
581
- expect(user.role).to eq "ADMIN"
582
- expect(user.name).to eq "Jane Doe"
583
- end
584
- end
585
-
586
- context "defined outside the factory" do
587
- before do
588
- FactoryGirl.define do
589
- trait :female do
590
- gender "female"
591
- to_create { |instance| instance.gender = instance.gender.upcase }
592
- end
593
-
594
- trait :jane_doe do
595
- initialize_with { new("Jane Doe") }
596
- end
597
-
598
- trait :admin do
599
- role "admin"
600
- after(:build) { |instance| instance.role = instance.role.upcase }
601
- end
602
-
603
- trait :female_admin do
604
- female
605
- admin
606
- jane_doe
607
- end
608
-
609
- factory :user
610
- end
611
- end
612
-
613
- it_should_behave_like "assigning data from traits"
614
- end
615
-
616
- context "defined inside the factory" do
617
- before do
618
- FactoryGirl.define do
619
- factory :user do
620
- trait :female do
621
- gender "female"
622
- to_create { |instance| instance.gender = instance.gender.upcase }
623
- end
624
-
625
- trait :jane_doe do
626
- initialize_with { new("Jane Doe") }
627
- end
628
-
629
- trait :admin do
630
- role "admin"
631
- after(:build) { |instance| instance.role = instance.role.upcase }
632
- end
633
-
634
- trait :female_admin do
635
- female
636
- admin
637
- jane_doe
638
- end
639
- end
640
- end
641
- end
642
-
643
- it_should_behave_like "assigning data from traits"
644
- end
645
- end
646
-
647
- describe "implicit traits containing callbacks" do
648
- before do
649
- define_model("User", value: :integer)
650
-
651
- FactoryGirl.define do
652
- factory :user do
653
- value 0
654
-
655
- trait :trait_with_callback do
656
- after(:build) { |user| user.value += 1 }
657
- end
658
-
659
- factory :user_with_trait_with_callback do
660
- trait_with_callback
661
- end
662
- end
663
- end
664
- end
665
-
666
- it "only runs the callback once" do
667
- expect(FactoryGirl.build(:user_with_trait_with_callback).value).to eq 1
668
- end
669
- end
670
-
671
- describe "traits used in associations" do
672
- before do
673
- define_model("User", admin: :boolean, name: :string)
674
-
675
- define_model("Comment", user_id: :integer) do
676
- belongs_to :user
677
- end
678
-
679
- define_model("Order", creator_id: :integer) do
680
- belongs_to :creator, class_name: 'User'
681
- end
682
-
683
- define_model("Post", author_id: :integer) do
684
- belongs_to :author, class_name: 'User'
685
- end
686
-
687
- FactoryGirl.define do
688
- factory :user do
689
- admin false
690
-
691
- trait :admin do
692
- admin true
693
- end
694
- end
695
-
696
- factory :post do
697
- association :author, factory: [:user, :admin], name: 'John Doe'
698
- end
699
-
700
- factory :comment do
701
- association :user, :admin, name: 'Joe Slick'
702
- end
703
-
704
- factory :order do
705
- association :creator, :admin, factory: :user, name: 'Joe Creator'
706
- end
707
- end
708
- end
709
-
710
- it "allows assigning traits for the factory of an association" do
711
- author = FactoryGirl.create(:post).author
712
- expect(author).to be_admin
713
- expect(author.name).to eq 'John Doe'
714
- end
715
-
716
- it "allows inline traits with the default association" do
717
- user = FactoryGirl.create(:comment).user
718
- expect(user).to be_admin
719
- expect(user.name).to eq 'Joe Slick'
720
- end
721
-
722
- it "allows inline traits with a specific factory for an association" do
723
- creator = FactoryGirl.create(:order).creator
724
- expect(creator).to be_admin
725
- expect(creator.name).to eq 'Joe Creator'
726
- end
727
- end