tiny-lite-mod 0.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 +7 -0
- data/factory_bot-6.6.0/CONTRIBUTING.md +105 -0
- data/factory_bot-6.6.0/GETTING_STARTED.md +2203 -0
- data/factory_bot-6.6.0/LICENSE +19 -0
- data/factory_bot-6.6.0/NAME.md +18 -0
- data/factory_bot-6.6.0/NEWS.md +607 -0
- data/factory_bot-6.6.0/README.md +99 -0
- data/factory_bot-6.6.0/lib/factory_bot/aliases.rb +18 -0
- data/factory_bot-6.6.0/lib/factory_bot/attribute/association.rb +27 -0
- data/factory_bot-6.6.0/lib/factory_bot/attribute/dynamic.rb +25 -0
- data/factory_bot-6.6.0/lib/factory_bot/attribute/sequence.rb +16 -0
- data/factory_bot-6.6.0/lib/factory_bot/attribute.rb +27 -0
- data/factory_bot-6.6.0/lib/factory_bot/attribute_assigner.rb +168 -0
- data/factory_bot-6.6.0/lib/factory_bot/attribute_list.rb +68 -0
- data/factory_bot-6.6.0/lib/factory_bot/callback.rb +33 -0
- data/factory_bot-6.6.0/lib/factory_bot/callbacks_observer.rb +39 -0
- data/factory_bot-6.6.0/lib/factory_bot/configuration.rb +33 -0
- data/factory_bot-6.6.0/lib/factory_bot/declaration/association.rb +58 -0
- data/factory_bot-6.6.0/lib/factory_bot/declaration/dynamic.rb +28 -0
- data/factory_bot-6.6.0/lib/factory_bot/declaration/implicit.rb +38 -0
- data/factory_bot-6.6.0/lib/factory_bot/declaration.rb +23 -0
- data/factory_bot-6.6.0/lib/factory_bot/declaration_list.rb +49 -0
- data/factory_bot-6.6.0/lib/factory_bot/decorator/attribute_hash.rb +16 -0
- data/factory_bot-6.6.0/lib/factory_bot/decorator/disallows_duplicates_registry.rb +13 -0
- data/factory_bot-6.6.0/lib/factory_bot/decorator/invocation_tracker.rb +20 -0
- data/factory_bot-6.6.0/lib/factory_bot/decorator/new_constructor.rb +12 -0
- data/factory_bot-6.6.0/lib/factory_bot/decorator.rb +25 -0
- data/factory_bot-6.6.0/lib/factory_bot/definition.rb +210 -0
- data/factory_bot-6.6.0/lib/factory_bot/definition_hierarchy.rb +38 -0
- data/factory_bot-6.6.0/lib/factory_bot/definition_proxy.rb +269 -0
- data/factory_bot-6.6.0/lib/factory_bot/enum.rb +27 -0
- data/factory_bot-6.6.0/lib/factory_bot/errors.rb +28 -0
- data/factory_bot-6.6.0/lib/factory_bot/evaluation.rb +23 -0
- data/factory_bot-6.6.0/lib/factory_bot/evaluator.rb +86 -0
- data/factory_bot-6.6.0/lib/factory_bot/evaluator_class_definer.rb +20 -0
- data/factory_bot-6.6.0/lib/factory_bot/factory.rb +178 -0
- data/factory_bot-6.6.0/lib/factory_bot/factory_runner.rb +35 -0
- data/factory_bot-6.6.0/lib/factory_bot/find_definitions.rb +25 -0
- data/factory_bot-6.6.0/lib/factory_bot/internal.rb +124 -0
- data/factory_bot-6.6.0/lib/factory_bot/linter.rb +121 -0
- data/factory_bot-6.6.0/lib/factory_bot/null_factory.rb +27 -0
- data/factory_bot-6.6.0/lib/factory_bot/null_object.rb +20 -0
- data/factory_bot-6.6.0/lib/factory_bot/registry.rb +59 -0
- data/factory_bot-6.6.0/lib/factory_bot/reload.rb +7 -0
- data/factory_bot-6.6.0/lib/factory_bot/sequence.rb +197 -0
- data/factory_bot-6.6.0/lib/factory_bot/strategy/attributes_for.rb +17 -0
- data/factory_bot-6.6.0/lib/factory_bot/strategy/build.rb +21 -0
- data/factory_bot-6.6.0/lib/factory_bot/strategy/create.rb +24 -0
- data/factory_bot-6.6.0/lib/factory_bot/strategy/null.rb +15 -0
- data/factory_bot-6.6.0/lib/factory_bot/strategy/stub.rb +129 -0
- data/factory_bot-6.6.0/lib/factory_bot/strategy.rb +15 -0
- data/factory_bot-6.6.0/lib/factory_bot/strategy_syntax_method_registrar.rb +65 -0
- data/factory_bot-6.6.0/lib/factory_bot/syntax/default.rb +64 -0
- data/factory_bot-6.6.0/lib/factory_bot/syntax/methods.rb +181 -0
- data/factory_bot-6.6.0/lib/factory_bot/syntax.rb +7 -0
- data/factory_bot-6.6.0/lib/factory_bot/syntax_runner.rb +6 -0
- data/factory_bot-6.6.0/lib/factory_bot/trait.rb +39 -0
- data/factory_bot-6.6.0/lib/factory_bot/uri_manager.rb +63 -0
- data/factory_bot-6.6.0/lib/factory_bot/version.rb +3 -0
- data/factory_bot-6.6.0/lib/factory_bot.rb +117 -0
- data/tiny-lite-mod.gemspec +12 -0
- metadata +101 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require "active_support/hash_with_indifferent_access"
|
|
2
|
+
|
|
3
|
+
module FactoryBot
|
|
4
|
+
class Registry
|
|
5
|
+
include Enumerable
|
|
6
|
+
|
|
7
|
+
attr_reader :name
|
|
8
|
+
|
|
9
|
+
def initialize(name)
|
|
10
|
+
@name = name
|
|
11
|
+
@items = ActiveSupport::HashWithIndifferentAccess.new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def clear
|
|
15
|
+
@items.clear
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def each(&block)
|
|
19
|
+
@items.values.uniq.each(&block)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def find(name)
|
|
23
|
+
@items.fetch(name)
|
|
24
|
+
rescue KeyError => e
|
|
25
|
+
raise key_error_with_custom_message(e)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
alias_method :[], :find
|
|
29
|
+
|
|
30
|
+
def register(name, item)
|
|
31
|
+
@items[name] = item
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def registered?(name)
|
|
35
|
+
@items.key?(name)
|
|
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
|
+
new_key_error(message, key_error).tap do |error|
|
|
43
|
+
error.set_backtrace(key_error.backtrace)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# detailed_message introduced in Ruby 3.2 for cleaner integration with
|
|
48
|
+
# did_you_mean. See https://bugs.ruby-lang.org/issues/18564
|
|
49
|
+
if KeyError.method_defined?(:detailed_message)
|
|
50
|
+
def new_key_error(message, key_error)
|
|
51
|
+
KeyError.new(message, key: key_error.key, receiver: key_error.receiver)
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
def new_key_error(message, _)
|
|
55
|
+
KeyError.new(message)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
require "timeout"
|
|
2
|
+
|
|
3
|
+
module FactoryBot
|
|
4
|
+
# Sequences are defined using sequence within a FactoryBot.define block.
|
|
5
|
+
# Sequence values are generated using next.
|
|
6
|
+
# @api private
|
|
7
|
+
class Sequence
|
|
8
|
+
attr_reader :name, :uri_manager, :aliases
|
|
9
|
+
|
|
10
|
+
def self.find(*uri_parts)
|
|
11
|
+
if uri_parts.empty?
|
|
12
|
+
fail ArgumentError, "wrong number of arguments, expected 1+)"
|
|
13
|
+
else
|
|
14
|
+
find_by_uri FactoryBot::UriManager.build_uri(*uri_parts)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.find_by_uri(uri)
|
|
19
|
+
uri = uri.to_sym
|
|
20
|
+
FactoryBot::Internal.sequences.to_a.find { |seq| seq.has_uri?(uri) } ||
|
|
21
|
+
FactoryBot::Internal.inline_sequences.find { |seq| seq.has_uri?(uri) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def initialize(name, *args, &proc)
|
|
25
|
+
options = args.extract_options!
|
|
26
|
+
@name = name
|
|
27
|
+
@proc = proc
|
|
28
|
+
@aliases = options.fetch(:aliases, []).map(&:to_sym)
|
|
29
|
+
@uri_manager = FactoryBot::UriManager.new(names, paths: options[:uri_paths])
|
|
30
|
+
@value = args.first || 1
|
|
31
|
+
|
|
32
|
+
unless @value.respond_to?(:peek)
|
|
33
|
+
@value = EnumeratorAdapter.new(@value)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def next(scope = nil)
|
|
38
|
+
if @proc && scope
|
|
39
|
+
scope.instance_exec(value, &@proc)
|
|
40
|
+
elsif @proc
|
|
41
|
+
@proc.call(value)
|
|
42
|
+
else
|
|
43
|
+
value
|
|
44
|
+
end
|
|
45
|
+
ensure
|
|
46
|
+
increment_value
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def names
|
|
50
|
+
[@name] + @aliases
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def has_name?(test_name)
|
|
54
|
+
names.include?(test_name.to_sym)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def has_uri?(uri)
|
|
58
|
+
uri_manager.include?(uri)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def for_factory?(test_factory_name)
|
|
62
|
+
FactoryBot::Internal.factory_by_name(factory_name).names.include?(test_factory_name.to_sym)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def rewind
|
|
66
|
+
@value.rewind
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
##
|
|
70
|
+
# If it's an Integer based sequence, set the new value directly,
|
|
71
|
+
# else rewind and seek from the beginning until a match is found.
|
|
72
|
+
#
|
|
73
|
+
def set_value(new_value)
|
|
74
|
+
if can_set_value_directly?(new_value)
|
|
75
|
+
@value.set_value(new_value)
|
|
76
|
+
elsif can_set_value_by_index?
|
|
77
|
+
set_value_by_index(new_value)
|
|
78
|
+
else
|
|
79
|
+
seek_value(new_value)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
protected
|
|
84
|
+
|
|
85
|
+
attr_reader :proc
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
def value
|
|
90
|
+
@value.peek
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def increment_value
|
|
94
|
+
@value.next
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def can_set_value_by_index?
|
|
98
|
+
@value.respond_to?(:find_index)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
##
|
|
102
|
+
# Set to the given value, or fail if not found
|
|
103
|
+
#
|
|
104
|
+
def set_value_by_index(value)
|
|
105
|
+
index = @value.find_index(value) || fail_value_not_found(value)
|
|
106
|
+
@value.rewind
|
|
107
|
+
index.times { @value.next }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
##
|
|
111
|
+
# Rewind index and seek until the value is found or the max attempts
|
|
112
|
+
# have been tried. If not found, the sequence is rewound to its original value
|
|
113
|
+
#
|
|
114
|
+
def seek_value(value)
|
|
115
|
+
original_value = @value.peek
|
|
116
|
+
|
|
117
|
+
# rewind and search for the new value
|
|
118
|
+
@value.rewind
|
|
119
|
+
Timeout.timeout(FactoryBot.sequence_setting_timeout) do
|
|
120
|
+
loop do
|
|
121
|
+
return if @value.peek == value
|
|
122
|
+
increment_value
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# loop auto-recues a StopIteration error, so if we
|
|
126
|
+
# reached this point, re-raise it now
|
|
127
|
+
fail StopIteration
|
|
128
|
+
end
|
|
129
|
+
rescue Timeout::Error, StopIteration
|
|
130
|
+
reset_original_value(original_value)
|
|
131
|
+
fail_value_not_found(value)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def reset_original_value(original_value)
|
|
135
|
+
@value.rewind
|
|
136
|
+
|
|
137
|
+
until @value.peek == original_value
|
|
138
|
+
increment_value
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def can_set_value_directly?(value)
|
|
143
|
+
return false unless value.is_a?(Integer)
|
|
144
|
+
return false unless @value.is_a?(EnumeratorAdapter)
|
|
145
|
+
@value.integer_value?
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def fail_value_not_found(value)
|
|
149
|
+
fail ArgumentError, "Unable to find '#{value}' in the sequence."
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
class EnumeratorAdapter
|
|
153
|
+
def initialize(initial_value)
|
|
154
|
+
@initial_value = initial_value
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def peek
|
|
158
|
+
value
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def next
|
|
162
|
+
@value = value.next
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def rewind
|
|
166
|
+
@value = first_value
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def set_value(new_value)
|
|
170
|
+
if new_value >= first_value
|
|
171
|
+
@value = new_value
|
|
172
|
+
else
|
|
173
|
+
fail ArgumentError, "Value cannot be less than: #{@first_value}"
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def integer_value?
|
|
178
|
+
first_value.is_a?(Integer)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
private
|
|
182
|
+
|
|
183
|
+
def first_value
|
|
184
|
+
@first_value ||= initial_value
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def value
|
|
188
|
+
@value ||= initial_value
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def initial_value
|
|
192
|
+
@value = @initial_value.respond_to?(:call) ? @initial_value.call : @initial_value
|
|
193
|
+
@first_value = @value
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module FactoryBot
|
|
2
|
+
module Strategy
|
|
3
|
+
class Build
|
|
4
|
+
def association(runner)
|
|
5
|
+
runner.run
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def result(evaluation)
|
|
9
|
+
evaluation.notify(:before_build, nil)
|
|
10
|
+
|
|
11
|
+
evaluation.object.tap do |instance|
|
|
12
|
+
evaluation.notify(:after_build, instance)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def to_sym
|
|
17
|
+
:build
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module FactoryBot
|
|
2
|
+
module Strategy
|
|
3
|
+
class Create
|
|
4
|
+
def association(runner)
|
|
5
|
+
runner.run
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def result(evaluation)
|
|
9
|
+
evaluation.notify(:before_build, nil)
|
|
10
|
+
|
|
11
|
+
evaluation.object.tap do |instance|
|
|
12
|
+
evaluation.notify(:after_build, instance)
|
|
13
|
+
evaluation.notify(:before_create, instance)
|
|
14
|
+
evaluation.create(instance)
|
|
15
|
+
evaluation.notify(:after_create, instance)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_sym
|
|
20
|
+
:create
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
module FactoryBot
|
|
2
|
+
module Strategy
|
|
3
|
+
class Stub
|
|
4
|
+
@@next_id = 1000
|
|
5
|
+
|
|
6
|
+
DISABLED_PERSISTENCE_METHODS = [
|
|
7
|
+
:connection,
|
|
8
|
+
:decrement!,
|
|
9
|
+
:delete,
|
|
10
|
+
:destroy!,
|
|
11
|
+
:destroy,
|
|
12
|
+
:increment!,
|
|
13
|
+
:reload,
|
|
14
|
+
:save!,
|
|
15
|
+
:save,
|
|
16
|
+
:toggle!,
|
|
17
|
+
:touch,
|
|
18
|
+
:update!,
|
|
19
|
+
:update,
|
|
20
|
+
:update_attribute,
|
|
21
|
+
:update_attributes!,
|
|
22
|
+
:update_attributes,
|
|
23
|
+
:update_column,
|
|
24
|
+
:update_columns
|
|
25
|
+
].freeze
|
|
26
|
+
|
|
27
|
+
def self.next_id=(id)
|
|
28
|
+
@@next_id = id
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def association(runner)
|
|
32
|
+
runner.run(:build_stubbed)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def result(evaluation)
|
|
36
|
+
evaluation.object.tap do |instance|
|
|
37
|
+
stub_database_interaction_on_result(instance)
|
|
38
|
+
set_timestamps(instance)
|
|
39
|
+
clear_changes_information(instance)
|
|
40
|
+
evaluation.notify(:after_stub, instance)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def to_sym
|
|
45
|
+
:stub
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def next_id(result_instance)
|
|
51
|
+
if uuid_primary_key?(result_instance)
|
|
52
|
+
SecureRandom.uuid
|
|
53
|
+
else
|
|
54
|
+
@@next_id += 1
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def stub_database_interaction_on_result(result_instance)
|
|
59
|
+
if has_settable_id?(result_instance)
|
|
60
|
+
result_instance.id ||= next_id(result_instance)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
result_instance.instance_eval do
|
|
64
|
+
def persisted?
|
|
65
|
+
true
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def new_record?
|
|
69
|
+
false
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def destroyed?
|
|
73
|
+
false
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
DISABLED_PERSISTENCE_METHODS.each do |write_method|
|
|
77
|
+
define_singleton_method(write_method) do |*args|
|
|
78
|
+
raise "stubbed models are not allowed to access the database - " \
|
|
79
|
+
"#{self.class}##{write_method}(#{args.join(",")})"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def has_settable_id?(result_instance)
|
|
86
|
+
result_instance.respond_to?(:id=) &&
|
|
87
|
+
(!result_instance.class.respond_to?(:primary_key) ||
|
|
88
|
+
result_instance.class.primary_key)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def uuid_primary_key?(result_instance)
|
|
92
|
+
result_instance.respond_to?(:column_for_attribute) &&
|
|
93
|
+
(column = result_instance.column_for_attribute(result_instance.class.primary_key)) &&
|
|
94
|
+
column.respond_to?(:sql_type) &&
|
|
95
|
+
column.sql_type == "uuid"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def clear_changes_information(result_instance)
|
|
99
|
+
if result_instance.respond_to?(:clear_changes_information)
|
|
100
|
+
result_instance.clear_changes_information
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def set_timestamps(result_instance)
|
|
105
|
+
timestamp = Time.current
|
|
106
|
+
|
|
107
|
+
if missing_created_at?(result_instance)
|
|
108
|
+
result_instance.created_at = timestamp
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
if missing_updated_at?(result_instance)
|
|
112
|
+
result_instance.updated_at = timestamp
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def missing_created_at?(result_instance)
|
|
117
|
+
result_instance.respond_to?(:created_at) &&
|
|
118
|
+
result_instance.respond_to?(:created_at=) &&
|
|
119
|
+
result_instance.created_at.blank?
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def missing_updated_at?(result_instance)
|
|
123
|
+
result_instance.respond_to?(:updated_at) &&
|
|
124
|
+
result_instance.respond_to?(:updated_at=) &&
|
|
125
|
+
result_instance.updated_at.blank?
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require "factory_bot/strategy/build"
|
|
2
|
+
require "factory_bot/strategy/create"
|
|
3
|
+
require "factory_bot/strategy/attributes_for"
|
|
4
|
+
require "factory_bot/strategy/stub"
|
|
5
|
+
require "factory_bot/strategy/null"
|
|
6
|
+
|
|
7
|
+
module FactoryBot
|
|
8
|
+
module Strategy
|
|
9
|
+
def self.lookup_strategy(name_or_object)
|
|
10
|
+
return name_or_object if name_or_object.is_a?(Class)
|
|
11
|
+
|
|
12
|
+
FactoryBot::Internal.strategy_by_name(name_or_object)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module FactoryBot
|
|
2
|
+
# @api private
|
|
3
|
+
class StrategySyntaxMethodRegistrar
|
|
4
|
+
def initialize(strategy_name)
|
|
5
|
+
@strategy_name = strategy_name
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def define_strategy_methods
|
|
9
|
+
define_singular_strategy_method
|
|
10
|
+
define_list_strategy_method
|
|
11
|
+
define_pair_strategy_method
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.with_index(block, index)
|
|
15
|
+
if block&.arity == 2
|
|
16
|
+
->(instance) { block.call(instance, index) }
|
|
17
|
+
else
|
|
18
|
+
block
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def define_singular_strategy_method
|
|
25
|
+
strategy_name = @strategy_name
|
|
26
|
+
|
|
27
|
+
define_syntax_method(strategy_name) do |name, *traits_and_overrides, &block|
|
|
28
|
+
FactoryRunner.new(name, strategy_name, traits_and_overrides).run(&block)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def define_list_strategy_method
|
|
33
|
+
strategy_name = @strategy_name
|
|
34
|
+
|
|
35
|
+
define_syntax_method("#{strategy_name}_list") do |name, amount, *traits_and_overrides, &block|
|
|
36
|
+
unless amount.respond_to?(:times)
|
|
37
|
+
raise ArgumentError, "count missing for #{strategy_name}_list"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
Array.new(amount) do |i|
|
|
41
|
+
block_with_index = StrategySyntaxMethodRegistrar.with_index(block, i)
|
|
42
|
+
send(strategy_name, name, *traits_and_overrides, &block_with_index)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def define_pair_strategy_method
|
|
48
|
+
strategy_name = @strategy_name
|
|
49
|
+
|
|
50
|
+
define_syntax_method("#{strategy_name}_pair") do |name, *traits_and_overrides, &block|
|
|
51
|
+
Array.new(2) { send(strategy_name, name, *traits_and_overrides, &block) }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def define_syntax_method(name, &block)
|
|
56
|
+
FactoryBot::Syntax::Methods.module_exec do
|
|
57
|
+
if method_defined?(name) || private_method_defined?(name)
|
|
58
|
+
undef_method(name)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
define_method(name, &block)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module FactoryBot
|
|
2
|
+
module Syntax
|
|
3
|
+
module Default
|
|
4
|
+
include Methods
|
|
5
|
+
|
|
6
|
+
def define(&block)
|
|
7
|
+
DSL.run(block)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def modify(&block)
|
|
11
|
+
ModifyDSL.run(block)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class DSL
|
|
15
|
+
def factory(name, options = {}, &block)
|
|
16
|
+
factory = Factory.new(name, options)
|
|
17
|
+
proxy = FactoryBot::DefinitionProxy.new(factory.definition)
|
|
18
|
+
proxy.instance_eval(&block) if block
|
|
19
|
+
|
|
20
|
+
Internal.register_factory(factory)
|
|
21
|
+
|
|
22
|
+
proxy.child_factories.each do |(child_name, child_options, child_block)|
|
|
23
|
+
parent_factory = child_options.delete(:parent) || name
|
|
24
|
+
factory(child_name, child_options.merge(parent: parent_factory), &child_block)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def sequence(name, ...)
|
|
29
|
+
Internal.register_sequence(Sequence.new(name, ...))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def trait(name, &block)
|
|
33
|
+
Internal.register_trait(Trait.new(name, &block))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.run(block)
|
|
37
|
+
new.instance_eval(&block)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
delegate :after,
|
|
41
|
+
:before,
|
|
42
|
+
:callback,
|
|
43
|
+
:initialize_with,
|
|
44
|
+
:skip_create,
|
|
45
|
+
:to_create,
|
|
46
|
+
to: FactoryBot::Internal
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class ModifyDSL
|
|
50
|
+
def factory(name, _options = {}, &block)
|
|
51
|
+
factory = Internal.factory_by_name(name)
|
|
52
|
+
proxy = FactoryBot::DefinitionProxy.new(factory.definition.overridable)
|
|
53
|
+
proxy.instance_eval(&block)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.run(block)
|
|
57
|
+
new.instance_eval(&block)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
extend Syntax::Default
|
|
64
|
+
end
|