sspec-core 3.8.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 +7 -0
- data/.document +5 -0
- data/.yardopts +8 -0
- data/Changelog.md +2232 -0
- data/LICENSE.md +26 -0
- data/README.md +384 -0
- data/exe/rspec +4 -0
- data/lib/rspec/autorun.rb +3 -0
- data/lib/rspec/core.rb +185 -0
- data/lib/rspec/core/backtrace_formatter.rb +65 -0
- data/lib/rspec/core/bisect/coordinator.rb +62 -0
- data/lib/rspec/core/bisect/example_minimizer.rb +173 -0
- data/lib/rspec/core/bisect/fork_runner.rb +134 -0
- data/lib/rspec/core/bisect/server.rb +61 -0
- data/lib/rspec/core/bisect/shell_command.rb +126 -0
- data/lib/rspec/core/bisect/shell_runner.rb +73 -0
- data/lib/rspec/core/bisect/utilities.rb +58 -0
- data/lib/rspec/core/configuration.rb +2289 -0
- data/lib/rspec/core/configuration_options.rb +233 -0
- data/lib/rspec/core/drb.rb +113 -0
- data/lib/rspec/core/dsl.rb +98 -0
- data/lib/rspec/core/example.rb +653 -0
- data/lib/rspec/core/example_group.rb +885 -0
- data/lib/rspec/core/example_status_persister.rb +235 -0
- data/lib/rspec/core/filter_manager.rb +231 -0
- data/lib/rspec/core/flat_map.rb +20 -0
- data/lib/rspec/core/formatters.rb +269 -0
- data/lib/rspec/core/formatters/base_bisect_formatter.rb +45 -0
- data/lib/rspec/core/formatters/base_formatter.rb +70 -0
- data/lib/rspec/core/formatters/base_text_formatter.rb +75 -0
- data/lib/rspec/core/formatters/bisect_drb_formatter.rb +29 -0
- data/lib/rspec/core/formatters/bisect_progress_formatter.rb +157 -0
- data/lib/rspec/core/formatters/console_codes.rb +68 -0
- data/lib/rspec/core/formatters/deprecation_formatter.rb +223 -0
- data/lib/rspec/core/formatters/documentation_formatter.rb +70 -0
- data/lib/rspec/core/formatters/exception_presenter.rb +508 -0
- data/lib/rspec/core/formatters/fallback_message_formatter.rb +28 -0
- data/lib/rspec/core/formatters/helpers.rb +110 -0
- data/lib/rspec/core/formatters/html_formatter.rb +153 -0
- data/lib/rspec/core/formatters/html_printer.rb +414 -0
- data/lib/rspec/core/formatters/html_snippet_extractor.rb +120 -0
- data/lib/rspec/core/formatters/json_formatter.rb +102 -0
- data/lib/rspec/core/formatters/profile_formatter.rb +68 -0
- data/lib/rspec/core/formatters/progress_formatter.rb +29 -0
- data/lib/rspec/core/formatters/protocol.rb +182 -0
- data/lib/rspec/core/formatters/snippet_extractor.rb +134 -0
- data/lib/rspec/core/formatters/syntax_highlighter.rb +91 -0
- data/lib/rspec/core/hooks.rb +624 -0
- data/lib/rspec/core/invocations.rb +87 -0
- data/lib/rspec/core/memoized_helpers.rb +554 -0
- data/lib/rspec/core/metadata.rb +499 -0
- data/lib/rspec/core/metadata_filter.rb +255 -0
- data/lib/rspec/core/minitest_assertions_adapter.rb +31 -0
- data/lib/rspec/core/mocking_adapters/flexmock.rb +31 -0
- data/lib/rspec/core/mocking_adapters/mocha.rb +57 -0
- data/lib/rspec/core/mocking_adapters/null.rb +14 -0
- data/lib/rspec/core/mocking_adapters/rr.rb +31 -0
- data/lib/rspec/core/mocking_adapters/rspec.rb +32 -0
- data/lib/rspec/core/notifications.rb +521 -0
- data/lib/rspec/core/option_parser.rb +309 -0
- data/lib/rspec/core/ordering.rb +158 -0
- data/lib/rspec/core/output_wrapper.rb +29 -0
- data/lib/rspec/core/pending.rb +165 -0
- data/lib/rspec/core/profiler.rb +34 -0
- data/lib/rspec/core/project_initializer.rb +48 -0
- data/lib/rspec/core/project_initializer/.rspec +1 -0
- data/lib/rspec/core/project_initializer/spec/spec_helper.rb +100 -0
- data/lib/rspec/core/rake_task.rb +168 -0
- data/lib/rspec/core/reporter.rb +257 -0
- data/lib/rspec/core/ruby_project.rb +53 -0
- data/lib/rspec/core/runner.rb +199 -0
- data/lib/rspec/core/sandbox.rb +37 -0
- data/lib/rspec/core/set.rb +54 -0
- data/lib/rspec/core/shared_context.rb +55 -0
- data/lib/rspec/core/shared_example_group.rb +269 -0
- data/lib/rspec/core/shell_escape.rb +49 -0
- data/lib/rspec/core/test_unit_assertions_adapter.rb +30 -0
- data/lib/rspec/core/version.rb +9 -0
- data/lib/rspec/core/warnings.rb +40 -0
- data/lib/rspec/core/world.rb +275 -0
- metadata +257 -0
@@ -0,0 +1,309 @@
|
|
1
|
+
# http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
module RSpec::Core
|
5
|
+
# @private
|
6
|
+
class Parser
|
7
|
+
def self.parse(args, source=nil)
|
8
|
+
new(args).parse(source)
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :original_args
|
12
|
+
|
13
|
+
def initialize(original_args)
|
14
|
+
@original_args = original_args
|
15
|
+
end
|
16
|
+
|
17
|
+
def parse(source=nil)
|
18
|
+
return { :files_or_directories_to_run => [] } if original_args.empty?
|
19
|
+
args = original_args.dup
|
20
|
+
|
21
|
+
options = args.delete('--tty') ? { :tty => true } : {}
|
22
|
+
begin
|
23
|
+
parser(options).parse!(args)
|
24
|
+
rescue OptionParser::InvalidOption => e
|
25
|
+
failure = e.message
|
26
|
+
failure << " (defined in #{source})" if source
|
27
|
+
abort "#{failure}\n\nPlease use --help for a listing of valid options"
|
28
|
+
end
|
29
|
+
|
30
|
+
options[:files_or_directories_to_run] = args
|
31
|
+
options
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# rubocop:disable MethodLength
|
37
|
+
# rubocop:disable Metrics/AbcSize
|
38
|
+
# rubocop:disable CyclomaticComplexity
|
39
|
+
# rubocop:disable PerceivedComplexity
|
40
|
+
def parser(options)
|
41
|
+
OptionParser.new do |parser|
|
42
|
+
parser.summary_width = 34
|
43
|
+
|
44
|
+
parser.banner = "Usage: rspec [options] [files or directories]\n\n"
|
45
|
+
|
46
|
+
parser.on('-I PATH', 'Specify PATH to add to $LOAD_PATH (may be used more than once).') do |dirs|
|
47
|
+
options[:libs] ||= []
|
48
|
+
options[:libs].concat(dirs.split(File::PATH_SEPARATOR))
|
49
|
+
end
|
50
|
+
|
51
|
+
parser.on('-r', '--require PATH', 'Require a file.') do |path|
|
52
|
+
options[:requires] ||= []
|
53
|
+
options[:requires] << path
|
54
|
+
end
|
55
|
+
|
56
|
+
parser.on('-O', '--options PATH', 'Specify the path to a custom options file.') do |path|
|
57
|
+
options[:custom_options_file] = path
|
58
|
+
end
|
59
|
+
|
60
|
+
parser.on('--order TYPE[:SEED]', 'Run examples by the specified order type.',
|
61
|
+
' [defined] examples and groups are run in the order they are defined',
|
62
|
+
' [rand] randomize the order of groups and examples',
|
63
|
+
' [random] alias for rand',
|
64
|
+
' [random:SEED] e.g. --order random:123') do |o|
|
65
|
+
options[:order] = o
|
66
|
+
end
|
67
|
+
|
68
|
+
parser.on('--seed SEED', Integer, 'Equivalent of --order rand:SEED.') do |seed|
|
69
|
+
options[:order] = "rand:#{seed}"
|
70
|
+
end
|
71
|
+
|
72
|
+
parser.on('--bisect[=verbose]', 'Repeatedly runs the suite in order to isolate the failures to the ',
|
73
|
+
' smallest reproducible case.') do |argument|
|
74
|
+
options[:bisect] = argument || true
|
75
|
+
options[:runner] = RSpec::Core::Invocations::Bisect.new
|
76
|
+
end
|
77
|
+
|
78
|
+
parser.on('--[no-]fail-fast[=COUNT]', 'Abort the run after a certain number of failures (1 by default).') do |argument|
|
79
|
+
if argument == true
|
80
|
+
value = 1
|
81
|
+
elsif argument == false || argument == 0
|
82
|
+
value = false
|
83
|
+
else
|
84
|
+
begin
|
85
|
+
value = Integer(argument)
|
86
|
+
rescue ArgumentError
|
87
|
+
RSpec.warning "Expected an integer value for `--fail-fast`, got: #{argument.inspect}", :call_site => nil
|
88
|
+
end
|
89
|
+
end
|
90
|
+
set_fail_fast(options, value)
|
91
|
+
end
|
92
|
+
|
93
|
+
parser.on('--failure-exit-code CODE', Integer,
|
94
|
+
'Override the exit code used when there are failing specs.') do |code|
|
95
|
+
options[:failure_exit_code] = code
|
96
|
+
end
|
97
|
+
|
98
|
+
parser.on('-X', '--[no-]drb', 'Run examples via DRb.') do |use_drb|
|
99
|
+
options[:drb] = use_drb
|
100
|
+
options[:runner] = RSpec::Core::Invocations::DRbWithFallback.new if use_drb
|
101
|
+
end
|
102
|
+
|
103
|
+
parser.on('--drb-port PORT', 'Port to connect to the DRb server.') do |o|
|
104
|
+
options[:drb_port] = o.to_i
|
105
|
+
end
|
106
|
+
|
107
|
+
parser.separator("\n **** Output ****\n\n")
|
108
|
+
|
109
|
+
parser.on('-f', '--format FORMATTER', 'Choose a formatter.',
|
110
|
+
' [p]rogress (default - dots)',
|
111
|
+
' [d]ocumentation (group and example names)',
|
112
|
+
' [h]tml',
|
113
|
+
' [j]son',
|
114
|
+
' custom formatter class name') do |o|
|
115
|
+
options[:formatters] ||= []
|
116
|
+
options[:formatters] << [o]
|
117
|
+
end
|
118
|
+
|
119
|
+
parser.on('-o', '--out FILE',
|
120
|
+
'Write output to a file instead of $stdout. This option applies',
|
121
|
+
' to the previously specified --format, or the default format',
|
122
|
+
' if no format is specified.'
|
123
|
+
) do |o|
|
124
|
+
options[:formatters] ||= [['progress']]
|
125
|
+
options[:formatters].last << o
|
126
|
+
end
|
127
|
+
|
128
|
+
parser.on('--deprecation-out FILE', 'Write deprecation warnings to a file instead of $stderr.') do |file|
|
129
|
+
options[:deprecation_stream] = file
|
130
|
+
end
|
131
|
+
|
132
|
+
parser.on('-b', '--backtrace', 'Enable full backtrace.') do |_o|
|
133
|
+
options[:full_backtrace] = true
|
134
|
+
end
|
135
|
+
|
136
|
+
parser.on('-c', '--color', '--colour', '') do |_o|
|
137
|
+
# flag will be excluded from `--help` output because it is deprecated
|
138
|
+
options[:color] = true
|
139
|
+
options[:color_mode] = :automatic
|
140
|
+
end
|
141
|
+
|
142
|
+
parser.on('--force-color', '--force-colour', 'Force the output to be in color, even if the output is not a TTY') do |_o|
|
143
|
+
if options[:color_mode] == :off
|
144
|
+
abort "Please only use one of `--force-color` and `--no-color`"
|
145
|
+
end
|
146
|
+
options[:color_mode] = :on
|
147
|
+
end
|
148
|
+
|
149
|
+
parser.on('--no-color', '--no-colour', 'Force the output to not be in color, even if the output is a TTY') do |_o|
|
150
|
+
if options[:color_mode] == :on
|
151
|
+
abort "Please only use one of --force-color and --no-color"
|
152
|
+
end
|
153
|
+
options[:color_mode] = :off
|
154
|
+
end
|
155
|
+
|
156
|
+
parser.on('-p', '--[no-]profile [COUNT]',
|
157
|
+
'Enable profiling of examples and list the slowest examples (default: 10).') do |argument|
|
158
|
+
options[:profile_examples] = if argument.nil?
|
159
|
+
true
|
160
|
+
elsif argument == false
|
161
|
+
false
|
162
|
+
else
|
163
|
+
begin
|
164
|
+
Integer(argument)
|
165
|
+
rescue ArgumentError
|
166
|
+
RSpec.warning "Non integer specified as profile count, separate " \
|
167
|
+
"your path from options with -- e.g. " \
|
168
|
+
"`rspec --profile -- #{argument}`",
|
169
|
+
:call_site => nil
|
170
|
+
true
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
parser.on('--dry-run', 'Print the formatter output of your suite without',
|
176
|
+
' running any examples or hooks') do |_o|
|
177
|
+
options[:dry_run] = true
|
178
|
+
end
|
179
|
+
|
180
|
+
parser.on('-w', '--warnings', 'Enable ruby warnings') do
|
181
|
+
$VERBOSE = true
|
182
|
+
end
|
183
|
+
|
184
|
+
parser.separator <<-FILTERING
|
185
|
+
|
186
|
+
**** Filtering/tags ****
|
187
|
+
|
188
|
+
In addition to the following options for selecting specific files, groups, or
|
189
|
+
examples, you can select individual examples by appending the line number(s) to
|
190
|
+
the filename:
|
191
|
+
|
192
|
+
rspec path/to/a_spec.rb:37:87
|
193
|
+
|
194
|
+
You can also pass example ids enclosed in square brackets:
|
195
|
+
|
196
|
+
rspec path/to/a_spec.rb[1:5,1:6] # run the 5th and 6th examples/groups defined in the 1st group
|
197
|
+
|
198
|
+
FILTERING
|
199
|
+
|
200
|
+
parser.on('--only-failures', "Filter to just the examples that failed the last time they ran.") do
|
201
|
+
configure_only_failures(options)
|
202
|
+
end
|
203
|
+
|
204
|
+
parser.on("-n", "--next-failure", "Apply `--only-failures` and abort after one failure.",
|
205
|
+
" (Equivalent to `--only-failures --fail-fast --order defined`)") do
|
206
|
+
configure_only_failures(options)
|
207
|
+
set_fail_fast(options, 1)
|
208
|
+
options[:order] ||= 'defined'
|
209
|
+
end
|
210
|
+
|
211
|
+
parser.on('-P', '--pattern PATTERN', 'Load files matching pattern (default: "spec/**/*_spec.rb").') do |o|
|
212
|
+
if options[:pattern]
|
213
|
+
options[:pattern] += ',' + o
|
214
|
+
else
|
215
|
+
options[:pattern] = o
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
parser.on('--exclude-pattern PATTERN',
|
220
|
+
'Load files except those matching pattern. Opposite effect of --pattern.') do |o|
|
221
|
+
options[:exclude_pattern] = o
|
222
|
+
end
|
223
|
+
|
224
|
+
parser.on('-e', '--example STRING', "Run examples whose full nested names include STRING (may be",
|
225
|
+
" used more than once)") do |o|
|
226
|
+
(options[:full_description] ||= []) << Regexp.compile(Regexp.escape(o))
|
227
|
+
end
|
228
|
+
|
229
|
+
parser.on('-t', '--tag TAG[:VALUE]',
|
230
|
+
'Run examples with the specified tag, or exclude examples',
|
231
|
+
'by adding ~ before the tag.',
|
232
|
+
' - e.g. ~slow',
|
233
|
+
' - TAG is always converted to a symbol') do |tag|
|
234
|
+
filter_type = tag =~ /^~/ ? :exclusion_filter : :inclusion_filter
|
235
|
+
|
236
|
+
name, value = tag.gsub(/^(~@|~|@)/, '').split(':', 2)
|
237
|
+
name = name.to_sym
|
238
|
+
|
239
|
+
parsed_value = case value
|
240
|
+
when nil then true # The default value for tags is true
|
241
|
+
when 'true' then true
|
242
|
+
when 'false' then false
|
243
|
+
when 'nil' then nil
|
244
|
+
when /^:/ then value[1..-1].to_sym
|
245
|
+
when /^\d+$/ then Integer(value)
|
246
|
+
when /^\d+.\d+$/ then Float(value)
|
247
|
+
else
|
248
|
+
value
|
249
|
+
end
|
250
|
+
|
251
|
+
add_tag_filter(options, filter_type, name, parsed_value)
|
252
|
+
end
|
253
|
+
|
254
|
+
parser.on('--default-path PATH', 'Set the default path where RSpec looks for examples (can',
|
255
|
+
' be a path to a file or a directory).') do |path|
|
256
|
+
options[:default_path] = path
|
257
|
+
end
|
258
|
+
|
259
|
+
parser.separator("\n **** Utility ****\n\n")
|
260
|
+
|
261
|
+
parser.on('--init', 'Initialize your project with RSpec.') do |_cmd|
|
262
|
+
options[:runner] = RSpec::Core::Invocations::InitializeProject.new
|
263
|
+
end
|
264
|
+
|
265
|
+
parser.on('-v', '--version', 'Display the version.') do
|
266
|
+
options[:runner] = RSpec::Core::Invocations::PrintVersion.new
|
267
|
+
end
|
268
|
+
|
269
|
+
# These options would otherwise be confusing to users, so we forcibly
|
270
|
+
# prevent them from executing.
|
271
|
+
#
|
272
|
+
# * --I is too similar to -I.
|
273
|
+
# * -d was a shorthand for --debugger, which is removed, but now would
|
274
|
+
# trigger --default-path.
|
275
|
+
invalid_options = %w[-d --I]
|
276
|
+
|
277
|
+
hidden_options = invalid_options + %w[-c]
|
278
|
+
|
279
|
+
parser.on_tail('-h', '--help', "You're looking at it.") do
|
280
|
+
options[:runner] = RSpec::Core::Invocations::PrintHelp.new(parser, hidden_options)
|
281
|
+
end
|
282
|
+
|
283
|
+
# This prevents usage of the invalid_options.
|
284
|
+
invalid_options.each do |option|
|
285
|
+
parser.on(option) do
|
286
|
+
raise OptionParser::InvalidOption.new
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
# rubocop:enable Metrics/AbcSize
|
292
|
+
# rubocop:enable MethodLength
|
293
|
+
# rubocop:enable CyclomaticComplexity
|
294
|
+
# rubocop:enable PerceivedComplexity
|
295
|
+
|
296
|
+
def add_tag_filter(options, filter_type, tag_name, value=true)
|
297
|
+
(options[filter_type] ||= {})[tag_name] = value
|
298
|
+
end
|
299
|
+
|
300
|
+
def set_fail_fast(options, value)
|
301
|
+
options[:fail_fast] = value
|
302
|
+
end
|
303
|
+
|
304
|
+
def configure_only_failures(options)
|
305
|
+
options[:only_failures] = true
|
306
|
+
add_tag_filter(options, :inclusion_filter, :last_run_status, 'failed')
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Core
|
3
|
+
# @private
|
4
|
+
module Ordering
|
5
|
+
# @private
|
6
|
+
# The default global ordering (defined order).
|
7
|
+
class Identity
|
8
|
+
def order(items)
|
9
|
+
items
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# @private
|
14
|
+
# Orders items randomly.
|
15
|
+
class Random
|
16
|
+
def initialize(configuration)
|
17
|
+
@configuration = configuration
|
18
|
+
@used = false
|
19
|
+
end
|
20
|
+
|
21
|
+
def used?
|
22
|
+
@used
|
23
|
+
end
|
24
|
+
|
25
|
+
def order(items)
|
26
|
+
@used = true
|
27
|
+
|
28
|
+
seed = @configuration.seed.to_s
|
29
|
+
items.sort_by { |item| jenkins_hash_digest(seed + item.id) }
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# http://en.wikipedia.org/wiki/Jenkins_hash_function
|
35
|
+
# Jenkins provides a good distribution and is simpler than MD5.
|
36
|
+
# It's a bit slower than MD5 (primarily because `Digest::MD5` is
|
37
|
+
# implemented in C) but has the advantage of not requiring us
|
38
|
+
# to load another part of stdlib, which we try to minimize.
|
39
|
+
def jenkins_hash_digest(string)
|
40
|
+
hash = 0
|
41
|
+
|
42
|
+
string.each_byte do |byte|
|
43
|
+
hash += byte
|
44
|
+
hash &= MAX_32_BIT
|
45
|
+
hash += ((hash << 10) & MAX_32_BIT)
|
46
|
+
hash &= MAX_32_BIT
|
47
|
+
hash ^= hash >> 6
|
48
|
+
end
|
49
|
+
|
50
|
+
hash += ((hash << 3) & MAX_32_BIT)
|
51
|
+
hash &= MAX_32_BIT
|
52
|
+
hash ^= hash >> 11
|
53
|
+
hash += ((hash << 15) & MAX_32_BIT)
|
54
|
+
hash &= MAX_32_BIT
|
55
|
+
hash
|
56
|
+
end
|
57
|
+
|
58
|
+
MAX_32_BIT = 4_294_967_295
|
59
|
+
end
|
60
|
+
|
61
|
+
# @private
|
62
|
+
# Orders items based on a custom block.
|
63
|
+
class Custom
|
64
|
+
def initialize(callable)
|
65
|
+
@callable = callable
|
66
|
+
end
|
67
|
+
|
68
|
+
def order(list)
|
69
|
+
@callable.call(list)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# @private
|
74
|
+
# Stores the different ordering strategies.
|
75
|
+
class Registry
|
76
|
+
def initialize(configuration)
|
77
|
+
@configuration = configuration
|
78
|
+
@strategies = {}
|
79
|
+
|
80
|
+
register(:random, Random.new(configuration))
|
81
|
+
|
82
|
+
identity = Identity.new
|
83
|
+
register(:defined, identity)
|
84
|
+
|
85
|
+
# The default global ordering is --defined.
|
86
|
+
register(:global, identity)
|
87
|
+
end
|
88
|
+
|
89
|
+
def fetch(name, &fallback)
|
90
|
+
@strategies.fetch(name, &fallback)
|
91
|
+
end
|
92
|
+
|
93
|
+
def register(sym, strategy)
|
94
|
+
@strategies[sym] = strategy
|
95
|
+
end
|
96
|
+
|
97
|
+
def used_random_seed?
|
98
|
+
@strategies[:random].used?
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# @private
|
103
|
+
# Manages ordering configuration.
|
104
|
+
#
|
105
|
+
# @note This is not intended to be used externally. Use
|
106
|
+
# the APIs provided by `RSpec::Core::Configuration` instead.
|
107
|
+
class ConfigurationManager
|
108
|
+
attr_reader :seed, :ordering_registry
|
109
|
+
|
110
|
+
def initialize
|
111
|
+
@ordering_registry = Registry.new(self)
|
112
|
+
@seed = rand(0xFFFF)
|
113
|
+
@seed_forced = false
|
114
|
+
@order_forced = false
|
115
|
+
end
|
116
|
+
|
117
|
+
def seed_used?
|
118
|
+
ordering_registry.used_random_seed?
|
119
|
+
end
|
120
|
+
|
121
|
+
def seed=(seed)
|
122
|
+
return if @seed_forced
|
123
|
+
register_ordering(:global, ordering_registry.fetch(:random))
|
124
|
+
@seed = seed.to_i
|
125
|
+
end
|
126
|
+
|
127
|
+
def order=(type)
|
128
|
+
order, seed = type.to_s.split(':')
|
129
|
+
@seed = seed.to_i if seed
|
130
|
+
|
131
|
+
ordering_name = if order.include?('rand')
|
132
|
+
:random
|
133
|
+
elsif order == 'defined'
|
134
|
+
:defined
|
135
|
+
end
|
136
|
+
|
137
|
+
register_ordering(:global, ordering_registry.fetch(ordering_name)) if ordering_name
|
138
|
+
end
|
139
|
+
|
140
|
+
def force(hash)
|
141
|
+
if hash.key?(:seed)
|
142
|
+
self.seed = hash[:seed]
|
143
|
+
@seed_forced = true
|
144
|
+
@order_forced = true
|
145
|
+
elsif hash.key?(:order)
|
146
|
+
self.order = hash[:order]
|
147
|
+
@order_forced = true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def register_ordering(name, strategy=Custom.new(Proc.new { |l| yield l }))
|
152
|
+
return if @order_forced && name == :global
|
153
|
+
ordering_registry.register(name, strategy)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|