factory_bot-with 0.1.0 → 0.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/CHANGELOG.md +5 -0
- data/README.md +13 -0
- data/lib/factory_bot/with/methods.rb +1 -8
- data/lib/factory_bot/with/version.rb +1 -1
- data/lib/factory_bot/with.rb +69 -26
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 01b5be917f74ffbdc5643be7bb5f9c9e7f1009484f688a8442aed6dda8dc5a0b
|
4
|
+
data.tar.gz: d773865f81b4aad3e87dea573db938b5393f0ecc988b5810b827741051ee6864
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93c900afe0c21747d9837a5c8e1b31b11a7ae3e127873cdf86f43f5f83fac4ba10be0295e7b43542d3399a78be377fd240f57a9251a8433471015767170d96a5
|
7
|
+
data.tar.gz: 1af4669b1afb19783332b2bed70d7cb76d210bb205766dcc3aae06bd07de0a4a614da1aadc0841e6cca0bf8c3b3965241a05703a898172a0c575ddcd93f8d273
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.2.0] - 2024-11-29
|
4
|
+
|
5
|
+
- Fixed: Fixed an incorrect factory resolution problem after factory names autocompletion
|
6
|
+
- Added: Smarter interpretation of positional arguments passed to factory methods
|
7
|
+
|
3
8
|
## [0.1.0] - 2024-11-27
|
4
9
|
|
5
10
|
- Initial release
|
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# FactoryBot::With
|
2
2
|
|
3
|
+
[](https://badge.fury.io/rb/factory_bot-with)
|
4
|
+
[](https://github.com/yubrot/factory_bot-with/actions/workflows/main.yml)
|
5
|
+
|
3
6
|
FactoryBot::With is a FactoryBot extension that wraps `FactoryBot::Syntax::Methods` to make it a little easier to use.
|
4
7
|
|
5
8
|
For example, with these factories:
|
@@ -68,6 +71,16 @@ build_stubbed.foo(...)
|
|
68
71
|
create_list.foo(10, ...)
|
69
72
|
```
|
70
73
|
|
74
|
+
### Smarter interpretation of positional arguments
|
75
|
+
|
76
|
+
FactoryBot::With adjusts the behavior of factory methods to accept `Hash`, `Array`, and falsy values (`false` or `nil`) as positional arguments.
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
create.foo({ title: "Recipe" }, is_new && %i[latest hot])
|
80
|
+
#=> create(:foo, :latest, :hot, title: "Recipe") if is_new
|
81
|
+
# create(:foo, title: "Recipe") otherwise
|
82
|
+
```
|
83
|
+
|
71
84
|
### `with`, `with_pair`, and `with_list` operator
|
72
85
|
|
73
86
|
FactoryBot::With provides a new operator `with` (and its family).
|
@@ -18,14 +18,7 @@ module FactoryBot
|
|
18
18
|
define_method(method_name) do |factory = nil, *args, **kwargs, &block|
|
19
19
|
return Proxy.new(self, __method__) unless factory
|
20
20
|
|
21
|
-
|
22
|
-
if factory.is_a? With
|
23
|
-
factory.merge(With.new(variation, factory.factory_name, *args, **kwargs, &block))
|
24
|
-
else
|
25
|
-
With.new(variation, factory, *args, **kwargs, &block)
|
26
|
-
end
|
27
|
-
|
28
|
-
with.instantiate(build_strategy)
|
21
|
+
With.build(variation, factory, *args, **kwargs, &block).instantiate(build_strategy)
|
29
22
|
end
|
30
23
|
end
|
31
24
|
end
|
data/lib/factory_bot/with.rb
CHANGED
@@ -15,25 +15,32 @@ module FactoryBot
|
|
15
15
|
attr_reader :factory_name
|
16
16
|
# @return [Array<With>]
|
17
17
|
attr_reader :withes
|
18
|
-
# @return [Array<
|
19
|
-
attr_reader :
|
18
|
+
# @return [Array<Numeric, Symbol>] Numeric is also treated as a trait for convenience
|
19
|
+
attr_reader :traits
|
20
20
|
# @return [{Symbol => Object}]
|
21
|
-
attr_reader :
|
21
|
+
attr_reader :attrs
|
22
22
|
# @return [Proc, nil]
|
23
23
|
attr_reader :block
|
24
24
|
|
25
25
|
# @!visibility private
|
26
|
-
def initialize(variation, factory_name,
|
26
|
+
def initialize(variation, factory_name, withes: [], traits: [], attrs: {}, &block)
|
27
|
+
raise ArgumentError unless %i[unit pair list].include? variation
|
28
|
+
raise TypeError unless factory_name.is_a? Symbol
|
29
|
+
raise TypeError unless withes.is_a?(Array) && withes.all? { _1.is_a? self.class }
|
30
|
+
raise TypeError unless traits.is_a?(Array) && traits.all? { _1.is_a?(Symbol) || _1.is_a?(Numeric) }
|
31
|
+
raise TypeError unless attrs.is_a?(Hash) && attrs.keys.all? { _1.is_a? Symbol }
|
32
|
+
|
27
33
|
@variation = variation
|
28
34
|
@factory_name = factory_name
|
29
|
-
@withes
|
30
|
-
@
|
35
|
+
@withes = withes
|
36
|
+
@traits = traits
|
37
|
+
@attrs = attrs
|
31
38
|
@block = block
|
32
39
|
end
|
33
40
|
|
34
41
|
# @!visibility private
|
35
42
|
# @return [Boolean]
|
36
|
-
def plain? = withes.empty? &&
|
43
|
+
def plain? = withes.empty? && traits.empty? && attrs.empty? && block.nil?
|
37
44
|
|
38
45
|
# @!visibility private
|
39
46
|
# @param other [With]
|
@@ -49,8 +56,9 @@ module FactoryBot
|
|
49
56
|
self.class.new(
|
50
57
|
variation,
|
51
58
|
factory_name,
|
52
|
-
|
53
|
-
|
59
|
+
withes: [*withes, *other.withes],
|
60
|
+
traits: [*traits, *other.traits],
|
61
|
+
attrs: { **attrs, **other.attrs },
|
54
62
|
&self.class.merge_block(block, other.block)
|
55
63
|
)
|
56
64
|
end
|
@@ -63,20 +71,20 @@ module FactoryBot
|
|
63
71
|
return self if build_strategy == :with
|
64
72
|
|
65
73
|
factory_bot_method = Methods::VARIATIONS[variation][build_strategy]
|
66
|
-
factory_name,
|
74
|
+
factory_name, attrs =
|
67
75
|
if ancestors
|
68
|
-
|
76
|
+
attrs = @attrs.dup
|
69
77
|
factory_name = AssocInfo.autocomplete_fully_qualified_factory_name(ancestors, @factory_name)
|
70
|
-
AssocInfo.get(factory_name).perform_automatic_association_resolution(ancestors,
|
71
|
-
[factory_name,
|
78
|
+
AssocInfo.get(factory_name).perform_automatic_association_resolution(ancestors, attrs)
|
79
|
+
[factory_name, attrs]
|
72
80
|
else
|
73
|
-
[@factory_name, @
|
81
|
+
[@factory_name, @attrs]
|
74
82
|
end
|
75
|
-
result = FactoryBot.__send__(factory_bot_method, factory_name, *
|
83
|
+
result = FactoryBot.__send__(factory_bot_method, factory_name, *traits, **attrs, &block)
|
76
84
|
|
77
85
|
unless withes.empty?
|
78
86
|
parents = variation == :unit ? [result] : result
|
79
|
-
assoc_info = AssocInfo.get(
|
87
|
+
assoc_info = AssocInfo.get(factory_name)
|
80
88
|
parents.each do |parent|
|
81
89
|
ancestors_for_children = [[assoc_info, parent], *ancestors || []]
|
82
90
|
withes.each { _1.instantiate(build_strategy, ancestors_for_children) }
|
@@ -86,17 +94,52 @@ module FactoryBot
|
|
86
94
|
result
|
87
95
|
end
|
88
96
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
97
|
+
class << self
|
98
|
+
# @!visibility private
|
99
|
+
# @param variation [:unit, :pair, :list]
|
100
|
+
# @param factory [Symbol, With]
|
101
|
+
# @param args [Array<Object>]
|
102
|
+
# @param kwargs [{Symbol => Object}]
|
103
|
+
def build(variation, factory, *, **, &)
|
104
|
+
return factory.merge(build(variation, factory.factory_name, *, **, &)) if factory.is_a? self
|
105
|
+
|
106
|
+
with = new(variation, factory, &)
|
107
|
+
insert_args!(with, *)
|
108
|
+
with.attrs.merge!(**)
|
109
|
+
with
|
110
|
+
end
|
96
111
|
|
97
|
-
|
98
|
-
|
99
|
-
|
112
|
+
def insert_args!(with, *args)
|
113
|
+
args.each do |arg|
|
114
|
+
case arg
|
115
|
+
when self
|
116
|
+
with.withes << arg
|
117
|
+
when Symbol, Numeric
|
118
|
+
with.traits << arg
|
119
|
+
when Array
|
120
|
+
insert_args!(with, *arg)
|
121
|
+
when Hash
|
122
|
+
with.attrs.merge!(arg)
|
123
|
+
when false, nil
|
124
|
+
# Ignored. This behavior is useful for conditional arguments like `is_premium && :premium`
|
125
|
+
else
|
126
|
+
raise ArgumentError, "Unsupported type for factory argument: #{arg}"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# @!visibility private
|
132
|
+
# @param first [Proc, nil]
|
133
|
+
# @param second [Proc, nil]
|
134
|
+
# @return [Proc, nil]
|
135
|
+
def merge_block(first, second)
|
136
|
+
return first unless second
|
137
|
+
return second unless first
|
138
|
+
|
139
|
+
lambda do |*args|
|
140
|
+
first.call(*args)
|
141
|
+
second.call(*args)
|
142
|
+
end
|
100
143
|
end
|
101
144
|
end
|
102
145
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: factory_bot-with
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yubrot
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: factory_bot
|
@@ -67,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
requirements: []
|
70
|
-
rubygems_version: 3.5.
|
70
|
+
rubygems_version: 3.5.22
|
71
71
|
signing_key:
|
72
72
|
specification_version: 4
|
73
73
|
summary: FactoryBot extension that wraps FactoryBot::Syntax::Methods to make it a
|