factory_bot 6.2.1 → 6.5.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3bcbbd8bee01abdb25a5cfdbbbbca29396f587236f0c20f8300adbf6e32f783c
4
- data.tar.gz: 94d8e73507ae61edba7fb3129ee74c4fe9998a8fb78614ecba9966199561c8e4
3
+ metadata.gz: '0658ea1fd8d3b33128d6a88be3b64855cf80238bc0d2bf109f85a59b4398504f'
4
+ data.tar.gz: 1cc9fb919e03d2ad95589e5519b19b1c8bd0ec1b6d0e45ee6479ff6d8f2541ad
5
5
  SHA512:
6
- metadata.gz: e97d9530810f0de00f6e0129df37db52722ee8d430f7b118ffdcebdc0eecc1e1532356b7c8e01cc85265c04f18eb174d3d5ff09fe235c5f30ceb7b5e16432508
7
- data.tar.gz: 71b77c30b16c89588d6946505be547374321597e8e16f89673766cda94b22188dc28070a34144ae126dad93042de0173e1d92173237ae1e929a3131e85569a51
6
+ metadata.gz: '092799b8ba784bb640a2422ff8556d5c13c92a67b8224bd4730c4b2791995d4f56797ccf2815416e2fb21a474c41b47cc87df61564adae4cb3d0dc832c22f520'
7
+ data.tar.gz: 1cc5060b814c06ed943ed825df2b913fb857b118837a850152f7b9044328de0a277f112365f10d8e66001d270b0059da77bef190ed712558c7186af00a1ccc4c
data/CONTRIBUTING.md CHANGED
@@ -94,12 +94,12 @@ Use [standard] to automatically format your code:
94
94
  bundle exec rake standard:fix
95
95
  ```
96
96
 
97
- [repo]: https://github.com/thoughtbot/factory_bot/tree/master
97
+ [repo]: https://github.com/thoughtbot/factory_bot/tree/main
98
98
  [fork]: https://help.github.com/articles/fork-a-repo/
99
99
  [branch]: https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/
100
100
  [pr]: https://help.github.com/articles/using-pull-requests/
101
101
  [standard]: https://github.com/testdouble/standard
102
102
  [appraisal]: https://github.com/thoughtbot/appraisal
103
- [reproduction script]: https://github.com/thoughtbot/factory_bot/blob/master/.github/REPRODUCTION_SCRIPT.rb
103
+ [reproduction script]: https://github.com/thoughtbot/factory_bot/blob/main/.github/REPRODUCTION_SCRIPT.rb
104
104
 
105
105
  Inspired by https://github.com/middleman/middleman-heroku/blob/master/CONTRIBUTING.md
data/GETTING_STARTED.md CHANGED
@@ -1,3 +1,19 @@
1
+ **Deprecated**
2
+
3
+ See our extensive reference, guides, and cookbook in [the factory_bot book][].
4
+
5
+ For information on integrations with third party libraries, such as RSpec or
6
+ Rails, see [the factory_bot wiki][].
7
+
8
+ We also have [a detailed introductory video][], available for free on Upcase.
9
+
10
+ [a detailed introductory video]: https://upcase.com/videos/factory-bot?utm_source=github&utm_medium=open-source&utm_campaign=factory-girl
11
+ [the factory_bot book]: https://thoughtbot.github.io/factory_bot
12
+ [the factory_bot wiki]: https://github.com/thoughtbot/factory_bot/wiki
13
+
14
+ This document is deprecated and preserved for historical use. It may disappear
15
+ at any time.
16
+
1
17
  Getting Started
2
18
  ===============
3
19
 
@@ -239,10 +255,12 @@ Factories can be defined anywhere, but will be automatically loaded after
239
255
  calling `FactoryBot.find_definitions` if factories are defined in files at the
240
256
  following locations:
241
257
 
258
+ factories.rb
259
+ factories/**/*.rb
242
260
  test/factories.rb
261
+ test/factories/**/*.rb
243
262
  spec/factories.rb
244
- test/factories/*.rb
245
- spec/factories/*.rb
263
+ spec/factories/**/*.rb
246
264
 
247
265
  ### Static Attributes
248
266
 
@@ -269,6 +287,9 @@ user = create(:user)
269
287
  # Returns a hash of attributes that can be used to build a User instance
270
288
  attrs = attributes_for(:user)
271
289
 
290
+ # Integrates with Ruby 3.0's support for pattern matching assignment
291
+ attributes_for(:user) => {email:, name:, **attrs}
292
+
272
293
  # Returns an object with all defined attributes stubbed out
273
294
  stub = build_stubbed(:user)
274
295
 
@@ -281,7 +302,7 @@ end
281
302
  ### Attribute overrides
282
303
 
283
304
  No matter which strategy is used, it's possible to override the defined
284
- attributes by passing a hash:
305
+ attributes by passing a Hash:
285
306
 
286
307
  ```ruby
287
308
  # Build a User instance and override the first_name property
@@ -290,6 +311,29 @@ user.first_name
290
311
  # => "Joe"
291
312
  ```
292
313
 
314
+ Overriding associations is also supported:
315
+
316
+ ```ruby
317
+ account = build(:account, :deluxe)
318
+ friends = build_list(:user, 2)
319
+
320
+ user = build(:user, account: account, friends: friends)
321
+ ```
322
+
323
+ Ruby 3.1's support for [omitting values][] from `Hash` literals dovetails with
324
+ attribute overrides and provides an opportunity to limit the repetition of
325
+ variable names:
326
+
327
+ ```ruby
328
+ account = build(:account, :deluxe)
329
+ friends = build_list(:user, 2)
330
+
331
+ # The keyword arguments correspond to local variable names, so omit their values
332
+ user = build(:user, account:, friends:)
333
+ ```
334
+
335
+ [omitting values]: https://docs.ruby-lang.org/en/3.1/syntax/literals_rdoc.html#label-Hash+Literals
336
+
293
337
  ### `build_stubbed` and `Marshal.dump`
294
338
 
295
339
  Note that objects created with `build_stubbed` cannot be serialized with
@@ -424,7 +468,7 @@ end
424
468
  Method Name / Reserved Word Attributes
425
469
  -------------------------------
426
470
 
427
- If your attributes conflict with existing methods or reserved words (all methods in the [DefinitionProxy](https://github.com/thoughtbot/factory_bot/blob/master/lib/factory_bot/definition_proxy.rb) class) you can define them with `add_attribute`.
471
+ If your attributes conflict with existing methods or reserved words (all methods in the [DefinitionProxy](https://github.com/thoughtbot/factory_bot/blob/main/lib/factory_bot/definition_proxy.rb) class) you can define them with `add_attribute`.
428
472
 
429
473
  ```ruby
430
474
  factory :dna do
@@ -929,7 +973,7 @@ end
929
973
  Note that this approach works with `build`, `build_stubbed`, and `create`, but
930
974
  the associations will return `nil` when using `attributes_for`.
931
975
 
932
- Also, note that if you assign any attributes inside a custom `initialize_with`
976
+ Also, note that if you assign any attributes inside a custom `initialize_with`
933
977
  (e.g. `initialize_with { new(**attributes) }`), those attributes should not refer to `instance`,
934
978
  since it will be `nil`.
935
979
 
@@ -992,6 +1036,17 @@ factory :user do
992
1036
  end
993
1037
  ```
994
1038
 
1039
+ With Ruby 2.7's support for [numbered parameters][], inline definitions can be
1040
+ even more abbreviated:
1041
+
1042
+ ```ruby
1043
+ factory :user do
1044
+ sequence(:email) { "person#{_1}@example.com" }
1045
+ end
1046
+ ```
1047
+
1048
+ [numbered parameters]: https://ruby-doc.org/core-2.7.1/Proc.html#class-Proc-label-Numbered+parameters
1049
+
995
1050
  ### Initial value
996
1051
 
997
1052
  You can override the initial value. Any value that responds to the `#next`
@@ -1206,11 +1261,11 @@ FactoryBot.define do
1206
1261
  created_at { 8.days.ago }
1207
1262
  updated_at { 4.days.ago }
1208
1263
  end
1209
-
1264
+
1210
1265
  factory :user, traits: [:timestamps] do
1211
1266
  username { "john_doe" }
1212
1267
  end
1213
-
1268
+
1214
1269
  factory :post do
1215
1270
  timestamps
1216
1271
  title { "Traits rock" }
@@ -1872,6 +1927,10 @@ class JsonStrategy
1872
1927
  def result(evaluation)
1873
1928
  @strategy.result(evaluation).to_json
1874
1929
  end
1930
+
1931
+ def to_sym
1932
+ :json
1933
+ end
1875
1934
  end
1876
1935
  ```
1877
1936
 
@@ -1912,6 +1971,10 @@ class JsonStrategy
1912
1971
  evaluation.notify(:make_json_awesome, json)
1913
1972
  end
1914
1973
  end
1974
+
1975
+ def to_sym
1976
+ :json
1977
+ end
1915
1978
  end
1916
1979
 
1917
1980
  FactoryBot.register_strategy(:json, JsonStrategy)
@@ -1966,7 +2029,7 @@ ActiveSupport Instrumentation
1966
2029
 
1967
2030
  In order to track what factories are created (and with what build strategy),
1968
2031
  `ActiveSupport::Notifications` are included to provide a way to subscribe to
1969
- factories being run. One example would be to track factories based on a
2032
+ factories being compiled and run. One example would be to track factories based on a
1970
2033
  threshold of execution time.
1971
2034
 
1972
2035
  ```ruby
@@ -2000,6 +2063,29 @@ config.after(:suite) do
2000
2063
  end
2001
2064
  ```
2002
2065
 
2066
+ Another example could involve tracking the attributes and traits that factories are compiled with. If you're using RSpec, you could add `before(:suite)` and `after(:suite)` blocks that subscribe to `factory_bot.compile_factory` notifications:
2067
+
2068
+ ```ruby
2069
+ factory_bot_results = {}
2070
+ config.before(:suite) do
2071
+ ActiveSupport::Notifications.subscribe("factory_bot.compile_factory") do |name, start, finish, id, payload|
2072
+ factory_name = payload[:name]
2073
+ factory_class = payload[:class]
2074
+ attributes = payload[:attributes]
2075
+ traits = payload[:traits]
2076
+ factory_bot_results[factory_class] ||= {}
2077
+ factory_bot_results[factory_class][factory_name] = {
2078
+ attributes: attributes.map(&:name)
2079
+ traits: traits.map(&:name)
2080
+ }
2081
+ end
2082
+ end
2083
+
2084
+ config.after(:suite) do
2085
+ puts factory_bot_results
2086
+ end
2087
+ ```
2088
+
2003
2089
  Rails Preloaders and RSpec
2004
2090
  --------------------------
2005
2091
 
data/NEWS.md CHANGED
@@ -1,9 +1,119 @@
1
1
  # News
2
2
 
3
+ ## 6.5.4 (June 13, 2025)
4
+
5
+ * Fix bug where user-defined method named `definition` could not be set through `method_missing` in factories. (CodeMeister)
6
+
7
+ ## 6.5.3 (June 2, 2025)
8
+
9
+ * Fix: Factory sequences without blocks (CodeMeister)
10
+ * Added: New methods for setting, generating and rewinding sequences (CodeMeister)
11
+
12
+ ## 6.5.2 (May 30, 2025)
13
+
14
+ * Changed: Updated "verbose linting" test to allow for backtrace changes in Ruby 3.4 (CodeMeister)
15
+ * Fix: Set the same timestamps for `created_at` and `updated_at` on `build_stubbed` (Kim Emmanuel)
16
+ * Fix: Refactored sequences to ensure cloned traits use parent sequences. (CodeMeister)
17
+ * Docs: Fix definition_file_paths comment (Milo Winningham)
18
+ * Docs: Add ruby-lsp extensions to Useful Tools in README.md (johansenja)
19
+ * Docs: Fix docs about definition file paths (Ryo Nakamura)
20
+ * Docs: Update has_many-associations.md to mention that traits can use inline associations (Matthew Zagaja)
21
+ * Docs: Fix "Transitioning from Factory Girl" guide link (Neil Carvalho)
22
+
23
+ ## 6.5.1 (January 31, 2025)
24
+
25
+ * Changed: execute linting tests within ActiveRecord transactions when available (Sean Doyle)
26
+ * Fix: Random test failure when tracking compilation time (CodeMeister)
27
+ * Fix: Bump the minimum required activesupport version to 6.1 (Earlopain)
28
+ * Internal: Update development dependencies (Neil Carvalho)
29
+
30
+ ## 6.5.0 (September 6, 2024)
31
+
32
+ * fix: issue 1621 broken links in ref/factory.md by @elasticspoon in https://github.com/thoughtbot/factory_bot/pull/1623
33
+ * Add standard settings by @ydah in https://github.com/thoughtbot/factory_bot/pull/1625
34
+ * Call dynamic-readme reusable workflow by @stefannibrasil in https://github.com/thoughtbot/factory_bot/pull/1628
35
+ * Update README again by @stefannibrasil in https://github.com/thoughtbot/factory_bot/pull/1630
36
+ * Only run this workflow if the README has been updated by @stefannibrasil in https://github.com/thoughtbot/factory_bot/pull/1635
37
+ * Automatically Generated: Update Dynamic Section in README by @github-actions in https://github.com/thoughtbot/factory_bot/pull/1637
38
+ * Added a case for build_class to handle class names with underscores passed as a string by @m-gizzi in https://github.com/thoughtbot/factory_bot/pull/1642
39
+ * Add Ruby 3.3 to CI by @berkos in https://github.com/thoughtbot/factory_bot/pull/1615
40
+ * Update Dependabot configuration by @smaboshe in https://github.com/thoughtbot/factory_bot/pull/1655
41
+ * Add new maintainers to CODEOWNERS by @sarahraqueld in https://github.com/thoughtbot/factory_bot/pull/1651
42
+ * Improve docs formatting and fix filename conflicts by @sarahraqueld in https://github.com/thoughtbot/factory_bot/pull/1666
43
+ * Add a dynamic security workflow and a SECURITY.md file by @sarahraqueld in https://github.com/thoughtbot/factory_bot/pull/1677
44
+ * Automatically Generated: Update Dynamic Section in SECURITY by @github-actions in https://github.com/thoughtbot/factory_bot/pull/1678
45
+ * Ensure rails 7.2 compatibility by @Earlopain in https://github.com/thoughtbot/factory_bot/pull/1686
46
+ * Fix the factory definition in traits documentation by @ddieulivol in https://github.com/thoughtbot/factory_bot/pull/1688
47
+
48
+ ## 6.4.6 (January 30, 2023)
49
+
50
+ * Fix: Bump minimum required Ruby in gemspec (Earlopain).
51
+ * Fix: Broken link in `FactoryBot.modify` docs (Matt Brictson).
52
+ * Fix: Broken link in `FactoryBot.lint` docs (Anton Dieterle).
53
+
54
+ ## 6.4.5 (December 29, 2023)
55
+
56
+ * Changed: Support Ruby 3.0+, Rails 6.1+ (Mike Burns).
57
+
58
+ ## 6.4.4 (December 27, 2023)
59
+
60
+ * Internal: Remove observer dependency (Earlopain).
61
+
62
+ ## 6.4.3 (December 26, 2023)
63
+
64
+ * Fix: Support models without ID setters in build_stubbed (Olivier Bellone).
65
+ * Fix: Explicit observer dependency (Oleg Antonyan).
66
+ * Internal: Add Rails 7.1 to CI (Olivier Bellone).
67
+ * Internal: Bump github actions/checkout to v4 (Lorenzo Zabot)
68
+ * Internal: Stop passing disable-error_highlight in CI (Mike Burns).
69
+ * Internal: Relax the exception message check (Mike Burns).
70
+
71
+ ## 6.4.2 (November 22, 2023)
72
+
73
+ * Fix: top-level traits pass their class to ActiveSupport::Notifications
74
+ (makicamel).
75
+
76
+ ## 6.4.1 (November 20, 2023)
77
+
78
+ * Fix: factories with traits pass their class to ActiveSupport::Notifications
79
+ (makicamel).
80
+
81
+ ## 6.4.0 (November 17, 2023)
82
+
83
+ * Added: if `build_stubbed` detects a UUID primary key, generate the correct
84
+ type (Peter Boling, Alexandre Ruban).
85
+ * Docs: show examples of Ruby 3 syntactic sugars (Sean Doyle).
86
+ * Internal: resolve test warning messages (Mike Burns).
87
+
88
+
89
+ ## 6.3.0 (September 1, 2023)
90
+
91
+ * Fix: link to changelog for RubyGems (Berkan Ünal).
92
+ * Fix: integrate with Ruby 3.2's `did_you_mean` library (Daniel Colson).
93
+ * Changed: explicitly define `#destroyed?` within the `Stub` strategy to return `false` to be consistent
94
+ with ActiveRecord (Benjamin Fleischer).
95
+ * Added: announce `factory_bot.compile_factory` notification (Sean Doyle).
96
+ * Docs: clarify that custom strategies need to define `#to_sym` (Edmund Korley, Jonas S).
97
+ * Docs: fix CI link in README (Mark Huk).
98
+ * Docs: fix GitHub links (Robert Fletcher).
99
+ * Docs: install this library with `bundle add` (Glauco Custódio).
100
+ * Docs: re-write into mdBook (Mike Burns, Sara Jackson, Stefanni Brasil)
101
+ * Docs: clarify that automatic trait definitions could introduce new linting errors (Lawrence Chou).
102
+ * Internal: skip TruffleRuby on Rails 5.0, 5.1, 5.2 (Andrii Konchyn).
103
+ * Internal: fix typoes throughout codebase (Yudai Takada).
104
+ * Internal: run CI on `actions/checkout` v3 (Yudai Takada).
105
+ * Internal: follow standardrb code style (Yudai Takada).
106
+ * Internal: stop using Hound (Daniel Nolan).
107
+ * Internal: only run simplecov on C Ruby (Daniel Colson).
108
+ * Internal: quieter Cucumber (Daniel Colson).
109
+ * Internal: Ruby 3.2 support (Daniel Colson).
110
+ * Internal: Mike Burns is the CODEOWNER (Stefanni Brasil).
111
+
3
112
  ## 6.2.1 (March 8, 2022)
4
113
  * Added: CI testing against truffleruby
5
114
  * Changed: Documentation improvements for sequences and traits
6
115
  * Fixed: ActiveSupport::Notifications reporting strategy through associations now report as symbols
116
+ * BREAKING CHANGE: Custom strategies now need to define a `to_sym` method to specify the strategy identifier
7
117
  * Fixed: `add_attribute` with reserved keywords assigns values correctly
8
118
 
9
119
  ## 6.2.0 (May 7, 2021)
@@ -27,7 +137,9 @@
27
137
  * Added: automatic definition of traits for Active Record enum attributes, enabled by default
28
138
  (Note that this required changing where factory_bot constantizes the build
29
139
  class, which may affect applications that were using abstract factories for
30
- inheritance. See issue #1409.)
140
+ inheritance. See issue #1409.) (This may break `FactoryBot.lint` because
141
+ there may be previously non-existing factory+trait combinations being
142
+ defined and checked)
31
143
  * Added: `traits_for_enum` method to define traits for non-Active Record enums
32
144
  * Added: `build_stubbed_starting_id=` option to define the starting id for `build_stubbed`
33
145
  * Removed: deprecated methods on the top-level `FactoryBot` module meant only for internal use
data/README.md CHANGED
@@ -10,30 +10,32 @@ _[Interested in the history of the project name?][NAME]_
10
10
 
11
11
  ### Transitioning from factory\_girl?
12
12
 
13
- Check out the [guide](https://github.com/thoughtbot/factory_bot/blob/4-9-0-stable/UPGRADE_FROM_FACTORY_GIRL.md).
13
+ Check out the [guide](https://github.com/thoughtbot/factory_bot/blob/v4.9.0/UPGRADE_FROM_FACTORY_GIRL.md).
14
14
 
15
15
 
16
16
  Documentation
17
17
  -------------
18
18
 
19
- You should find the documentation for your version of factory_bot on [Rubygems](https://rubygems.org/gems/factory_bot).
19
+ See our extensive reference, guides, and cookbook in [the factory_bot book][].
20
20
 
21
- See [GETTING_STARTED] for information on defining and using factories. We also
22
- have [a detailed introductory video][], available for free on Upcase.
21
+ For information on integrations with third party libraries, such as RSpec or
22
+ Rails, see [the factory_bot wiki][].
23
+
24
+ We also have [a detailed introductory video][], available for free on Upcase.
23
25
 
24
26
  [a detailed introductory video]: https://upcase.com/videos/factory-bot?utm_source=github&utm_medium=open-source&utm_campaign=factory-girl
27
+ [the factory_bot book]: https://thoughtbot.github.io/factory_bot
28
+ [the factory_bot wiki]: https://github.com/thoughtbot/factory_bot/wiki
25
29
 
26
30
  Install
27
31
  --------
28
32
 
29
- Add the following line to Gemfile:
33
+ Run:
30
34
 
31
35
  ```ruby
32
- gem 'factory_bot'
36
+ bundle add factory_bot
33
37
  ```
34
38
 
35
- and run `bundle install` from your shell.
36
-
37
39
  To install the gem manually from your shell, run:
38
40
 
39
41
  ```shell
@@ -43,7 +45,7 @@ gem install factory_bot
43
45
  Supported Ruby versions
44
46
  -----------------------
45
47
 
46
- Supported Ruby versions are listed in [`.github/workflows/build.yml`](https://github.com/thoughtbot/factory_bot/blob/master/.github/workflows/build.yml)
48
+ Supported Ruby versions are listed in [`.github/workflows/build.yml`](https://github.com/thoughtbot/factory_bot/blob/main/.github/workflows/build.yml)
47
49
 
48
50
  More Information
49
51
  ----------------
@@ -53,18 +55,19 @@ More Information
53
55
  * [Issues](https://github.com/thoughtbot/factory_bot/issues)
54
56
  * [GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS](https://robots.thoughtbot.com/)
55
57
 
56
- [GETTING_STARTED]: https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md
57
- [NAME]: https://github.com/thoughtbot/factory_bot/blob/master/NAME.md
58
+ [GETTING_STARTED]: https://github.com/thoughtbot/factory_bot/blob/main/GETTING_STARTED.md
59
+ [NAME]: https://github.com/thoughtbot/factory_bot/blob/main/NAME.md
58
60
 
59
61
  Useful Tools
60
62
  ------------
61
63
 
62
64
  * [FactoryTrace](https://github.com/djezzzl/factory_trace) - helps to find unused factories and traits.
65
+ * [ruby-lsp-factory_bot](https://github.com/donny741/ruby-lsp-factory_bot) / [ruby-lsp-rails-factory-bot](https://github.com/johansenja/ruby-lsp-rails-factory-bot) - integration with [ruby-lsp](https://github.com/Shopify/ruby-lsp) to provide intellisense
63
66
 
64
67
  Contributing
65
68
  ------------
66
69
 
67
- Please see [CONTRIBUTING.md](https://github.com/thoughtbot/factory_bot/blob/master/CONTRIBUTING.md).
70
+ Please see [CONTRIBUTING.md](https://github.com/thoughtbot/factory_bot/blob/main/CONTRIBUTING.md).
68
71
 
69
72
  factory_bot was originally written by Joe Ferris and is maintained by thoughtbot.
70
73
  Many improvements and bugfixes were contributed by the [open source
@@ -73,29 +76,31 @@ community](https://github.com/thoughtbot/factory_bot/graphs/contributors).
73
76
  License
74
77
  -------
75
78
 
76
- factory_bot is Copyright © 2008-2020 Joe Ferris and thoughtbot. It is free
79
+ factory_bot is Copyright © 2008 Joe Ferris and thoughtbot. It is free
77
80
  software, and may be redistributed under the terms specified in the
78
81
  [LICENSE] file.
79
82
 
80
- [LICENSE]: https://github.com/thoughtbot/factory_bot/blob/master/LICENSE
81
-
83
+ [LICENSE]: https://github.com/thoughtbot/factory_bot/blob/main/LICENSE
82
84
 
83
- About thoughtbot
84
- ----------------
85
+ <!-- START /templates/footer.md -->
86
+ ## About thoughtbot
85
87
 
86
- ![thoughtbot](https://thoughtbot.com/brand_assets/93:44.svg)
88
+ ![thoughtbot](https://thoughtbot.com/thoughtbot-logo-for-readmes.svg)
87
89
 
88
- factory_bot is maintained and funded by thoughtbot, inc.
90
+ This repo is maintained and funded by thoughtbot, inc.
89
91
  The names and logos for thoughtbot are trademarks of thoughtbot, inc.
90
92
 
91
93
  We love open source software!
92
- See [our other projects][community] or
93
- [hire us][hire] to design, develop, and grow your product.
94
+ See [our other projects][community].
95
+ We are [available for hire][hire].
94
96
 
95
97
  [community]: https://thoughtbot.com/community?utm_source=github
96
98
  [hire]: https://thoughtbot.com/hire-us?utm_source=github
97
- [ci-image]: https://github.com/thoughtbot/factory_bot/actions/workflows/build.yml/badge.svg
98
- [ci]: https://github.com/thoughtbot/factory_bot/actions?query=workflow%3A.github%2Fworkflows%2Fbuild.yml+branch%3Amaster++
99
+
100
+ <!-- END /templates/footer.md -->
101
+
102
+ [ci-image]: https://github.com/thoughtbot/factory_bot/actions/workflows/build.yml/badge.svg?branch=main
103
+ [ci]: https://github.com/thoughtbot/factory_bot/actions?query=workflow%3ABuild+branch%3Amain
99
104
  [grade-image]: https://codeclimate.com/github/thoughtbot/factory_bot/badges/gpa.svg
100
105
  [grade]: https://codeclimate.com/github/thoughtbot/factory_bot
101
106
  [version-image]: https://badge.fury.io/rb/factory_bot.svg
@@ -12,8 +12,8 @@ module FactoryBot
12
12
 
13
13
  -> {
14
14
  value = case block.arity
15
- when 1, -1, -2 then instance_exec(self, &block)
16
- else instance_exec(&block)
15
+ when 1, -1, -2 then instance_exec(self, &block)
16
+ else instance_exec(&block)
17
17
  end
18
18
  raise SequenceAbuseError if FactoryBot::Sequence === value
19
19
 
@@ -13,7 +13,7 @@ module FactoryBot
13
13
  @evaluator.instance = build_class_instance
14
14
  build_class_instance.tap do |instance|
15
15
  attributes_to_set_on_instance.each do |attribute|
16
- instance.public_send("#{attribute}=", get(attribute))
16
+ instance.public_send(:"#{attribute}=", get(attribute))
17
17
  @attribute_names_assigned << attribute
18
18
  end
19
19
  end
@@ -6,24 +6,12 @@ module FactoryBot
6
6
  @component = component
7
7
  end
8
8
 
9
- if ::Gem::Version.new(::RUBY_VERSION) >= ::Gem::Version.new("2.7")
10
- class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
11
- def method_missing(...) # rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing
12
- @component.send(...)
13
- end
14
-
15
- def send(...)
16
- __send__(...)
17
- end
18
- RUBY
19
- else
20
- def method_missing(name, *args, &block) # rubocop:disable Style/MissingRespondToMissing
21
- @component.send(name, *args, &block)
22
- end
9
+ def method_missing(...) # rubocop:disable Style/MethodMissingSuper
10
+ @component.send(...)
11
+ end
23
12
 
24
- def send(symbol, *args, &block)
25
- __send__(symbol, *args, &block)
26
- end
13
+ def send(...)
14
+ __send__(...)
27
15
  end
28
16
 
29
17
  def respond_to_missing?(name, include_private = false)
@@ -1,10 +1,12 @@
1
1
  module FactoryBot
2
2
  # @api private
3
3
  class Definition
4
- attr_reader :defined_traits, :declarations, :name, :registered_enums
4
+ attr_reader :defined_traits, :declarations, :name, :registered_enums, :uri_manager
5
+ attr_accessor :klass
5
6
 
6
- def initialize(name, base_traits = [])
7
+ def initialize(name, base_traits = [], **opts)
7
8
  @name = name
9
+ @uri_manager = opts[:uri_manager]
8
10
  @declarations = DeclarationList.new(name)
9
11
  @callbacks = []
10
12
  @defined_traits = Set.new
@@ -51,12 +53,21 @@ module FactoryBot
51
53
 
52
54
  declarations.attributes
53
55
 
56
+ self.klass ||= klass
54
57
  defined_traits.each do |defined_trait|
58
+ defined_trait.klass ||= klass
55
59
  base_traits.each { |bt| bt.define_trait defined_trait }
56
60
  additional_traits.each { |at| at.define_trait defined_trait }
57
61
  end
58
62
 
59
63
  @compiled = true
64
+
65
+ ActiveSupport::Notifications.instrument "factory_bot.compile_factory", {
66
+ name: name,
67
+ attributes: declarations.attributes,
68
+ traits: defined_traits,
69
+ class: klass || self.klass
70
+ }
60
71
  end
61
72
  end
62
73
 
@@ -85,6 +96,10 @@ module FactoryBot
85
96
  @defined_traits.add(trait)
86
97
  end
87
98
 
99
+ def defined_traits_names
100
+ @defined_traits.map(&:name)
101
+ end
102
+
88
103
  def register_enum(enum)
89
104
  @registered_enums << enum
90
105
  end
@@ -115,15 +130,26 @@ module FactoryBot
115
130
  raise error_with_definition_name(error)
116
131
  end
117
132
 
118
- def error_with_definition_name(error)
119
- message = error.message
120
- message.insert(
121
- message.index("\nDid you mean?") || message.length,
122
- " referenced within \"#{name}\" definition"
123
- )
133
+ # detailed_message introduced in Ruby 3.2 for cleaner integration with
134
+ # did_you_mean. See https://bugs.ruby-lang.org/issues/18564
135
+ if KeyError.method_defined?(:detailed_message)
136
+ def error_with_definition_name(error)
137
+ message = error.message + " referenced within \"#{name}\" definition"
124
138
 
125
- error.class.new(message).tap do |new_error|
126
- new_error.set_backtrace(error.backtrace)
139
+ error.class.new(message, key: error.key, receiver: error.receiver)
140
+ .tap { |new_error| new_error.set_backtrace(error.backtrace) }
141
+ end
142
+ else
143
+ def error_with_definition_name(error)
144
+ message = error.message
145
+ message.insert(
146
+ message.index("\nDid you mean?") || message.length,
147
+ " referenced within \"#{name}\" definition"
148
+ )
149
+
150
+ error.class.new(message).tap do |new_error|
151
+ new_error.set_backtrace(error.backtrace)
152
+ end
127
153
  end
128
154
  end
129
155
 
@@ -132,7 +158,7 @@ module FactoryBot
132
158
  end
133
159
 
134
160
  def trait_by_name(name)
135
- trait_for(name) || Internal.trait_by_name(name)
161
+ trait_for(name) || Internal.trait_by_name(name, klass)
136
162
  end
137
163
 
138
164
  def trait_for(name)
@@ -120,9 +120,13 @@ module FactoryBot
120
120
  #
121
121
  # Except that no globally available sequence will be defined.
122
122
  def sequence(name, *args, &block)
123
- sequence = Sequence.new(name, *args, &block)
124
- FactoryBot::Internal.register_inline_sequence(sequence)
125
- add_attribute(name) { increment_sequence(sequence) }
123
+ options = args.extract_options!
124
+ options[:uri_paths] = @definition.uri_manager.to_a
125
+ args << options
126
+
127
+ new_sequence = Sequence.new(name, *args, &block)
128
+ registered_sequence = __fetch_or_register_sequence(new_sequence)
129
+ add_attribute(name) { increment_sequence(registered_sequence) }
126
130
  end
127
131
 
128
132
  # Adds an attribute that builds an association. The associated instance will
@@ -151,7 +155,7 @@ module FactoryBot
151
155
  def association(name, *options)
152
156
  if block_given?
153
157
  raise AssociationDefinitionError.new(
154
- "Unexpected block passed to '#{name}' association "\
158
+ "Unexpected block passed to '#{name}' association " \
155
159
  "in '#{@definition.name}' factory"
156
160
  )
157
161
  else
@@ -169,11 +173,11 @@ module FactoryBot
169
173
  end
170
174
 
171
175
  def factory(name, options = {}, &block)
172
- @child_factories << [name, options, block]
176
+ child_factories << [name, options, block]
173
177
  end
174
178
 
175
179
  def trait(name, &block)
176
- @definition.define_trait(Trait.new(name, &block))
180
+ @definition.define_trait(Trait.new(name, uri_paths: @definition.uri_manager.to_a, &block))
177
181
  end
178
182
 
179
183
  # Creates traits for enumerable values.
@@ -252,5 +256,14 @@ module FactoryBot
252
256
  def __valid_association_options?(options)
253
257
  options.respond_to?(:has_key?) && options.has_key?(:factory)
254
258
  end
259
+
260
+ ##
261
+ # If the inline sequence has already been registered by a parent,
262
+ # return that one, otherwise register and return the given sequence
263
+ #
264
+ def __fetch_or_register_sequence(sequence)
265
+ FactoryBot::Sequence.find_by_uri(sequence.uri_manager.first) ||
266
+ FactoryBot::Internal.register_inline_sequence(sequence)
267
+ end
255
268
  end
256
269
  end