rspec-core 3.2.3 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|