Skip to content

Commit a5b6686

Browse files
committed
Code review feedback
1 parent 77af14f commit a5b6686

16 files changed

+324
-740
lines changed

docs/src/sequences/setting-the-value.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ generate(:user, :with_email, :email) # "user_1234567@example.com"
4848

4949
- A fixed collection sequence can accept any value within the collection.
5050

51-
- An unlimited sequence, such as a charcter `sequence(:unlimited,'a')` will timeout if not found within the default maximum search time of three seconds.
51+
- An unlimited sequence, such as a character `sequence(:unlimited,'a')` will timeout if not found within the default maximum search time of three seconds.
5252

53-
- The timeout can be set with: `ENV["FACTORY_BOT_SET_SEQUENCE_TIMEOUT"] = "1.5"`
53+
- The timeout can be configured with: `FactoryBot.sequence_setting_timeout = 1.5`
5454

5555
</div>

lib/factory_bot.rb

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ module FactoryBot
5959
mattr_accessor :automatically_define_enum_traits, instance_accessor: false
6060
self.automatically_define_enum_traits = true
6161

62+
mattr_accessor :sequence_setting_timeout, instance_accessor: false
63+
self.sequence_setting_timeout = 3
64+
6265
# Look for errors in factories and (optionally) their traits.
6366
# Parameters:
6467
# factories - which factories to lint; omit for all factories
@@ -74,14 +77,38 @@ def self.lint(*args)
7477

7578
# Set the starting value for ids when using the build_stubbed strategy
7679
#
77-
# Arguments:
78-
# * starting_id +Integer+
79-
# The new starting id value.
80+
# @param [Integer] starting_id The new starting id value.
8081
def self.build_stubbed_starting_id=(starting_id)
8182
Strategy::Stub.next_id = starting_id - 1
8283
end
8384

8485
class << self
86+
# @!method rewind_sequence(*uri_parts)
87+
# Rewind an individual global or inline sequence.
88+
#
89+
# @param [Array<Symbol>, String] uri_parts The components of the sequence URI.
90+
#
91+
# @example Rewinding a sequence by its URI parts
92+
# rewind_sequence(:factory_name, :trait_name, :sequence_name)
93+
#
94+
# @example Rewinding a sequence by its URI string
95+
# rewind_sequence("factory_name/trait_name/sequence_name")
96+
#
97+
# @!method set_sequence(*uri_parts, value)
98+
# Set the sequence to a specific value, providing the new value is within
99+
# the sequence set.
100+
#
101+
# @param [Array<Symbol>, String] uri_parts The components of the sequence URI.
102+
# @param [Object] value The new value for the sequence. This must be a value that is
103+
# within the sequence definition. For example, you cannot set
104+
# a String sequence to an Integer value.
105+
#
106+
# @example
107+
# set_sequence(:factory_name, :trait_name, :sequence_name, 450)
108+
# @example
109+
# set_sequence([:factory_name, :trait_name, :sequence_name], 450)
110+
# @example
111+
# set_sequence("factory_name/trait_name/sequence_name", 450)
85112
delegate :factories,
86113
:register_strategy,
87114
:rewind_sequences,

lib/factory_bot/definition.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
module FactoryBot
22
# @api private
33
class Definition
4-
attr_reader :defined_traits, :declarations, :name, :registered_enums, :uri_mgr
4+
attr_reader :defined_traits, :declarations, :name, :registered_enums, :uri_manager
55
attr_accessor :klass
66

77
def initialize(name, base_traits = [], **opts)
88
@name = name
9-
@uri_mgr = opts[:uri_mgr]
9+
@uri_manager = opts[:uri_manager]
1010
@declarations = DeclarationList.new(name)
1111
@callbacks = []
1212
@defined_traits = Set.new

lib/factory_bot/definition_proxy.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def method_missing(name, *args, &block) # rubocop:disable Style/MissingRespondTo
121121
# Except that no globally available sequence will be defined.
122122
def sequence(name, *args, &block)
123123
options = args.extract_options!
124-
options[:uri_paths] = definition.uri_mgr.to_a
124+
options[:uri_paths] = definition.uri_manager.to_a
125125
args << options
126126

127127
new_sequence = Sequence.new(name, *args, &block)
@@ -177,7 +177,7 @@ def factory(name, options = {}, &block)
177177
end
178178

179179
def trait(name, &block)
180-
@definition.define_trait(Trait.new(name, uri_paths: definition.uri_mgr.to_a, &block))
180+
@definition.define_trait(Trait.new(name, uri_paths: definition.uri_manager.to_a, &block))
181181
end
182182

183183
# Creates traits for enumerable values.
@@ -262,7 +262,7 @@ def __valid_association_options?(options)
262262
# return that one, otherwise register and return the given sequence
263263
#
264264
def __fetch_or_register_sequence(sequence)
265-
FactoryBot::Sequence.find_by_uri(sequence.uri_mgr.first) ||
265+
FactoryBot::Sequence.find_by_uri(sequence.uri_manager.first) ||
266266
FactoryBot::Internal.register_inline_sequence(sequence)
267267
end
268268
end

lib/factory_bot/factory.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ def initialize(name, options = {})
1212
@parent = options[:parent]
1313
@aliases = options[:aliases] || []
1414
@class_name = options[:class]
15-
@uri_mgr = FactoryBot::UriManager.new(names)
16-
@definition = Definition.new(@name, options[:traits] || [], uri_mgr: @uri_mgr)
15+
@uri_manager = FactoryBot::UriManager.new(names)
16+
@definition = Definition.new(@name, options[:traits] || [], uri_manager: @uri_manager)
1717
@compiled = false
1818
end
1919

lib/factory_bot/internal.rb

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,6 @@ def rewind_sequences
6060
rewind_inline_sequences
6161
end
6262

63-
##
64-
# Rewind an individual global or inline sequence.
65-
#
66-
# Arguments:
67-
# uri_parts: (Array of Symbols)
68-
# The components of the sequence URI
69-
#
70-
# Example:
71-
# rewind_sequence(:factory_name, :trait_name, :sequence_name)
72-
# or
73-
# rewind_sequence("factory_name/trait_name/sequence_name")
74-
#
7563
def rewind_sequence(*uri_parts)
7664
fail_argument_count(0, "1+") if uri_parts.empty?
7765

@@ -81,25 +69,6 @@ def rewind_sequence(*uri_parts)
8169
sequence.rewind
8270
end
8371

84-
##
85-
# Set the squence to a specific value, providing the new value is
86-
# within the sequence set.
87-
#
88-
# Arguments:
89-
# uri_parts: (Array of Symbols)
90-
# The URI components of the sequence
91-
# value: (Object)
92-
# The new value for the sequence. This must be a value that is
93-
# within the sequence definition. For example, you cannot set
94-
# a String sequence to an Integer value.
95-
#
96-
# Example:
97-
# set_sequence(:factory_name, :trait_name, :sequence_name, 450)
98-
# or
99-
# set_sequence([:factory_name, :trait_name, :sequence_name], 450)
100-
# or
101-
# set_sequence("factory_name/trait_name/sequence_name", 450)
102-
#
10372
def set_sequence(*uri_parts, value)
10473
uri = build_uri(uri_parts) || fail_argument_count(uri_parts.size, "2+")
10574
sequence = Sequence.find(*uri) || fail_unregistered_sequence(uri)
@@ -135,10 +104,6 @@ def register_default_strategies
135104
register_strategy(:null, FactoryBot::Strategy::Null)
136105
end
137106

138-
# ======================================================================
139-
# = PRIVATE
140-
# ======================================================================
141-
#
142107
private
143108

144109
def build_uri(...)

lib/factory_bot/sequence.rb

Lines changed: 28 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,8 @@ module FactoryBot
55
# Sequence values are generated using next.
66
# @api private
77
class Sequence
8-
attr_reader :name, :uri_mgr, :aliases
8+
attr_reader :name, :uri_manager, :aliases
99

10-
@sequence_setting_timeout = nil
11-
12-
# = Class Methods
13-
# ======================================================================
14-
15-
##
16-
# Find a sequence by context and name.
17-
#
18-
# Arguments:
19-
# uri_parts: (Array of Strings or Symbols)
20-
# comprises the sequence URI parts
21-
#
22-
# Example:
23-
# Sequence.find :my_factory, :my_trait, :my_sequence
24-
#
2510
def self.find(*uri_parts)
2611
if uri_parts.empty?
2712
fail ArgumentError, "wrong number of arguments, expected 1+)"
@@ -30,42 +15,18 @@ def self.find(*uri_parts)
3015
end
3116
end
3217

33-
##
34-
# Find a sequence by URI. Searches both Global and inline sequences.
35-
#
36-
# Arguments:
37-
# uri: (Symbol)
38-
# The uri name to search for
39-
#
4018
def self.find_by_uri(uri)
4119
uri = uri.to_sym
4220
(FactoryBot::Internal.sequences.to_a.find { |seq| seq.has_uri?(uri) }) ||
4321
(FactoryBot::Internal.inline_sequences.find { |seq| seq.has_uri?(uri) })
4422
end
4523

46-
##
47-
# Returns the number of seconds to allow for setting sequence.
48-
# Defaults to 3 seconds, but can be overriden with an
49-
# environment variable 'FACTORY_BOT_SET_SEQUENCE_TIMEOUT'
50-
#
51-
def self.sequence_setting_timeout
52-
@sequence_setting_timeout ||= begin
53-
user_time = ENV["FACTORY_BOT_SET_SEQUENCE_TIMEOUT"].to_f
54-
(user_time >= 0.1) ? user_time : 3
55-
rescue
56-
3
57-
end
58-
end
59-
60-
# = Instance Methods
61-
# ======================================================================
62-
6324
def initialize(name, *args, &proc)
6425
options = args.extract_options!
6526
@name = name
6627
@proc = proc
6728
@aliases = options.fetch(:aliases, []).map(&:to_sym)
68-
@uri_mgr = FactoryBot::UriManager.new(names, paths: options[:uri_paths])
29+
@uri_manager = FactoryBot::UriManager.new(names, paths: options[:uri_paths])
6930
@value = args.first || 1
7031

7132
unless @value.respond_to?(:peek)
@@ -94,7 +55,7 @@ def has_name?(test_name)
9455
end
9556

9657
def has_uri?(uri)
97-
uri_mgr.include?(uri)
58+
uri_manager.include?(uri)
9859
end
9960

10061
def for_factory?(test_factory_name)
@@ -109,13 +70,13 @@ def rewind
10970
# If it's an Integer based sequence, set the new value directly,
11071
# else rewind and seek from the beginning until a match is found.
11172
#
112-
def set_value(new_val)
113-
if can_set_value_directly?(new_val)
114-
@value.set_value(new_val)
73+
def set_value(new_value)
74+
if can_set_value_directly?(new_value)
75+
@value.set_value(new_value)
11576
elsif can_set_value_by_index?
116-
set_value_by_index(new_val)
77+
set_value_by_index(new_value)
11778
else
118-
seek_value(new_val)
79+
seek_value(new_value)
11980
end
12081
end
12182

@@ -138,10 +99,10 @@ def can_set_value_by_index?
13899
end
139100

140101
##
141-
# Set to the given val, or fail if not found
102+
# Set to the given value, or fail if not found
142103
#
143-
def set_value_by_index(val)
144-
index = @value.find_index(val) || fail_value_not_found(val)
104+
def set_value_by_index(value)
105+
index = @value.find_index(value) || fail_value_not_found(value)
145106
@value.rewind
146107
index.times { @value.next }
147108
end
@@ -150,14 +111,14 @@ def set_value_by_index(val)
150111
# Rewind index and seek until the value is found or the max attempts
151112
# have been tried. If not found, the sequence is rewound to its original value
152113
#
153-
def seek_value(val)
114+
def seek_value(value)
154115
original_value = @value.peek
155116

156117
# rewind and search for the new value
157118
@value.rewind
158-
Timeout.timeout(Sequence.sequence_setting_timeout) do
119+
Timeout.timeout(FactoryBot.sequence_setting_timeout) do
159120
loop do
160-
return if @value.peek == val
121+
return if @value.peek == value
161122
increment_value
162123
end
163124

@@ -166,23 +127,26 @@ def seek_value(val)
166127
fail StopIteration
167128
end
168129
rescue Timeout::Error, StopIteration
169-
reset_originl_value(original_value)
170-
fail_value_not_found(val)
130+
reset_original_value(original_value)
131+
fail_value_not_found(value)
171132
end
172133

173-
def reset_originl_value(original_value)
134+
def reset_original_value(original_value)
174135
@value.rewind
175-
until @value.peek == original_value do increment_value end
136+
137+
until @value.peek == original_value
138+
increment_value
139+
end
176140
end
177141

178-
def can_set_value_directly?(val)
179-
return false unless val.is_a?(Integer)
142+
def can_set_value_directly?(value)
143+
return false unless value.is_a?(Integer)
180144
return false unless @value.is_a?(EnumeratorAdapter)
181145
@value.integer_value?
182146
end
183147

184-
def fail_value_not_found(val)
185-
fail ArgumentError, "Unable to find '#{val}' in the sequence."
148+
def fail_value_not_found(value)
149+
fail ArgumentError, "Unable to find '#{value}' in the sequence."
186150
end
187151

188152
class EnumeratorAdapter
@@ -203,9 +167,9 @@ def rewind
203167
@value = @first_value
204168
end
205169

206-
def set_value(new_val)
207-
if new_val >= @first_value
208-
@value = new_val
170+
def set_value(new_value)
171+
if new_value >= @first_value
172+
@value = new_value
209173
else
210174
fail ArgumentError, "Value cannot be less than: #{@first_value}"
211175
end

lib/factory_bot/trait.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ class Trait
99
def initialize(name, **options, &block)
1010
@name = name.to_s
1111
@block = block
12-
@uri_mgr = FactoryBot::UriManager.new(names, paths: options[:uri_paths])
12+
@uri_manager = FactoryBot::UriManager.new(names, paths: options[:uri_paths])
1313

14-
@definition = Definition.new(@name, uri_mgr: @uri_mgr)
14+
@definition = Definition.new(@name, uri_manager: @uri_manager)
1515
proxy = FactoryBot::DefinitionProxy.new(@definition)
1616

1717
if block
@@ -20,7 +20,7 @@ def initialize(name, **options, &block)
2020
end
2121

2222
def clone
23-
Trait.new(name, uri_paths: definition.uri_mgr.paths, &block)
23+
Trait.new(name, uri_paths: definition.uri_manager.paths, &block)
2424
end
2525

2626
def names

0 commit comments

Comments
 (0)