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 +4 -4
- data/CONTRIBUTING.md +6 -0
- data/GETTING_STARTED.md +254 -73
- data/NEWS.md +7 -0
- data/README.md +3 -3
- data/lib/factory_bot/attribute/dynamic.rb +1 -1
- data/lib/factory_bot/callback.rb +1 -1
- data/lib/factory_bot/decorator/invocation_tracker.rb +4 -10
- data/lib/factory_bot/definition.rb +15 -1
- data/lib/factory_bot/evaluator.rb +6 -15
- data/lib/factory_bot/registry.rb +1 -1
- data/lib/factory_bot/syntax/default.rb +1 -1
- data/lib/factory_bot/trait.rb +1 -1
- data/lib/factory_bot/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a928c94babd835a0756175aa3d7a1f03d4dae15b0782818a8c9688489f6e18d3
|
4
|
+
data.tar.gz: e2875eca60137531b83267dcdfd87ba1329ed8a52e460a0e609fa5fb04f39244
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
204
|
-
|
205
|
-
|
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
|
-
|
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
|
-
|
624
|
-
|
625
|
-
|
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
|
-
|
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
|
643
|
-
#
|
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
|
-
|
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
|
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
|
-
|
680
|
-
|
681
|
-
|
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
|
-
|
688
|
-
factory :profile do
|
689
|
-
name { "John Doe" }
|
817
|
+
Or with the callback approach:
|
690
818
|
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
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
|
-
|
701
|
-
|
702
|
-
|
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
|
-
|
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
|
-
|
717
|
-
|
718
|
-
|
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
|
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 :
|
1146
|
+
trait :active do
|
964
1147
|
name { "John Doe" }
|
965
|
-
|
966
|
-
login { "#{name} (
|
1148
|
+
status { :active }
|
1149
|
+
login { "#{name} (active)" }
|
967
1150
|
end
|
968
1151
|
|
969
|
-
trait :
|
1152
|
+
trait :inactive do
|
970
1153
|
name { "Jane Doe" }
|
971
|
-
|
972
|
-
login { "#{name} (
|
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 :
|
981
|
-
factory :
|
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 :
|
1177
|
+
trait :active do
|
995
1178
|
name { "John Doe" }
|
996
|
-
|
1179
|
+
status { :active }
|
997
1180
|
login { "#{name} (M)" }
|
998
1181
|
end
|
999
1182
|
|
1000
1183
|
factory :brandon do
|
1001
|
-
|
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 :
|
1199
|
+
trait :active do
|
1017
1200
|
name { "John Doe" }
|
1018
|
-
|
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
|
1027
|
-
create(:user, :admin, :
|
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
|
1046
|
-
create_list(:user, 3, :admin, :
|
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 [`.
|
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://
|
98
|
-
[ci]: https://
|
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
|
data/lib/factory_bot/callback.rb
CHANGED
@@ -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
|
-
|
10
|
-
|
11
|
-
|
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
|
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
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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)
|
data/lib/factory_bot/registry.rb
CHANGED
@@ -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
|
18
|
+
proxy.instance_eval(&block) if block
|
19
19
|
|
20
20
|
Internal.register_factory(factory)
|
21
21
|
|
data/lib/factory_bot/trait.rb
CHANGED
data/lib/factory_bot/version.rb
CHANGED
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.
|
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:
|
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.
|
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.
|