factory_bot 5.2.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 802da48aa95dce3321f20d0173c5dcf041c5393fb0c270fb8ae2029ce12b6ed9
4
- data.tar.gz: 0aa227896ef66ccf100f88b1aa4e9aa26c5bc657fee76739a73e15072bc80572
3
+ metadata.gz: 2f060c0b183a1d65b69542b917a19ad16d1de52d7f69dd692839eceaa316ad2a
4
+ data.tar.gz: 4f2286b4cabd1b562352fed5d20f00ba29a7ede89c8a855657f0f0075527d0f4
5
5
  SHA512:
6
- metadata.gz: 63554d6765398f0c524cb8cd45b1a0da83da1d8aba9f359d0e4c44e42cdbd0d93edb8e38c668e0310ad709905c5cd6a3c35e640ad8c45a06a8b7d4090b4e6161
7
- data.tar.gz: fe3be69bdd601384da0a7f2ec7e1fcf00ae7d4984c65423e31e94c1b7f3d7bb04345371daaea19d794365972b59f69f9f3403b0ef8b8ef7d7349d89404284ac2
6
+ metadata.gz: 67230581c94a6e476ba8fa8aeb123d2ccfe18cd14af2d9d292cc871d9d1dda63cbd827e455c165f9eac7211fe9770fd41b87ab349db55a000e32ee23a319fda1
7
+ data.tar.gz: 8ce7be2d33e08ddc24c50082a2025c7c59877457558720dfbdc4920e70f881e30a52cfb322fe129ae9690b512bbf42059bb24db973c81b3a585d8693ff484a1c
@@ -12,7 +12,7 @@ Here are some ways *you* can contribute:
12
12
  * by suggesting new features
13
13
  * by writing or editing documentation
14
14
  * by writing specifications
15
- * by writing code ( **no patch is too small** : fix typos, add comments, clean up inconsistent whitespace )
15
+ * by writing code ( **no patch is too small** : fix typos, add comments, etc. )
16
16
  * by refactoring code
17
17
  * by closing [issues][]
18
18
  * by reviewing patches
@@ -23,13 +23,10 @@ Here are some ways *you* can contribute:
23
23
 
24
24
  * We use the [GitHub issue tracker][issues] to track bugs and features.
25
25
  * Before submitting a bug report or feature request, check to make sure it hasn't
26
- already been submitted.
27
- * When submitting a bug report, please include a [Gist][] that includes a stack
28
- trace and any details that may be necessary to reproduce the bug, including
29
- your gem version, Ruby version, and operating system. Ideally, a bug report
30
- should include a pull request with failing specs.
31
-
32
- [gist]: https://gist.github.com/
26
+ already been submitted.
27
+ * When submitting a bug report, please include a [reproduction script] and any
28
+ other details that may be necessary to reproduce the bug, including your gem
29
+ version, Ruby version, and operating system.
33
30
 
34
31
  ## Cleaning up issues
35
32
 
@@ -40,21 +37,63 @@ already been submitted.
40
37
  We will happily reopen the issue.
41
38
 
42
39
  ## Submitting a Pull Request
40
+
43
41
  1. [Fork][fork] the [official repository][repo].
44
- 2. [Create a topic branch.][branch]
45
- 3. Implement your feature or bug fix.
46
- 4. Add, commit, and push your changes.
47
- 5. [Submit a pull request.][pr]
42
+ 1. [Create a topic branch.][branch]
43
+ 1. Implement your feature or bug fix.
44
+ 1. Add, commit, and push your changes.
45
+ 1. [Submit a pull request.][pr]
46
+
47
+ ### Notes
48
48
 
49
- ## Notes
50
49
  * Please add tests if you changed code. Contributions without tests won't be accepted.
51
50
  * If you don't know how to add tests, please put in a PR and leave a comment
52
51
  asking for help. We love helping!
53
52
  * Please don't update the Gem version.
54
53
 
54
+ ## Running the test suite
55
+
56
+ The default rake task will run the full test suite and [standard]:
57
+
58
+ ```sh
59
+ bundle exec rake
60
+ ```
61
+
62
+ You can also run a single group of tests (unit, spec, or feature)
63
+
64
+ ```sh
65
+ bundle exec rake spec:unit
66
+ bundle exec rake spec:acceptance
67
+ bundle exec rake features
68
+ ```
69
+
70
+ To run an individual rspec test, you can provide a path and line number:
71
+
72
+ ```sh
73
+ bundle exec rspec spec/path/to/spec.rb:123
74
+ ```
75
+
76
+ You can run tests with a specific version of rails via [appraisal]. To run
77
+ the default rake task against Rails 6, for example:
78
+
79
+ ```sh
80
+ bundle exec appraisal 6.0 rake
81
+ ```
82
+
83
+ ## Formatting
84
+
85
+ Use [standard] to automatically format your code:
86
+
87
+ ```sh
88
+ bundle exec rake standard:fix
89
+ ```
90
+
55
91
  [repo]: https://github.com/thoughtbot/factory_bot/tree/master
56
92
  [fork]: https://help.github.com/articles/fork-a-repo/
57
93
  [branch]: https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/
58
94
  [pr]: https://help.github.com/articles/using-pull-requests/
95
+ [standard]: https://github.com/testdouble/standard
96
+ [appraisal]: https://github.com/thoughtbot/appraisal
97
+ [reproduction script]: https://github.com/thoughtbot/factory_bot/blob/master/.github/REPRODUCTION_SCRIPT.rb
59
98
 
60
99
  Inspired by https://github.com/middleman/middleman-heroku/blob/master/CONTRIBUTING.md
@@ -1,8 +1,87 @@
1
1
  Getting Started
2
2
  ===============
3
3
 
4
- Update Your Gemfile
5
- -------------------
4
+ * [Setup](#setup)
5
+ + [Update Your Gemfile](#update-your-gemfile)
6
+ + [Configure your test suite](#configure-your-test-suite)
7
+ - [RSpec](#rspec)
8
+ - [Test::Unit](#testunit)
9
+ - [Cucumber](#cucumber)
10
+ - [Spinach](#spinach)
11
+ - [Minitest](#minitest)
12
+ - [Minitest::Spec](#minitestspec)
13
+ - [minitest-rails](#minitest-rails)
14
+ * [Defining factories](#defining-factories)
15
+ + [Factory name and attributes](#factory-name-and-attributes)
16
+ + [Specifying the class explicitly](#specifying-the-class-explicitly)
17
+ + [Hash attributes](#hash-attributes)
18
+ + [Best practices](#best-practices)
19
+ + [Definition file paths](#definition-file-paths)
20
+ + [Static Attributes](#static-attributes)
21
+ * [Using factories](#using-factories)
22
+ + [Build strategies](#build-strategies)
23
+ + [Attribute overrides](#attribute-overrides)
24
+ + [`build_stubbed` and `Marshal.dump`](#build_stubbed-and-marshaldump)
25
+ * [Aliases](#aliases)
26
+ * [Dependent Attributes](#dependent-attributes)
27
+ * [Transient Attributes](#transient-attributes)
28
+ + [With other attributes](#with-other-attributes)
29
+ + [With `attributes_for`](#with-attributes_for)
30
+ + [With callbacks](#with-callbacks)
31
+ + [With associations](#with-associations)
32
+ * [Method Name / Reserved Word Attributes](#method-name--reserved-word-attributes)
33
+ * [Inheritance](#inheritance)
34
+ + [Nested factories](#nested-factories)
35
+ + [Assigning parent explicitly](#assigning-parent-explicitly)
36
+ + [Best practices](#best-practices-1)
37
+ * [Associations](#associations)
38
+ + [Implicit definition](#implicit-definition)
39
+ + [Explicit definition](#explicit-definition)
40
+ + [Specifying the factory](#specifying-the-factory)
41
+ + [Overriding attributes](#overriding-attributes)
42
+ + [Build strategies](#build-strategies-1)
43
+ + [`has_many` associations](#has_many-associations)
44
+ + [`has_and_belongs_to_many` associations](#has_and_belongs_to_many-associations)
45
+ + [Polymorphic associations](#polymorphic-associations)
46
+ * [Sequences](#sequences)
47
+ + [Global sequences](#global-sequences)
48
+ + [With dynamic attributes](#with-dynamic-attributes)
49
+ + [As implicit attributes](#as-implicit-attributes)
50
+ + [Inline sequences](#inline-sequences)
51
+ + [Initial value](#initial-value)
52
+ + [Without a block](#without-a-block)
53
+ + [Aliases](#aliases-1)
54
+ + [Rewinding](#rewinding)
55
+ * [Traits](#traits)
56
+ + [Defining traits](#defining-traits)
57
+ + [As implicit attributes](#as-implicit-attributes-1)
58
+ + [Attribute precedence](#attribute-precedence)
59
+ + [In child factories](#in-child-factories)
60
+ + [Using traits](#using-traits)
61
+ + [With associations](#with-associations-1)
62
+ + [Traits within traits](#traits-within-traits)
63
+ + [With transient attributes](#with-transient-attributes)
64
+ + [Enum traits](#enum-traits)
65
+ * [Callbacks](#callbacks)
66
+ + [Default callbacks](#default-callbacks)
67
+ + [Multiple callbacks](#multiple-callbacks)
68
+ + [Global callbacks](#global-callbacks)
69
+ + [Symbol#to_proc](#symbolto_proc)
70
+ * [Modifying factories](#modifying-factories)
71
+ * [Building or Creating Multiple Records](#building-or-creating-multiple-records)
72
+ * [Linting Factories](#linting-factories)
73
+ * [Custom Construction](#custom-construction)
74
+ * [Custom Strategies](#custom-strategies)
75
+ * [Custom Callbacks](#custom-callbacks)
76
+ * [Custom Methods to Persist Objects](#custom-methods-to-persist-objects)
77
+ * [ActiveSupport Instrumentation](#activesupport-instrumentation)
78
+ * [Rails Preloaders and RSpec](#rails-preloaders-and-rspec)
79
+ * [Using Without Bundler](#using-without-bundler)
80
+
81
+ Setup
82
+ -----
83
+
84
+ ### Update Your Gemfile
6
85
 
7
86
  If you're using Rails:
8
87
 
@@ -16,21 +95,13 @@ If you're *not* using Rails:
16
95
  gem "factory_bot"
17
96
  ```
18
97
 
19
- JRuby users: factory_bot works with JRuby starting with 1.6.7.2 (latest stable, as per July 2012).
20
- JRuby has to be used in 1.9 mode, for that, use JRUBY_OPTS environment variable:
21
-
22
- ```bash
23
- export JRUBY_OPTS=--1.9
24
- ```
25
-
26
- Once your Gemfile is updated, you'll want to update your bundle.
27
-
28
- Configure your test suite
29
- -------------------------
98
+ ### Configure your test suite
30
99
 
31
- ### RSpec
100
+ #### RSpec
32
101
 
33
- If you're using Rails, add the following configuration to `spec/support/factory_bot.rb` and be sure to require that file in `rails_helper.rb`:
102
+ If you're using Rails, add the following configuration to
103
+ `spec/support/factory_bot.rb` and be sure to require that file in
104
+ `rails_helper.rb`:
34
105
 
35
106
  ```ruby
36
107
  RSpec.configure do |config|
@@ -50,7 +121,7 @@ RSpec.configure do |config|
50
121
  end
51
122
  ```
52
123
 
53
- ### Test::Unit
124
+ #### Test::Unit
54
125
 
55
126
  ```ruby
56
127
  class Test::Unit::TestCase
@@ -58,14 +129,14 @@ class Test::Unit::TestCase
58
129
  end
59
130
  ```
60
131
 
61
- ### Cucumber
132
+ #### Cucumber
62
133
 
63
134
  ```ruby
64
135
  # env.rb (Rails example location - RAILS_ROOT/features/support/env.rb)
65
136
  World(FactoryBot::Syntax::Methods)
66
137
  ```
67
138
 
68
- ### Spinach
139
+ #### Spinach
69
140
 
70
141
  ```ruby
71
142
  class Spinach::FeatureSteps
@@ -73,7 +144,7 @@ class Spinach::FeatureSteps
73
144
  end
74
145
  ```
75
146
 
76
- ### Minitest
147
+ #### Minitest
77
148
 
78
149
  ```ruby
79
150
  class Minitest::Unit::TestCase
@@ -81,7 +152,7 @@ class Minitest::Unit::TestCase
81
152
  end
82
153
  ```
83
154
 
84
- ### Minitest::Spec
155
+ #### Minitest::Spec
85
156
 
86
157
  ```ruby
87
158
  class Minitest::Spec
@@ -89,7 +160,7 @@ class Minitest::Spec
89
160
  end
90
161
  ```
91
162
 
92
- ### minitest-rails
163
+ #### minitest-rails
93
164
 
94
165
  ```ruby
95
166
  class ActiveSupport::TestCase
@@ -97,12 +168,16 @@ class ActiveSupport::TestCase
97
168
  end
98
169
  ```
99
170
 
100
- If you do not include `FactoryBot::Syntax::Methods` in your test suite, then all factory_bot methods will need to be prefaced with `FactoryBot`.
171
+ If you do not include `FactoryBot::Syntax::Methods` in your test suite, then all
172
+ factory\_bot methods will need to be prefaced with `FactoryBot`.
101
173
 
102
174
  Defining factories
103
175
  ------------------
104
176
 
105
- Each factory has a name and a set of attributes. The name is used to guess the class of the object by default:
177
+ ### Factory name and attributes
178
+
179
+ Each factory has a name and a set of attributes. The name is used to guess the
180
+ class of the object by default:
106
181
 
107
182
  ```ruby
108
183
  # This will guess the User class
@@ -115,6 +190,8 @@ FactoryBot.define do
115
190
  end
116
191
  ```
117
192
 
193
+ ### Specifying the class explicitly
194
+
118
195
  It is also possible to explicitly specify the class:
119
196
 
120
197
  ```ruby
@@ -125,13 +202,15 @@ factory :admin, class: User
125
202
  If the constant is not available
126
203
  (if you are using a Rails engine that waits to load models, for example),
127
204
  you can also pass a symbol or string,
128
- which factory_bot will constantize later, once you start building objects:
205
+ which factory\_bot will constantize later, once you start building objects:
129
206
 
130
207
  ```ruby
131
208
  # It's OK if Doorkeeper::AccessToken isn't loaded yet
132
209
  factory :access_token, class: "Doorkeeper::AccessToken"
133
210
  ```
134
211
 
212
+ ### Hash attributes
213
+
135
214
  Because of the block syntax in Ruby, defining attributes as `Hash`es (for
136
215
  serialized/JSON columns, for example) requires two sets of curly brackets:
137
216
 
@@ -141,10 +220,19 @@ factory :program do
141
220
  end
142
221
  ```
143
222
 
144
- It is highly recommended that you have one factory for each class that provides the simplest set of attributes necessary to create an instance of that class. If you're creating ActiveRecord objects, that means that you should only provide attributes that are required through validations and that do not have defaults. Other factories can be created through inheritance to cover common scenarios for each class.
223
+ ### Best practices
224
+
225
+ It is recommended that you have one factory for each class that provides
226
+ the simplest set of attributes necessary to create an instance of that class. If
227
+ you're creating ActiveRecord objects, that means that you should only provide
228
+ attributes that are required through validations and that do not have defaults.
229
+ Other factories can be created through inheritance to cover common scenarios for
230
+ each class.
145
231
 
146
232
  Attempting to define multiple factories with the same name will raise an error.
147
233
 
234
+ ### Definition file paths
235
+
148
236
  Factories can be defined anywhere, but will be automatically loaded after
149
237
  calling `FactoryBot.find_definitions` if factories are defined in files at the
150
238
  following locations:
@@ -154,10 +242,20 @@ following locations:
154
242
  test/factories/*.rb
155
243
  spec/factories/*.rb
156
244
 
245
+ ### Static Attributes
246
+
247
+ Static attributes (without a block) are no longer available in factory\_bot 5.
248
+ You can read more about the decision to remove them in
249
+ [this blog post](https://robots.thoughtbot.com/deprecating-static-attributes-in-factory_bot-4-11).
250
+
251
+
157
252
  Using factories
158
253
  ---------------
159
254
 
160
- factory\_bot supports several different build strategies: build, create, attributes\_for and build\_stubbed:
255
+ ### Build strategies
256
+
257
+ factory\_bot supports several different build strategies: build, create,
258
+ attributes\_for and build\_stubbed:
161
259
 
162
260
  ```ruby
163
261
  # Returns a User instance that's not saved
@@ -178,7 +276,10 @@ create(:user) do |user|
178
276
  end
179
277
  ```
180
278
 
181
- No matter which strategy is used, it's possible to override the defined attributes by passing a hash:
279
+ ### Attribute overrides
280
+
281
+ No matter which strategy is used, it's possible to override the defined
282
+ attributes by passing a hash:
182
283
 
183
284
  ```ruby
184
285
  # Build a User instance and override the first_name property
@@ -187,19 +288,20 @@ user.first_name
187
288
  # => "Joe"
188
289
  ```
189
290
 
190
- Note that objects created with `build_stubbed` cannot be serialized with
191
- `Marshal.dump`, since factory_bot defines singleton methods on these objects.
192
-
193
- Static Attributes
194
- ------------------
291
+ ### `build_stubbed` and `Marshal.dump`
195
292
 
196
- Static attributes (without a block) are no longer available in factory\_bot 5.
197
- You can read more about the decision to remove them in
198
- [this blog post](https://robots.thoughtbot.com/deprecating-static-attributes-in-factory_bot-4-11).
293
+ Note that objects created with `build_stubbed` cannot be serialized with
294
+ `Marshal.dump`, since factory\_bot defines singleton methods on these objects.
199
295
 
200
296
  Aliases
201
297
  -------
202
- factory_bot allows you to define aliases to existing factories to make them easier to re-use. This could come in handy when, for example, your Post object has an author attribute that actually refers to an instance of a User class. While normally factory_bot can infer the factory name from the association name, in this case it will look for an author factory in vain. So, alias your user factory so it can be used under alias names.
298
+
299
+ factory\_bot allows you to define aliases to existing factories to make them
300
+ easier to re-use. This could come in handy when, for example, your Post object
301
+ has an author attribute that actually refers to an instance of a User class.
302
+ While normally factory\_bot can infer the factory name from the association name,
303
+ in this case it will look for an author factory in vain. So, alias your user
304
+ factory so it can be used under alias names.
203
305
 
204
306
  ```ruby
205
307
  factory :user, aliases: [:author, :commenter] do
@@ -244,35 +346,77 @@ create(:user, last_name: "Doe").email
244
346
  Transient Attributes
245
347
  --------------------
246
348
 
247
- There may be times where your code can be DRYed up by passing in transient attributes to factories.
349
+ ### With other attributes
350
+
351
+ There may be times where your code can be DRYed up by passing in transient
352
+ attributes to factories. You can access transient attributes within other
353
+ attributes (see [Dependent Attributes](#dependent-attributes)):
248
354
 
249
355
  ```ruby
250
356
  factory :user do
251
357
  transient do
252
358
  rockstar { true }
253
- upcased { false }
254
359
  end
255
360
 
256
361
  name { "John Doe#{" - Rockstar" if rockstar}" }
257
- email { "#{name.downcase}@example.com" }
362
+ end
363
+
364
+ create(:user).name
365
+ #=> "John Doe - ROCKSTAR"
366
+
367
+ create(:user, rockstar: false).name
368
+ #=> "John Doe"
369
+ ```
370
+
371
+ ### With `attributes_for`
372
+
373
+ Transient attributes will be ignored within attributes\_for and won't be set on
374
+ the model, even if the attribute exists or you attempt to override it.
375
+
376
+ ### With callbacks
377
+
378
+ If you need to access the evaluator in a factory\_bot callback,
379
+ you'll need to declare a second block argument (for the evaluator) and access
380
+ transient attributes from there.
381
+
382
+ ```ruby
383
+ factory :user do
384
+ transient do
385
+ upcased { false }
386
+ end
387
+
388
+ name { "John Doe" }
258
389
 
259
390
  after(:create) do |user, evaluator|
260
391
  user.name.upcase! if evaluator.upcased
261
392
  end
262
393
  end
263
394
 
395
+ create(:user).name
396
+ #=> "John Doe"
397
+
264
398
  create(:user, upcased: true).name
265
- #=> "JOHN DOE - ROCKSTAR"
399
+ #=> "JOHN DOE"
266
400
  ```
267
401
 
268
- Transient attributes will be ignored within attributes\_for and won't be
269
- set on the model,
270
- even if the attribute exists or you attempt to override it.
402
+ ### With associations
271
403
 
272
- Within factory_bot's dynamic attributes, you can access transient attributes as
273
- you would expect. If you need to access the evaluator in a factory_bot callback,
274
- you'll need to declare a second block argument (for the evaluator) and access
275
- transient attributes from there.
404
+ Transient [associations](#associations) are not supported in factory\_bot.
405
+ Associations within the transient block will be treated as regular,
406
+ non-transient associations.
407
+
408
+ If needed, you can generally work around this by building a factory within a
409
+ transient attribute:
410
+
411
+ ```ruby
412
+ factory :post
413
+
414
+ factory :user do
415
+ transient do
416
+ post { build(:post) }
417
+ end
418
+ end
419
+ ```
276
420
 
277
421
  Method Name / Reserved Word Attributes
278
422
  -------------------------------
@@ -293,7 +437,10 @@ end
293
437
  Inheritance
294
438
  -----------
295
439
 
296
- You can easily create multiple factories for the same class without repeating common attributes by nesting factories:
440
+ ### Nested factories
441
+
442
+ You can easily create multiple factories for the same class without repeating
443
+ common attributes by nesting factories:
297
444
 
298
445
  ```ruby
299
446
  factory :post do
@@ -309,6 +456,8 @@ approved_post.title # => "A title"
309
456
  approved_post.approved # => true
310
457
  ```
311
458
 
459
+ ### Assigning parent explicitly
460
+
312
461
  You can also assign the parent explicitly:
313
462
 
314
463
  ```ruby
@@ -321,6 +470,8 @@ factory :approved_post, parent: :post do
321
470
  end
322
471
  ```
323
472
 
473
+ ### Best practices
474
+
324
475
  As mentioned above, it's good practice to define a basic factory for each class
325
476
  with only the attributes required to create it. Then, create more specific
326
477
  factories that inherit from this basic parent. Factory definitions are still
@@ -329,7 +480,10 @@ code, so keep them DRY.
329
480
  Associations
330
481
  ------------
331
482
 
332
- It's possible to set up associations within factories. If the factory name is the same as the association name, the factory name can be left out.
483
+ ### Implicit definition
484
+
485
+ It's possible to set up associations within factories. If the factory name is
486
+ the same as the association name, the factory name can be left out.
333
487
 
334
488
  ```ruby
335
489
  factory :post do
@@ -338,15 +492,66 @@ factory :post do
338
492
  end
339
493
  ```
340
494
 
341
- You can also specify a different factory or override attributes:
495
+ ### Explicit definition
496
+
497
+ You can define associations explicitly. This can be handy especially when
498
+ [Overriding attributes](#overriding-attributes)
499
+
500
+ ```ruby
501
+ factory :post do
502
+ # ...
503
+ association :author
504
+ end
505
+ ```
506
+
507
+ ### Specifying the factory
508
+
509
+ You can specify a different factory (although [Aliases](#aliases) might also
510
+ help you out here).
511
+
512
+ Implicitly:
513
+
514
+ ```ruby
515
+ factory :post do
516
+ # ...
517
+ author factory: :user
518
+ end
519
+ ```
520
+
521
+ Explicitly:
522
+
523
+ ```ruby
524
+ factory :post do
525
+ # ...
526
+ association :author, factory: :user
527
+ end
528
+ ```
529
+
530
+ ### Overriding attributes
531
+
532
+ You can also override attributes.
533
+
534
+ Implicitly:
342
535
 
343
536
  ```ruby
344
537
  factory :post do
345
538
  # ...
346
- association :author, factory: :user, last_name: "Writely"
539
+ author factory: :author, last_name: "Writely"
347
540
  end
348
541
  ```
349
542
 
543
+ Explicitly:
544
+
545
+
546
+ ```ruby
547
+ factory :post do
548
+ # ...
549
+ association :author, last_name: "Writely"
550
+ end
551
+ ```
552
+
553
+ ### Build strategies
554
+
350
555
  In factory\_bot 5, associations default to using the same build strategy as
351
556
  their parent object:
352
557
 
@@ -412,6 +617,8 @@ factory :post do
412
617
  author strategy: :build # <<< this does *not* work; causes author_id to be nil
413
618
  ```
414
619
 
620
+ ### `has_many` associations
621
+
415
622
  Generating data for a `has_many` relationship is a bit more involved,
416
623
  depending on the amount of flexibility desired, but here's a surefire example
417
624
  of generating associated data.
@@ -457,6 +664,8 @@ create(:user_with_posts).posts.length # 5
457
664
  create(:user_with_posts, posts_count: 15).posts.length # 15
458
665
  ```
459
666
 
667
+ ### `has_and_belongs_to_many` associations
668
+
460
669
  Generating data for a `has_and_belongs_to_many` relationship is very similar
461
670
  to the above `has_many` relationship, with a small change, you need to pass an
462
671
  array of objects to the model's pluralized attribute name rather than a single
@@ -508,6 +717,8 @@ create(:profile_with_languages).languages.length # 5
508
717
  create(:profile_with_languages, languages_count: 15).languages.length # 15
509
718
  ```
510
719
 
720
+ ### Polymorphic associations
721
+
511
722
  Polymorphic associations can be handled with traits:
512
723
 
513
724
  ```ruby
@@ -541,6 +752,8 @@ create(:comment, :for_photo)
541
752
  Sequences
542
753
  ---------
543
754
 
755
+ ### Global sequences
756
+
544
757
  Unique values in a specific format (for example, e-mail addresses) can be
545
758
  generated using sequences. Sequences are defined by calling `sequence` in a
546
759
  definition block, and values in a sequence are generated by calling
@@ -561,6 +774,8 @@ generate :email
561
774
  # => "person2@example.com"
562
775
  ```
563
776
 
777
+ ### With dynamic attributes
778
+
564
779
  Sequences can be used in dynamic attributes:
565
780
 
566
781
  ```ruby
@@ -569,6 +784,8 @@ factory :invite do
569
784
  end
570
785
  ```
571
786
 
787
+ ### As implicit attributes
788
+
572
789
  Or as implicit attributes:
573
790
 
574
791
  ```ruby
@@ -580,6 +797,8 @@ end
580
797
  Note that defining sequences as implicit attributes will not work if you have a
581
798
  factory with the same name as the sequence.
582
799
 
800
+ ### Inline sequences
801
+
583
802
  And it's also possible to define an in-line sequence that is only used in
584
803
  a particular factory:
585
804
 
@@ -589,7 +808,10 @@ factory :user do
589
808
  end
590
809
  ```
591
810
 
592
- You can also override the initial value:
811
+ ### Initial value
812
+
813
+ You can override the initial value. Any value that response to the `#next`
814
+ method will work (e.g. 1, 2, 3, 'a', 'b', 'c')
593
815
 
594
816
  ```ruby
595
817
  factory :user do
@@ -597,6 +819,8 @@ factory :user do
597
819
  end
598
820
  ```
599
821
 
822
+ ### Without a block
823
+
600
824
  Without a block, the value will increment itself, starting at its initial value:
601
825
 
602
826
  ```ruby
@@ -605,6 +829,8 @@ factory :post do
605
829
  end
606
830
  ```
607
831
 
832
+ ### Aliases
833
+
608
834
  Sequences can also have aliases. The sequence aliases share the same counter:
609
835
 
610
836
  ```ruby
@@ -634,6 +860,8 @@ end
634
860
 
635
861
  The value just needs to support the `#next` method. Here the next value will be 'a', then 'b', etc.
636
862
 
863
+ ### Rewinding
864
+
637
865
  Sequences can also be rewound with `FactoryBot.rewind_sequences`:
638
866
 
639
867
  ```ruby
@@ -653,6 +881,8 @@ This rewinds all registered sequences.
653
881
  Traits
654
882
  ------
655
883
 
884
+ ### Defining traits
885
+
656
886
  Traits allow you to group attributes together and then apply them
657
887
  to any factory.
658
888
 
@@ -688,6 +918,8 @@ factory :story do
688
918
  end
689
919
  ```
690
920
 
921
+ ### As implicit attributes
922
+
691
923
  Traits can be used as implicit attributes:
692
924
 
693
925
  ```ruby
@@ -701,6 +933,8 @@ end
701
933
  Note that defining traits as implicit attributes will not work if you have a
702
934
  factory or sequence with the same name as the trait.
703
935
 
936
+ ### Attribute precedence
937
+
704
938
  Traits that define the same attributes won't raise AttributeDefinitionErrors;
705
939
  the trait that defines the attribute latest gets precedence.
706
940
 
@@ -731,7 +965,9 @@ factory :user do
731
965
  end
732
966
  ```
733
967
 
734
- You can also override individual attributes granted by a trait in subclasses.
968
+ ### In child factories
969
+
970
+ You can override individual attributes granted by a trait in a child factory:
735
971
 
736
972
  ```ruby
737
973
  factory :user do
@@ -751,7 +987,10 @@ factory :user do
751
987
  end
752
988
  ```
753
989
 
754
- Traits can also be passed in as a list of symbols when you construct an instance from factory_bot.
990
+ ### Using traits
991
+
992
+ Traits can also be passed in as a list of symbols when you construct an instance
993
+ from factory\_bot.
755
994
 
756
995
  ```ruby
757
996
  factory :user do
@@ -790,6 +1029,8 @@ end
790
1029
  create_list(:user, 3, :admin, :male, name: "Jon Snow")
791
1030
  ```
792
1031
 
1032
+ ### With associations
1033
+
793
1034
  Traits can be used with associations easily too:
794
1035
 
795
1036
  ```ruby
@@ -830,6 +1071,8 @@ end
830
1071
  create(:post).author
831
1072
  ```
832
1073
 
1074
+ ### Traits within traits
1075
+
833
1076
  Traits can be used within other traits to mix in their attributes.
834
1077
 
835
1078
  ```ruby
@@ -845,6 +1088,8 @@ factory :order do
845
1088
  end
846
1089
  ```
847
1090
 
1091
+ ### With transient attributes
1092
+
848
1093
  Finally, traits can accept transient attributes.
849
1094
 
850
1095
  ```ruby
@@ -863,9 +1108,103 @@ end
863
1108
  create :invoice, :with_amount, amount: 2
864
1109
  ```
865
1110
 
1111
+ ### Enum traits
1112
+
1113
+ Given an Active Record model with an enum attribute:
1114
+
1115
+ ```rb
1116
+ class Task < ActiveRecord::Base
1117
+ enum status: {queued: 0, started: 1, finished: 2}
1118
+ end
1119
+
1120
+ ```
1121
+
1122
+ factory\_bot will automatically define traits for each possible value of the
1123
+ enum:
1124
+
1125
+ ```rb
1126
+ FactoryBot.define do
1127
+ factory :task
1128
+ end
1129
+
1130
+ FactoryBot.build(:task, :queued)
1131
+ FactoryBot.build(:task, :started)
1132
+ FactoryBot.build(:task, :finished)
1133
+ ```
1134
+
1135
+ Writing the traits out manually would be cumbersome, and is not necessary:
1136
+
1137
+ ```rb
1138
+ FactoryBot.define do
1139
+ factory :task do
1140
+ trait :queued do
1141
+ status { :queued }
1142
+ end
1143
+
1144
+ trait :started do
1145
+ status { :started }
1146
+ end
1147
+
1148
+ trait :finished do
1149
+ status { :finished }
1150
+ end
1151
+ end
1152
+ end
1153
+ ```
1154
+
1155
+ If automatically defining traits for enum attributes on every factory is not
1156
+ desired, it is possible to disable the feature by setting
1157
+ `FactoryBot.automatically_define_enum_traits = false`
1158
+
1159
+ In that case, it is still possible to explicitly define traits for an enum
1160
+ attribute in a particular factory:
1161
+
1162
+ ```rb
1163
+ FactoryBot.automatically_define_enum_traits = false
1164
+
1165
+ FactoryBot.define do
1166
+ factory :task do
1167
+ traits_for_enum(:status)
1168
+ end
1169
+ end
1170
+ ```
1171
+
1172
+ It is also possible to use this feature for other enumerable values, not
1173
+ specifically tied to Active Record enum attributes.
1174
+
1175
+ With an array:
1176
+
1177
+ ```rb
1178
+ class Task
1179
+ attr_accessor :status
1180
+ end
1181
+
1182
+ FactoryBot.define do
1183
+ factory :task do
1184
+ traits_for_enum(:status, ["queued", "started", "finished"])
1185
+ end
1186
+ end
1187
+ ```
1188
+
1189
+ Or with a hash:
1190
+
1191
+ ```rb
1192
+ class Task
1193
+ attr_accessor :status
1194
+ end
1195
+
1196
+ FactoryBot.define do
1197
+ factory :task do
1198
+ traits_for_enum(:status, { queued: 0, started: 1, finished: 2 })
1199
+ end
1200
+ end
1201
+ ```
1202
+
866
1203
  Callbacks
867
1204
  ---------
868
1205
 
1206
+ ### Default callbacks
1207
+
869
1208
  factory\_bot makes available four callbacks for injecting some code:
870
1209
 
871
1210
  * after(:build) - called after a factory is built (via `FactoryBot.build`, `FactoryBot.create`)
@@ -884,6 +1223,8 @@ end
884
1223
 
885
1224
  Note that you'll have an instance of the user in the block. This can be useful.
886
1225
 
1226
+ ### Multiple callbacks
1227
+
887
1228
  You can also define multiple types of callbacks on the same factory:
888
1229
 
889
1230
  ```ruby
@@ -893,7 +1234,8 @@ factory :user do
893
1234
  end
894
1235
  ```
895
1236
 
896
- Factories can also define any number of the same kind of callback. These callbacks will be executed in the order they are specified:
1237
+ Factories can also define any number of the same kind of callback. These
1238
+ callbacks will be executed in the order they are specified:
897
1239
 
898
1240
  ```ruby
899
1241
  factory :user do
@@ -904,9 +1246,12 @@ end
904
1246
 
905
1247
  Calling `create` will invoke both `after_build` and `after_create` callbacks.
906
1248
 
907
- Also, like standard attributes, child factories will inherit (and can also define) callbacks from their parent factory.
1249
+ Also, like standard attributes, child factories will inherit (and can also
1250
+ define) callbacks from their parent factory.
908
1251
 
909
- Multiple callbacks can be assigned to run a block; this is useful when building various strategies that run the same code (since there are no callbacks that are shared across all strategies).
1252
+ Multiple callbacks can be assigned to run a block; this is useful when building
1253
+ various strategies that run the same code (since there are no callbacks that are
1254
+ shared across all strategies).
910
1255
 
911
1256
  ```ruby
912
1257
  factory :user do
@@ -916,6 +1261,8 @@ factory :user do
916
1261
  end
917
1262
  ```
918
1263
 
1264
+ ### Global callbacks
1265
+
919
1266
  To override callbacks for all factories, define them within the
920
1267
  `FactoryBot.define` block:
921
1268
 
@@ -930,7 +1277,9 @@ FactoryBot.define do
930
1277
  end
931
1278
  ```
932
1279
 
933
- You can also call callbacks that rely on `Symbol#to_proc`:
1280
+ ### Symbol#to_proc
1281
+
1282
+ You can call callbacks that rely on `Symbol#to_proc`:
934
1283
 
935
1284
  ```ruby
936
1285
  # app/models/user.rb
@@ -953,8 +1302,9 @@ create(:user) # creates the user and confirms it
953
1302
  Modifying factories
954
1303
  -------------------
955
1304
 
956
- If you're given a set of factories (say, from a gem developer) but want to change them to fit into your application better, you can
957
- modify that factory instead of creating a child factory and adding attributes there.
1305
+ If you're given a set of factories (say, from a gem developer) but want to
1306
+ change them to fit into your application better, you can modify that factory
1307
+ instead of creating a child factory and adding attributes there.
958
1308
 
959
1309
  If a gem were to give you a User factory:
960
1310
 
@@ -1048,7 +1398,7 @@ users_attrs = attributes_for_list(:user, 25) # array of attribute hashes
1048
1398
  Linting Factories
1049
1399
  -----------------
1050
1400
 
1051
- factory_bot allows for linting known factories:
1401
+ factory\_bot allows for linting known factories:
1052
1402
 
1053
1403
  ```ruby
1054
1404
  FactoryBot.lint
@@ -1134,7 +1484,7 @@ FactoryBot.lint verbose: true
1134
1484
  Custom Construction
1135
1485
  -------------------
1136
1486
 
1137
- If you want to use factory_bot to construct an object where some attributes
1487
+ If you want to use factory\_bot to construct an object where some attributes
1138
1488
  are passed to `initialize` or if you want to do something other than simply
1139
1489
  calling `new` on your build class, you can override the default behavior by
1140
1490
  defining `initialize_with` on your factory. Example:
@@ -1162,7 +1512,7 @@ end
1162
1512
  build(:user).name # Jane Doe
1163
1513
  ```
1164
1514
 
1165
- Although factory_bot is written to work with ActiveRecord out of the box, it
1515
+ Although factory\_bot is written to work with ActiveRecord out of the box, it
1166
1516
  can also work with any Ruby class. For maximum compatibility with ActiveRecord,
1167
1517
  the default initializer builds all instances by calling `new` on your build class
1168
1518
  without any arguments. It then calls attribute writer methods to assign all the
@@ -1173,7 +1523,7 @@ You can override the initializer in order to:
1173
1523
 
1174
1524
  * Build non-ActiveRecord objects that require arguments to `initialize`
1175
1525
  * Use a method other than `new` to instantiate the instance
1176
- * Do crazy things like decorate the instance after it's built
1526
+ * Do wild things like decorate the instance after it's built
1177
1527
 
1178
1528
  When using `initialize_with`, you don't have to declare the class itself when
1179
1529
  calling `new`; however, any other class methods you want to call will have to
@@ -1235,7 +1585,7 @@ build(:user)
1235
1585
  User.new('value')
1236
1586
  ```
1237
1587
 
1238
- This prevents duplicate assignment; in versions of factory_bot before 4.0, it
1588
+ This prevents duplicate assignment; in versions of factory\_bot before 4.0, it
1239
1589
  would run this:
1240
1590
 
1241
1591
  ```ruby