factory_bot 6.5.2 → 6.5.6
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/GETTING_STARTED.md +106 -85
- data/NEWS.md +436 -331
- data/README.md +11 -19
- data/lib/factory_bot/attribute_assigner.rb +74 -18
- data/lib/factory_bot/callbacks_observer.rb +19 -1
- data/lib/factory_bot/definition.rb +3 -2
- data/lib/factory_bot/definition_proxy.rb +12 -13
- data/lib/factory_bot/evaluator.rb +9 -3
- data/lib/factory_bot/factory.rb +10 -5
- data/lib/factory_bot/internal.rb +33 -0
- data/lib/factory_bot/registry.rb +1 -1
- data/lib/factory_bot/sequence.rb +131 -15
- data/lib/factory_bot/strategy/build.rb +2 -0
- data/lib/factory_bot/strategy/create.rb +2 -0
- data/lib/factory_bot/strategy.rb +15 -0
- data/lib/factory_bot/syntax/methods.rb +62 -15
- data/lib/factory_bot/trait.rb +9 -7
- data/lib/factory_bot/uri_manager.rb +63 -0
- data/lib/factory_bot/version.rb +1 -1
- data/lib/factory_bot.rb +34 -9
- metadata +6 -5
- data/lib/factory_bot/strategy_calculator.rb +0 -26
|
@@ -83,52 +83,99 @@ module FactoryBot
|
|
|
83
83
|
# (see #strategy_method_pair)
|
|
84
84
|
# @return [Array<Hash>] pair of attribute hashes for the factory
|
|
85
85
|
|
|
86
|
-
# @!method strategy_method
|
|
86
|
+
# @!method strategy_method(name, traits_and_overrides, &block)
|
|
87
87
|
# @!visibility private
|
|
88
88
|
# @param [Symbol] name the name of the factory to build
|
|
89
89
|
# @param [Array<Symbol, Symbol, Hash>] traits_and_overrides splat args traits and a hash of overrides
|
|
90
90
|
# @param [Proc] block block to be executed
|
|
91
91
|
|
|
92
|
-
# @!method strategy_method_list
|
|
92
|
+
# @!method strategy_method_list(name, amount, traits_and_overrides, &block)
|
|
93
93
|
# @!visibility private
|
|
94
94
|
# @param [Symbol] name the name of the factory to execute
|
|
95
95
|
# @param [Integer] amount the number of instances to execute
|
|
96
96
|
# @param [Array<Symbol, Symbol, Hash>] traits_and_overrides splat args traits and a hash of overrides
|
|
97
97
|
# @param [Proc] block block to be executed
|
|
98
98
|
|
|
99
|
-
# @!method strategy_method_pair
|
|
99
|
+
# @!method strategy_method_pair(name, traits_and_overrides, &block)
|
|
100
100
|
# @!visibility private
|
|
101
101
|
# @param [Symbol] name the name of the factory to execute
|
|
102
102
|
# @param [Array<Symbol, Symbol, Hash>] traits_and_overrides splat args traits and a hash of overrides
|
|
103
103
|
# @param [Proc] block block to be executed
|
|
104
104
|
|
|
105
|
-
# Generates and returns the next value in a sequence.
|
|
105
|
+
# Generates and returns the next value in a global or factory sequence.
|
|
106
106
|
#
|
|
107
107
|
# Arguments:
|
|
108
|
-
#
|
|
109
|
-
# The
|
|
108
|
+
# context: (Array of Symbols)
|
|
109
|
+
# The definition context of the sequence, with the sequence name
|
|
110
|
+
# as the final entry
|
|
111
|
+
# scope: (object)(optional)
|
|
112
|
+
# The object the sequence should be evaluated within
|
|
110
113
|
#
|
|
111
114
|
# Returns:
|
|
112
115
|
# The next value in the sequence. (Object)
|
|
113
|
-
|
|
114
|
-
|
|
116
|
+
#
|
|
117
|
+
# Example:
|
|
118
|
+
# generate(:my_factory, :my_trair, :my_sequence)
|
|
119
|
+
#
|
|
120
|
+
def generate(*uri_parts, scope: nil)
|
|
121
|
+
uri = FactoryBot::UriManager.build_uri(uri_parts)
|
|
122
|
+
sequence = Sequence.find_by_uri(uri) ||
|
|
123
|
+
raise(KeyError,
|
|
124
|
+
"Sequence not registered: #{FactoryBot::UriManager.build_uri(uri_parts)}")
|
|
125
|
+
|
|
126
|
+
increment_sequence(sequence, scope: scope)
|
|
115
127
|
end
|
|
116
128
|
|
|
117
|
-
# Generates and returns the list of values in a sequence.
|
|
129
|
+
# Generates and returns the list of values in a global or factory sequence.
|
|
118
130
|
#
|
|
119
131
|
# Arguments:
|
|
120
|
-
#
|
|
121
|
-
# The
|
|
122
|
-
#
|
|
123
|
-
#
|
|
132
|
+
# uri_parts: (Array of Symbols)
|
|
133
|
+
# The definition context of the sequence, with the sequence name
|
|
134
|
+
# as the final entry
|
|
135
|
+
# scope: (object)(optional)
|
|
136
|
+
# The object the sequence should be evaluated within
|
|
124
137
|
#
|
|
125
138
|
# Returns:
|
|
126
139
|
# The next value in the sequence. (Object)
|
|
127
|
-
|
|
140
|
+
#
|
|
141
|
+
# Example:
|
|
142
|
+
# generate_list(:my_factory, :my_trair, :my_sequence, 5)
|
|
143
|
+
#
|
|
144
|
+
def generate_list(*uri_parts, count, scope: nil)
|
|
145
|
+
uri = FactoryBot::UriManager.build_uri(uri_parts)
|
|
146
|
+
sequence = Sequence.find_by_uri(uri) ||
|
|
147
|
+
raise(KeyError, "Sequence not registered: '#{uri}'")
|
|
148
|
+
|
|
128
149
|
(1..count).map do
|
|
129
|
-
|
|
150
|
+
increment_sequence(sequence, scope: scope)
|
|
130
151
|
end
|
|
131
152
|
end
|
|
153
|
+
|
|
154
|
+
# ======================================================================
|
|
155
|
+
# = PRIVATE
|
|
156
|
+
# ======================================================================
|
|
157
|
+
#
|
|
158
|
+
private
|
|
159
|
+
|
|
160
|
+
##
|
|
161
|
+
# Increments the given sequence and returns the value.
|
|
162
|
+
#
|
|
163
|
+
# Arguments:
|
|
164
|
+
# sequence:
|
|
165
|
+
# The sequence instance
|
|
166
|
+
# scope: (object)(optional)
|
|
167
|
+
# The object the sequence should be evaluated within
|
|
168
|
+
#
|
|
169
|
+
def increment_sequence(sequence, scope: nil)
|
|
170
|
+
value = sequence.next(scope)
|
|
171
|
+
|
|
172
|
+
raise if value.respond_to?(:start_with?) && value.start_with?("#<FactoryBot::Declaration")
|
|
173
|
+
|
|
174
|
+
value
|
|
175
|
+
rescue
|
|
176
|
+
raise ArgumentError, "Sequence '#{sequence.uri_manager.first}' failed to " \
|
|
177
|
+
"return a value. Perhaps it needs a scope to operate? (scope: <object>)"
|
|
178
|
+
end
|
|
132
179
|
end
|
|
133
180
|
end
|
|
134
181
|
end
|
data/lib/factory_bot/trait.rb
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
module FactoryBot
|
|
2
2
|
# @api private
|
|
3
3
|
class Trait
|
|
4
|
-
attr_reader :name, :definition
|
|
4
|
+
attr_reader :name, :uid, :definition
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
delegate :add_callback, :declare_attribute, :to_create, :define_trait, :constructor,
|
|
7
|
+
:callbacks, :attributes, :klass, :klass=, to: :@definition
|
|
8
|
+
|
|
9
|
+
def initialize(name, **options, &block)
|
|
7
10
|
@name = name.to_s
|
|
8
11
|
@block = block
|
|
9
|
-
@
|
|
12
|
+
@uri_manager = FactoryBot::UriManager.new(names, paths: options[:uri_paths])
|
|
13
|
+
|
|
14
|
+
@definition = Definition.new(@name, uri_manager: @uri_manager)
|
|
10
15
|
proxy = FactoryBot::DefinitionProxy.new(@definition)
|
|
11
16
|
|
|
12
17
|
if block
|
|
@@ -15,12 +20,9 @@ module FactoryBot
|
|
|
15
20
|
end
|
|
16
21
|
|
|
17
22
|
def clone
|
|
18
|
-
Trait.new(name, &block)
|
|
23
|
+
Trait.new(name, uri_paths: definition.uri_manager.paths, &block)
|
|
19
24
|
end
|
|
20
25
|
|
|
21
|
-
delegate :add_callback, :declare_attribute, :to_create, :define_trait, :constructor,
|
|
22
|
-
:callbacks, :attributes, :klass, :klass=, to: :@definition
|
|
23
|
-
|
|
24
26
|
def names
|
|
25
27
|
[@name]
|
|
26
28
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module FactoryBot
|
|
2
|
+
# @api private
|
|
3
|
+
class UriManager
|
|
4
|
+
attr_reader :endpoints, :paths, :uri_list
|
|
5
|
+
|
|
6
|
+
delegate :size, :any?, :empty?, :each?, :include?, :first, to: :@uri_list
|
|
7
|
+
delegate :build_uri, to: :class
|
|
8
|
+
|
|
9
|
+
# Concatenate the parts, sripping leading/following slashes
|
|
10
|
+
# and returning a Symbolized String or nil.
|
|
11
|
+
#
|
|
12
|
+
# Example:
|
|
13
|
+
# build_uri(:my_factory, :my_trait, :my_sequence)
|
|
14
|
+
# #=> :"myfactory/my_trait/my_sequence"
|
|
15
|
+
#
|
|
16
|
+
def self.build_uri(*parts)
|
|
17
|
+
return nil if parts.empty?
|
|
18
|
+
|
|
19
|
+
parts.join("/")
|
|
20
|
+
.sub(/\A\/+/, "")
|
|
21
|
+
.sub(/\/+\z/, "")
|
|
22
|
+
.tr(" ", "_")
|
|
23
|
+
.to_sym
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Configures the new UriManager
|
|
27
|
+
#
|
|
28
|
+
# Arguments:
|
|
29
|
+
# endpoints: (Array of Strings or Symbols)
|
|
30
|
+
# the objects endpoints.
|
|
31
|
+
#
|
|
32
|
+
# paths: (Array of Strings or Symbols)
|
|
33
|
+
# the parent URIs to prepend to each endpoint
|
|
34
|
+
#
|
|
35
|
+
def initialize(*endpoints, paths: [])
|
|
36
|
+
if endpoints.empty?
|
|
37
|
+
fail ArgumentError, "wrong number of arguments (given 0, expected 1+)"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
@uri_list = []
|
|
41
|
+
@endpoints = endpoints.flatten
|
|
42
|
+
@paths = Array(paths).flatten
|
|
43
|
+
|
|
44
|
+
build_uri_list
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def to_a
|
|
48
|
+
@uri_list.dup
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def build_uri_list
|
|
54
|
+
@endpoints.each do |endpoint|
|
|
55
|
+
if @paths.any?
|
|
56
|
+
@paths.each { |path| @uri_list << build_uri(path, endpoint) }
|
|
57
|
+
else
|
|
58
|
+
@uri_list << build_uri(endpoint)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
data/lib/factory_bot/version.rb
CHANGED
data/lib/factory_bot.rb
CHANGED
|
@@ -11,12 +11,7 @@ require "factory_bot/configuration"
|
|
|
11
11
|
require "factory_bot/errors"
|
|
12
12
|
require "factory_bot/factory_runner"
|
|
13
13
|
require "factory_bot/strategy_syntax_method_registrar"
|
|
14
|
-
require "factory_bot/
|
|
15
|
-
require "factory_bot/strategy/build"
|
|
16
|
-
require "factory_bot/strategy/create"
|
|
17
|
-
require "factory_bot/strategy/attributes_for"
|
|
18
|
-
require "factory_bot/strategy/stub"
|
|
19
|
-
require "factory_bot/strategy/null"
|
|
14
|
+
require "factory_bot/strategy"
|
|
20
15
|
require "factory_bot/registry"
|
|
21
16
|
require "factory_bot/null_factory"
|
|
22
17
|
require "factory_bot/null_object"
|
|
@@ -46,6 +41,7 @@ require "factory_bot/decorator/attribute_hash"
|
|
|
46
41
|
require "factory_bot/decorator/disallows_duplicates_registry"
|
|
47
42
|
require "factory_bot/decorator/invocation_tracker"
|
|
48
43
|
require "factory_bot/decorator/new_constructor"
|
|
44
|
+
require "factory_bot/uri_manager"
|
|
49
45
|
require "factory_bot/linter"
|
|
50
46
|
require "factory_bot/version"
|
|
51
47
|
|
|
@@ -58,6 +54,9 @@ module FactoryBot
|
|
|
58
54
|
mattr_accessor :automatically_define_enum_traits, instance_accessor: false
|
|
59
55
|
self.automatically_define_enum_traits = true
|
|
60
56
|
|
|
57
|
+
mattr_accessor :sequence_setting_timeout, instance_accessor: false
|
|
58
|
+
self.sequence_setting_timeout = 3
|
|
59
|
+
|
|
61
60
|
# Look for errors in factories and (optionally) their traits.
|
|
62
61
|
# Parameters:
|
|
63
62
|
# factories - which factories to lint; omit for all factories
|
|
@@ -73,17 +72,43 @@ module FactoryBot
|
|
|
73
72
|
|
|
74
73
|
# Set the starting value for ids when using the build_stubbed strategy
|
|
75
74
|
#
|
|
76
|
-
#
|
|
77
|
-
# * starting_id +Integer+
|
|
78
|
-
# The new starting id value.
|
|
75
|
+
# @param [Integer] starting_id The new starting id value.
|
|
79
76
|
def self.build_stubbed_starting_id=(starting_id)
|
|
80
77
|
Strategy::Stub.next_id = starting_id - 1
|
|
81
78
|
end
|
|
82
79
|
|
|
83
80
|
class << self
|
|
81
|
+
# @!method rewind_sequence(*uri_parts)
|
|
82
|
+
# Rewind an individual global or inline sequence.
|
|
83
|
+
#
|
|
84
|
+
# @param [Array<Symbol>, String] uri_parts The components of the sequence URI.
|
|
85
|
+
#
|
|
86
|
+
# @example Rewinding a sequence by its URI parts
|
|
87
|
+
# rewind_sequence(:factory_name, :trait_name, :sequence_name)
|
|
88
|
+
#
|
|
89
|
+
# @example Rewinding a sequence by its URI string
|
|
90
|
+
# rewind_sequence("factory_name/trait_name/sequence_name")
|
|
91
|
+
#
|
|
92
|
+
# @!method set_sequence(*uri_parts, value)
|
|
93
|
+
# Set the sequence to a specific value, providing the new value is within
|
|
94
|
+
# the sequence set.
|
|
95
|
+
#
|
|
96
|
+
# @param [Array<Symbol>, String] uri_parts The components of the sequence URI.
|
|
97
|
+
# @param [Object] value The new value for the sequence. This must be a value that is
|
|
98
|
+
# within the sequence definition. For example, you cannot set
|
|
99
|
+
# a String sequence to an Integer value.
|
|
100
|
+
#
|
|
101
|
+
# @example
|
|
102
|
+
# set_sequence(:factory_name, :trait_name, :sequence_name, 450)
|
|
103
|
+
# @example
|
|
104
|
+
# set_sequence([:factory_name, :trait_name, :sequence_name], 450)
|
|
105
|
+
# @example
|
|
106
|
+
# set_sequence("factory_name/trait_name/sequence_name", 450)
|
|
84
107
|
delegate :factories,
|
|
85
108
|
:register_strategy,
|
|
86
109
|
:rewind_sequences,
|
|
110
|
+
:rewind_sequence,
|
|
111
|
+
:set_sequence,
|
|
87
112
|
:strategy_by_name,
|
|
88
113
|
to: Internal
|
|
89
114
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: factory_bot
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 6.5.
|
|
4
|
+
version: 6.5.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Josh Clayton
|
|
@@ -67,7 +67,7 @@ dependencies:
|
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '0'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
70
|
+
name: mutex_m
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
73
|
- - ">="
|
|
@@ -81,7 +81,7 @@ dependencies:
|
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '0'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
84
|
+
name: ostruct
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
87
|
- - ">="
|
|
@@ -233,18 +233,19 @@ files:
|
|
|
233
233
|
- lib/factory_bot/registry.rb
|
|
234
234
|
- lib/factory_bot/reload.rb
|
|
235
235
|
- lib/factory_bot/sequence.rb
|
|
236
|
+
- lib/factory_bot/strategy.rb
|
|
236
237
|
- lib/factory_bot/strategy/attributes_for.rb
|
|
237
238
|
- lib/factory_bot/strategy/build.rb
|
|
238
239
|
- lib/factory_bot/strategy/create.rb
|
|
239
240
|
- lib/factory_bot/strategy/null.rb
|
|
240
241
|
- lib/factory_bot/strategy/stub.rb
|
|
241
|
-
- lib/factory_bot/strategy_calculator.rb
|
|
242
242
|
- lib/factory_bot/strategy_syntax_method_registrar.rb
|
|
243
243
|
- lib/factory_bot/syntax.rb
|
|
244
244
|
- lib/factory_bot/syntax/default.rb
|
|
245
245
|
- lib/factory_bot/syntax/methods.rb
|
|
246
246
|
- lib/factory_bot/syntax_runner.rb
|
|
247
247
|
- lib/factory_bot/trait.rb
|
|
248
|
+
- lib/factory_bot/uri_manager.rb
|
|
248
249
|
- lib/factory_bot/version.rb
|
|
249
250
|
homepage: https://github.com/thoughtbot/factory_bot
|
|
250
251
|
licenses:
|
|
@@ -265,7 +266,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
265
266
|
- !ruby/object:Gem::Version
|
|
266
267
|
version: '0'
|
|
267
268
|
requirements: []
|
|
268
|
-
rubygems_version: 3.
|
|
269
|
+
rubygems_version: 3.7.1
|
|
269
270
|
specification_version: 4
|
|
270
271
|
summary: factory_bot provides a framework and DSL for defining and using model instance
|
|
271
272
|
factories.
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
module FactoryBot
|
|
2
|
-
# @api private
|
|
3
|
-
class StrategyCalculator
|
|
4
|
-
def initialize(name_or_object)
|
|
5
|
-
@name_or_object = name_or_object
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def strategy
|
|
9
|
-
if strategy_is_object?
|
|
10
|
-
@name_or_object
|
|
11
|
-
else
|
|
12
|
-
strategy_name_to_object
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
private
|
|
17
|
-
|
|
18
|
-
def strategy_is_object?
|
|
19
|
-
@name_or_object.is_a?(Class)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def strategy_name_to_object
|
|
23
|
-
FactoryBot::Internal.strategy_by_name(@name_or_object)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|