factory_bot 4.11.1 → 5.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/GETTING_STARTED.md +121 -37
- data/LICENSE +1 -1
- data/NEWS.md +351 -0
- data/README.md +18 -22
- data/lib/factory_bot/aliases.rb +1 -1
- data/lib/factory_bot/attribute/dynamic.rb +1 -0
- data/lib/factory_bot/attribute.rb +4 -39
- data/lib/factory_bot/attribute_assigner.rb +21 -6
- data/lib/factory_bot/attribute_list.rb +2 -1
- data/lib/factory_bot/callback.rb +3 -2
- data/lib/factory_bot/configuration.rb +16 -20
- data/lib/factory_bot/declaration/association.rb +14 -1
- data/lib/factory_bot/declaration/dynamic.rb +3 -1
- data/lib/factory_bot/declaration/implicit.rb +7 -2
- data/lib/factory_bot/declaration.rb +4 -4
- data/lib/factory_bot/declaration_list.rb +1 -1
- data/lib/factory_bot/decorator/attribute_hash.rb +1 -1
- data/lib/factory_bot/decorator/invocation_tracker.rb +1 -1
- data/lib/factory_bot/decorator.rb +5 -1
- data/lib/factory_bot/definition.rb +10 -7
- data/lib/factory_bot/definition_hierarchy.rb +1 -11
- data/lib/factory_bot/definition_proxy.rb +59 -62
- data/lib/factory_bot/errors.rb +7 -4
- data/lib/factory_bot/evaluation.rb +1 -1
- data/lib/factory_bot/evaluator.rb +5 -5
- data/lib/factory_bot/factory.rb +8 -8
- data/lib/factory_bot/factory_runner.rb +3 -3
- data/lib/factory_bot/find_definitions.rb +1 -1
- data/lib/factory_bot/internal.rb +104 -0
- data/lib/factory_bot/linter.rb +36 -19
- data/lib/factory_bot/null_factory.rb +4 -1
- data/lib/factory_bot/null_object.rb +2 -2
- data/lib/factory_bot/registry.rb +15 -6
- data/lib/factory_bot/reload.rb +3 -3
- data/lib/factory_bot/sequence.rb +0 -1
- data/lib/factory_bot/strategy/null.rb +2 -4
- data/lib/factory_bot/strategy/stub.rb +32 -31
- data/lib/factory_bot/strategy_calculator.rb +1 -1
- data/lib/factory_bot/strategy_syntax_method_registrar.rb +13 -2
- data/lib/factory_bot/syntax/default.rb +12 -24
- data/lib/factory_bot/syntax/methods.rb +32 -9
- data/lib/factory_bot/syntax.rb +2 -2
- data/lib/factory_bot/trait.rb +6 -3
- data/lib/factory_bot/version.rb +1 -1
- data/lib/factory_bot.rb +103 -138
- metadata +72 -32
- data/NEWS +0 -306
- data/lib/factory_bot/attribute/static.rb +0 -16
- data/lib/factory_bot/declaration/static.rb +0 -26
- data/lib/factory_bot/decorator/class_key_hash.rb +0 -28
@@ -1,6 +1,19 @@
|
|
1
1
|
module FactoryBot
|
2
2
|
class DefinitionProxy
|
3
|
-
UNPROXIED_METHODS = %w(
|
3
|
+
UNPROXIED_METHODS = %w(
|
4
|
+
__send__
|
5
|
+
__id__
|
6
|
+
nil?
|
7
|
+
send
|
8
|
+
object_id
|
9
|
+
extend
|
10
|
+
instance_eval
|
11
|
+
initialize
|
12
|
+
block_given?
|
13
|
+
raise
|
14
|
+
caller
|
15
|
+
method
|
16
|
+
).freeze
|
4
17
|
|
5
18
|
(instance_methods + private_instance_methods).each do |method|
|
6
19
|
undef_method(method) unless UNPROXIED_METHODS.include?(method.to_s)
|
@@ -21,43 +34,21 @@ module FactoryBot
|
|
21
34
|
raise FactoryBot::MethodDefinitionError, message
|
22
35
|
end
|
23
36
|
|
24
|
-
# Adds an attribute
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
# called with a block, the attribute will be generated "lazily," whenever an
|
29
|
-
# instance is generated. Lazy attribute blocks will not be called if that
|
37
|
+
# Adds an attribute to the factory.
|
38
|
+
# The attribute value will be generated "lazily"
|
39
|
+
# by calling the block whenever an instance is generated.
|
40
|
+
# The block will not be called if the
|
30
41
|
# attribute is overridden for a specific instance.
|
31
42
|
#
|
32
|
-
# When defining lazy attributes, an instance of FactoryBot::Strategy will
|
33
|
-
# be yielded, allowing associations to be built using the correct build
|
34
|
-
# strategy.
|
35
|
-
#
|
36
43
|
# Arguments:
|
37
44
|
# * name: +Symbol+ or +String+
|
38
45
|
# The name of this attribute. This will be assigned using "name=" for
|
39
46
|
# generated instances.
|
40
|
-
|
41
|
-
|
42
|
-
def add_attribute(name, value = nil, &block)
|
43
|
-
raise AttributeDefinitionError, 'Both value and block given' if value && block_given?
|
44
|
-
|
45
|
-
declaration = if block_given?
|
46
|
-
Declaration::Dynamic.new(name, @ignore, block)
|
47
|
-
else
|
48
|
-
warn_static_attribute_deprecation(name, value)
|
49
|
-
Declaration::Static.new(name, value, @ignore)
|
50
|
-
end
|
51
|
-
|
47
|
+
def add_attribute(name, &block)
|
48
|
+
declaration = Declaration::Dynamic.new(name, @ignore, block)
|
52
49
|
@definition.declare_attribute(declaration)
|
53
50
|
end
|
54
51
|
|
55
|
-
def ignore(&block)
|
56
|
-
ActiveSupport::Deprecation.warn "`#ignore` is deprecated and will be "\
|
57
|
-
"removed in 5.0. Please use `#transient` instead."
|
58
|
-
transient(&block)
|
59
|
-
end
|
60
|
-
|
61
52
|
def transient(&block)
|
62
53
|
proxy = DefinitionProxy.new(@definition, true)
|
63
54
|
proxy.instance_eval(&block)
|
@@ -67,40 +58,48 @@ module FactoryBot
|
|
67
58
|
# attribute, so that:
|
68
59
|
#
|
69
60
|
# factory :user do
|
70
|
-
# name 'Billy Idol'
|
61
|
+
# name { 'Billy Idol' }
|
71
62
|
# end
|
72
63
|
#
|
73
64
|
# and:
|
74
65
|
#
|
75
66
|
# factory :user do
|
76
|
-
# add_attribute
|
67
|
+
# add_attribute(:name) { 'Billy Idol' }
|
77
68
|
# end
|
78
69
|
#
|
79
70
|
# are equivalent.
|
80
71
|
#
|
81
|
-
# If no argument or block is given, factory_bot will look for
|
82
|
-
#
|
72
|
+
# If no argument or block is given, factory_bot will first look for an
|
73
|
+
# association, then for a sequence, and finally for a trait with the same
|
74
|
+
# name. This means that given an "admin" trait, an "email" sequence, and an
|
75
|
+
# "account" factory:
|
83
76
|
#
|
84
|
-
# factory :user do
|
85
|
-
# email {
|
77
|
+
# factory :user, traits: [:admin] do
|
78
|
+
# email { generate(:email) }
|
86
79
|
# association :account
|
87
80
|
# end
|
88
81
|
#
|
89
82
|
# and:
|
90
83
|
#
|
91
84
|
# factory :user do
|
85
|
+
# admin
|
92
86
|
# email
|
93
87
|
# account
|
94
88
|
# end
|
95
89
|
#
|
96
90
|
# are equivalent.
|
97
|
-
def method_missing(name, *args, &block)
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
91
|
+
def method_missing(name, *args, &block) # rubocop:disable Style/MissingRespondToMissing, Style/MethodMissingSuper
|
92
|
+
association_options = args.first
|
93
|
+
|
94
|
+
if association_options.nil?
|
95
|
+
__declare_attribute__(name, block)
|
96
|
+
elsif __valid_association_options?(association_options)
|
97
|
+
association(name, association_options)
|
102
98
|
else
|
103
|
-
|
99
|
+
raise NoMethodError.new(<<~MSG)
|
100
|
+
undefined method '#{name}' in '#{@definition.name}' factory
|
101
|
+
Did you mean? '#{name} { #{association_options.inspect} }'
|
102
|
+
MSG
|
104
103
|
end
|
105
104
|
end
|
106
105
|
|
@@ -122,6 +121,7 @@ module FactoryBot
|
|
122
121
|
# Except that no globally available sequence will be defined.
|
123
122
|
def sequence(name, *args, &block)
|
124
123
|
sequence = Sequence.new(name, *args, &block)
|
124
|
+
FactoryBot::Internal.register_inline_sequence(sequence)
|
125
125
|
add_attribute(name) { increment_sequence(sequence) }
|
126
126
|
end
|
127
127
|
|
@@ -149,7 +149,15 @@ module FactoryBot
|
|
149
149
|
# name of the factory. For example, a "user" association will by
|
150
150
|
# default use the "user" factory.
|
151
151
|
def association(name, *options)
|
152
|
-
|
152
|
+
if block_given?
|
153
|
+
raise AssociationDefinitionError.new(
|
154
|
+
"Unexpected block passed to '#{name}' association "\
|
155
|
+
"in '#{@definition.name}' factory",
|
156
|
+
)
|
157
|
+
else
|
158
|
+
declaration = Declaration::Association.new(name, *options)
|
159
|
+
@definition.declare_attribute(declaration)
|
160
|
+
end
|
153
161
|
end
|
154
162
|
|
155
163
|
def to_create(&block)
|
@@ -174,28 +182,17 @@ module FactoryBot
|
|
174
182
|
|
175
183
|
private
|
176
184
|
|
177
|
-
def
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
185
|
+
def __declare_attribute__(name, block)
|
186
|
+
if block.nil?
|
187
|
+
declaration = Declaration::Implicit.new(name, @definition, @ignore)
|
188
|
+
@definition.declare_attribute(declaration)
|
189
|
+
else
|
190
|
+
add_attribute(name, &block)
|
182
191
|
end
|
192
|
+
end
|
183
193
|
|
184
|
-
|
185
|
-
|
186
|
-
attributes instead by wrapping the attribute value in a block:
|
187
|
-
|
188
|
-
#{name} { #{value.inspect} }
|
189
|
-
|
190
|
-
To automatically update from static attributes to dynamic ones,
|
191
|
-
install rubocop-rspec and run:
|
192
|
-
|
193
|
-
rubocop \\
|
194
|
-
--require rubocop-rspec \\
|
195
|
-
--only FactoryBot/AttributeDefinedStatically \\
|
196
|
-
--auto-correct
|
197
|
-
|
198
|
-
MSG
|
194
|
+
def __valid_association_options?(options)
|
195
|
+
options.respond_to?(:has_key?) && options.has_key?(:factory)
|
199
196
|
end
|
200
197
|
end
|
201
198
|
end
|
data/lib/factory_bot/errors.rb
CHANGED
@@ -2,6 +2,9 @@ module FactoryBot
|
|
2
2
|
# Raised when a factory is defined that attempts to instantiate itself.
|
3
3
|
class AssociationDefinitionError < RuntimeError; end
|
4
4
|
|
5
|
+
# Raised when a trait is defined that references itself.
|
6
|
+
class TraitDefinitionError < RuntimeError; end
|
7
|
+
|
5
8
|
# Raised when a callback is defined that has an invalid name
|
6
9
|
class InvalidCallbackNameError < RuntimeError; end
|
7
10
|
|
@@ -11,12 +14,12 @@ module FactoryBot
|
|
11
14
|
# Raised when attempting to register a sequence from a dynamic attribute block
|
12
15
|
class SequenceAbuseError < RuntimeError; end
|
13
16
|
|
14
|
-
# Raised when defining an
|
15
|
-
# * Defining an attribute which has a name ending in "="
|
16
|
-
# * Defining an attribute with both a static and lazy value
|
17
|
-
# * Defining an attribute twice in the same factory
|
17
|
+
# Raised when defining an attribute twice in the same factory
|
18
18
|
class AttributeDefinitionError < RuntimeError; end
|
19
19
|
|
20
|
+
# Raised when attempting to pass a block to an association definition
|
21
|
+
class AssociationDefinitionError < RuntimeError; end
|
22
|
+
|
20
23
|
# Raised when a method is defined in a factory or trait with arguments
|
21
24
|
class MethodDefinitionError < RuntimeError; end
|
22
25
|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "active_support/core_ext/hash/except"
|
2
|
+
require "active_support/core_ext/class/attribute"
|
3
3
|
|
4
4
|
module FactoryBot
|
5
5
|
# @api private
|
@@ -37,7 +37,7 @@ module FactoryBot
|
|
37
37
|
@instance = object_instance
|
38
38
|
end
|
39
39
|
|
40
|
-
def method_missing(method_name, *args, &block)
|
40
|
+
def method_missing(method_name, *args, &block) # rubocop:disable Style/MethodMissingSuper
|
41
41
|
if @instance.respond_to?(method_name)
|
42
42
|
@instance.send(method_name, *args, &block)
|
43
43
|
else
|
@@ -45,7 +45,7 @@ module FactoryBot
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
def respond_to_missing?(method_name,
|
48
|
+
def respond_to_missing?(method_name, _include_private = false)
|
49
49
|
@instance.respond_to?(method_name) || SyntaxRunner.new.respond_to?(method_name)
|
50
50
|
end
|
51
51
|
|
@@ -66,7 +66,7 @@ module FactoryBot
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def self.define_attribute(name, &block)
|
69
|
-
if
|
69
|
+
if instance_methods(false).include?(name) || private_instance_methods(false).include?(name)
|
70
70
|
undef_method(name)
|
71
71
|
end
|
72
72
|
|
data/lib/factory_bot/factory.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "active_support/core_ext/hash/keys"
|
2
|
+
require "active_support/inflector"
|
3
3
|
|
4
4
|
module FactoryBot
|
5
5
|
# @api private
|
@@ -21,10 +21,10 @@ module FactoryBot
|
|
21
21
|
|
22
22
|
def build_class
|
23
23
|
@build_class ||= if class_name.is_a? Class
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
class_name
|
25
|
+
else
|
26
|
+
class_name.to_s.camelize.constantize
|
27
|
+
end
|
28
28
|
end
|
29
29
|
|
30
30
|
def run(build_strategy, overrides, &block)
|
@@ -91,7 +91,7 @@ module FactoryBot
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def with_traits(traits)
|
94
|
-
|
94
|
+
clone.tap do |factory_with_traits|
|
95
95
|
factory_with_traits.append_traits traits
|
96
96
|
end
|
97
97
|
end
|
@@ -145,7 +145,7 @@ module FactoryBot
|
|
145
145
|
|
146
146
|
def parent
|
147
147
|
if @parent
|
148
|
-
FactoryBot.factory_by_name(@parent)
|
148
|
+
FactoryBot::Internal.factory_by_name(@parent)
|
149
149
|
else
|
150
150
|
NullFactory.new
|
151
151
|
end
|
@@ -9,7 +9,7 @@ module FactoryBot
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def run(runner_strategy = @strategy, &block)
|
12
|
-
factory = FactoryBot.factory_by_name(@name)
|
12
|
+
factory = FactoryBot::Internal.factory_by_name(@name)
|
13
13
|
|
14
14
|
factory.compile
|
15
15
|
|
@@ -22,10 +22,10 @@ module FactoryBot
|
|
22
22
|
strategy: runner_strategy,
|
23
23
|
traits: @traits,
|
24
24
|
overrides: @overrides,
|
25
|
-
factory: factory
|
25
|
+
factory: factory,
|
26
26
|
}
|
27
27
|
|
28
|
-
ActiveSupport::Notifications.instrument(
|
28
|
+
ActiveSupport::Notifications.instrument("factory_bot.run_factory", instrumentation_payload) do
|
29
29
|
factory.run(runner_strategy, @overrides, &block)
|
30
30
|
end
|
31
31
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module FactoryBot
|
2
|
+
# @api private
|
3
|
+
module Internal
|
4
|
+
class << self
|
5
|
+
delegate :after,
|
6
|
+
:before,
|
7
|
+
:callback_names,
|
8
|
+
:callbacks,
|
9
|
+
:constructor,
|
10
|
+
:factories,
|
11
|
+
:initialize_with,
|
12
|
+
:inline_sequences,
|
13
|
+
:sequences,
|
14
|
+
:skip_create,
|
15
|
+
:strategies,
|
16
|
+
:to_create,
|
17
|
+
:traits,
|
18
|
+
to: :configuration
|
19
|
+
|
20
|
+
def configuration
|
21
|
+
@configuration ||= Configuration.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def reset_configuration
|
25
|
+
@configuration = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def register_inline_sequence(sequence)
|
29
|
+
inline_sequences.push(sequence)
|
30
|
+
end
|
31
|
+
|
32
|
+
def rewind_inline_sequences
|
33
|
+
inline_sequences.each(&:rewind)
|
34
|
+
end
|
35
|
+
|
36
|
+
def register_trait(trait)
|
37
|
+
trait.names.each do |name|
|
38
|
+
traits.register(name, trait)
|
39
|
+
end
|
40
|
+
trait
|
41
|
+
end
|
42
|
+
|
43
|
+
def trait_by_name(name)
|
44
|
+
traits.find(name)
|
45
|
+
end
|
46
|
+
|
47
|
+
def register_sequence(sequence)
|
48
|
+
sequence.names.each do |name|
|
49
|
+
sequences.register(name, sequence)
|
50
|
+
end
|
51
|
+
sequence
|
52
|
+
end
|
53
|
+
|
54
|
+
def sequence_by_name(name)
|
55
|
+
sequences.find(name)
|
56
|
+
end
|
57
|
+
|
58
|
+
def rewind_sequences
|
59
|
+
sequences.each(&:rewind)
|
60
|
+
rewind_inline_sequences
|
61
|
+
end
|
62
|
+
|
63
|
+
def register_factory(factory)
|
64
|
+
factory.names.each do |name|
|
65
|
+
factories.register(name, factory)
|
66
|
+
end
|
67
|
+
factory
|
68
|
+
end
|
69
|
+
|
70
|
+
def factory_by_name(name)
|
71
|
+
factories.find(name)
|
72
|
+
end
|
73
|
+
|
74
|
+
def register_strategy(strategy_name, strategy_class)
|
75
|
+
strategies.register(strategy_name, strategy_class)
|
76
|
+
StrategySyntaxMethodRegistrar.new(strategy_name).define_strategy_methods
|
77
|
+
end
|
78
|
+
|
79
|
+
def strategy_by_name(name)
|
80
|
+
strategies.find(name)
|
81
|
+
end
|
82
|
+
|
83
|
+
def register_default_strategies
|
84
|
+
register_strategy(:build, FactoryBot::Strategy::Build)
|
85
|
+
register_strategy(:create, FactoryBot::Strategy::Create)
|
86
|
+
register_strategy(:attributes_for, FactoryBot::Strategy::AttributesFor)
|
87
|
+
register_strategy(:build_stubbed, FactoryBot::Strategy::Stub)
|
88
|
+
register_strategy(:null, FactoryBot::Strategy::Null)
|
89
|
+
end
|
90
|
+
|
91
|
+
def register_default_callbacks
|
92
|
+
register_callback(:after_create)
|
93
|
+
register_callback(:after_build)
|
94
|
+
register_callback(:after_stub)
|
95
|
+
register_callback(:before_create)
|
96
|
+
end
|
97
|
+
|
98
|
+
def register_callback(name)
|
99
|
+
name = name.to_sym
|
100
|
+
callback_names << name
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/lib/factory_bot/linter.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
module FactoryBot
|
2
2
|
class Linter
|
3
|
-
|
4
|
-
def initialize(factories, linting_strategy, factory_strategy = :create)
|
3
|
+
def initialize(factories, strategy: :create, traits: false, verbose: false)
|
5
4
|
@factories_to_lint = factories
|
6
|
-
@
|
7
|
-
@
|
5
|
+
@factory_strategy = strategy
|
6
|
+
@traits = traits
|
7
|
+
@verbose = verbose
|
8
8
|
@invalid_factories = calculate_invalid_factories
|
9
9
|
end
|
10
10
|
|
@@ -20,7 +20,7 @@ module FactoryBot
|
|
20
20
|
|
21
21
|
def calculate_invalid_factories
|
22
22
|
factories_to_lint.reduce(Hash.new([])) do |result, factory|
|
23
|
-
errors =
|
23
|
+
errors = lint(factory)
|
24
24
|
result[factory] |= errors unless errors.empty?
|
25
25
|
result
|
26
26
|
end
|
@@ -37,6 +37,13 @@ module FactoryBot
|
|
37
37
|
"* #{location} - #{message} (#{@wrapped_error.class.name})"
|
38
38
|
end
|
39
39
|
|
40
|
+
def verbose_message
|
41
|
+
<<~MESSAGE
|
42
|
+
#{message}
|
43
|
+
#{@wrapped_error.backtrace.join("\n ")}
|
44
|
+
MESSAGE
|
45
|
+
end
|
46
|
+
|
40
47
|
def location
|
41
48
|
@factory.name
|
42
49
|
end
|
@@ -53,12 +60,20 @@ module FactoryBot
|
|
53
60
|
end
|
54
61
|
end
|
55
62
|
|
63
|
+
def lint(factory)
|
64
|
+
if @traits
|
65
|
+
lint_factory(factory) + lint_traits(factory)
|
66
|
+
else
|
67
|
+
lint_factory(factory)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
56
71
|
def lint_factory(factory)
|
57
72
|
result = []
|
58
73
|
begin
|
59
74
|
FactoryBot.public_send(factory_strategy, factory.name)
|
60
|
-
rescue =>
|
61
|
-
result |= [FactoryError.new(
|
75
|
+
rescue StandardError => e
|
76
|
+
result |= [FactoryError.new(e, factory)]
|
62
77
|
end
|
63
78
|
result
|
64
79
|
end
|
@@ -68,30 +83,32 @@ module FactoryBot
|
|
68
83
|
factory.definition.defined_traits.map(&:name).each do |trait_name|
|
69
84
|
begin
|
70
85
|
FactoryBot.public_send(factory_strategy, factory.name, trait_name)
|
71
|
-
rescue =>
|
86
|
+
rescue StandardError => e
|
72
87
|
result |=
|
73
|
-
|
88
|
+
[FactoryTraitError.new(e, factory, trait_name)]
|
74
89
|
end
|
75
90
|
end
|
76
91
|
result
|
77
92
|
end
|
78
93
|
|
79
|
-
def lint_factory_and_traits(factory)
|
80
|
-
errors = lint_factory(factory)
|
81
|
-
errors |= lint_traits(factory)
|
82
|
-
errors
|
83
|
-
end
|
84
|
-
|
85
94
|
def error_message
|
86
95
|
lines = invalid_factories.map do |_factory, exceptions|
|
87
|
-
exceptions.map(
|
96
|
+
exceptions.map(&error_message_type)
|
88
97
|
end.flatten
|
89
98
|
|
90
|
-
|
91
|
-
The following factories are invalid:
|
99
|
+
<<~ERROR_MESSAGE.strip
|
100
|
+
The following factories are invalid:
|
92
101
|
|
93
|
-
#{lines.join("\n")}
|
102
|
+
#{lines.join("\n")}
|
94
103
|
ERROR_MESSAGE
|
95
104
|
end
|
105
|
+
|
106
|
+
def error_message_type
|
107
|
+
if @verbose
|
108
|
+
:verbose_message
|
109
|
+
else
|
110
|
+
:message
|
111
|
+
end
|
112
|
+
end
|
96
113
|
end
|
97
114
|
end
|
@@ -8,11 +8,14 @@ module FactoryBot
|
|
8
8
|
end
|
9
9
|
|
10
10
|
delegate :defined_traits, :callbacks, :attributes, :constructor,
|
11
|
-
|
11
|
+
:to_create, to: :definition
|
12
12
|
|
13
13
|
def compile; end
|
14
|
+
|
14
15
|
def class_name; end
|
16
|
+
|
15
17
|
def evaluator_class; FactoryBot::Evaluator; end
|
18
|
+
|
16
19
|
def hierarchy_class; FactoryBot::DefinitionHierarchy; end
|
17
20
|
end
|
18
21
|
end
|
@@ -13,11 +13,11 @@ module FactoryBot
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
def respond_to?(method,
|
16
|
+
def respond_to?(method, _include_private = false)
|
17
17
|
@methods_to_respond_to.include? method.to_s
|
18
18
|
end
|
19
19
|
|
20
|
-
def respond_to_missing?(*
|
20
|
+
def respond_to_missing?(*)
|
21
21
|
false
|
22
22
|
end
|
23
23
|
end
|
data/lib/factory_bot/registry.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "active_support/core_ext/hash/indifferent_access"
|
2
|
+
|
1
3
|
module FactoryBot
|
2
4
|
class Registry
|
3
5
|
include Enumerable
|
@@ -6,7 +8,7 @@ module FactoryBot
|
|
6
8
|
|
7
9
|
def initialize(name)
|
8
10
|
@name = name
|
9
|
-
@items =
|
11
|
+
@items = ActiveSupport::HashWithIndifferentAccess.new
|
10
12
|
end
|
11
13
|
|
12
14
|
def clear
|
@@ -18,11 +20,9 @@ module FactoryBot
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def find(name)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
raise ArgumentError, "#{@name} not registered: #{name}"
|
25
|
-
end
|
23
|
+
@items.fetch(name)
|
24
|
+
rescue KeyError => e
|
25
|
+
raise key_error_with_custom_message(e)
|
26
26
|
end
|
27
27
|
|
28
28
|
alias :[] :find
|
@@ -34,5 +34,14 @@ module FactoryBot
|
|
34
34
|
def registered?(name)
|
35
35
|
@items.key?(name)
|
36
36
|
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def key_error_with_custom_message(key_error)
|
41
|
+
message = key_error.message.sub("key not found", "#{@name} not registered")
|
42
|
+
error = KeyError.new(message)
|
43
|
+
error.set_backtrace(key_error.backtrace)
|
44
|
+
error
|
45
|
+
end
|
37
46
|
end
|
38
47
|
end
|
data/lib/factory_bot/reload.rb
CHANGED
data/lib/factory_bot/sequence.rb
CHANGED