rspec-core 3.2.3 → 3.3.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +75 -0
- data/README.md +137 -20
- data/lib/rspec/autorun.rb +1 -0
- data/lib/rspec/core.rb +8 -16
- data/lib/rspec/core/backtrace_formatter.rb +1 -3
- data/lib/rspec/core/bisect/coordinator.rb +66 -0
- data/lib/rspec/core/bisect/example_minimizer.rb +130 -0
- data/lib/rspec/core/bisect/runner.rb +139 -0
- data/lib/rspec/core/bisect/server.rb +61 -0
- data/lib/rspec/core/bisect/subset_enumerator.rb +39 -0
- data/lib/rspec/core/configuration.rb +134 -5
- data/lib/rspec/core/configuration_options.rb +21 -10
- data/lib/rspec/core/example.rb +84 -50
- data/lib/rspec/core/example_group.rb +46 -18
- data/lib/rspec/core/example_status_persister.rb +235 -0
- data/lib/rspec/core/filter_manager.rb +43 -28
- data/lib/rspec/core/flat_map.rb +2 -0
- data/lib/rspec/core/formatters.rb +30 -20
- data/lib/rspec/core/formatters/base_text_formatter.rb +1 -0
- data/lib/rspec/core/formatters/bisect_formatter.rb +68 -0
- data/lib/rspec/core/formatters/bisect_progress_formatter.rb +115 -0
- data/lib/rspec/core/formatters/deprecation_formatter.rb +0 -1
- data/lib/rspec/core/formatters/documentation_formatter.rb +0 -4
- data/lib/rspec/core/formatters/exception_presenter.rb +389 -0
- data/lib/rspec/core/formatters/fallback_message_formatter.rb +28 -0
- data/lib/rspec/core/formatters/helpers.rb +22 -2
- data/lib/rspec/core/formatters/html_formatter.rb +1 -4
- data/lib/rspec/core/formatters/html_printer.rb +2 -6
- data/lib/rspec/core/formatters/json_formatter.rb +6 -4
- data/lib/rspec/core/formatters/snippet_extractor.rb +12 -7
- data/lib/rspec/core/hooks.rb +8 -2
- data/lib/rspec/core/memoized_helpers.rb +77 -17
- data/lib/rspec/core/metadata.rb +24 -10
- data/lib/rspec/core/metadata_filter.rb +16 -3
- data/lib/rspec/core/mutex.rb +63 -0
- data/lib/rspec/core/notifications.rb +84 -189
- data/lib/rspec/core/option_parser.rb +105 -32
- data/lib/rspec/core/ordering.rb +28 -25
- data/lib/rspec/core/profiler.rb +32 -0
- data/lib/rspec/core/project_initializer/spec/spec_helper.rb +6 -1
- data/lib/rspec/core/rake_task.rb +6 -20
- data/lib/rspec/core/reentrant_mutex.rb +52 -0
- data/lib/rspec/core/reporter.rb +65 -17
- data/lib/rspec/core/runner.rb +38 -14
- data/lib/rspec/core/set.rb +49 -0
- data/lib/rspec/core/shared_example_group.rb +3 -1
- data/lib/rspec/core/shell_escape.rb +49 -0
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/world.rb +31 -20
- metadata +35 -7
- metadata.gz.sig +0 -0
- data/lib/rspec/core/backport_random.rb +0 -339
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'erb'
|
2
2
|
require 'shellwords'
|
3
|
-
require 'set'
|
4
3
|
|
5
4
|
module RSpec
|
6
5
|
module Core
|
@@ -53,12 +52,12 @@ module RSpec
|
|
53
52
|
end
|
54
53
|
end
|
55
54
|
|
56
|
-
UNFORCED_OPTIONS = [
|
55
|
+
UNFORCED_OPTIONS = Set.new([
|
57
56
|
:requires, :profile, :drb, :libs, :files_or_directories_to_run,
|
58
57
|
:full_description, :full_backtrace, :tty
|
59
|
-
]
|
58
|
+
])
|
60
59
|
|
61
|
-
UNPROCESSABLE_OPTIONS = [:formatters]
|
60
|
+
UNPROCESSABLE_OPTIONS = Set.new([:formatters])
|
62
61
|
|
63
62
|
def force?(key)
|
64
63
|
!UNFORCED_OPTIONS.include?(key)
|
@@ -82,7 +81,7 @@ module RSpec
|
|
82
81
|
|
83
82
|
# `files_or_directories_to_run` uses `default_path` so it must be
|
84
83
|
# set before it.
|
85
|
-
:default_path,
|
84
|
+
:default_path, :only_failures,
|
86
85
|
|
87
86
|
# These must be set before `requires` to support checking
|
88
87
|
# `config.files_to_run` from within `spec_helper.rb` when a
|
@@ -120,11 +119,16 @@ module RSpec
|
|
120
119
|
end
|
121
120
|
|
122
121
|
def env_options
|
123
|
-
|
122
|
+
return {} unless ENV['SPEC_OPTS']
|
123
|
+
|
124
|
+
parse_args_ignoring_files_or_dirs_to_run(
|
125
|
+
Shellwords.split(ENV["SPEC_OPTS"]),
|
126
|
+
"ENV['SPEC_OPTS']"
|
127
|
+
)
|
124
128
|
end
|
125
129
|
|
126
130
|
def command_line_options
|
127
|
-
@command_line_options ||= Parser.parse(@args)
|
131
|
+
@command_line_options ||= Parser.parse(@args)
|
128
132
|
end
|
129
133
|
|
130
134
|
def custom_options
|
@@ -144,7 +148,14 @@ module RSpec
|
|
144
148
|
end
|
145
149
|
|
146
150
|
def options_from(path)
|
147
|
-
|
151
|
+
args = args_from_options_file(path)
|
152
|
+
parse_args_ignoring_files_or_dirs_to_run(args, path)
|
153
|
+
end
|
154
|
+
|
155
|
+
def parse_args_ignoring_files_or_dirs_to_run(args, source)
|
156
|
+
options = Parser.parse(args, source)
|
157
|
+
options.delete(:files_or_directories_to_run)
|
158
|
+
options
|
148
159
|
end
|
149
160
|
|
150
161
|
def args_from_options_file(path)
|
@@ -162,11 +173,11 @@ module RSpec
|
|
162
173
|
end
|
163
174
|
|
164
175
|
def project_options_file
|
165
|
-
"
|
176
|
+
"./.rspec"
|
166
177
|
end
|
167
178
|
|
168
179
|
def local_options_file
|
169
|
-
"
|
180
|
+
"./.rspec-local"
|
170
181
|
end
|
171
182
|
|
172
183
|
def global_options_file
|
data/lib/rspec/core/example.rb
CHANGED
@@ -92,15 +92,32 @@ module RSpec
|
|
92
92
|
inspect_output
|
93
93
|
end
|
94
94
|
|
95
|
-
# Returns the argument that can be passed to the `rspec` command to rerun this example.
|
96
|
-
def
|
97
|
-
|
95
|
+
# Returns the location-based argument that can be passed to the `rspec` command to rerun this example.
|
96
|
+
def location_rerun_argument
|
97
|
+
@location_rerun_argument ||= begin
|
98
|
+
loaded_spec_files = RSpec.configuration.loaded_spec_files
|
98
99
|
|
99
|
-
|
100
|
-
|
100
|
+
Metadata.ascending(metadata) do |meta|
|
101
|
+
return meta[:location] if loaded_spec_files.include?(meta[:absolute_file_path])
|
102
|
+
end
|
101
103
|
end
|
102
104
|
end
|
103
105
|
|
106
|
+
# Returns the location-based argument that can be passed to the `rspec` command to rerun this example.
|
107
|
+
#
|
108
|
+
# @deprecated Use {#location_rerun_argument} instead.
|
109
|
+
# @note If there are multiple examples identified by this location, they will use {#id}
|
110
|
+
# to rerun instead, but this method will still return the location (that's why it is deprecated!).
|
111
|
+
def rerun_argument
|
112
|
+
location_rerun_argument
|
113
|
+
end
|
114
|
+
|
115
|
+
# @return [String] the unique id of this example. Pass
|
116
|
+
# this at the command line to re-run this exact example.
|
117
|
+
def id
|
118
|
+
@id ||= Metadata.id_from(metadata)
|
119
|
+
end
|
120
|
+
|
104
121
|
# @attr_reader
|
105
122
|
#
|
106
123
|
# Returns the first exception raised in the context of running this
|
@@ -138,13 +155,24 @@ module RSpec
|
|
138
155
|
@example_block = example_block
|
139
156
|
|
140
157
|
@metadata = Metadata::ExampleHash.create(
|
141
|
-
@example_group_class.metadata, user_metadata,
|
158
|
+
@example_group_class.metadata, user_metadata,
|
159
|
+
example_group_class.method(:next_runnable_index_for),
|
160
|
+
description, example_block
|
142
161
|
)
|
143
162
|
|
163
|
+
# This should perhaps be done in `Metadata::ExampleHash.create`,
|
164
|
+
# but the logic there has no knowledge of `RSpec.world` and we
|
165
|
+
# want to keep it that way. It's easier to just assign it here.
|
166
|
+
@metadata[:last_run_status] = RSpec.configuration.last_run_statuses[id]
|
167
|
+
|
144
168
|
@example_group_instance = @exception = nil
|
145
169
|
@clock = RSpec::Core::Time
|
170
|
+
@reporter = RSpec::Core::NullReporter
|
146
171
|
end
|
147
172
|
|
173
|
+
# @return [RSpec::Core::Reporter] the current reporter for the example
|
174
|
+
attr_reader :reporter
|
175
|
+
|
148
176
|
# Returns the example group class that provides the context for running
|
149
177
|
# this example.
|
150
178
|
def example_group
|
@@ -160,6 +188,7 @@ module RSpec
|
|
160
188
|
# @param example_group_instance the instance of an ExampleGroup subclass
|
161
189
|
def run(example_group_instance, reporter)
|
162
190
|
@example_group_instance = example_group_instance
|
191
|
+
@reporter = reporter
|
163
192
|
hooks.register_global_singleton_context_hooks(self, RSpec.configuration.hooks)
|
164
193
|
RSpec.configuration.configure_example(self)
|
165
194
|
RSpec.current_example = self
|
@@ -196,10 +225,7 @@ module RSpec
|
|
196
225
|
rescue Exception => e
|
197
226
|
set_exception(e)
|
198
227
|
ensure
|
199
|
-
|
200
|
-
@example_group_instance.instance_variable_set(ivar, nil)
|
201
|
-
end
|
202
|
-
@example_group_instance = nil
|
228
|
+
@example_group_instance = nil # if you love something... let it go
|
203
229
|
end
|
204
230
|
|
205
231
|
finish(reporter)
|
@@ -278,29 +304,55 @@ module RSpec
|
|
278
304
|
|
279
305
|
# @private
|
280
306
|
#
|
281
|
-
#
|
282
|
-
#
|
283
|
-
def
|
284
|
-
|
285
|
-
|
307
|
+
# The exception that will be displayed to the user -- either the failure of
|
308
|
+
# the example or the `pending_exception` if the example is pending.
|
309
|
+
def display_exception
|
310
|
+
@exception || execution_result.pending_exception
|
311
|
+
end
|
312
|
+
|
313
|
+
# @private
|
314
|
+
#
|
315
|
+
# Assigns the exception that will be displayed to the user -- either the failure of
|
316
|
+
# the example or the `pending_exception` if the example is pending.
|
317
|
+
def display_exception=(ex)
|
318
|
+
if pending? && !(Pending::PendingExampleFixedError === ex)
|
319
|
+
@exception = nil
|
320
|
+
execution_result.pending_fixed = false
|
321
|
+
execution_result.pending_exception = ex
|
286
322
|
else
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
msg = <<-EOS
|
323
|
+
@exception = ex
|
324
|
+
end
|
325
|
+
end
|
291
326
|
|
292
|
-
|
293
|
-
#{exception.class}: #{exception.message}
|
294
|
-
occurred at #{exception.backtrace.first}
|
327
|
+
# rubocop:disable Style/AccessorMethodName
|
295
328
|
|
296
|
-
|
297
|
-
|
298
|
-
|
329
|
+
# @private
|
330
|
+
#
|
331
|
+
# Used internally to set an exception in an after hook, which
|
332
|
+
# captures the exception but doesn't raise it.
|
333
|
+
def set_exception(exception)
|
334
|
+
return self.display_exception = exception unless display_exception
|
299
335
|
|
300
|
-
|
336
|
+
unless RSpec::Core::MultipleExceptionError === display_exception
|
337
|
+
self.display_exception = RSpec::Core::MultipleExceptionError.new(display_exception)
|
301
338
|
end
|
339
|
+
|
340
|
+
display_exception.add exception
|
341
|
+
end
|
342
|
+
|
343
|
+
# @private
|
344
|
+
#
|
345
|
+
# Used to set the exception when `aggregate_failures` fails.
|
346
|
+
def set_aggregate_failures_exception(exception)
|
347
|
+
return set_exception(exception) unless display_exception
|
348
|
+
|
349
|
+
exception = RSpec::Core::MultipleExceptionError::InterfaceTag.for(exception)
|
350
|
+
exception.add display_exception
|
351
|
+
self.display_exception = exception
|
302
352
|
end
|
303
353
|
|
354
|
+
# rubocop:enable Style/AccessorMethodName
|
355
|
+
|
304
356
|
# @private
|
305
357
|
#
|
306
358
|
# Used internally to set an exception and fail without actually executing
|
@@ -321,13 +373,6 @@ module RSpec
|
|
321
373
|
finish(reporter)
|
322
374
|
end
|
323
375
|
|
324
|
-
# @private
|
325
|
-
def instance_exec_with_rescue(context, &block)
|
326
|
-
@example_group_instance.instance_exec(self, &block)
|
327
|
-
rescue Exception => e
|
328
|
-
set_exception(e, context)
|
329
|
-
end
|
330
|
-
|
331
376
|
# @private
|
332
377
|
def instance_exec(*args, &block)
|
333
378
|
@example_group_instance.instance_exec(*args, &block)
|
@@ -342,7 +387,7 @@ module RSpec
|
|
342
387
|
def with_around_example_hooks
|
343
388
|
hooks.run(:around, :example, self) { yield }
|
344
389
|
rescue Exception => e
|
345
|
-
set_exception(e
|
390
|
+
set_exception(e)
|
346
391
|
end
|
347
392
|
|
348
393
|
def start(reporter)
|
@@ -398,13 +443,7 @@ module RSpec
|
|
398
443
|
def verify_mocks
|
399
444
|
@example_group_instance.verify_mocks_for_rspec if mocks_need_verification?
|
400
445
|
rescue Exception => e
|
401
|
-
|
402
|
-
execution_result.pending_fixed = false
|
403
|
-
execution_result.pending_exception = e
|
404
|
-
@exception = nil
|
405
|
-
else
|
406
|
-
set_exception(e)
|
407
|
-
end
|
446
|
+
set_exception(e)
|
408
447
|
end
|
409
448
|
|
410
449
|
def mocks_need_verification?
|
@@ -431,14 +470,6 @@ module RSpec
|
|
431
470
|
"example at #{location}"
|
432
471
|
end
|
433
472
|
|
434
|
-
def skip_message
|
435
|
-
if String === skip
|
436
|
-
skip
|
437
|
-
else
|
438
|
-
Pending::NO_REASON_GIVEN
|
439
|
-
end
|
440
|
-
end
|
441
|
-
|
442
473
|
# Represents the result of executing an example.
|
443
474
|
# Behaves like a hash for backwards compatibility.
|
444
475
|
class ExecutionResult
|
@@ -529,10 +560,13 @@ module RSpec
|
|
529
560
|
super(AnonymousExampleGroup, "", {})
|
530
561
|
end
|
531
562
|
|
563
|
+
# rubocop:disable Style/AccessorMethodName
|
564
|
+
|
532
565
|
# To ensure we don't silence errors.
|
533
|
-
def set_exception(exception
|
566
|
+
def set_exception(exception)
|
534
567
|
raise exception
|
535
568
|
end
|
569
|
+
# rubocop:enable Style/AccessorMethodName
|
536
570
|
end
|
537
571
|
end
|
538
572
|
end
|
@@ -142,8 +142,9 @@ module RSpec
|
|
142
142
|
options.update(:skip => RSpec::Core::Pending::NOT_YET_IMPLEMENTED) unless block
|
143
143
|
options.update(extra_options)
|
144
144
|
|
145
|
-
|
146
|
-
examples
|
145
|
+
example = RSpec::Core::Example.new(self, desc, options, block)
|
146
|
+
examples << example
|
147
|
+
example
|
147
148
|
end
|
148
149
|
end
|
149
150
|
|
@@ -230,7 +231,7 @@ module RSpec
|
|
230
231
|
# @see DSL#describe
|
231
232
|
def self.define_example_group_method(name, metadata={})
|
232
233
|
idempotently_define_singleton_method(name) do |*args, &example_group_block|
|
233
|
-
thread_data = RSpec.
|
234
|
+
thread_data = RSpec::Support.thread_local_data
|
234
235
|
top_level = self == ExampleGroup
|
235
236
|
|
236
237
|
if top_level
|
@@ -359,7 +360,6 @@ module RSpec
|
|
359
360
|
def self.subclass(parent, description, args, &example_group_block)
|
360
361
|
subclass = Class.new(parent)
|
361
362
|
subclass.set_it_up(description, *args, &example_group_block)
|
362
|
-
ExampleGroups.assign_const(subclass)
|
363
363
|
subclass.module_exec(&example_group_block) if example_group_block
|
364
364
|
|
365
365
|
# The LetDefinitions module must be included _after_ other modules
|
@@ -372,7 +372,7 @@ module RSpec
|
|
372
372
|
end
|
373
373
|
|
374
374
|
# @private
|
375
|
-
def self.set_it_up(*args, &example_group_block)
|
375
|
+
def self.set_it_up(description, *args, &example_group_block)
|
376
376
|
# Ruby 1.9 has a bug that can lead to infinite recursion and a
|
377
377
|
# SystemStackError if you include a module in a superclass after
|
378
378
|
# including it in a subclass: https://gist.github.com/845896
|
@@ -383,13 +383,14 @@ module RSpec
|
|
383
383
|
# here.
|
384
384
|
ensure_example_groups_are_configured
|
385
385
|
|
386
|
-
description = args.shift
|
387
386
|
user_metadata = Metadata.build_hash_from(args)
|
388
|
-
args.unshift(description)
|
389
387
|
|
390
388
|
@metadata = Metadata::ExampleGroupHash.create(
|
391
|
-
superclass_metadata, user_metadata,
|
389
|
+
superclass_metadata, user_metadata,
|
390
|
+
superclass.method(:next_runnable_index_for),
|
391
|
+
description, *args, &example_group_block
|
392
392
|
)
|
393
|
+
ExampleGroups.assign_const(self)
|
393
394
|
|
394
395
|
hooks.register_globals(self, RSpec.configuration.hooks)
|
395
396
|
RSpec.configuration.configure_group(self)
|
@@ -416,6 +417,15 @@ module RSpec
|
|
416
417
|
@children ||= []
|
417
418
|
end
|
418
419
|
|
420
|
+
# @private
|
421
|
+
def self.next_runnable_index_for(file)
|
422
|
+
if self == ExampleGroup
|
423
|
+
RSpec.world.num_example_groups_defined_in(file)
|
424
|
+
else
|
425
|
+
children.count + examples.count
|
426
|
+
end + 1
|
427
|
+
end
|
428
|
+
|
419
429
|
# @private
|
420
430
|
def self.descendants
|
421
431
|
@_descendants ||= [self] + FlatMap.flat_map(children, &:descendants)
|
@@ -428,7 +438,7 @@ module RSpec
|
|
428
438
|
|
429
439
|
# @private
|
430
440
|
def self.top_level?
|
431
|
-
|
441
|
+
superclass == ExampleGroup
|
432
442
|
end
|
433
443
|
|
434
444
|
# @private
|
@@ -458,7 +468,7 @@ module RSpec
|
|
458
468
|
def self.run_before_context_hooks(example_group_instance)
|
459
469
|
set_ivars(example_group_instance, superclass_before_context_ivars)
|
460
470
|
|
461
|
-
|
471
|
+
ContextHookMemoized::Before.isolate_for_context_hook(example_group_instance) do
|
462
472
|
hooks.run(:before, :context, example_group_instance)
|
463
473
|
end
|
464
474
|
ensure
|
@@ -471,6 +481,7 @@ module RSpec
|
|
471
481
|
superclass.before_context_ivars
|
472
482
|
end
|
473
483
|
else # 1.8.7
|
484
|
+
# :nocov:
|
474
485
|
# @private
|
475
486
|
def self.superclass_before_context_ivars
|
476
487
|
if superclass.respond_to?(:before_context_ivars)
|
@@ -485,13 +496,14 @@ module RSpec
|
|
485
496
|
ancestors.find { |a| a.respond_to?(:before_context_ivars) }.before_context_ivars
|
486
497
|
end
|
487
498
|
end
|
499
|
+
# :nocov:
|
488
500
|
end
|
489
501
|
|
490
502
|
# @private
|
491
503
|
def self.run_after_context_hooks(example_group_instance)
|
492
504
|
set_ivars(example_group_instance, before_context_ivars)
|
493
505
|
|
494
|
-
|
506
|
+
ContextHookMemoized::After.isolate_for_context_hook(example_group_instance) do
|
495
507
|
hooks.run(:after, :context, example_group_instance)
|
496
508
|
end
|
497
509
|
ensure
|
@@ -499,11 +511,8 @@ module RSpec
|
|
499
511
|
end
|
500
512
|
|
501
513
|
# Runs all the examples in this group.
|
502
|
-
def self.run(reporter=RSpec::Core::NullReporter
|
503
|
-
if RSpec.world.wants_to_quit
|
504
|
-
RSpec.world.clear_remaining_example_groups if top_level?
|
505
|
-
return
|
506
|
-
end
|
514
|
+
def self.run(reporter=RSpec::Core::NullReporter)
|
515
|
+
return if RSpec.world.wants_to_quit
|
507
516
|
reporter.example_group_started(self)
|
508
517
|
|
509
518
|
should_run_context_hooks = descendant_filtered_examples.any?
|
@@ -518,6 +527,7 @@ module RSpec
|
|
518
527
|
rescue Exception => ex
|
519
528
|
RSpec.world.wants_to_quit = true if fail_fast?
|
520
529
|
for_filtered_examples(reporter) { |example| example.fail_with_exception(reporter, ex) }
|
530
|
+
false
|
521
531
|
ensure
|
522
532
|
run_after_context_hooks(new('after(:context) hook')) if should_run_context_hooks
|
523
533
|
reporter.example_group_finished(self)
|
@@ -576,6 +586,12 @@ module RSpec
|
|
576
586
|
FlatMap.flat_map(children, &:declaration_line_numbers)
|
577
587
|
end
|
578
588
|
|
589
|
+
# @return [String] the unique id of this example group. Pass
|
590
|
+
# this at the command line to re-run this exact example group.
|
591
|
+
def self.id
|
592
|
+
Metadata.id_from(metadata)
|
593
|
+
end
|
594
|
+
|
579
595
|
# @private
|
580
596
|
def self.top_level_description
|
581
597
|
parent_groups.last.description
|
@@ -587,8 +603,10 @@ module RSpec
|
|
587
603
|
end
|
588
604
|
|
589
605
|
if RUBY_VERSION.to_f < 1.9
|
606
|
+
# :nocov:
|
590
607
|
# @private
|
591
608
|
INSTANCE_VARIABLE_TO_IGNORE = '@__inspect_output'.freeze
|
609
|
+
# :nocov:
|
592
610
|
else
|
593
611
|
# @private
|
594
612
|
INSTANCE_VARIABLE_TO_IGNORE = :@__inspect_output
|
@@ -603,6 +621,7 @@ module RSpec
|
|
603
621
|
|
604
622
|
def initialize(inspect_output=nil)
|
605
623
|
@__inspect_output = inspect_output || '(no description provided)'
|
624
|
+
super() # no args get passed
|
606
625
|
end
|
607
626
|
|
608
627
|
# @private
|
@@ -611,10 +630,12 @@ module RSpec
|
|
611
630
|
end
|
612
631
|
|
613
632
|
unless method_defined?(:singleton_class) # for 1.8.7
|
633
|
+
# :nocov:
|
614
634
|
# @private
|
615
635
|
def singleton_class
|
616
636
|
class << self; self; end
|
617
637
|
end
|
638
|
+
# :nocov:
|
618
639
|
end
|
619
640
|
|
620
641
|
# Raised when an RSpec API is called in the wrong scope, such as `before`
|
@@ -689,17 +710,22 @@ module RSpec
|
|
689
710
|
|
690
711
|
# @private
|
691
712
|
def self.current_backtrace
|
692
|
-
|
713
|
+
shared_example_group_inclusions.reverse
|
693
714
|
end
|
694
715
|
|
695
716
|
# @private
|
696
717
|
def self.with_frame(name, location)
|
697
|
-
current_stack =
|
718
|
+
current_stack = shared_example_group_inclusions
|
698
719
|
current_stack << new(name, location)
|
699
720
|
yield
|
700
721
|
ensure
|
701
722
|
current_stack.pop
|
702
723
|
end
|
724
|
+
|
725
|
+
# @private
|
726
|
+
def self.shared_example_group_inclusions
|
727
|
+
RSpec::Support.thread_local_data[:shared_example_group_inclusions] ||= []
|
728
|
+
end
|
703
729
|
end
|
704
730
|
end
|
705
731
|
|
@@ -746,6 +772,7 @@ module RSpec
|
|
746
772
|
end
|
747
773
|
|
748
774
|
if RUBY_VERSION == '1.9.2'
|
775
|
+
# :nocov:
|
749
776
|
class << self
|
750
777
|
alias _base_name_for base_name_for
|
751
778
|
def base_name_for(group)
|
@@ -753,6 +780,7 @@ module RSpec
|
|
753
780
|
end
|
754
781
|
end
|
755
782
|
private_class_method :_base_name_for
|
783
|
+
# :nocov:
|
756
784
|
end
|
757
785
|
|
758
786
|
def self.disambiguate(name, const_scope)
|