factory_bot-with 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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