rspec-core 3.11.0 → 3.13.3

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.
data/README.md CHANGED
@@ -116,6 +116,11 @@ pretty much the same as `shared_examples` and `include_examples`, providing
116
116
  more accurate naming when you share hooks, `let` declarations, helper methods,
117
117
  etc, but no examples.
118
118
 
119
+ If you want to reuse shared examples or contexts across your RSpec suite you can
120
+ define them in a stand alone _*.rb_ files (_spec/support/shared_examples/definition.rb_
121
+ for example). But you will have to manually `require` them (there is no autoloading of
122
+ _spec/support/_ directory unless you set it up yourself).
123
+
119
124
  ## Metadata
120
125
 
121
126
  rspec-core stores a metadata hash with every example and group, which
@@ -322,14 +327,14 @@ Failures:
322
327
  got: nil
323
328
 
324
329
  (compared using ==)
325
- # ./spec/calcalator_spec.rb:6:in `block (3 levels) in <top (required)>'
330
+ # ./spec/calculator_spec.rb:6:in `block (3 levels) in <top (required)>'
326
331
 
327
332
  Finished in 0.00131 seconds (files took 0.10968 seconds to load)
328
333
  1 example, 1 failure
329
334
 
330
335
  Failed examples:
331
336
 
332
- rspec ./spec/calcalator_spec.rb:5 # Calculator#add returns the sum of its arguments
337
+ rspec ./spec/calculator_spec.rb:5 # Calculator#add returns the sum of its arguments
333
338
  ```
334
339
 
335
340
  Implement the simplest solution, by changing the definition of `Calculator#add` to:
@@ -136,7 +136,7 @@ module RSpec
136
136
  end
137
137
 
138
138
  def get_expected_failures_for?(ids)
139
- ids_to_run = ids + failed_example_ids
139
+ ids_to_run = all_example_ids & (ids + failed_example_ids)
140
140
  notify(
141
141
  :bisect_individual_run_start,
142
142
  :command => shell_command.repro_command_from(ids_to_run),
@@ -102,6 +102,7 @@ module RSpec
102
102
  private
103
103
 
104
104
  def run_specs(run_descriptor)
105
+ # :nocov: - Executed in a forked process, by integration/bisect_spec
105
106
  $stdout = $stderr = @spec_output
106
107
  formatter = CaptureFormatter.new(run_descriptor.failed_example_ids)
107
108
 
@@ -125,6 +126,7 @@ module RSpec
125
126
  else
126
127
  @channel.send(latest_run_results)
127
128
  end
129
+ # :nocov:
128
130
  end
129
131
  end
130
132
 
@@ -453,11 +453,30 @@ module RSpec
453
453
  add_setting :threadsafe
454
454
 
455
455
  # @macro add_setting
456
- # Maximum count of failed source lines to display in the failure reports.
457
- # (default `10`).
456
+ # Maximum count of failed source lines to display in the failure reports
457
+ # (defaults to `10`).
458
458
  # return [Integer]
459
459
  add_setting :max_displayed_failure_line_count
460
460
 
461
+ # @macro full_cause_backtrace
462
+ # Display the full backtrace of an exceptions cause (defaults to `false`).
463
+ # return [Boolean]
464
+ add_setting :full_cause_backtrace
465
+
466
+ # @macro add_setting
467
+ # Format the output for pending examples. Can be set to:
468
+ # - :full (default) - pending examples appear similarly to failures
469
+ # - :no_backtrace - same as above, but with no backtrace
470
+ # - :skip - do not show the section at all
471
+ # return [Symbol]
472
+ add_read_only_setting :pending_failure_output
473
+ def pending_failure_output=(mode)
474
+ raise ArgumentError,
475
+ "`pending_failure_output` can be set to :full, :no_backtrace, " \
476
+ "or :skip" unless [:full, :no_backtrace, :skip].include?(mode)
477
+ @pending_failure_output = mode
478
+ end
479
+
461
480
  # Determines which bisect runner implementation gets used to run subsets
462
481
  # of the suite during a bisection. Your choices are:
463
482
  #
@@ -502,7 +521,8 @@ module RSpec
502
521
  # @private
503
522
  attr_reader :backtrace_formatter, :ordering_manager, :loaded_spec_files
504
523
 
505
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
524
+ # rubocop:disable Metrics/AbcSize
525
+ # rubocop:disable Metrics/MethodLength
506
526
 
507
527
  # Build an object to store runtime configuration options and set defaults
508
528
  def initialize
@@ -556,12 +576,15 @@ module RSpec
556
576
  @derived_metadata_blocks = FilterableItemRepository::QueryOptimized.new(:any?)
557
577
  @threadsafe = true
558
578
  @max_displayed_failure_line_count = 10
579
+ @full_cause_backtrace = false
559
580
  @world = World::Null
560
581
  @shared_context_metadata_behavior = :trigger_inclusion
582
+ @pending_failure_output = :full
561
583
 
562
584
  define_built_in_hooks
563
585
  end
564
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
586
+ # rubocop:enable Metrics/AbcSize
587
+ # rubocop:enable Metrics/MethodLength
565
588
 
566
589
  # @private
567
590
  #
@@ -676,7 +699,7 @@ module RSpec
676
699
  end
677
700
 
678
701
  # Set regular expressions used to exclude lines in backtrace.
679
- # @param patterns [Array<Regexp>] set backtrace_formatter exlusion_patterns
702
+ # @param patterns [Array<Regexp>] set backtrace_formatter exclusion_patterns
680
703
  def backtrace_exclusion_patterns=(patterns)
681
704
  @backtrace_formatter.exclusion_patterns = patterns
682
705
  end
@@ -1379,6 +1402,9 @@ module RSpec
1379
1402
  #
1380
1403
  # # included in examples with `:type => :request` metadata
1381
1404
  # config.include(AuthenticationHelpers, :type => :request)
1405
+ #
1406
+ # # included in examples where the `:type` metadata matches a proc condition
1407
+ # config.include(AuthenticationHelpers, :type => proc { |type, _metadata| [:request, :controller].include?(type) })
1382
1408
  # end
1383
1409
  #
1384
1410
  # describe "edit profile", :preferences, :type => :request do
@@ -1571,8 +1597,10 @@ module RSpec
1571
1597
  def requires=(paths)
1572
1598
  directories = ['lib', default_path].select { |p| File.directory? p }
1573
1599
  RSpec::Core::RubyProject.add_to_load_path(*directories)
1574
- paths.each { |path| load_file_handling_errors(:require, path) }
1575
- @requires += paths
1600
+ paths.each { |path|
1601
+ load_file_handling_errors(:require, path)
1602
+ @requires << path
1603
+ }
1576
1604
  end
1577
1605
 
1578
1606
  # @private
@@ -1741,8 +1769,9 @@ module RSpec
1741
1769
  # @private
1742
1770
  RAISE_ERROR_WARNING_NOTIFIER = lambda { |message| raise message }
1743
1771
 
1744
- # Turns warnings into errors. This can be useful when
1772
+ # Turns RSpec warnings into errors. This can be useful when
1745
1773
  # you want RSpec to run in a 'strict' no warning situation.
1774
+ # (Note this does not capture or raise on Ruby warnings).
1746
1775
  #
1747
1776
  # @example
1748
1777
  #
@@ -1818,7 +1847,7 @@ module RSpec
1818
1847
  # by not setting `mock_with` or `expect_with` to anything else).
1819
1848
  #
1820
1849
  # @note If the user uses this options with `mock_with :mocha`
1821
- # (or similiar) they will still have monkey patching active
1850
+ # (or similar) they will still have monkey patching active
1822
1851
  # in their test environment from mocha.
1823
1852
  #
1824
1853
  # @example
@@ -2118,6 +2147,13 @@ module RSpec
2118
2147
  suggestions = DidYouMean.new(relative_file).call
2119
2148
  reporter.notify_non_example_exception(ex, "An error occurred while loading #{relative_file}.#{suggestions}")
2120
2149
  RSpec.world.wants_to_quit = true
2150
+ rescue SyntaxError => ex
2151
+ relative_file = Metadata.relative_path(file)
2152
+ reporter.notify_non_example_exception(
2153
+ ex,
2154
+ "While loading #{relative_file} a `raise SyntaxError` occurred, RSpec will now quit."
2155
+ )
2156
+ RSpec.world.rspec_is_quitting = true
2121
2157
  rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex
2122
2158
  relative_file = Metadata.relative_path(file)
2123
2159
  reporter.notify_non_example_exception(ex, "An error occurred while loading #{relative_file}.")
@@ -79,6 +79,10 @@ module RSpec
79
79
  # deprecation (or otherwise access the reporter).
80
80
  :deprecation_stream,
81
81
 
82
+ # In order for `RSpec.configuration.dry_run?` to return `true` during
83
+ # processing the `requires` option, it must be parsed before it.
84
+ :dry_run,
85
+
82
86
  # load paths depend on nothing, but must be set before `requires`
83
87
  # to support load-path-relative requires.
84
88
  :libs,
@@ -169,9 +173,11 @@ module RSpec
169
173
  def args_from_options_file(path)
170
174
  return [] unless path && File.exist?(path)
171
175
  config_string = options_file_as_erb_string(path)
172
- FlatMap.flat_map(config_string.split(/\n+/), &:shellsplit)
176
+ config_lines = config_string.split(/\n+/).reject { |s| s =~ /\A\s*#/ }
177
+ FlatMap.flat_map(config_lines, &:shellsplit)
173
178
  end
174
179
 
180
+ # :nocov:
175
181
  def options_file_as_erb_string(path)
176
182
  if RUBY_VERSION >= '2.6'
177
183
  ERB.new(File.read(path), :trim_mode => '-').result(binding)
@@ -179,6 +185,7 @@ module RSpec
179
185
  ERB.new(File.read(path), nil, '-').result(binding)
180
186
  end
181
187
  end
188
+ # :nocov:
182
189
 
183
190
  def custom_options_file
184
191
  command_line_options[:custom_options_file]
@@ -11,6 +11,7 @@ module RSpec
11
11
 
12
12
  if defined?(::DidYouMean::SpellChecker)
13
13
  # provide probable suggestions
14
+ # :nocov: - not installed on CI
14
15
  def call
15
16
  checker = ::DidYouMean::SpellChecker.new(:dictionary => Dir["spec/**/*.rb"])
16
17
  probables = checker.correct(relative_file_name.sub('./', ''))[0..2]
@@ -18,15 +19,19 @@ module RSpec
18
19
 
19
20
  formats probables
20
21
  end
22
+ # :nocov:
21
23
  else
22
24
  # return a hint if API for ::DidYouMean::SpellChecker not supported
25
+ # :nocov:
23
26
  def call
24
27
  "\nHint: Install the `did_you_mean` gem in order to provide suggestions for similarly named files."
25
28
  end
29
+ # :nocov:
26
30
  end
27
31
 
28
32
  private
29
33
 
34
+ # :nocov:
30
35
  def formats(probables)
31
36
  rspec_format = probables.map { |s, _| "rspec ./#{s}" }
32
37
  red_font(top_and_tail rspec_format)
@@ -41,6 +46,7 @@ module RSpec
41
46
  colorizer = ::RSpec::Core::Formatters::ConsoleCodes
42
47
  colorizer.wrap mytext, :failure
43
48
  end
49
+ # :nocov:
44
50
  end
45
51
  end
46
52
  end
@@ -91,7 +91,7 @@ module RSpec
91
91
  def add_filter(argv, name, hash)
92
92
  hash.each_pair do |k, v|
93
93
  next if CONDITIONAL_FILTERS.include?(k)
94
- tag = name == :inclusion ? k.to_s : "~#{k}".dup
94
+ tag = name == :inclusion ? k.to_s.dup : "~#{k}".dup
95
95
  tag << ":#{v}" if v.is_a?(String)
96
96
  argv << "--tag" << tag
97
97
  end unless hash.empty?
@@ -98,7 +98,7 @@ module RSpec
98
98
  loaded_spec_files = RSpec.configuration.loaded_spec_files
99
99
 
100
100
  Metadata.ascending(metadata) do |meta|
101
- return meta[:location] if loaded_spec_files.include?(meta[:absolute_file_path])
101
+ break meta[:location] if loaded_spec_files.include?(meta[:absolute_file_path])
102
102
  end
103
103
  end
104
104
  end
@@ -63,7 +63,7 @@ module RSpec
63
63
  # were loaded but not executed (due to filtering, `--fail-fast`
64
64
  # or whatever) should have a `:status` of `UNKNOWN_STATUS`.
65
65
  #
66
- # This willl produce a new list that:
66
+ # This will produce a new list that:
67
67
  # - Will be missing examples from previous runs that we know for sure
68
68
  # no longer exist.
69
69
  # - Will have the latest known status for any examples that either
@@ -164,7 +164,7 @@ module RSpec
164
164
  end
165
165
 
166
166
  def formatted_value_rows
167
- @foramtted_value_rows ||= rows.map do |row|
167
+ @formatted_value_rows ||= rows.map do |row|
168
168
  formatted_row_from(row)
169
169
  end
170
170
  end
@@ -202,8 +202,8 @@ module RSpec
202
202
 
203
203
  def split_file_scoped_rules
204
204
  rules_dup = @rules.dup
205
- locations = rules_dup.delete(:locations) { Hash.new([]) }
206
- ids = rules_dup.delete(:ids) { Hash.new([]) }
205
+ locations = rules_dup.delete(:locations) { Hash.new { [] } }
206
+ ids = rules_dup.delete(:ids) { Hash.new { [] } }
207
207
 
208
208
  return locations, ids, self.class.new(rules_dup)
209
209
  end
@@ -56,7 +56,12 @@ module RSpec
56
56
  end
57
57
 
58
58
  unless last_cause.backtrace.nil? || last_cause.backtrace.empty?
59
- cause << (" #{backtrace_formatter.format_backtrace(last_cause.backtrace, example.metadata).first}")
59
+ lines = backtrace_formatter.format_backtrace(last_cause.backtrace, example.metadata)
60
+ lines = [lines[0]] unless RSpec.configuration.full_cause_backtrace # rubocop:disable Metrics/BlockNesting
61
+
62
+ lines.each do |line|
63
+ cause << (" #{line}")
64
+ end
60
65
  end
61
66
  end
62
67
 
@@ -175,11 +180,25 @@ module RSpec
175
180
  end
176
181
 
177
182
  # rubocop:disable Lint/RescueException
178
- def exception_message_string(exception)
179
- exception.message.to_s
180
- rescue Exception => other
181
- "A #{exception.class} for which `exception.message.to_s` raises #{other.class}."
183
+ # :nocov:
184
+ if SyntaxError.instance_methods.include?(:detailed_message)
185
+ def exception_message_string(exception)
186
+ case exception
187
+ when SyntaxError then exception.detailed_message.to_s
188
+ else
189
+ exception.message.to_s
190
+ end
191
+ rescue Exception => other
192
+ "A #{exception.class} for which `exception.message.to_s` raises #{other.class}."
193
+ end
194
+ else
195
+ def exception_message_string(exception)
196
+ exception.message.to_s
197
+ rescue Exception => other
198
+ "A #{exception.class} for which `exception.message.to_s` raises #{other.class}."
199
+ end
182
200
  end
201
+ # :nocov:
183
202
  # rubocop:enable Lint/RescueException
184
203
 
185
204
  def exception_lines
@@ -197,8 +216,8 @@ module RSpec
197
216
  @extra_failure_lines ||= begin
198
217
  lines = Array(example.metadata[:extra_failure_lines])
199
218
  unless lines.empty?
200
- lines.unshift('')
201
- lines.push('')
219
+ lines.unshift('') unless lines.first == ''
220
+ lines.push('') unless lines.last == ''
202
221
  end
203
222
  lines
204
223
  end
@@ -235,13 +254,19 @@ module RSpec
235
254
  rescue SnippetExtractor::NoSuchLineError
236
255
  ["Unable to find matching line in #{file_path}"]
237
256
  rescue SecurityError
257
+ # :nocov: - SecurityError is no longer produced starting in ruby 2.7
238
258
  ["Unable to read failed line"]
259
+ # :nocov:
239
260
  end
240
261
 
241
262
  def find_failed_line
242
263
  line_regex = RSpec.configuration.in_project_source_dir_regex
243
264
  loaded_spec_files = RSpec.configuration.loaded_spec_files
244
265
 
266
+ exception_backtrace.reject! do |line|
267
+ line.start_with?("<internal:")
268
+ end
269
+
245
270
  exception_backtrace.find do |line|
246
271
  next unless (line_path = line[/(.+?):(\d+)(|:\d+)/, 1])
247
272
  path = File.expand_path(line_path)
@@ -263,9 +288,11 @@ module RSpec
263
288
  encoded_string(description)
264
289
  end
265
290
  else # for 1.8.7
291
+ # :nocov:
266
292
  def encoded_description(description)
267
293
  description
268
294
  end
295
+ # :nocov:
269
296
  end
270
297
 
271
298
  def exception_backtrace
@@ -308,10 +335,14 @@ module RSpec
308
335
  ]
309
336
  }
310
337
  elsif @execution_result.status == :pending
311
- {
338
+ options = {
312
339
  :message_color => RSpec.configuration.pending_color,
313
340
  :detail_formatter => PENDING_DETAIL_FORMATTER
314
341
  }
342
+ if RSpec.configuration.pending_failure_output == :no_backtrace
343
+ options[:backtrace_formatter] = EmptyBacktraceFormatter
344
+ end
345
+ options
315
346
  end
316
347
  end
317
348
 
@@ -33,10 +33,8 @@ module RSpec
33
33
  "<span class='duration'>#{formatted_run_time}s</span></dd>"
34
34
  end
35
35
 
36
- # rubocop:disable Metrics/ParameterLists
37
36
  def print_example_failed(pending_fixed, description, run_time, failure_id,
38
37
  exception, extra_content)
39
- # rubocop:enable Metrics/ParameterLists
40
38
  formatted_run_time = "%.5f" % run_time
41
39
 
42
40
  @output.puts " <dd class=\"example #{pending_fixed ? 'pending_fixed' : 'failed'}\">"
@@ -215,7 +213,7 @@ function assign_display_style_for_group(classname, display_flag, subgroup_flag)
215
213
  }
216
214
  }
217
215
  EOF
218
- # rubocop:enable LineLength
216
+ # rubocop:enable Layout/LineLength
219
217
 
220
218
  GLOBAL_STYLES = <<-EOF
221
219
  #rspec-header {
@@ -43,7 +43,7 @@ module RSpec
43
43
  #
44
44
  # @param backtrace [String] the backtrace from a test failure
45
45
  # @return [String] highlighted code snippet indicating where the test
46
- # failure occured
46
+ # failure occurred
47
47
  #
48
48
  # @see #post_process
49
49
  def snippet(backtrace)
@@ -93,7 +93,9 @@ module RSpec
93
93
  "# Couldn't get snippet for #{file}"
94
94
  end
95
95
  rescue SecurityError
96
+ # :nocov: - SecurityError is no longer produced starting in ruby 2.7
96
97
  "# Couldn't get snippet for #{file}"
98
+ # :nocov:
97
99
  end
98
100
 
99
101
  # @api private
@@ -103,7 +105,7 @@ module RSpec
103
105
  #
104
106
  # @param highlighted [String] syntax-highlighted snippet surrounding the
105
107
  # offending line of code
106
- # @param offending_line [Fixnum] line where failure occured
108
+ # @param offending_line [Fixnum] line where failure occurred
107
109
  # @return [String] completed snippet
108
110
  def post_process(highlighted, offending_line)
109
111
  new_lines = []
@@ -32,15 +32,16 @@ module RSpec
32
32
  @output_hash[:summary_line] = summary.totals_line
33
33
  end
34
34
 
35
- def stop(notification)
36
- @output_hash[:examples] = notification.examples.map do |example|
37
- format_example(example).tap do |hash|
38
- e = example.exception
35
+ def stop(group_notification)
36
+ @output_hash[:examples] = group_notification.notifications.map do |notification|
37
+ format_example(notification.example).tap do |hash|
38
+ e = notification.example.exception
39
+
39
40
  if e
40
- hash[:exception] = {
41
+ hash[:exception] = {
41
42
  :class => e.class.name,
42
43
  :message => e.message,
43
- :backtrace => e.backtrace,
44
+ :backtrace => notification.formatted_backtrace,
44
45
  }
45
46
  end
46
47
  end
@@ -461,7 +461,7 @@ module RSpec
461
461
  # TODO: consider making this an error in RSpec 4. For SemVer reasons,
462
462
  # we are only warning in RSpec 3.
463
463
  RSpec.warn_with "WARNING: `around(:context)` hooks are not supported and " \
464
- "behave like `around(:example)."
464
+ "behave like `around(:example)`."
465
465
  end
466
466
 
467
467
  hook = HOOK_TYPES[position][scope].new(block, options)
@@ -47,7 +47,7 @@ module RSpec
47
47
  return nil if line == '-e:1'.freeze
48
48
  line
49
49
  rescue SecurityError
50
- # :nocov:
50
+ # :nocov: - SecurityError is no longer produced starting in ruby 2.7
51
51
  nil
52
52
  # :nocov:
53
53
  end
@@ -92,7 +92,7 @@ module RSpec
92
92
  #
93
93
  # This is ideal for use by a example or example group, which may
94
94
  # be updated multiple times with globally configured hooks, etc,
95
- # but will not be queried frequently by other examples or examle
95
+ # but will not be queried frequently by other examples or example
96
96
  # groups.
97
97
  # @private
98
98
  class UpdateOptimized
@@ -120,6 +120,8 @@ module RSpec::Core
120
120
  # @return [String] The list of pending examples, fully formatted in the
121
121
  # way that RSpec's built-in formatters emit.
122
122
  def fully_formatted_pending_examples(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
123
+ return if RSpec.configuration.pending_failure_output == :skip
124
+
123
125
  formatted = "\nPending: (Failures listed here are expected and do not affect your suite's status)\n".dup
124
126
 
125
127
  pending_notifications.each_with_index do |notification, index|
@@ -32,11 +32,10 @@ module RSpec::Core
32
32
 
33
33
  private
34
34
 
35
- # rubocop:disable MethodLength
36
35
  # rubocop:disable Metrics/AbcSize
37
- # rubocop:disable CyclomaticComplexity
38
- # rubocop:disable PerceivedComplexity
39
- # rubocop:disable Metrics/BlockLength
36
+ # rubocop:disable Metrics/MethodLength
37
+ # rubocop:disable Metrics/CyclomaticComplexity
38
+ # rubocop:disable Metrics/PerceivedComplexity
40
39
  def parser(options)
41
40
  OptionParser.new do |parser|
42
41
  parser.summary_width = 34
@@ -186,7 +185,9 @@ module RSpec::Core
186
185
 
187
186
  parser.on('-w', '--warnings', 'Enable ruby warnings') do
188
187
  if Object.const_defined?(:Warning) && Warning.respond_to?(:[]=)
188
+ # :nocov: on older Ruby without Warning
189
189
  Warning[:deprecated] = true
190
+ # :nocov:
190
191
  end
191
192
  $VERBOSE = true
192
193
  end
@@ -303,11 +304,10 @@ FILTERING
303
304
  end
304
305
  end
305
306
  end
306
- # rubocop:enable Metrics/BlockLength
307
307
  # rubocop:enable Metrics/AbcSize
308
- # rubocop:enable MethodLength
309
- # rubocop:enable CyclomaticComplexity
310
- # rubocop:enable PerceivedComplexity
308
+ # rubocop:enable Metrics/MethodLength
309
+ # rubocop:enable Metrics/CyclomaticComplexity
310
+ # rubocop:enable Metrics/PerceivedComplexity
311
311
 
312
312
  def add_tag_filter(options, filter_type, tag_name, value=true)
313
313
  (options[filter_type] ||= {})[tag_name] = value
@@ -78,6 +78,30 @@ module RSpec
78
78
  end
79
79
  end
80
80
 
81
+ # @private
82
+ # A strategy which delays looking up the ordering until needed
83
+ class Delayed
84
+ def initialize(registry, name)
85
+ @registry = registry
86
+ @name = name
87
+ end
88
+
89
+ def order(list)
90
+ strategy.order(list)
91
+ end
92
+
93
+ private
94
+
95
+ def strategy
96
+ @strategy ||= lookup_strategy
97
+ end
98
+
99
+ def lookup_strategy
100
+ raise "Undefined ordering strategy #{@name.inspect}" unless @registry.has_strategy?(@name)
101
+ @registry.fetch(@name)
102
+ end
103
+ end
104
+
81
105
  # @private
82
106
  # Stores the different ordering strategies.
83
107
  class Registry
@@ -99,6 +123,10 @@ module RSpec
99
123
  @strategies.fetch(name, &fallback)
100
124
  end
101
125
 
126
+ def has_strategy?(name)
127
+ @strategies.key?(name)
128
+ end
129
+
102
130
  def register(sym, strategy)
103
131
  @strategies[sym] = strategy
104
132
  end
@@ -143,9 +171,20 @@ module RSpec
143
171
  :defined
144
172
  elsif order == 'recently-modified'
145
173
  :recently_modified
174
+ else
175
+ order.to_sym
146
176
  end
147
177
 
148
- register_ordering(:global, ordering_registry.fetch(ordering_name)) if ordering_name
178
+ if ordering_name
179
+ strategy =
180
+ if ordering_registry.has_strategy?(ordering_name)
181
+ ordering_registry.fetch(ordering_name)
182
+ else
183
+ Delayed.new(ordering_registry, ordering_name)
184
+ end
185
+
186
+ register_ordering(:global, strategy)
187
+ end
149
188
  end
150
189
 
151
190
  def force(hash)
@@ -15,13 +15,13 @@ module RSpec
15
15
  end
16
16
 
17
17
  def method_missing(name, *args, &block)
18
- output.send(name, *args, &block)
18
+ output.__send__(name, *args, &block)
19
19
  end
20
20
 
21
21
  # Redirect calls for IO interface methods
22
22
  IO.instance_methods(false).each do |method|
23
23
  define_method(method) do |*args, &block|
24
- output.send(method, *args, &block)
24
+ output.__send__(method, *args, &block)
25
25
  end
26
26
  end
27
27
  end
@@ -59,7 +59,7 @@ module RSpec
59
59
  # executed. If you need to consider hooks as pending as well you can use
60
60
  # the pending metadata as an alternative, e.g.
61
61
  # `it "does something", pending: "message"`.
62
- def pending(message=nil)
62
+ def pending(message=nil, &_block)
63
63
  current_example = RSpec.current_example
64
64
 
65
65
  if block_given?
@@ -61,7 +61,7 @@ RSpec.configure do |config|
61
61
 
62
62
  # Limits the available syntax to the non-monkey patched syntax that is
63
63
  # recommended. For more details, see:
64
- # https://relishapp.com/rspec/rspec-core/docs/configuration/zero-monkey-patching-mode
64
+ # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/
65
65
  config.disable_monkey_patching!
66
66
 
67
67
  # This setting enables warnings. It's recommended, but in some cases may