factory_bot-with 0.2.1 → 0.3.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: abe0a558801602a366eb21e5aacf753e8cb3fb75a2e45b6df492308c4244d85f
4
- data.tar.gz: 514e5d0190f7dfa9cd0744062217a99c2ba5964be8f2bcf2fa64864044a84465
3
+ metadata.gz: 330ba97b29d7109bb0cb89cf0493cced5300e17c3a1465066405e46c66cbcd76
4
+ data.tar.gz: 504cbcee6a16323d2a9494f10bcb68754d84130b343c316eab7a9f4c01432a0c
5
5
  SHA512:
6
- metadata.gz: 8243dd0f2ea730d9266964806a48934856254b2ecd1f73bf839f19198e2540061c373a8778413ddcfcc5a68aface18cd3debfa9ae0b5f8b1f8416a1ed2459d98
7
- data.tar.gz: 78031d8c55fef101fb7cf9c5511beeae3374813faa62f5925deb3ed70a80872e01baf1c127192d694f1a7546f10e1156534408a91fb61e8e39d5e6830b4d320a
6
+ metadata.gz: 11ed1a26a0ebd2590398eef94ebbf8aaeb23419cdd2b0d5e3979f3a64bbe4179e1f96d731804ccbd042535806a4999de62f5a6d5b72cf7ff5c2fbf379cd30372
7
+ data.tar.gz: 5da17d95d18e8c746ddd5ce0a1213a8cf24dec8766753655ea912bc91a6b7c38dde9c7d85d73bca4165b7d17f126af31c2a4fd71be3cdbb5807c40a0434ef259
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.0] - 2024-12-09
4
+
5
+ - Added: Added `FactoryBot::With.register_strategy` to support custom strategies
6
+
3
7
  ## [0.2.1] - 2024-11-29
4
8
 
5
9
  - Fixed: Adjusted priority of factory names autocompletion
@@ -5,23 +5,6 @@ module FactoryBot
5
5
  # A <code>FactoryBot::Syntax::Methods</code> replacement to enable <code>factory_bot-with</code> features.
6
6
  module Methods
7
7
  include FactoryBot::Syntax::Methods
8
-
9
- BUILD_STRATEGIES = %i[build build_stubbed create attributes_for with].freeze
10
- VARIATIONS = {
11
- unit: BUILD_STRATEGIES.to_h { [_1, _1] }.freeze,
12
- pair: BUILD_STRATEGIES.to_h { [_1, :"#{_1}_pair"] }.freeze,
13
- list: BUILD_STRATEGIES.to_h { [_1, :"#{_1}_list"] }.freeze,
14
- }.freeze
15
-
16
- VARIATIONS.each do |variation, build_strategies|
17
- build_strategies.each do |build_strategy, method_name|
18
- define_method(method_name) do |factory = nil, *args, **kwargs, &block|
19
- return Proxy.new(self, __method__) unless factory
20
-
21
- With.build(variation, factory, *args, **kwargs, &block).instantiate(build_strategy)
22
- end
23
- end
24
- end
25
8
  end
26
9
  end
27
10
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module FactoryBot
4
4
  class With
5
- VERSION = "0.2.1"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
@@ -9,7 +9,7 @@ require_relative "with/methods"
9
9
  module FactoryBot
10
10
  # An intermediate state for <code>with</code> operator.
11
11
  class With
12
- # @return [:unit, :pair, :list]
12
+ # @return [:singular, :pair, :list]
13
13
  attr_reader :variation
14
14
  # @return [Symbol]
15
15
  attr_reader :factory_name
@@ -24,7 +24,7 @@ module FactoryBot
24
24
 
25
25
  # @!visibility private
26
26
  def initialize(variation, factory_name, withes: [], traits: [], attrs: {}, &block)
27
- raise ArgumentError unless %i[unit pair list].include? variation
27
+ raise ArgumentError unless %i[singular pair list].include? variation
28
28
  raise TypeError unless factory_name.is_a? Symbol
29
29
  raise TypeError unless withes.is_a?(Array) && withes.all? { _1.is_a? self.class }
30
30
  raise TypeError unless traits.is_a?(Array) && traits.all? { _1.is_a?(Symbol) || _1.is_a?(Numeric) }
@@ -59,18 +59,48 @@ module FactoryBot
59
59
  withes: [*withes, *other.withes],
60
60
  traits: [*traits, *other.traits],
61
61
  attrs: { **attrs, **other.attrs },
62
- &self.class.merge_block(block, other.block)
62
+ &lambda do |first, second|
63
+ return first unless second
64
+ return second unless first
65
+
66
+ lambda do |*args|
67
+ first.call(*args)
68
+ second.call(*args)
69
+ end
70
+ end.call(block, other.block)
63
71
  )
64
72
  end
65
73
 
66
74
  # @!visibility private
67
- # @param build_strategy [:build, :build_stubbed, :create, :attributes_for, :with]
75
+ def extend!(*args)
76
+ args.each do |arg|
77
+ case arg
78
+ when self.class
79
+ withes << arg
80
+ when Symbol, Numeric
81
+ traits << arg
82
+ when Array
83
+ extend!(*arg)
84
+ when Hash
85
+ attrs.merge!(arg)
86
+ when false, nil
87
+ # Ignored. This behavior is useful for conditional arguments like `is_premium && :premium`
88
+ else
89
+ raise ArgumentError, "Unsupported type for factory argument: #{arg}"
90
+ end
91
+ end
92
+ self
93
+ end
94
+
95
+ # @!visibility private
96
+ # @param build_strategy [Symbol]
68
97
  # @param ancestors [Array<Array(AssocInfo, Object)>, nil]
69
98
  # @return [Object]
70
99
  def instantiate(build_strategy, ancestors = nil)
71
100
  return self if build_strategy == :with
72
101
 
73
- factory_bot_method = Methods::VARIATIONS[variation][build_strategy]
102
+ factory_bot_method =
103
+ variation == :singular ? build_strategy : :"#{build_strategy}_#{variation}"
74
104
  factory_name, attrs =
75
105
  if ancestors
76
106
  attrs = @attrs.dup
@@ -83,7 +113,7 @@ module FactoryBot
83
113
  result = FactoryBot.__send__(factory_bot_method, factory_name, *traits, **attrs, &block)
84
114
 
85
115
  unless withes.empty?
86
- parents = variation == :unit ? [result] : result
116
+ parents = variation == :singular ? [result] : result
87
117
  assoc_info = AssocInfo.get(factory_name)
88
118
  parents.each do |parent|
89
119
  ancestors_for_children = [[assoc_info, parent], *ancestors || []]
@@ -96,51 +126,36 @@ module FactoryBot
96
126
 
97
127
  class << self
98
128
  # @!visibility private
99
- # @param variation [:unit, :pair, :list]
129
+ # @param variation [:singular, :pair, :list]
100
130
  # @param factory [Symbol, With]
101
131
  # @param args [Array<Object>]
102
132
  # @param kwargs [{Symbol => Object}]
103
133
  def build(variation, factory, *, **, &)
104
134
  return factory.merge(build(variation, factory.factory_name, *, **, &)) if factory.is_a? self
105
135
 
106
- with = new(variation, factory, &)
107
- insert_args!(with, *)
108
- with.attrs.merge!(**)
109
- with
136
+ new(variation, factory, &).extend!(*, { ** })
110
137
  end
111
138
 
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}"
139
+ # If you want to use a custom strategy, call this along with <code>FactoryBot.register_strategy</code>.
140
+ # @param build_strategy [Symbol]
141
+ # @example
142
+ # FactoryBot.register_strategy(:json, JsonStrategy)
143
+ # FactoryBot::With.register_strategy(:json)
144
+ def register_strategy(build_strategy)
145
+ {
146
+ singular: build_strategy,
147
+ pair: :"#{build_strategy}_pair",
148
+ list: :"#{build_strategy}_list",
149
+ }.each do |variation, method_name|
150
+ Methods.define_method(method_name) do |factory = nil, *args, **kwargs, &block|
151
+ return Proxy.new(self, __method__) unless factory
152
+
153
+ With.build(variation, factory, *args, **kwargs, &block).instantiate(build_strategy)
127
154
  end
128
155
  end
129
156
  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
143
- end
144
157
  end
158
+
159
+ %i[build build_stubbed create attributes_for with].each { register_strategy _1 }
145
160
  end
146
161
  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.2.1
4
+ version: 0.3.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-29 00:00:00.000000000 Z
11
+ date: 2024-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: factory_bot