factory_bot 4.11.1 → 5.0.0.rc1

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/GETTING_STARTED.md +105 -29
  3. data/NEWS +17 -0
  4. data/README.md +3 -14
  5. data/lib/factory_bot.rb +56 -56
  6. data/lib/factory_bot/aliases.rb +1 -1
  7. data/lib/factory_bot/attribute.rb +4 -39
  8. data/lib/factory_bot/attribute_assigner.rb +20 -5
  9. data/lib/factory_bot/attribute_list.rb +2 -1
  10. data/lib/factory_bot/callback.rb +1 -0
  11. data/lib/factory_bot/configuration.rb +6 -18
  12. data/lib/factory_bot/declaration.rb +4 -4
  13. data/lib/factory_bot/declaration/association.rb +3 -1
  14. data/lib/factory_bot/declaration/dynamic.rb +3 -1
  15. data/lib/factory_bot/declaration/implicit.rb +3 -1
  16. data/lib/factory_bot/declaration_list.rb +1 -1
  17. data/lib/factory_bot/decorator.rb +5 -1
  18. data/lib/factory_bot/decorator/attribute_hash.rb +1 -1
  19. data/lib/factory_bot/decorator/invocation_tracker.rb +1 -1
  20. data/lib/factory_bot/definition.rb +4 -3
  21. data/lib/factory_bot/definition_proxy.rb +53 -62
  22. data/lib/factory_bot/errors.rb +4 -4
  23. data/lib/factory_bot/evaluation.rb +1 -1
  24. data/lib/factory_bot/evaluator.rb +4 -4
  25. data/lib/factory_bot/factory.rb +7 -7
  26. data/lib/factory_bot/factory_runner.rb +3 -3
  27. data/lib/factory_bot/find_definitions.rb +1 -1
  28. data/lib/factory_bot/linter.rb +35 -18
  29. data/lib/factory_bot/null_factory.rb +3 -0
  30. data/lib/factory_bot/null_object.rb +2 -2
  31. data/lib/factory_bot/registry.rb +15 -6
  32. data/lib/factory_bot/sequence.rb +0 -1
  33. data/lib/factory_bot/strategy/null.rb +2 -4
  34. data/lib/factory_bot/strategy/stub.rb +23 -29
  35. data/lib/factory_bot/strategy_syntax_method_registrar.rb +2 -2
  36. data/lib/factory_bot/syntax.rb +2 -2
  37. data/lib/factory_bot/syntax/default.rb +1 -1
  38. data/lib/factory_bot/trait.rb +2 -1
  39. data/lib/factory_bot/version.rb +1 -1
  40. metadata +68 -29
  41. data/lib/factory_bot/attribute/static.rb +0 -16
  42. data/lib/factory_bot/declaration/static.rb +0 -26
  43. data/lib/factory_bot/decorator/class_key_hash.rb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14d67d2d0498cdfe3d47717279561f299566ecd20084af6958e3c5143188ccae
4
- data.tar.gz: bb6daffb31d969293032bbb2d655c3628095bdd285708fdc93fe2a60e4cd072e
3
+ metadata.gz: c22373774f12578e26bfcb3885c5cb3e03651230880b1d7817458c8b09637581
4
+ data.tar.gz: f75b530fbfce32a94367db37ecfe55a2b5c568f95d0b24e9a55d9d6b63e4fbcc
5
5
  SHA512:
6
- metadata.gz: 24178c541ce3b726ad7274febd2bbf69ccaff9446a15a79b9bfce5525b0e2f63cc4af50a48950abe5b8b80397151bf86c31263463b0d7309093c870cb925c97d
7
- data.tar.gz: 630e120e664a503de162d11d9dc36f83a7fc5602a8935875cacfb905b28c3cf1c8f0978137281b5aa8d2fed3fa40c236dd567cb7544bca44cb85e1f43fb2ac83
6
+ metadata.gz: '08c78ce623a22e0b9b7da186fdc66acc24e267ecda60ff79940ff41756d1065ef30fa52fc5e5f58d619137db876b3f8cd611f211d919f50724839272ad0e449d'
7
+ data.tar.gz: fff4a17d150ccdd07ed4c6efacfd51dc6c64cd07e563f042b864983b2569215f431ed67481e8907c4b48ba190d64369432c0259f3b6d860fbd4b588c97ec645b
data/GETTING_STARTED.md CHANGED
@@ -4,16 +4,16 @@ Getting Started
4
4
  Update Your Gemfile
5
5
  -------------------
6
6
 
7
- If you're using Rails, you'll need to change the required version of `factory_bot_rails`:
7
+ If you're using Rails:
8
8
 
9
9
  ```ruby
10
- gem "factory_bot_rails", "~> 4.0"
10
+ gem "factory_bot_rails"
11
11
  ```
12
12
 
13
- If you're *not* using Rails, you'll just have to change the required version of `factory_bot`:
13
+ If you're *not* using Rails:
14
14
 
15
15
  ```ruby
16
- gem "factory_bot", "~> 4.0"
16
+ gem "factory_bot"
17
17
  ```
18
18
 
19
19
  JRuby users: factory_bot works with JRuby starting with 1.6.7.2 (latest stable, as per July 2012).
@@ -102,7 +102,7 @@ If you do not include `FactoryBot::Syntax::Methods` in your test suite, then all
102
102
  Defining factories
103
103
  ------------------
104
104
 
105
- Each factory has a name and a set of attributes. The name is used to guess the class of the object by default, but it's possible to explicitly specify it:
105
+ Each factory has a name and a set of attributes. The name is used to guess the class of the object by default:
106
106
 
107
107
  ```ruby
108
108
  # This will guess the User class
@@ -112,16 +112,26 @@ FactoryBot.define do
112
112
  last_name { "Doe" }
113
113
  admin { false }
114
114
  end
115
-
116
- # This will use the User class (Admin would have been guessed)
117
- factory :admin, class: User do
118
- first_name { "Admin" }
119
- last_name { "User" }
120
- admin { true }
121
- end
122
115
  end
123
116
  ```
124
117
 
118
+ It is also possible to explicitly specify the class:
119
+
120
+ ```ruby
121
+ # This will use the User class (otherwise Admin would have been guessed)
122
+ factory :admin, class: User
123
+ ```
124
+
125
+ If the constant is not available
126
+ (if you are using a Rails engine that waits to load models, for example),
127
+ you can also pass a symbol or string,
128
+ which factory_bot will constantize later, once you start building objects:
129
+
130
+ ```ruby
131
+ # It's OK if Doorkeeper::AccessToken isn't loaded yet
132
+ factory :access_token, class: "Doorkeeper::AccessToken"
133
+ ```
134
+
125
135
  Because of the block syntax in Ruby, defining attributes as `Hash`es (for
126
136
  serialized/JSON columns, for example) requires two sets of curly brackets:
127
137
 
@@ -177,21 +187,15 @@ user.first_name
177
187
  # => "Joe"
178
188
  ```
179
189
 
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
+
180
193
  Static Attributes
181
194
  ------------------
182
195
 
183
- Static attributes, without a block, are deprecated and will be removed in
184
- factory\_bot 5.
185
-
186
- ```ruby
187
- factory :user do
188
- # Do not use deprecated static attributes
189
- admin true
190
-
191
- # Use dynamic attributes instead
192
- admin { true }
193
- end
194
- ```
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).
195
199
 
196
200
  Aliases
197
201
  -------
@@ -261,8 +265,8 @@ create(:user, upcased: true).name
261
265
  #=> "JOHN DOE - ROCKSTAR"
262
266
  ```
263
267
 
264
- Static and dynamic attributes can be created as transient attributes. Transient
265
- attributes will be ignored within attributes\_for and won't be set on the model,
268
+ Transient attributes will be ignored within attributes\_for and won't be
269
+ set on the model,
266
270
  even if the attribute exists or you attempt to override it.
267
271
 
268
272
  Within factory_bot's dynamic attributes, you can access transient attributes as
@@ -273,7 +277,7 @@ transient attributes from there.
273
277
  Method Name / Reserved Word Attributes
274
278
  -------------------------------
275
279
 
276
- If your attributes conflict with existing methods or reserved words you can define them with `add_attribute`.
280
+ 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`.
277
281
 
278
282
  ```ruby
279
283
  factory :dna do
@@ -343,9 +347,35 @@ factory :post do
343
347
  end
344
348
  ```
345
349
 
346
- The behavior of the association method varies depending on the build strategy used for the parent object.
350
+ In factory\_bot 5, associations default to using the same build strategy as
351
+ their parent object:
347
352
 
348
353
  ```ruby
354
+ FactoryBot.define do
355
+ factory :author
356
+
357
+ factory :post do
358
+ author
359
+ end
360
+ end
361
+
362
+ post = build(:post)
363
+ post.new_record? # => true
364
+ post.author.new_record? # => true
365
+
366
+ post = create(:post)
367
+ post.new_record? # => false
368
+ post.author.new_record? # => false
369
+ ```
370
+
371
+ This is different than the default behavior for previous versions of
372
+ factory\_bot, where the association strategy would not always match the strategy
373
+ of the parent object. If you want to continue using the old behavior, you can
374
+ set the `use_parent_strategy` configuration option to `false`.
375
+
376
+ ```ruby
377
+ FactoryBot.use_parent_strategy = false
378
+
349
379
  # Builds and saves a User and a Post
350
380
  post = create(:post)
351
381
  post.new_record? # => false
@@ -360,6 +390,8 @@ post.author.new_record? # => false
360
390
  To not save the associated object, specify strategy: :build in the factory:
361
391
 
362
392
  ```ruby
393
+ FactoryBot.use_parent_strategy = false
394
+
363
395
  factory :post do
364
396
  # ...
365
397
  association :author, factory: :user, strategy: :build
@@ -476,6 +508,36 @@ create(:profile_with_languages).languages.length # 5
476
508
  create(:profile_with_languages, languages_count: 15).languages.length # 15
477
509
  ```
478
510
 
511
+ Polymorphic associations can be handled with traits:
512
+
513
+ ```
514
+ FactoryBot.define do
515
+ factory :video
516
+ factory :photo
517
+
518
+ factory :comment do
519
+ for_photo
520
+
521
+ trait :for_video do
522
+ association(:commentable, factory: :video)
523
+ end
524
+
525
+ trait :for_photo do
526
+ association(:commentable, factory: :photo)
527
+ end
528
+ end
529
+ end
530
+ ```
531
+
532
+ This allows us to do:
533
+
534
+ ```
535
+ create(:comment)
536
+ create(:comment, :for_video)
537
+ create(:comment, :for_photo)
538
+ ```
539
+
540
+
479
541
  Sequences
480
542
  ---------
481
543
 
@@ -515,6 +577,9 @@ factory :user do
515
577
  end
516
578
  ```
517
579
 
580
+ Note that defining sequences as implicit attributes will not work if you have a
581
+ factory with the same name as the sequence.
582
+
518
583
  And it's also possible to define an in-line sequence that is only used in
519
584
  a particular factory:
520
585
 
@@ -623,7 +688,7 @@ factory :story do
623
688
  end
624
689
  ```
625
690
 
626
- Traits can be used as attributes:
691
+ Traits can be used as implicit attributes:
627
692
 
628
693
  ```ruby
629
694
  factory :week_long_published_story_with_title, parent: :story do
@@ -633,6 +698,9 @@ factory :week_long_published_story_with_title, parent: :story do
633
698
  end
634
699
  ```
635
700
 
701
+ Note that defining traits as implicit attributes will not work if you have a
702
+ factory or sequence with the same name as the trait.
703
+
636
704
  Traits that define the same attributes won't raise AttributeDefinitionErrors;
637
705
  the trait that defines the attribute latest gets precedence.
638
706
 
@@ -999,6 +1067,7 @@ namespace :factory_bot do
999
1067
  desc "Verify that all FactoryBot factories are valid"
1000
1068
  task lint: :environment do
1001
1069
  if Rails.env.test?
1070
+ DatabaseCleaner.clean_with(:deletion)
1002
1071
  DatabaseCleaner.cleaning do
1003
1072
  FactoryBot.lint
1004
1073
  end
@@ -1047,6 +1116,13 @@ You can also specify the strategy used for linting:
1047
1116
  FactoryBot.lint strategy: :build
1048
1117
  ```
1049
1118
 
1119
+ Verbose linting will include full backtraces for each error, which can be
1120
+ helpful for debugging:
1121
+
1122
+ ```ruby
1123
+ FactoryBot.lint verbose: :true
1124
+ ```
1125
+
1050
1126
  Custom Construction
1051
1127
  -------------------
1052
1128
 
data/NEWS CHANGED
@@ -1,3 +1,20 @@
1
+ 5.0.0
2
+ Added: Verbose option to include full backtraces in the linting output
3
+ Changed: use_parent_strategy now defaults to true, so by default the
4
+ build strategy will build, rather than create associations
5
+ Changed: Passing a block when defining associations now raises an error
6
+ Bugfix: use_parent_strategy is no longer reset by FactoryBot.reload
7
+ Bugfix: rewind_sequences will now rewind local sequences along with the global ones
8
+ Bugfix: the build_stubbed strategy now sets timestamps without changing the
9
+ the original behavior of the timestamp methods
10
+ Bugfix: avoid a stack error when referring to an "attributes" attribute in initialize_with
11
+ Removed: support for EOL versions of Ruby and Rails
12
+ Removed: static attributes (use dynamic attributes with a block instead)
13
+ Removed: looking up factories by class
14
+ Removed: ignore method (use transient instead)
15
+ Removed: duplicate_attribute_assignment_from_initialize_with configuration option
16
+ Deprecated: allow_class_lookup configuration option
17
+
1
18
  4.11.1 (September 7, 2018)
2
19
  Documentation: Include .yardopts in the gem to fix broken RubyDoc links
3
20
 
data/README.md CHANGED
@@ -21,7 +21,7 @@ You should find the documentation for your version of factory_bot on [Rubygems](
21
21
  See [GETTING_STARTED] for information on defining and using factories. We also
22
22
  have [a detailed introductory video][], available for free on Upcase.
23
23
 
24
- [a detailed introductory video]: https://upcase.com/videos/factory-girl?utm_source=github&utm_medium=open-source&utm_campaign=factory-girl
24
+ [a detailed introductory video]: https://upcase.com/videos/factory-bot?utm_source=github&utm_medium=open-source&utm_campaign=factory-girl
25
25
 
26
26
  Install
27
27
  --------
@@ -40,22 +40,11 @@ To install the gem manually from your shell, run:
40
40
  gem install factory_bot
41
41
  ```
42
42
 
43
- **Caveat:** As of ActiveSupport 5.0 and above, Ruby 2.2.2+ is required. Because
44
- of Rubygems' dependency resolution when installing gems, you may see an error
45
- similar to:
46
-
47
- ```
48
- $ gem install factory_bot
49
- ERROR: Error installing factory_bot:
50
- activesupport requires Ruby version >= 2.2.2.
51
- ```
52
-
53
- To bypass this, install a pre-5.0 version of ActiveSupport before installing
54
- manually.
55
-
56
43
  Supported Ruby versions
57
44
  -----------------------
58
45
 
46
+ The factory_bot 5.x series supports MRI Ruby 2.3+.
47
+
59
48
  The factory_bot 3.x+ series supports MRI Ruby 1.9. Additionally, factory_bot
60
49
  3.6+ supports JRuby 1.6.7.2+ while running in 1.9 mode. See [GETTING_STARTED]
61
50
  for more information on configuring the JRuby environment.
data/lib/factory_bot.rb CHANGED
@@ -1,52 +1,54 @@
1
- require 'set'
2
- require 'active_support/core_ext/module/delegation'
3
- require 'active_support/deprecation'
4
- require 'active_support/notifications'
5
-
6
- require 'factory_bot/definition_hierarchy'
7
- require 'factory_bot/configuration'
8
- require 'factory_bot/errors'
9
- require 'factory_bot/factory_runner'
10
- require 'factory_bot/strategy_syntax_method_registrar'
11
- require 'factory_bot/strategy_calculator'
12
- require 'factory_bot/strategy/build'
13
- require 'factory_bot/strategy/create'
14
- require 'factory_bot/strategy/attributes_for'
15
- require 'factory_bot/strategy/stub'
16
- require 'factory_bot/strategy/null'
17
- require 'factory_bot/registry'
18
- require 'factory_bot/null_factory'
19
- require 'factory_bot/null_object'
20
- require 'factory_bot/evaluation'
21
- require 'factory_bot/factory'
22
- require 'factory_bot/attribute_assigner'
23
- require 'factory_bot/evaluator'
24
- require 'factory_bot/evaluator_class_definer'
25
- require 'factory_bot/attribute'
26
- require 'factory_bot/callback'
27
- require 'factory_bot/callbacks_observer'
28
- require 'factory_bot/declaration_list'
29
- require 'factory_bot/declaration'
30
- require 'factory_bot/sequence'
31
- require 'factory_bot/attribute_list'
32
- require 'factory_bot/trait'
33
- require 'factory_bot/aliases'
34
- require 'factory_bot/definition'
35
- require 'factory_bot/definition_proxy'
36
- require 'factory_bot/syntax'
37
- require 'factory_bot/syntax_runner'
38
- require 'factory_bot/find_definitions'
39
- require 'factory_bot/reload'
40
- require 'factory_bot/decorator'
41
- require 'factory_bot/decorator/attribute_hash'
42
- require 'factory_bot/decorator/class_key_hash'
43
- require 'factory_bot/decorator/disallows_duplicates_registry'
44
- require 'factory_bot/decorator/invocation_tracker'
45
- require 'factory_bot/decorator/new_constructor'
46
- require 'factory_bot/linter'
47
- require 'factory_bot/version'
1
+ require "set"
2
+ require "active_support/core_ext/module/delegation"
3
+ require "active_support/core_ext/module/attribute_accessors"
4
+ require "active_support/deprecation"
5
+ require "active_support/notifications"
6
+
7
+ require "factory_bot/definition_hierarchy"
8
+ require "factory_bot/configuration"
9
+ require "factory_bot/errors"
10
+ require "factory_bot/factory_runner"
11
+ require "factory_bot/strategy_syntax_method_registrar"
12
+ require "factory_bot/strategy_calculator"
13
+ require "factory_bot/strategy/build"
14
+ require "factory_bot/strategy/create"
15
+ require "factory_bot/strategy/attributes_for"
16
+ require "factory_bot/strategy/stub"
17
+ require "factory_bot/strategy/null"
18
+ require "factory_bot/registry"
19
+ require "factory_bot/null_factory"
20
+ require "factory_bot/null_object"
21
+ require "factory_bot/evaluation"
22
+ require "factory_bot/factory"
23
+ require "factory_bot/attribute_assigner"
24
+ require "factory_bot/evaluator"
25
+ require "factory_bot/evaluator_class_definer"
26
+ require "factory_bot/attribute"
27
+ require "factory_bot/callback"
28
+ require "factory_bot/callbacks_observer"
29
+ require "factory_bot/declaration_list"
30
+ require "factory_bot/declaration"
31
+ require "factory_bot/sequence"
32
+ require "factory_bot/attribute_list"
33
+ require "factory_bot/trait"
34
+ require "factory_bot/aliases"
35
+ require "factory_bot/definition"
36
+ require "factory_bot/definition_proxy"
37
+ require "factory_bot/syntax"
38
+ require "factory_bot/syntax_runner"
39
+ require "factory_bot/find_definitions"
40
+ require "factory_bot/reload"
41
+ require "factory_bot/decorator"
42
+ require "factory_bot/decorator/attribute_hash"
43
+ require "factory_bot/decorator/disallows_duplicates_registry"
44
+ require "factory_bot/decorator/invocation_tracker"
45
+ require "factory_bot/decorator/new_constructor"
46
+ require "factory_bot/linter"
47
+ require "factory_bot/version"
48
48
 
49
49
  module FactoryBot
50
+ DEPRECATOR = ActiveSupport::Deprecation.new("6.0", "factory_bot")
51
+
50
52
  def self.configuration
51
53
  @configuration ||= Configuration.new
52
54
  end
@@ -55,18 +57,19 @@ module FactoryBot
55
57
  @configuration = nil
56
58
  end
57
59
 
60
+ mattr_accessor :use_parent_strategy, instance_accessor: false, default: true
61
+
58
62
  # Look for errors in factories and (optionally) their traits.
59
63
  # Parameters:
60
64
  # factories - which factories to lint; omit for all factories
61
65
  # options:
62
66
  # traits: true - to lint traits as well as factories
63
67
  # strategy: :create - to specify the strategy for linting
68
+ # verbose: true - to include full backtraces for each linting error
64
69
  def self.lint(*args)
65
70
  options = args.extract_options!
66
71
  factories_to_lint = args[0] || FactoryBot.factories
67
- linting_strategy = options[:traits] ? :factory_and_traits : :factory
68
- factory_strategy = options[:strategy] || :create
69
- Linter.new(factories_to_lint, linting_strategy, factory_strategy).lint!
72
+ Linter.new(factories_to_lint, options).lint!
70
73
  end
71
74
 
72
75
  class << self
@@ -80,13 +83,10 @@ module FactoryBot
80
83
  :skip_create,
81
84
  :initialize_with,
82
85
  :constructor,
83
- :duplicate_attribute_assignment_from_initialize_with,
84
- :duplicate_attribute_assignment_from_initialize_with=,
85
- :allow_class_lookup,
86
- :allow_class_lookup=,
87
- :use_parent_strategy,
88
- :use_parent_strategy=,
89
86
  to: :configuration
87
+
88
+ attr_accessor :allow_class_lookup
89
+ deprecate :allow_class_lookup, :allow_class_lookup=, deprecator: DEPRECATOR
90
90
  end
91
91
 
92
92
  def self.register_factory(factory)