factory_bot 6.1.0 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe33ad3bb5d907e38ceac543f969484fb0ec67a4708a701cdfea0696d4a292c4
4
- data.tar.gz: 54cdb44f4ac7782360c8e9efd02ac46f40336d00c34a5767d5d7fc0f86f8d7a5
3
+ metadata.gz: a928c94babd835a0756175aa3d7a1f03d4dae15b0782818a8c9688489f6e18d3
4
+ data.tar.gz: e2875eca60137531b83267dcdfd87ba1329ed8a52e460a0e609fa5fb04f39244
5
5
  SHA512:
6
- metadata.gz: cdc3ec9def71e797058fb13cff95b911eceb61d1488f193ef1bfb6bdf12c6c7835d1f67dc1885d5539e6da7135f04e4a417a16fbc60cbc0c4d60056a1948c89d
7
- data.tar.gz: 2f04ab1a184266a86cf8510be688b8a01b0dd570615d25e314176b4492f9635053596636aa4ec9ab8133e86e4c9f630acdb52468c01ea1bfd2fb8777fc27b2ab
6
+ metadata.gz: bf8f7006ff4e0f34533259c6e747bb61cd8ebcd6d68b7a9076b811bf4b152662997f18ad467953c07f3a0c7c10585b48b4f0489ce6aa1a16b42ad02641e7169b
7
+ data.tar.gz: a80c3ed49517c2cee0dc7bdafc9dd3459d7fcd83443873e2a8c72db8a3c96b6d902975c8a586ecbfb1cd6b8dab9513a4bdfaa22f84c297f81b2736a8f4317e8d
data/CONTRIBUTING.md CHANGED
@@ -51,6 +51,12 @@ Here are some ways *you* can contribute:
51
51
  asking for help. We love helping!
52
52
  * Please don't update the Gem version.
53
53
 
54
+ ## Setting up
55
+
56
+ ```sh
57
+ bundle install
58
+ ```
59
+
54
60
  ## Running the test suite
55
61
 
56
62
  The default rake task will run the full test suite and [standard]:
data/GETTING_STARTED.md CHANGED
@@ -37,12 +37,15 @@ Getting Started
37
37
  * [Associations](#associations)
38
38
  + [Implicit definition](#implicit-definition)
39
39
  + [Explicit definition](#explicit-definition)
40
+ + [Inline definition](#inline-definition)
40
41
  + [Specifying the factory](#specifying-the-factory)
41
42
  + [Overriding attributes](#overriding-attributes)
43
+ + [Association overrides](#association-overrides)
42
44
  + [Build strategies](#build-strategies-1)
43
45
  + [`has_many` associations](#has_many-associations)
44
46
  + [`has_and_belongs_to_many` associations](#has_and_belongs_to_many-associations)
45
47
  + [Polymorphic associations](#polymorphic-associations)
48
+ + [Interconnected associations](#interconnected-associations)
46
49
  * [Sequences](#sequences)
47
50
  + [Global sequences](#global-sequences)
48
51
  + [With dynamic attributes](#with-dynamic-attributes)
@@ -197,17 +200,15 @@ It is also possible to explicitly specify the class:
197
200
 
198
201
  ```ruby
199
202
  # This will use the User class (otherwise Admin would have been guessed)
200
- factory :admin, class: User
203
+ factory :admin, class: "User"
201
204
  ```
202
205
 
203
- If the constant is not available
204
- (if you are using a Rails engine that waits to load models, for example),
205
- you can also pass a symbol or string,
206
- which factory\_bot will constantize later, once you start building objects:
206
+ You can pass a constant as well, if the constant is available (note that this
207
+ can cause test performance problems in large Rails applications, since
208
+ referring to the constant will cause it to be eagerly loaded).
207
209
 
208
210
  ```ruby
209
- # It's OK if Doorkeeper::AccessToken isn't loaded yet
210
- factory :access_token, class: "Doorkeeper::AccessToken"
211
+ factory :access_token, class: User
211
212
  ```
212
213
 
213
214
  ### Hash attributes
@@ -312,17 +313,17 @@ factory :user, aliases: [:author, :commenter] do
312
313
  end
313
314
 
314
315
  factory :post do
315
- author
316
- # instead of
316
+ # The alias allows us to write author instead of
317
317
  # association :author, factory: :user
318
+ author
318
319
  title { "How to read a book effectively" }
319
320
  body { "There are five steps involved." }
320
321
  end
321
322
 
322
323
  factory :comment do
323
- commenter
324
- # instead of
324
+ # The alias allows us to write commenter instead of
325
325
  # association :commenter, factory: :user
326
+ commenter
326
327
  body { "Great article!" }
327
328
  end
328
329
  ```
@@ -346,6 +347,7 @@ create(:user, last_name: "Doe").email
346
347
 
347
348
  Transient Attributes
348
349
  --------------------
350
+ Transient attributes are attributes only available within the factory definition, and not set on the object being built. This allows for more complex logic inside factories.
349
351
 
350
352
  ### With other attributes
351
353
 
@@ -505,6 +507,19 @@ factory :post do
505
507
  end
506
508
  ```
507
509
 
510
+ ### Inline definition
511
+
512
+ You can also define associations inline within regular attributes,
513
+ but note that the value will be `nil`
514
+ when using the `attributes_for` strategy.
515
+
516
+ ```ruby
517
+ factory :post do
518
+ # ...
519
+ author { association :author }
520
+ end
521
+ ```
522
+
508
523
  ### Specifying the factory
509
524
 
510
525
  You can specify a different factory (although [Aliases](#aliases) might also
@@ -528,6 +543,15 @@ factory :post do
528
543
  end
529
544
  ```
530
545
 
546
+ Inline:
547
+
548
+ ```ruby
549
+ factory :post do
550
+ # ...
551
+ author { association :user }
552
+ end
553
+ ```
554
+
531
555
  ### Overriding attributes
532
556
 
533
557
  You can also override attributes.
@@ -551,6 +575,35 @@ factory :post do
551
575
  end
552
576
  ```
553
577
 
578
+ Or inline using attributes from the factory:
579
+
580
+ ```rb
581
+ factory :post do
582
+ # ...
583
+ author_last_name { "Writely" }
584
+ author { association :author, last_name: author_last_name }
585
+ end
586
+ ```
587
+
588
+ ### Association overrides
589
+
590
+ Attribute overrides can be used to link associated objects:
591
+
592
+ ```ruby
593
+ FactoryBot.define do
594
+ factory :author do
595
+ author_last_name { 'Taylor' }
596
+ end
597
+
598
+ factory :post do
599
+ author
600
+ end
601
+ end
602
+
603
+ eunji = build(:author, name: 'Eunji')
604
+ post = build(:post, author: eunji)
605
+ ```
606
+
554
607
  ### Build strategies
555
608
 
556
609
  In factory\_bot 5, associations default to using the same build strategy as
@@ -620,27 +673,51 @@ factory :post do
620
673
 
621
674
  ### `has_many` associations
622
675
 
623
- Generating data for a `has_many` relationship is a bit more involved,
624
- depending on the amount of flexibility desired, but here's a surefire example
625
- of generating associated data.
676
+ There are a few ways to generate data for a `has_many` relationship. The
677
+ simplest approach is to write a helper method in plain Ruby to tie together the
678
+ different records:
626
679
 
627
680
  ```ruby
628
681
  FactoryBot.define do
682
+ factory :post do
683
+ title { "Through the Looking Glass" }
684
+ user
685
+ end
686
+
687
+ factory :user do
688
+ name { "Rachel Sanchez" }
689
+ end
690
+ end
691
+
692
+ def user_with_posts(posts_count: 5)
693
+ FactoryBot.create(:user) do |user|
694
+ FactoryBot.create_list(:post, posts_count, user: user)
695
+ end
696
+ end
697
+
698
+ create(:user).posts.length # 0
699
+ user_with_posts.posts.length # 5
700
+ user_with_posts(posts_count: 15).posts.length # 15
701
+ ```
702
+
703
+ If you prefer to keep the object creation fully within factory\_bot, you can
704
+ build the posts in an `after(:create)` callback.
629
705
 
630
- # post factory with a `belongs_to` association for the user
706
+
707
+ ```ruby
708
+ FactoryBot.define do
631
709
  factory :post do
632
710
  title { "Through the Looking Glass" }
633
711
  user
634
712
  end
635
713
 
636
- # user factory without associated posts
637
714
  factory :user do
638
715
  name { "John Doe" }
639
716
 
640
717
  # user_with_posts will create post data after the user has been created
641
718
  factory :user_with_posts do
642
- # posts_count is declared as a transient attribute and available in
643
- # attributes on the factory, as well as the callback via the evaluator
719
+ # posts_count is declared as a transient attribute available in the
720
+ # callback via the evaluator
644
721
  transient do
645
722
  posts_count { 5 }
646
723
  end
@@ -651,71 +728,122 @@ FactoryBot.define do
651
728
  # to create and we make sure the user is associated properly to the post
652
729
  after(:create) do |user, evaluator|
653
730
  create_list(:post, evaluator.posts_count, user: user)
731
+
732
+ # You may need to reload the record here, depending on your application
733
+ user.reload
654
734
  end
655
735
  end
656
736
  end
657
737
  end
738
+
739
+ create(:user).posts.length # 0
740
+ create(:user_with_posts).posts.length # 5
741
+ create(:user_with_posts, posts_count: 15).posts.length # 15
658
742
  ```
659
743
 
660
- This allows us to do:
744
+ Or, for a solution that works with `build`, `build_stubbed`, and `create`
745
+ (although it doesn't work well with `attributes_for`), you can use inline
746
+ associations:
661
747
 
662
748
  ```ruby
749
+ FactoryBot.define do
750
+ factory :post do
751
+ title { "Through the Looking Glass" }
752
+ user
753
+ end
754
+
755
+ factory :user do
756
+ name { "Taylor Kim" }
757
+
758
+ factory :user_with_posts do
759
+ posts { [association(:post)] }
760
+ end
761
+ end
762
+ end
763
+
663
764
  create(:user).posts.length # 0
765
+ create(:user_with_posts).posts.length # 1
766
+ build(:user_with_posts).posts.length # 1
767
+ build_stubbed(:user_with_posts).posts.length # 1
768
+ ```
769
+
770
+ For more flexibility you can combine this with the `posts_count` transient
771
+ attribute from the callback example:
772
+
773
+ ```ruby
774
+ FactoryBot.define do
775
+ factory :post do
776
+ title { "Through the Looking Glass" }
777
+ user
778
+ end
779
+
780
+ factory :user do
781
+ name { "Adiza Kumato" }
782
+
783
+ factory :user_with_posts do
784
+ transient do
785
+ posts_count { 5 }
786
+ end
787
+
788
+ posts do
789
+ Array.new(posts_count) { association(:post) }
790
+ end
791
+ end
792
+ end
793
+ end
794
+
664
795
  create(:user_with_posts).posts.length # 5
665
796
  create(:user_with_posts, posts_count: 15).posts.length # 15
797
+ build(:user_with_posts, posts_count: 15).posts.length # 15
798
+ build_stubbed(:user_with_posts, posts_count: 15).posts.length # 15
666
799
  ```
667
800
 
668
801
  ### `has_and_belongs_to_many` associations
669
802
 
670
803
  Generating data for a `has_and_belongs_to_many` relationship is very similar
671
- to the above `has_many` relationship, with a small change, you need to pass an
804
+ to the above `has_many` relationship, with a small change: you need to pass an
672
805
  array of objects to the model's pluralized attribute name rather than a single
673
806
  object to the singular version of the attribute name.
674
807
 
675
- Here's an example with two models that are related via
676
- `has_and_belongs_to_many`:
677
808
 
678
809
  ```ruby
679
- FactoryBot.define do
680
-
681
- # language factory with a `belongs_to` association for the profile
682
- factory :language do
683
- title { "Through the Looking Glass" }
684
- profile
810
+ def profile_with_languages(languages_count: 2)
811
+ FactoryBot.create(:profile) do |profile|
812
+ FactoryBot.create_list(:language, languages_count, profiles: [profile])
685
813
  end
814
+ end
815
+ ```
686
816
 
687
- # profile factory without associated languages
688
- factory :profile do
689
- name { "John Doe" }
817
+ Or with the callback approach:
690
818
 
691
- # profile_with_languages will create language data after the profile has
692
- # been created
693
- factory :profile_with_languages do
694
- # languages_count is declared as an ignored attribute and available in
695
- # attributes on the factory, as well as the callback via the evaluator
696
- transient do
697
- languages_count { 5 }
698
- end
819
+ ```ruby
820
+ factory :profile_with_languages do
821
+ transient do
822
+ languages_count { 2 }
823
+ end
699
824
 
700
- # the after(:create) yields two values; the profile instance itself and
701
- # the evaluator, which stores all values from the factory, including
702
- # ignored attributes; `create_list`'s second argument is the number of
703
- # records to create and we make sure the profile is associated properly
704
- # to the language
705
- after(:create) do |profile, evaluator|
706
- create_list(:language, evaluator.languages_count, profiles: [profile])
707
- end
708
- end
825
+ after(:create) do |profile, evaluator|
826
+ create_list(:language, evaluator.languages_count, profiles: [profile])
827
+ profile.reload
709
828
  end
710
829
  end
711
830
  ```
712
831
 
713
- This allows us to do:
832
+ Or the inline association approach (note the use of the `instance` method here
833
+ to refer to the profile being built):
714
834
 
715
835
  ```ruby
716
- create(:profile).languages.length # 0
717
- create(:profile_with_languages).languages.length # 5
718
- create(:profile_with_languages, languages_count: 15).languages.length # 15
836
+ factory :profile_with_languages do
837
+ transient do
838
+ languages_count { 2 }
839
+ end
840
+
841
+ languages do
842
+ Array.new(languages_count) do
843
+ association(:language, profiles: [instance])
844
+ end
845
+ end
846
+ end
719
847
  ```
720
848
 
721
849
  ### Polymorphic associations
@@ -749,6 +877,61 @@ create(:comment, :for_video)
749
877
  create(:comment, :for_photo)
750
878
  ```
751
879
 
880
+ ### Interconnected associations
881
+
882
+ There are limitless ways objects might be interconnected, and
883
+ factory\_bot may not always be suited to handle those relationships. In some
884
+ cases it makes sense to use factory\_bot to build each individual object, and
885
+ then to write helper methods in plain Ruby to tie those objects together.
886
+
887
+ That said, some more complex, interconnected relationships can be built in factory\_bot
888
+ using inline associations with reference to the `instance` being built.
889
+
890
+ Let's say your models look like this, where an associated `Student` and
891
+ `Profile` should both belong to the same `School`:
892
+
893
+ ```ruby
894
+ class Student < ApplicationRecord
895
+ belongs_to :school
896
+ has_one :profile
897
+ end
898
+
899
+ class Profile < ApplicationRecord
900
+ belongs_to :school
901
+ belongs_to :student
902
+ end
903
+
904
+ class School < ApplicationRecord
905
+ has_many :students
906
+ has_many :profiles
907
+ end
908
+ ```
909
+
910
+ We can ensure the student and profile are connected to each other and to the
911
+ same school with a factory like this:
912
+
913
+ ```ruby
914
+ FactoryBot.define do
915
+ factory :student do
916
+ school
917
+ profile { association :profile, student: instance, school: school }
918
+ end
919
+
920
+ factory :profile do
921
+ school
922
+ student { association :student, profile: instance, school: school }
923
+ end
924
+
925
+ factory :school
926
+ end
927
+ ```
928
+
929
+ Note that this approach works with `build`, `build_stubbed`, and `create`, but
930
+ the associations will return `nil` when using `attributes_for`.
931
+
932
+ Also, note that if you assign any attributes inside a custom `initialize_with`
933
+ (e.g. `initialize_with { new(**attributes) }`), those attributes should not refer to `instance`,
934
+ since it will be `nil`.
752
935
 
753
936
  Sequences
754
937
  ---------
@@ -811,7 +994,7 @@ end
811
994
 
812
995
  ### Initial value
813
996
 
814
- You can override the initial value. Any value that response to the `#next`
997
+ You can override the initial value. Any value that responds to the `#next`
815
998
  method will work (e.g. 1, 2, 3, 'a', 'b', 'c')
816
999
 
817
1000
  ```ruby
@@ -960,16 +1143,16 @@ factory :user do
960
1143
  name { "Friendly User" }
961
1144
  login { name }
962
1145
 
963
- trait :male do
1146
+ trait :active do
964
1147
  name { "John Doe" }
965
- gender { "Male" }
966
- login { "#{name} (M)" }
1148
+ status { :active }
1149
+ login { "#{name} (active)" }
967
1150
  end
968
1151
 
969
- trait :female do
1152
+ trait :inactive do
970
1153
  name { "Jane Doe" }
971
- gender { "Female" }
972
- login { "#{name} (F)" }
1154
+ status { :inactive }
1155
+ login { "#{name} (inactive)" }
973
1156
  end
974
1157
 
975
1158
  trait :admin do
@@ -977,8 +1160,8 @@ factory :user do
977
1160
  login { "admin-#{name}" }
978
1161
  end
979
1162
 
980
- factory :male_admin, traits: [:male, :admin] # login will be "admin-John Doe"
981
- factory :female_admin, traits: [:admin, :female] # login will be "Jane Doe (F)"
1163
+ factory :active_admin, traits: [:active, :admin] # login will be "admin-John Doe"
1164
+ factory :inactive_admin, traits: [:admin, :inactive] # login will be "Jane Doe (inactive)"
982
1165
  end
983
1166
  ```
984
1167
 
@@ -991,14 +1174,14 @@ factory :user do
991
1174
  name { "Friendly User" }
992
1175
  login { name }
993
1176
 
994
- trait :male do
1177
+ trait :active do
995
1178
  name { "John Doe" }
996
- gender { "Male" }
1179
+ status { :active }
997
1180
  login { "#{name} (M)" }
998
1181
  end
999
1182
 
1000
1183
  factory :brandon do
1001
- male
1184
+ active
1002
1185
  name { "Brandon" }
1003
1186
  end
1004
1187
  end
@@ -1013,9 +1196,9 @@ from factory\_bot.
1013
1196
  factory :user do
1014
1197
  name { "Friendly User" }
1015
1198
 
1016
- trait :male do
1199
+ trait :active do
1017
1200
  name { "John Doe" }
1018
- gender { "Male" }
1201
+ status { :active }
1019
1202
  end
1020
1203
 
1021
1204
  trait :admin do
@@ -1023,8 +1206,8 @@ factory :user do
1023
1206
  end
1024
1207
  end
1025
1208
 
1026
- # creates an admin user with gender "Male" and name "Jon Snow"
1027
- create(:user, :admin, :male, name: "Jon Snow")
1209
+ # creates an admin user with :active status and name "Jon Snow"
1210
+ create(:user, :admin, :active, name: "Jon Snow")
1028
1211
  ```
1029
1212
 
1030
1213
  This ability works with `build`, `build_stubbed`, `attributes_for`, and `create`.
@@ -1042,8 +1225,8 @@ factory :user do
1042
1225
  end
1043
1226
  end
1044
1227
 
1045
- # creates 3 admin users with gender "Male" and name "Jon Snow"
1046
- create_list(:user, 3, :admin, :male, name: "Jon Snow")
1228
+ # creates 3 admin users with :active status and name "Jon Snow"
1229
+ create_list(:user, 3, :admin, :active, name: "Jon Snow")
1047
1230
  ```
1048
1231
 
1049
1232
  ### With associations
@@ -1342,7 +1525,6 @@ FactoryBot.define do
1342
1525
  factory :application_user, parent: :user do
1343
1526
  full_name { "Jane Doe" }
1344
1527
  date_of_birth { 21.years.ago }
1345
- gender { "Female" }
1346
1528
  health { 90 }
1347
1529
  end
1348
1530
  end
@@ -1355,7 +1537,6 @@ FactoryBot.modify do
1355
1537
  factory :user do
1356
1538
  full_name { "Jane Doe" }
1357
1539
  date_of_birth { 21.years.ago }
1358
- gender { "Female" }
1359
1540
  health { 90 }
1360
1541
  end
1361
1542
  end
@@ -1567,7 +1748,7 @@ factory :user do
1567
1748
 
1568
1749
  name "John Doe"
1569
1750
 
1570
- initialize_with { new(attributes) }
1751
+ initialize_with { new(**attributes) }
1571
1752
  end
1572
1753
  ```
1573
1754
 
data/NEWS.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # News
2
2
 
3
+ ## 6.2.0 (May 7, 2021)
4
+ * Added: support for Ruby 3.0
5
+ * Changed: Include factory or trait name in error messages for missing traits. d05a9a3c
6
+ * Changed: Switched from Travis CI to GitHub Actions
7
+ * Fixed: More Ruby 2.7 kwarg deprecation warnings
8
+
3
9
  ## 6.1.0 (July 8, 2020)
4
10
  * Added: public reader for the evaluation instance, helpful for building interrelated associations
5
11
  * Changed: raise a more helpful error when passing an invalid argument to an association
@@ -20,6 +26,7 @@
20
26
  * Added: `build_stubbed_starting_id=` option to define the starting id for `build_stubbed`
21
27
  * Removed: deprecated methods on the top-level `FactoryBot` module meant only for internal use
22
28
  * Removed: support for EOL versions of Ruby (2.3, 2.4) and Rails (4.2)
29
+ * Removed: support for "abstract" factories with no associated class; use traits instead.
23
30
 
24
31
  ## 5.2.0 (April 24, 2020)
25
32
  * Added: Pass index to block for `*_list` methods
data/README.md CHANGED
@@ -43,7 +43,7 @@ gem install factory_bot
43
43
  Supported Ruby versions
44
44
  -----------------------
45
45
 
46
- Supported Ruby versions are listed in [`.travis.yml`](https://github.com/thoughtbot/factory_bot/blob/master/.travis.yml)
46
+ Supported Ruby versions are listed in [`.github/workflows/build.yml`](https://github.com/thoughtbot/factory_bot/blob/master/.github/workflows/build.yml)
47
47
 
48
48
  More Information
49
49
  ----------------
@@ -94,8 +94,8 @@ See [our other projects][community] or
94
94
 
95
95
  [community]: https://thoughtbot.com/community?utm_source=github
96
96
  [hire]: https://thoughtbot.com/hire-us?utm_source=github
97
- [ci-image]: https://travis-ci.org/thoughtbot/factory_bot.svg
98
- [ci]: https://travis-ci.org/thoughtbot/factory_bot?branch=master
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
99
  [grade-image]: https://codeclimate.com/github/thoughtbot/factory_bot/badges/gpa.svg
100
100
  [grade]: https://codeclimate.com/github/thoughtbot/factory_bot
101
101
  [version-image]: https://badge.fury.io/rb/factory_bot.svg
@@ -12,7 +12,7 @@ module FactoryBot
12
12
 
13
13
  -> {
14
14
  value = case block.arity
15
- when 1, -1 then instance_exec(self, &block)
15
+ when 1, -1, -2 then instance_exec(self, &block)
16
16
  else instance_exec(&block)
17
17
  end
18
18
  raise SequenceAbuseError if FactoryBot::Sequence === value
@@ -9,7 +9,7 @@ module FactoryBot
9
9
 
10
10
  def run(instance, evaluator)
11
11
  case block.arity
12
- when 1, -1 then syntax_runner.instance_exec(instance, &block)
12
+ when 1, -1, -2 then syntax_runner.instance_exec(instance, &block)
13
13
  when 2 then syntax_runner.instance_exec(instance, evaluator, &block)
14
14
  else syntax_runner.instance_exec(&block)
15
15
  end
@@ -6,17 +6,11 @@ module FactoryBot
6
6
  @invoked_methods = []
7
7
  end
8
8
 
9
- if ::Gem::Version.new(::RUBY_VERSION) >= ::Gem::Version.new("2.7")
10
- def method_missing(name, *args, **kwargs, &block) # rubocop:disable Style/MissingRespondToMissing
11
- @invoked_methods << name
12
- super
13
- end
14
- else
15
- def method_missing(name, *args, &block) # rubocop:disable Style/MissingRespondToMissing
16
- @invoked_methods << name
17
- super
18
- end
9
+ def method_missing(name, *args, &block) # rubocop:disable Style/MissingRespondToMissing
10
+ @invoked_methods << name
11
+ super
19
12
  end
13
+ ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)
20
14
 
21
15
  def __invoked_methods__
22
16
  @invoked_methods.uniq
@@ -30,7 +30,7 @@ module FactoryBot
30
30
  end
31
31
 
32
32
  def to_create(&block)
33
- if block_given?
33
+ if block
34
34
  @to_create = block
35
35
  else
36
36
  aggregate_from_traits_and_self(:to_create) { @to_create }.last
@@ -111,6 +111,20 @@ module FactoryBot
111
111
 
112
112
  def base_traits
113
113
  @base_traits.map { |name| trait_by_name(name) }
114
+ rescue KeyError => error
115
+ raise error_with_definition_name(error)
116
+ end
117
+
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
+ )
124
+
125
+ error.class.new(message).tap do |new_error|
126
+ new_error.set_backtrace(error.backtrace)
127
+ end
114
128
  end
115
129
 
116
130
  def additional_traits
@@ -35,23 +35,14 @@ module FactoryBot
35
35
 
36
36
  attr_accessor :instance
37
37
 
38
- if ::Gem::Version.new(::RUBY_VERSION) >= ::Gem::Version.new("2.7")
39
- def method_missing(method_name, *args, **kwargs, &block) # rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing
40
- if @instance.respond_to?(method_name)
41
- @instance.send(method_name, *args, **kwargs, &block)
42
- else
43
- SyntaxRunner.new.send(method_name, *args, **kwargs, &block)
44
- end
45
- end
46
- else
47
- def method_missing(method_name, *args, &block) # rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing
48
- if @instance.respond_to?(method_name)
49
- @instance.send(method_name, *args, &block)
50
- else
51
- SyntaxRunner.new.send(method_name, *args, &block)
52
- end
38
+ def method_missing(method_name, *args, &block) # rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing
39
+ if @instance.respond_to?(method_name)
40
+ @instance.send(method_name, *args, &block)
41
+ else
42
+ SyntaxRunner.new.send(method_name, *args, &block)
53
43
  end
54
44
  end
45
+ ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)
55
46
 
56
47
  def respond_to_missing?(method_name, _include_private = false)
57
48
  @instance.respond_to?(method_name) || SyntaxRunner.new.respond_to?(method_name)
@@ -25,7 +25,7 @@ module FactoryBot
25
25
  raise key_error_with_custom_message(e)
26
26
  end
27
27
 
28
- alias [] find
28
+ alias_method :[], :find
29
29
 
30
30
  def register(name, item)
31
31
  @items[name] = item
@@ -15,7 +15,7 @@ module FactoryBot
15
15
  def factory(name, options = {}, &block)
16
16
  factory = Factory.new(name, options)
17
17
  proxy = FactoryBot::DefinitionProxy.new(factory.definition)
18
- proxy.instance_eval(&block) if block_given?
18
+ proxy.instance_eval(&block) if block
19
19
 
20
20
  Internal.register_factory(factory)
21
21
 
@@ -9,7 +9,7 @@ module FactoryBot
9
9
  @definition = Definition.new(@name)
10
10
  proxy = FactoryBot::DefinitionProxy.new(@definition)
11
11
 
12
- if block_given?
12
+ if block
13
13
  proxy.instance_eval(&@block)
14
14
  end
15
15
  end
@@ -1,3 +1,3 @@
1
1
  module FactoryBot
2
- VERSION = "6.1.0".freeze
2
+ VERSION = "6.2.0".freeze
3
3
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factory_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.0
4
+ version: 6.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Clayton
8
8
  - Joe Ferris
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-07-08 00:00:00.000000000 Z
12
+ date: 2021-05-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -237,7 +237,7 @@ homepage: https://github.com/thoughtbot/factory_bot
237
237
  licenses:
238
238
  - MIT
239
239
  metadata: {}
240
- post_install_message:
240
+ post_install_message:
241
241
  rdoc_options: []
242
242
  require_paths:
243
243
  - lib
@@ -252,8 +252,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
252
252
  - !ruby/object:Gem::Version
253
253
  version: '0'
254
254
  requirements: []
255
- rubygems_version: 3.1.2
256
- signing_key:
255
+ rubygems_version: 3.2.16
256
+ signing_key:
257
257
  specification_version: 4
258
258
  summary: factory_bot provides a framework and DSL for defining and using model instance
259
259
  factories.