factory_bot 5.1.1 → 6.0.1
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/CONTRIBUTING.md +52 -13
- data/GETTING_STARTED.md +426 -68
- data/NEWS.md +18 -1
- data/README.md +4 -4
- data/lib/factory_bot/aliases.rb +3 -3
- data/lib/factory_bot/attribute/association.rb +2 -2
- data/lib/factory_bot/attribute/dynamic.rb +2 -1
- data/lib/factory_bot/attribute_assigner.rb +9 -10
- data/lib/factory_bot/attribute_list.rb +1 -1
- data/lib/factory_bot/callback.rb +2 -10
- data/lib/factory_bot/configuration.rb +6 -6
- data/lib/factory_bot/declaration.rb +1 -1
- data/lib/factory_bot/declaration_list.rb +2 -2
- data/lib/factory_bot/decorator/invocation_tracker.rb +1 -1
- data/lib/factory_bot/decorator.rb +1 -1
- data/lib/factory_bot/definition.rb +42 -16
- data/lib/factory_bot/definition_hierarchy.rb +1 -11
- data/lib/factory_bot/definition_proxy.rb +64 -6
- data/lib/factory_bot/enum.rb +27 -0
- data/lib/factory_bot/evaluator.rb +5 -7
- data/lib/factory_bot/evaluator_class_definer.rb +1 -1
- data/lib/factory_bot/factory.rb +12 -12
- data/lib/factory_bot/factory_runner.rb +3 -3
- data/lib/factory_bot/find_definitions.rb +1 -1
- data/lib/factory_bot/internal.rb +18 -29
- data/lib/factory_bot/linter.rb +9 -13
- data/lib/factory_bot/null_factory.rb +10 -4
- data/lib/factory_bot/null_object.rb +2 -6
- data/lib/factory_bot/registry.rb +4 -4
- data/lib/factory_bot/reload.rb +0 -1
- data/lib/factory_bot/sequence.rb +5 -5
- data/lib/factory_bot/strategy/null.rb +4 -2
- data/lib/factory_bot/strategy/stub.rb +6 -2
- data/lib/factory_bot/strategy_syntax_method_registrar.rb +12 -1
- data/lib/factory_bot/syntax/default.rb +7 -19
- data/lib/factory_bot/trait.rb +1 -1
- data/lib/factory_bot/version.rb +1 -1
- data/lib/factory_bot.rb +21 -55
- metadata +12 -11
data/NEWS.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# News
|
|
2
2
|
|
|
3
|
+
## 6.0.1 (June 19, 2020)
|
|
4
|
+
* Fixed: bug with constant resolution causing unexpected uninitialized constant errors
|
|
5
|
+
|
|
6
|
+
## 6.0.0 (June 18, 2020)
|
|
7
|
+
* Added: automatic definition of traits for Active Record enum attributes, enabled by default
|
|
8
|
+
* Added: `traits_for_enum` method to define traits for non-Active Record enums
|
|
9
|
+
* Added: `build_stubbed_starting_id=` option to define the starting id for `build_stubbed`
|
|
10
|
+
* Removed: deprecated methods on the top-level `FactoryBot` module meant only for internal use
|
|
11
|
+
* Removed: support for EOL versions of Ruby (2.3, 2.4) and Rails (4.2)
|
|
12
|
+
|
|
13
|
+
## 5.2.0 (April 24, 2020)
|
|
14
|
+
* Added: Pass index to block for `*_list` methods
|
|
15
|
+
* Deprecated: methods on the top-level `FactoryBot` module meant only for internal use: `callbacks`, `configuration`, `constructor`, `initialize_with`, `register_sequence`, `resent_configuration`, `skip_create`, `to_create`
|
|
16
|
+
|
|
17
|
+
## 5.1.2 (March 25, 2020)
|
|
18
|
+
* Fixed: Ruby 2.7 keyword deprecation warning in FactoryBot.lint
|
|
19
|
+
|
|
3
20
|
## 5.1.1 (October 2, 2019)
|
|
4
21
|
* Improved: performance of traits
|
|
5
22
|
* Fixed: registering strategies on JRuby
|
|
@@ -10,7 +27,7 @@
|
|
|
10
27
|
* Fixed: avoid undefining inherited evaluator methods
|
|
11
28
|
* Fixed: avoid stubbing id for records without a primary key
|
|
12
29
|
* Fixed: raise a helpful error for self-referencing traits to avoid a `SystemStackError`
|
|
13
|
-
* Deprecated: top-level
|
|
30
|
+
* Deprecated: methods on the top-level `FactoryBot` module meant only for internal use: `allow_class_lookup`, `allow_class_lookup`=, `register_trait`, `trait_by_name`, `traits`, `sequence_by_name`, `sequences`, `factory_by_name`, `register_factory`, `callback_names`, `register_callback`, `register_default_callbacks`, `register_default_strategies`, `strategies`
|
|
14
31
|
|
|
15
32
|
## 5.0.2 (February 22, 2019)
|
|
16
33
|
* Bugfix: raise "Trait not registered" error when passing invalid trait arguments
|
data/README.md
CHANGED
|
@@ -72,14 +72,14 @@ Contributing
|
|
|
72
72
|
|
|
73
73
|
Please see [CONTRIBUTING.md](https://github.com/thoughtbot/factory_bot/blob/master/CONTRIBUTING.md).
|
|
74
74
|
|
|
75
|
-
factory_bot was originally written by Joe Ferris and is
|
|
76
|
-
|
|
75
|
+
factory_bot was originally written by Joe Ferris and is maintained by thoughtbot.
|
|
76
|
+
Many improvements and bugfixes were contributed by the [open source
|
|
77
77
|
community](https://github.com/thoughtbot/factory_bot/graphs/contributors).
|
|
78
78
|
|
|
79
79
|
License
|
|
80
80
|
-------
|
|
81
81
|
|
|
82
|
-
factory_bot is Copyright © 2008-
|
|
82
|
+
factory_bot is Copyright © 2008-2020 Joe Ferris and thoughtbot. It is free
|
|
83
83
|
software, and may be redistributed under the terms specified in the
|
|
84
84
|
[LICENSE] file.
|
|
85
85
|
|
|
@@ -89,7 +89,7 @@ software, and may be redistributed under the terms specified in the
|
|
|
89
89
|
About thoughtbot
|
|
90
90
|
----------------
|
|
91
91
|
|
|
92
|
-

|
|
93
93
|
|
|
94
94
|
factory_bot is maintained and funded by thoughtbot, inc.
|
|
95
95
|
The names and logos for thoughtbot are trademarks of thoughtbot, inc.
|
data/lib/factory_bot/aliases.rb
CHANGED
|
@@ -5,14 +5,14 @@ module FactoryBot
|
|
|
5
5
|
|
|
6
6
|
self.aliases = [
|
|
7
7
|
[/(.+)_id/, '\1'],
|
|
8
|
-
[/(.*)/, '\1_id']
|
|
8
|
+
[/(.*)/, '\1_id']
|
|
9
9
|
]
|
|
10
10
|
|
|
11
11
|
def self.aliases_for(attribute)
|
|
12
|
-
aliases.map
|
|
12
|
+
aliases.map { |(pattern, replace)|
|
|
13
13
|
if pattern.match(attribute.to_s)
|
|
14
14
|
attribute.to_s.sub(pattern, replace).to_sym
|
|
15
15
|
end
|
|
16
|
-
|
|
16
|
+
}.compact << attribute
|
|
17
17
|
end
|
|
18
18
|
end
|
|
@@ -6,12 +6,12 @@ module FactoryBot
|
|
|
6
6
|
|
|
7
7
|
def initialize(name, factory, overrides)
|
|
8
8
|
super(name, false)
|
|
9
|
-
@factory
|
|
9
|
+
@factory = factory
|
|
10
10
|
@overrides = overrides
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def to_proc
|
|
14
|
-
factory
|
|
14
|
+
factory = @factory
|
|
15
15
|
overrides = @overrides
|
|
16
16
|
traits_and_overrides = [factory, overrides].flatten
|
|
17
17
|
factory_name = traits_and_overrides.shift
|
|
@@ -2,10 +2,10 @@ module FactoryBot
|
|
|
2
2
|
# @api private
|
|
3
3
|
class AttributeAssigner
|
|
4
4
|
def initialize(evaluator, build_class, &instance_builder)
|
|
5
|
-
@build_class
|
|
6
|
-
@instance_builder
|
|
7
|
-
@evaluator
|
|
8
|
-
@attribute_list
|
|
5
|
+
@build_class = build_class
|
|
6
|
+
@instance_builder = instance_builder
|
|
7
|
+
@evaluator = evaluator
|
|
8
|
+
@attribute_list = evaluator.class.attribute_list
|
|
9
9
|
@attribute_names_assigned = []
|
|
10
10
|
end
|
|
11
11
|
|
|
@@ -22,9 +22,8 @@ module FactoryBot
|
|
|
22
22
|
def hash
|
|
23
23
|
@evaluator.instance = build_hash
|
|
24
24
|
|
|
25
|
-
attributes_to_set_on_hash.
|
|
25
|
+
attributes_to_set_on_hash.each_with_object({}) do |attribute, result|
|
|
26
26
|
result[attribute] = get(attribute)
|
|
27
|
-
result
|
|
28
27
|
end
|
|
29
28
|
end
|
|
30
29
|
|
|
@@ -33,13 +32,13 @@ module FactoryBot
|
|
|
33
32
|
def method_tracking_evaluator
|
|
34
33
|
@method_tracking_evaluator ||= Decorator::AttributeHash.new(
|
|
35
34
|
decorated_evaluator,
|
|
36
|
-
attribute_names_to_assign
|
|
35
|
+
attribute_names_to_assign
|
|
37
36
|
)
|
|
38
37
|
end
|
|
39
38
|
|
|
40
39
|
def decorated_evaluator
|
|
41
40
|
Decorator::InvocationTracker.new(
|
|
42
|
-
Decorator::NewConstructor.new(@evaluator, @build_class)
|
|
41
|
+
Decorator::NewConstructor.new(@evaluator, @build_class)
|
|
43
42
|
)
|
|
44
43
|
end
|
|
45
44
|
|
|
@@ -96,11 +95,11 @@ module FactoryBot
|
|
|
96
95
|
end
|
|
97
96
|
|
|
98
97
|
def alias_names_to_ignore
|
|
99
|
-
@attribute_list.non_ignored.flat_map
|
|
98
|
+
@attribute_list.non_ignored.flat_map { |attribute|
|
|
100
99
|
override_names.map do |override|
|
|
101
100
|
attribute.name if ignorable_alias?(attribute, override)
|
|
102
101
|
end
|
|
103
|
-
|
|
102
|
+
}.compact
|
|
104
103
|
end
|
|
105
104
|
|
|
106
105
|
def ignorable_alias?(attribute, override)
|
data/lib/factory_bot/callback.rb
CHANGED
|
@@ -3,16 +3,15 @@ module FactoryBot
|
|
|
3
3
|
attr_reader :name
|
|
4
4
|
|
|
5
5
|
def initialize(name, block)
|
|
6
|
-
@name
|
|
6
|
+
@name = name.to_sym
|
|
7
7
|
@block = block
|
|
8
|
-
ensure_valid_callback_name!
|
|
9
8
|
end
|
|
10
9
|
|
|
11
10
|
def run(instance, evaluator)
|
|
12
11
|
case block.arity
|
|
13
12
|
when 1, -1 then syntax_runner.instance_exec(instance, &block)
|
|
14
13
|
when 2 then syntax_runner.instance_exec(instance, evaluator, &block)
|
|
15
|
-
else
|
|
14
|
+
else syntax_runner.instance_exec(&block)
|
|
16
15
|
end
|
|
17
16
|
end
|
|
18
17
|
|
|
@@ -27,13 +26,6 @@ module FactoryBot
|
|
|
27
26
|
|
|
28
27
|
private
|
|
29
28
|
|
|
30
|
-
def ensure_valid_callback_name!
|
|
31
|
-
unless FactoryBot::Internal.callback_names.include?(name)
|
|
32
|
-
raise InvalidCallbackNameError, "#{name} is not a valid callback name. " +
|
|
33
|
-
"Valid callback names are #{FactoryBot::Internal.callback_names.inspect}"
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
29
|
def syntax_runner
|
|
38
30
|
@syntax_runner ||= SyntaxRunner.new
|
|
39
31
|
end
|
|
@@ -7,16 +7,16 @@ module FactoryBot
|
|
|
7
7
|
:inline_sequences,
|
|
8
8
|
:sequences,
|
|
9
9
|
:strategies,
|
|
10
|
-
:traits
|
|
10
|
+
:traits
|
|
11
11
|
)
|
|
12
12
|
|
|
13
13
|
def initialize
|
|
14
|
-
@factories
|
|
15
|
-
@sequences
|
|
16
|
-
@traits
|
|
17
|
-
@strategies
|
|
14
|
+
@factories = Decorator::DisallowsDuplicatesRegistry.new(Registry.new("Factory"))
|
|
15
|
+
@sequences = Decorator::DisallowsDuplicatesRegistry.new(Registry.new("Sequence"))
|
|
16
|
+
@traits = Decorator::DisallowsDuplicatesRegistry.new(Registry.new("Trait"))
|
|
17
|
+
@strategies = Registry.new("Strategy")
|
|
18
18
|
@callback_names = Set.new
|
|
19
|
-
@definition
|
|
19
|
+
@definition = Definition.new(:configuration)
|
|
20
20
|
@inline_sequences = []
|
|
21
21
|
|
|
22
22
|
to_create(&:save!)
|
|
@@ -6,7 +6,7 @@ module FactoryBot
|
|
|
6
6
|
@component = component
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
def method_missing(name, *args, &block) # rubocop:disable Style/
|
|
9
|
+
def method_missing(name, *args, &block) # rubocop:disable Style/MethodMissingSuper
|
|
10
10
|
@component.send(name, *args, &block)
|
|
11
11
|
end
|
|
12
12
|
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
module FactoryBot
|
|
2
2
|
# @api private
|
|
3
3
|
class Definition
|
|
4
|
-
attr_reader :defined_traits, :declarations, :name
|
|
4
|
+
attr_reader :defined_traits, :declarations, :name, :registered_enums
|
|
5
5
|
|
|
6
6
|
def initialize(name, base_traits = [])
|
|
7
|
-
@name
|
|
8
|
-
@declarations
|
|
9
|
-
@callbacks
|
|
10
|
-
@defined_traits
|
|
11
|
-
@
|
|
12
|
-
@
|
|
7
|
+
@name = name
|
|
8
|
+
@declarations = DeclarationList.new(name)
|
|
9
|
+
@callbacks = []
|
|
10
|
+
@defined_traits = Set.new
|
|
11
|
+
@registered_enums = []
|
|
12
|
+
@to_create = nil
|
|
13
|
+
@base_traits = base_traits
|
|
13
14
|
@additional_traits = []
|
|
14
|
-
@constructor
|
|
15
|
-
@attributes
|
|
16
|
-
@compiled
|
|
15
|
+
@constructor = nil
|
|
16
|
+
@attributes = nil
|
|
17
|
+
@compiled = false
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
delegate :declare_attribute, to: :declarations
|
|
@@ -43,13 +44,15 @@ module FactoryBot
|
|
|
43
44
|
aggregate_from_traits_and_self(:callbacks) { @callbacks }
|
|
44
45
|
end
|
|
45
46
|
|
|
46
|
-
def compile
|
|
47
|
+
def compile(klass = nil)
|
|
47
48
|
unless @compiled
|
|
49
|
+
expand_enum_traits(klass) unless klass.nil?
|
|
50
|
+
|
|
48
51
|
declarations.attributes
|
|
49
52
|
|
|
50
53
|
defined_traits.each do |defined_trait|
|
|
51
|
-
base_traits.each
|
|
52
|
-
additional_traits.each { |
|
|
54
|
+
base_traits.each { |bt| bt.define_trait defined_trait }
|
|
55
|
+
additional_traits.each { |at| at.define_trait defined_trait }
|
|
53
56
|
end
|
|
54
57
|
|
|
55
58
|
@compiled = true
|
|
@@ -81,6 +84,10 @@ module FactoryBot
|
|
|
81
84
|
@defined_traits.add(trait)
|
|
82
85
|
end
|
|
83
86
|
|
|
87
|
+
def register_enum(enum)
|
|
88
|
+
@registered_enums << enum
|
|
89
|
+
end
|
|
90
|
+
|
|
84
91
|
def define_constructor(&block)
|
|
85
92
|
@constructor = block
|
|
86
93
|
end
|
|
@@ -95,7 +102,6 @@ module FactoryBot
|
|
|
95
102
|
|
|
96
103
|
def callback(*names, &block)
|
|
97
104
|
names.each do |name|
|
|
98
|
-
FactoryBot::Internal.register_callback(name)
|
|
99
105
|
add_callback(Callback.new(name, block))
|
|
100
106
|
end
|
|
101
107
|
end
|
|
@@ -122,7 +128,7 @@ module FactoryBot
|
|
|
122
128
|
def initialize_copy(source)
|
|
123
129
|
super
|
|
124
130
|
@attributes = nil
|
|
125
|
-
@compiled
|
|
131
|
+
@compiled = false
|
|
126
132
|
@defined_traits_by_name = nil
|
|
127
133
|
end
|
|
128
134
|
|
|
@@ -132,8 +138,28 @@ module FactoryBot
|
|
|
132
138
|
[
|
|
133
139
|
base_traits.map(&method_name),
|
|
134
140
|
instance_exec(&block),
|
|
135
|
-
additional_traits.map(&method_name)
|
|
141
|
+
additional_traits.map(&method_name)
|
|
136
142
|
].flatten.compact
|
|
137
143
|
end
|
|
144
|
+
|
|
145
|
+
def expand_enum_traits(klass)
|
|
146
|
+
if automatically_register_defined_enums?(klass)
|
|
147
|
+
automatically_register_defined_enums(klass)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
registered_enums.each do |enum|
|
|
151
|
+
traits = enum.build_traits(klass)
|
|
152
|
+
traits.each { |trait| define_trait(trait) }
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def automatically_register_defined_enums(klass)
|
|
157
|
+
klass.defined_enums.each_key { |name| register_enum(Enum.new(name)) }
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def automatically_register_defined_enums?(klass)
|
|
161
|
+
FactoryBot.automatically_define_enum_traits &&
|
|
162
|
+
klass.respond_to?(:defined_enums)
|
|
163
|
+
end
|
|
138
164
|
end
|
|
139
165
|
end
|
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
module FactoryBot
|
|
2
2
|
class DefinitionHierarchy
|
|
3
|
-
|
|
4
|
-
FactoryBot.callbacks
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
def constructor
|
|
8
|
-
FactoryBot.constructor
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def to_create
|
|
12
|
-
FactoryBot.to_create
|
|
13
|
-
end
|
|
3
|
+
delegate :callbacks, :constructor, :to_create, to: Internal
|
|
14
4
|
|
|
15
5
|
def self.build_from_definition(definition)
|
|
16
6
|
build_to_create(&definition.to_create)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module FactoryBot
|
|
2
2
|
class DefinitionProxy
|
|
3
|
-
UNPROXIED_METHODS = %w
|
|
3
|
+
UNPROXIED_METHODS = %w[
|
|
4
4
|
__send__
|
|
5
5
|
__id__
|
|
6
6
|
nil?
|
|
@@ -13,7 +13,7 @@ module FactoryBot
|
|
|
13
13
|
raise
|
|
14
14
|
caller
|
|
15
15
|
method
|
|
16
|
-
|
|
16
|
+
].freeze
|
|
17
17
|
|
|
18
18
|
(instance_methods + private_instance_methods).each do |method|
|
|
19
19
|
undef_method(method) unless UNPROXIED_METHODS.include?(method.to_s)
|
|
@@ -24,8 +24,8 @@ module FactoryBot
|
|
|
24
24
|
attr_reader :child_factories
|
|
25
25
|
|
|
26
26
|
def initialize(definition, ignore = false)
|
|
27
|
-
@definition
|
|
28
|
-
@ignore
|
|
27
|
+
@definition = definition
|
|
28
|
+
@ignore = ignore
|
|
29
29
|
@child_factories = []
|
|
30
30
|
end
|
|
31
31
|
|
|
@@ -88,7 +88,7 @@ module FactoryBot
|
|
|
88
88
|
# end
|
|
89
89
|
#
|
|
90
90
|
# are equivalent.
|
|
91
|
-
def method_missing(name, *args, &block) # rubocop:disable Style/
|
|
91
|
+
def method_missing(name, *args, &block) # rubocop:disable Style/MissingRespondToMissing, Style/MethodMissingSuper
|
|
92
92
|
association_options = args.first
|
|
93
93
|
|
|
94
94
|
if association_options.nil?
|
|
@@ -152,7 +152,7 @@ module FactoryBot
|
|
|
152
152
|
if block_given?
|
|
153
153
|
raise AssociationDefinitionError.new(
|
|
154
154
|
"Unexpected block passed to '#{name}' association "\
|
|
155
|
-
"in '#{@definition.name}' factory"
|
|
155
|
+
"in '#{@definition.name}' factory"
|
|
156
156
|
)
|
|
157
157
|
else
|
|
158
158
|
declaration = Declaration::Association.new(name, *options)
|
|
@@ -176,6 +176,64 @@ module FactoryBot
|
|
|
176
176
|
@definition.define_trait(Trait.new(name, &block))
|
|
177
177
|
end
|
|
178
178
|
|
|
179
|
+
# Creates traits for enumerable values.
|
|
180
|
+
#
|
|
181
|
+
# Example:
|
|
182
|
+
# factory :task do
|
|
183
|
+
# traits_for_enum :status, [:started, :finished]
|
|
184
|
+
# end
|
|
185
|
+
#
|
|
186
|
+
# Equivalent to:
|
|
187
|
+
# factory :task do
|
|
188
|
+
# trait :started do
|
|
189
|
+
# status { :started }
|
|
190
|
+
# end
|
|
191
|
+
#
|
|
192
|
+
# trait :finished do
|
|
193
|
+
# status { :finished }
|
|
194
|
+
# end
|
|
195
|
+
# end
|
|
196
|
+
#
|
|
197
|
+
# Example:
|
|
198
|
+
# factory :task do
|
|
199
|
+
# traits_for_enum :status, {started: 1, finished: 2}
|
|
200
|
+
# end
|
|
201
|
+
#
|
|
202
|
+
# Example:
|
|
203
|
+
# class Task
|
|
204
|
+
# def statuses
|
|
205
|
+
# {started: 1, finished: 2}
|
|
206
|
+
# end
|
|
207
|
+
# end
|
|
208
|
+
#
|
|
209
|
+
# factory :task do
|
|
210
|
+
# traits_for_enum :status
|
|
211
|
+
# end
|
|
212
|
+
#
|
|
213
|
+
# Both equivalent to:
|
|
214
|
+
# factory :task do
|
|
215
|
+
# trait :started do
|
|
216
|
+
# status { 1 }
|
|
217
|
+
# end
|
|
218
|
+
#
|
|
219
|
+
# trait :finished do
|
|
220
|
+
# status { 2 }
|
|
221
|
+
# end
|
|
222
|
+
# end
|
|
223
|
+
#
|
|
224
|
+
#
|
|
225
|
+
# Arguments:
|
|
226
|
+
# attribute_name: +Symbol+ or +String+
|
|
227
|
+
# the name of the attribute these traits will set the value of
|
|
228
|
+
# values: +Array+, +Hash+, or other +Enumerable+
|
|
229
|
+
# An array of trait names, or a mapping of trait names to values for
|
|
230
|
+
# those traits. When this argument is not provided, factory_bot will
|
|
231
|
+
# attempt to get the values by calling the pluralized `attribute_name`
|
|
232
|
+
# class method.
|
|
233
|
+
def traits_for_enum(attribute_name, values = nil)
|
|
234
|
+
@definition.register_enum(Enum.new(attribute_name, values))
|
|
235
|
+
end
|
|
236
|
+
|
|
179
237
|
def initialize_with(&block)
|
|
180
238
|
@definition.define_constructor(&block)
|
|
181
239
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module FactoryBot
|
|
2
|
+
# @api private
|
|
3
|
+
class Enum
|
|
4
|
+
def initialize(attribute_name, values = nil)
|
|
5
|
+
@attribute_name = attribute_name
|
|
6
|
+
@values = values
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def build_traits(klass)
|
|
10
|
+
enum_values(klass).map do |trait_name, value|
|
|
11
|
+
build_trait(trait_name, @attribute_name, value || trait_name)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def enum_values(klass)
|
|
18
|
+
@values || klass.send(@attribute_name.to_s.pluralize)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def build_trait(trait_name, attribute_name, value)
|
|
22
|
+
Trait.new(trait_name) do
|
|
23
|
+
add_attribute(attribute_name) { value }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -7,7 +7,7 @@ module FactoryBot
|
|
|
7
7
|
class_attribute :attribute_lists
|
|
8
8
|
|
|
9
9
|
private_instance_methods.each do |method|
|
|
10
|
-
undef_method(method) unless method
|
|
10
|
+
undef_method(method) unless method.match?(/^__|initialize/)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def initialize(build_strategy, overrides = {})
|
|
@@ -23,9 +23,9 @@ module FactoryBot
|
|
|
23
23
|
|
|
24
24
|
def association(factory_name, *traits_and_overrides)
|
|
25
25
|
overrides = traits_and_overrides.extract_options!
|
|
26
|
-
strategy_override = overrides.fetch(:strategy)
|
|
26
|
+
strategy_override = overrides.fetch(:strategy) {
|
|
27
27
|
FactoryBot.use_parent_strategy ? @build_strategy.class : :create
|
|
28
|
-
|
|
28
|
+
}
|
|
29
29
|
|
|
30
30
|
traits_and_overrides += [overrides.except(:strategy)]
|
|
31
31
|
|
|
@@ -33,11 +33,9 @@ module FactoryBot
|
|
|
33
33
|
@build_strategy.association(runner)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
@instance = object_instance
|
|
38
|
-
end
|
|
36
|
+
attr_writer :instance
|
|
39
37
|
|
|
40
|
-
def method_missing(method_name, *args, &block) # rubocop:disable Style/
|
|
38
|
+
def method_missing(method_name, *args, &block) # rubocop:disable Style/MethodMissingSuper
|
|
41
39
|
if @instance.respond_to?(method_name)
|
|
42
40
|
@instance.send(method_name, *args, &block)
|
|
43
41
|
else
|
|
@@ -3,7 +3,7 @@ module FactoryBot
|
|
|
3
3
|
class EvaluatorClassDefiner
|
|
4
4
|
def initialize(attributes, parent_class)
|
|
5
5
|
@parent_class = parent_class
|
|
6
|
-
@attributes
|
|
6
|
+
@attributes = attributes
|
|
7
7
|
|
|
8
8
|
attributes.each do |attribute|
|
|
9
9
|
evaluator_class.define_attribute(attribute.name, &attribute.to_proc)
|
data/lib/factory_bot/factory.rb
CHANGED
|
@@ -8,23 +8,23 @@ module FactoryBot
|
|
|
8
8
|
|
|
9
9
|
def initialize(name, options = {})
|
|
10
10
|
assert_valid_options(options)
|
|
11
|
-
@name
|
|
12
|
-
@parent
|
|
13
|
-
@aliases
|
|
14
|
-
@class_name
|
|
15
|
-
@definition
|
|
16
|
-
@compiled
|
|
11
|
+
@name = name.respond_to?(:to_sym) ? name.to_sym : name.to_s.underscore.to_sym
|
|
12
|
+
@parent = options[:parent]
|
|
13
|
+
@aliases = options[:aliases] || []
|
|
14
|
+
@class_name = options[:class]
|
|
15
|
+
@definition = Definition.new(@name, options[:traits] || [])
|
|
16
|
+
@compiled = false
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
delegate :add_callback, :declare_attribute, :to_create, :define_trait, :constructor,
|
|
20
|
-
|
|
20
|
+
:defined_traits, :inherit_traits, :append_traits, to: :@definition
|
|
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)
|
|
@@ -84,7 +84,7 @@ module FactoryBot
|
|
|
84
84
|
unless @compiled
|
|
85
85
|
parent.compile
|
|
86
86
|
parent.defined_traits.each { |trait| define_trait(trait) }
|
|
87
|
-
@definition.compile
|
|
87
|
+
@definition.compile(build_class)
|
|
88
88
|
build_hierarchy
|
|
89
89
|
@compiled = true
|
|
90
90
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
module FactoryBot
|
|
2
2
|
class FactoryRunner
|
|
3
3
|
def initialize(name, strategy, traits_and_overrides)
|
|
4
|
-
@name
|
|
4
|
+
@name = name
|
|
5
5
|
@strategy = strategy
|
|
6
6
|
|
|
7
7
|
@overrides = traits_and_overrides.extract_options!
|
|
8
|
-
@traits
|
|
8
|
+
@traits = traits_and_overrides
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def run(runner_strategy = @strategy, &block)
|
|
@@ -22,7 +22,7 @@ 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
28
|
ActiveSupport::Notifications.instrument("factory_bot.run_factory", instrumentation_payload) do
|
|
@@ -7,7 +7,7 @@ module FactoryBot
|
|
|
7
7
|
attr_accessor :definition_file_paths
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
self.definition_file_paths = %w
|
|
10
|
+
self.definition_file_paths = %w[factories test/factories spec/factories]
|
|
11
11
|
|
|
12
12
|
def self.find_definitions
|
|
13
13
|
absolute_definition_file_paths = definition_file_paths.map { |path| File.expand_path(path) }
|