rspec-core 3.5.4 → 3.9.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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +165 -2
- data/README.md +16 -16
- data/lib/rspec/core.rb +2 -1
- data/lib/rspec/core/bisect/coordinator.rb +26 -30
- data/lib/rspec/core/bisect/example_minimizer.rb +12 -8
- data/lib/rspec/core/bisect/fork_runner.rb +134 -0
- data/lib/rspec/core/bisect/server.rb +10 -14
- data/lib/rspec/core/bisect/{runner.rb → shell_command.rb} +27 -70
- 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 +315 -79
- data/lib/rspec/core/configuration_options.rb +43 -4
- data/lib/rspec/core/did_you_mean.rb +46 -0
- data/lib/rspec/core/drb.rb +3 -1
- data/lib/rspec/core/example.rb +19 -12
- data/lib/rspec/core/example_group.rb +17 -7
- data/lib/rspec/core/formatters.rb +28 -11
- data/lib/rspec/core/formatters/base_bisect_formatter.rb +45 -0
- data/lib/rspec/core/formatters/base_formatter.rb +1 -1
- data/lib/rspec/core/formatters/base_text_formatter.rb +3 -5
- data/lib/rspec/core/formatters/bisect_drb_formatter.rb +29 -0
- data/lib/rspec/core/formatters/bisect_progress_formatter.rb +29 -16
- data/lib/rspec/core/formatters/console_codes.rb +7 -4
- data/lib/rspec/core/formatters/deprecation_formatter.rb +9 -9
- data/lib/rspec/core/formatters/documentation_formatter.rb +37 -4
- data/lib/rspec/core/formatters/exception_presenter.rb +21 -4
- data/lib/rspec/core/formatters/failure_list_formatter.rb +23 -0
- data/lib/rspec/core/formatters/html_formatter.rb +4 -2
- data/lib/rspec/core/formatters/html_printer.rb +3 -3
- data/lib/rspec/core/formatters/html_snippet_extractor.rb +4 -0
- data/lib/rspec/core/formatters/json_formatter.rb +9 -3
- data/lib/rspec/core/formatters/progress_formatter.rb +1 -0
- data/lib/rspec/core/formatters/protocol.rb +43 -42
- data/lib/rspec/core/formatters/snippet_extractor.rb +1 -3
- data/lib/rspec/core/{source → formatters}/syntax_highlighter.rb +21 -1
- data/lib/rspec/core/hooks.rb +18 -10
- data/lib/rspec/core/invocations.rb +30 -10
- data/lib/rspec/core/memoized_helpers.rb +36 -14
- data/lib/rspec/core/metadata.rb +2 -3
- data/lib/rspec/core/metadata_filter.rb +29 -17
- data/lib/rspec/core/notifications.rb +34 -11
- data/lib/rspec/core/option_parser.rb +32 -4
- data/lib/rspec/core/output_wrapper.rb +29 -0
- data/lib/rspec/core/profiler.rb +3 -1
- data/lib/rspec/core/project_initializer/.rspec +0 -1
- data/lib/rspec/core/project_initializer/spec/spec_helper.rb +1 -4
- data/lib/rspec/core/rake_task.rb +21 -1
- data/lib/rspec/core/reporter.rb +33 -16
- data/lib/rspec/core/runner.rb +31 -15
- data/lib/rspec/core/set.rb +5 -0
- data/lib/rspec/core/shared_example_group.rb +41 -19
- data/lib/rspec/core/shell_escape.rb +2 -2
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/world.rb +24 -5
- metadata +26 -20
- metadata.gz.sig +0 -0
- data/lib/rspec/core/formatters/bisect_formatter.rb +0 -69
- data/lib/rspec/core/source.rb +0 -86
- data/lib/rspec/core/source/location.rb +0 -13
- data/lib/rspec/core/source/node.rb +0 -93
- data/lib/rspec/core/source/token.rb +0 -87
@@ -4,8 +4,9 @@ require 'shellwords'
|
|
4
4
|
module RSpec
|
5
5
|
module Core
|
6
6
|
# Responsible for utilizing externally provided configuration options,
|
7
|
-
# whether via the command line, `.rspec`, `~/.rspec`,
|
8
|
-
# or a custom options
|
7
|
+
# whether via the command line, `.rspec`, `~/.rspec`,
|
8
|
+
# `$XDG_CONFIG_HOME/rspec/options`, `.rspec-local` or a custom options
|
9
|
+
# file.
|
9
10
|
class ConfigurationOptions
|
10
11
|
# @param args [Array<String>] command line arguments
|
11
12
|
def initialize(args)
|
@@ -118,7 +119,11 @@ module RSpec
|
|
118
119
|
end
|
119
120
|
|
120
121
|
def file_options
|
121
|
-
custom_options_file
|
122
|
+
if custom_options_file
|
123
|
+
[custom_options]
|
124
|
+
else
|
125
|
+
[global_options, project_options, local_options]
|
126
|
+
end
|
122
127
|
end
|
123
128
|
|
124
129
|
def env_options
|
@@ -168,7 +173,11 @@ module RSpec
|
|
168
173
|
end
|
169
174
|
|
170
175
|
def options_file_as_erb_string(path)
|
171
|
-
|
176
|
+
if RUBY_VERSION >= '2.6'
|
177
|
+
ERB.new(File.read(path), :trim_mode => '-').result(binding)
|
178
|
+
else
|
179
|
+
ERB.new(File.read(path), nil, '-').result(binding)
|
180
|
+
end
|
172
181
|
end
|
173
182
|
|
174
183
|
def custom_options_file
|
@@ -184,10 +193,40 @@ module RSpec
|
|
184
193
|
end
|
185
194
|
|
186
195
|
def global_options_file
|
196
|
+
xdg_options_file_if_exists || home_options_file_path
|
197
|
+
end
|
198
|
+
|
199
|
+
def xdg_options_file_if_exists
|
200
|
+
path = xdg_options_file_path
|
201
|
+
if path && File.exist?(path)
|
202
|
+
path
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def home_options_file_path
|
187
207
|
File.join(File.expand_path("~"), ".rspec")
|
188
208
|
rescue ArgumentError
|
209
|
+
# :nocov:
|
189
210
|
RSpec.warning "Unable to find ~/.rspec because the HOME environment variable is not set"
|
190
211
|
nil
|
212
|
+
# :nocov:
|
213
|
+
end
|
214
|
+
|
215
|
+
def xdg_options_file_path
|
216
|
+
xdg_config_home = resolve_xdg_config_home
|
217
|
+
if xdg_config_home
|
218
|
+
File.join(xdg_config_home, "rspec", "options")
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def resolve_xdg_config_home
|
223
|
+
File.expand_path(ENV.fetch("XDG_CONFIG_HOME", "~/.config"))
|
224
|
+
rescue ArgumentError
|
225
|
+
# :nocov:
|
226
|
+
# On Ruby 2.4, `File.expand("~")` works even if `ENV['HOME']` is not set.
|
227
|
+
# But on earlier versions, it fails.
|
228
|
+
nil
|
229
|
+
# :nocov:
|
191
230
|
end
|
192
231
|
end
|
193
232
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Core
|
3
|
+
# @private
|
4
|
+
# Wrapper around Ruby's `DidYouMean::SpellChecker` when available to provide file name suggestions.
|
5
|
+
class DidYouMean
|
6
|
+
attr_reader :relative_file_name
|
7
|
+
|
8
|
+
def initialize(relative_file_name)
|
9
|
+
@relative_file_name = relative_file_name
|
10
|
+
end
|
11
|
+
|
12
|
+
if defined?(::DidYouMean::SpellChecker)
|
13
|
+
# provide probable suggestions
|
14
|
+
def call
|
15
|
+
checker = ::DidYouMean::SpellChecker.new(:dictionary => Dir["spec/**/*.rb"])
|
16
|
+
probables = checker.correct(relative_file_name.sub('./', ''))[0..2]
|
17
|
+
return '' unless probables.any?
|
18
|
+
|
19
|
+
formats probables
|
20
|
+
end
|
21
|
+
else
|
22
|
+
# return a hint if API for ::DidYouMean::SpellChecker not supported
|
23
|
+
def call
|
24
|
+
"\nHint: Install the `did_you_mean` gem in order to provide suggestions for similarly named files."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def formats(probables)
|
31
|
+
rspec_format = probables.map { |s, _| "rspec ./#{s}" }
|
32
|
+
red_font(top_and_tail rspec_format)
|
33
|
+
end
|
34
|
+
|
35
|
+
def top_and_tail(rspec_format)
|
36
|
+
spaces = ' ' * 20
|
37
|
+
rspec_format.insert(0, ' - Did you mean?').join("\n#{spaces}") + "\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
def red_font(mytext)
|
41
|
+
colorizer = ::RSpec::Core::Formatters::ConsoleCodes
|
42
|
+
colorizer.wrap mytext, :failure
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/rspec/core/drb.rb
CHANGED
@@ -41,6 +41,8 @@ module RSpec
|
|
41
41
|
def options
|
42
42
|
argv = []
|
43
43
|
argv << "--color" if @submitted_options[:color]
|
44
|
+
argv << "--force-color" if @submitted_options[:color_mode] == :on
|
45
|
+
argv << "--no-color" if @submitted_options[:color_mode] == :off
|
44
46
|
argv << "--profile" if @submitted_options[:profile_examples]
|
45
47
|
argv << "--backtrace" if @submitted_options[:full_backtrace]
|
46
48
|
argv << "--tty" if @submitted_options[:tty]
|
@@ -82,7 +84,7 @@ module RSpec
|
|
82
84
|
def add_filter(argv, name, hash)
|
83
85
|
hash.each_pair do |k, v|
|
84
86
|
next if CONDITIONAL_FILTERS.include?(k)
|
85
|
-
tag = name == :inclusion ? k.to_s : "~#{k}"
|
87
|
+
tag = name == :inclusion ? k.to_s : "~#{k}".dup
|
86
88
|
tag << ":#{v}" if v.is_a?(String)
|
87
89
|
argv << "--tag" << tag
|
88
90
|
end unless hash.empty?
|
data/lib/rspec/core/example.rb
CHANGED
@@ -87,7 +87,7 @@ module RSpec
|
|
87
87
|
def inspect_output
|
88
88
|
inspect_output = "\"#{description}\""
|
89
89
|
unless metadata[:description].to_s.empty?
|
90
|
-
inspect_output
|
90
|
+
inspect_output += " (#{location})"
|
91
91
|
end
|
92
92
|
inspect_output
|
93
93
|
end
|
@@ -203,10 +203,13 @@ module RSpec
|
|
203
203
|
description, example_block
|
204
204
|
)
|
205
205
|
|
206
|
+
config = RSpec.configuration
|
207
|
+
config.apply_derived_metadata_to(@metadata)
|
208
|
+
|
206
209
|
# This should perhaps be done in `Metadata::ExampleHash.create`,
|
207
210
|
# but the logic there has no knowledge of `RSpec.world` and we
|
208
211
|
# want to keep it that way. It's easier to just assign it here.
|
209
|
-
@metadata[:last_run_status] =
|
212
|
+
@metadata[:last_run_status] = config.last_run_statuses[id]
|
210
213
|
|
211
214
|
@example_group_instance = @exception = nil
|
212
215
|
@clock = RSpec::Core::Time
|
@@ -260,7 +263,11 @@ module RSpec
|
|
260
263
|
'Expected example to fail since it is pending, but it passed.',
|
261
264
|
[location]
|
262
265
|
end
|
263
|
-
rescue Pending::SkipDeclaredInExample
|
266
|
+
rescue Pending::SkipDeclaredInExample => _
|
267
|
+
# The "=> _" is normally useless but on JRuby it is a workaround
|
268
|
+
# for a bug that prevents us from getting backtraces:
|
269
|
+
# https://github.com/jruby/jruby/issues/4467
|
270
|
+
#
|
264
271
|
# no-op, required metadata has already been set by the `skip`
|
265
272
|
# method.
|
266
273
|
rescue AllExceptionsExcludingDangerousOnesOnRubiesThatAllowIt => e
|
@@ -389,7 +396,7 @@ module RSpec
|
|
389
396
|
end
|
390
397
|
end
|
391
398
|
|
392
|
-
# rubocop:disable
|
399
|
+
# rubocop:disable Naming/AccessorMethodName
|
393
400
|
|
394
401
|
# @private
|
395
402
|
#
|
@@ -416,7 +423,7 @@ module RSpec
|
|
416
423
|
self.display_exception = exception
|
417
424
|
end
|
418
425
|
|
419
|
-
# rubocop:enable
|
426
|
+
# rubocop:enable Naming/AccessorMethodName
|
420
427
|
|
421
428
|
# @private
|
422
429
|
#
|
@@ -465,22 +472,22 @@ module RSpec
|
|
465
472
|
|
466
473
|
if @exception
|
467
474
|
execution_result.exception = @exception
|
468
|
-
record_finished :failed
|
475
|
+
record_finished :failed, reporter
|
469
476
|
reporter.example_failed self
|
470
477
|
false
|
471
478
|
elsif pending_message
|
472
479
|
execution_result.pending_message = pending_message
|
473
|
-
record_finished :pending
|
480
|
+
record_finished :pending, reporter
|
474
481
|
reporter.example_pending self
|
475
482
|
true
|
476
483
|
else
|
477
|
-
record_finished :passed
|
484
|
+
record_finished :passed, reporter
|
478
485
|
reporter.example_passed self
|
479
486
|
true
|
480
487
|
end
|
481
488
|
end
|
482
489
|
|
483
|
-
def record_finished(status)
|
490
|
+
def record_finished(status, reporter)
|
484
491
|
execution_result.record_finished(status, clock.now)
|
485
492
|
reporter.example_finished(self)
|
486
493
|
end
|
@@ -519,7 +526,7 @@ module RSpec
|
|
519
526
|
def assign_generated_description
|
520
527
|
if metadata[:description].empty? && (description = generate_description)
|
521
528
|
metadata[:description] = description
|
522
|
-
metadata[:full_description]
|
529
|
+
metadata[:full_description] += description
|
523
530
|
end
|
524
531
|
ensure
|
525
532
|
RSpec::Matchers.clear_generated_description
|
@@ -638,12 +645,12 @@ module RSpec
|
|
638
645
|
@reporter = reporter
|
639
646
|
end
|
640
647
|
|
641
|
-
# rubocop:disable
|
648
|
+
# rubocop:disable Naming/AccessorMethodName
|
642
649
|
def set_exception(exception)
|
643
650
|
reporter.notify_non_example_exception(exception, "An error occurred in #{description}.")
|
644
651
|
RSpec.world.wants_to_quit = true
|
645
652
|
end
|
646
|
-
# rubocop:enable
|
653
|
+
# rubocop:enable Naming/AccessorMethodName
|
647
654
|
end
|
648
655
|
end
|
649
656
|
end
|
@@ -3,10 +3,11 @@ RSpec::Support.require_rspec_support 'recursive_const_methods'
|
|
3
3
|
module RSpec
|
4
4
|
module Core
|
5
5
|
# rubocop:disable Metrics/ClassLength
|
6
|
+
|
6
7
|
# ExampleGroup and {Example} are the main structural elements of
|
7
8
|
# rspec-core. Consider this example:
|
8
9
|
#
|
9
|
-
# describe Thing do
|
10
|
+
# RSpec.describe Thing do
|
10
11
|
# it "does something" do
|
11
12
|
# end
|
12
13
|
# end
|
@@ -89,7 +90,7 @@ module RSpec
|
|
89
90
|
# Returns the class or module passed to the `describe` method (or alias).
|
90
91
|
# Returns nil if the subject is not a class or module.
|
91
92
|
# @example
|
92
|
-
# describe Thing do
|
93
|
+
# RSpec.describe Thing do
|
93
94
|
# it "does something" do
|
94
95
|
# described_class == Thing
|
95
96
|
# end
|
@@ -106,6 +107,7 @@ module RSpec
|
|
106
107
|
# @private
|
107
108
|
# @macro [attach] define_example_method
|
108
109
|
# @!scope class
|
110
|
+
# @method $1
|
109
111
|
# @overload $1
|
110
112
|
# @overload $1(&example_implementation)
|
111
113
|
# @param example_implementation [Block] The implementation of the example.
|
@@ -422,11 +424,15 @@ module RSpec
|
|
422
424
|
superclass.method(:next_runnable_index_for),
|
423
425
|
description, *args, &example_group_block
|
424
426
|
)
|
427
|
+
|
428
|
+
config = RSpec.configuration
|
429
|
+
config.apply_derived_metadata_to(@metadata)
|
430
|
+
|
425
431
|
ExampleGroups.assign_const(self)
|
426
432
|
|
427
433
|
@currently_executing_a_context_hook = false
|
428
434
|
|
429
|
-
|
435
|
+
config.configure_group(self)
|
430
436
|
end
|
431
437
|
|
432
438
|
# @private
|
@@ -793,8 +799,12 @@ module RSpec
|
|
793
799
|
# @private
|
794
800
|
def self.with_frame(name, location)
|
795
801
|
current_stack = shared_example_group_inclusions
|
796
|
-
current_stack
|
797
|
-
|
802
|
+
if current_stack.any? { |frame| frame.shared_group_name == name }
|
803
|
+
raise ArgumentError, "can't include shared examples recursively"
|
804
|
+
else
|
805
|
+
current_stack << new(name, location)
|
806
|
+
yield
|
807
|
+
end
|
798
808
|
ensure
|
799
809
|
current_stack.pop
|
800
810
|
end
|
@@ -834,10 +844,10 @@ module RSpec
|
|
834
844
|
end
|
835
845
|
|
836
846
|
def self.base_name_for(group)
|
837
|
-
return "Anonymous" if group.description.empty?
|
847
|
+
return "Anonymous".dup if group.description.empty?
|
838
848
|
|
839
849
|
# Convert to CamelCase.
|
840
|
-
name = ' '
|
850
|
+
name = ' ' + group.description
|
841
851
|
name.gsub!(/[^0-9a-zA-Z]+([0-9a-zA-Z])/) do
|
842
852
|
match = ::Regexp.last_match[1]
|
843
853
|
match.upcase!
|
@@ -24,7 +24,7 @@ RSpec::Support.require_rspec_support "directory_maker"
|
|
24
24
|
# ## Custom Formatters
|
25
25
|
#
|
26
26
|
# You can tell RSpec to use a custom formatter by passing its path and name to
|
27
|
-
# the `rspec`
|
27
|
+
# the `rspec` command. For example, if you define MyCustomFormatter in
|
28
28
|
# path/to/my_custom_formatter.rb, you would type this command:
|
29
29
|
#
|
30
30
|
# rspec --require path/to/my_custom_formatter.rb --format MyCustomFormatter
|
@@ -72,8 +72,9 @@ module RSpec::Core::Formatters
|
|
72
72
|
autoload :ProgressFormatter, 'rspec/core/formatters/progress_formatter'
|
73
73
|
autoload :ProfileFormatter, 'rspec/core/formatters/profile_formatter'
|
74
74
|
autoload :JsonFormatter, 'rspec/core/formatters/json_formatter'
|
75
|
-
autoload :
|
75
|
+
autoload :BisectDRbFormatter, 'rspec/core/formatters/bisect_drb_formatter'
|
76
76
|
autoload :ExceptionPresenter, 'rspec/core/formatters/exception_presenter'
|
77
|
+
autoload :FailureListFormatter, 'rspec/core/formatters/failure_list_formatter'
|
77
78
|
|
78
79
|
# Register the formatter class
|
79
80
|
# @param formatter_class [Class] formatter class to register
|
@@ -115,6 +116,11 @@ module RSpec::Core::Formatters
|
|
115
116
|
# @return [String] the default formatter to setup, defaults to `progress`
|
116
117
|
attr_accessor :default_formatter
|
117
118
|
|
119
|
+
# @private
|
120
|
+
def prepare_default(output_stream, deprecation_stream)
|
121
|
+
reporter.prepare_default(self, output_stream, deprecation_stream)
|
122
|
+
end
|
123
|
+
|
118
124
|
# @private
|
119
125
|
def setup_default(output_stream, deprecation_stream)
|
120
126
|
add default_formatter, output_stream if @formatters.empty?
|
@@ -128,9 +134,6 @@ module RSpec::Core::Formatters
|
|
128
134
|
end
|
129
135
|
|
130
136
|
return unless RSpec.configuration.profile_examples?
|
131
|
-
|
132
|
-
@reporter.setup_profiler
|
133
|
-
|
134
137
|
return if existing_formatter_implements?(:dump_profile)
|
135
138
|
|
136
139
|
add RSpec::Core::Formatters::ProfileFormatter, output_stream
|
@@ -138,9 +141,16 @@ module RSpec::Core::Formatters
|
|
138
141
|
|
139
142
|
# @private
|
140
143
|
def add(formatter_to_use, *paths)
|
144
|
+
# If a formatter instance was passed, we can register it directly,
|
145
|
+
# with no need for any of the further processing that happens below.
|
146
|
+
if Loader.formatters.key?(formatter_to_use.class)
|
147
|
+
register formatter_to_use, notifications_for(formatter_to_use.class)
|
148
|
+
return
|
149
|
+
end
|
150
|
+
|
141
151
|
formatter_class = find_formatter(formatter_to_use)
|
142
152
|
|
143
|
-
args = paths.map { |p| p.respond_to?(:puts) ? p :
|
153
|
+
args = paths.map { |p| p.respond_to?(:puts) ? p : open_stream(p) }
|
144
154
|
|
145
155
|
if !Loader.formatters[formatter_class].nil?
|
146
156
|
formatter = formatter_class.new(*args)
|
@@ -201,8 +211,10 @@ module RSpec::Core::Formatters
|
|
201
211
|
ProgressFormatter
|
202
212
|
when 'j', 'json'
|
203
213
|
JsonFormatter
|
204
|
-
when 'bisect'
|
205
|
-
|
214
|
+
when 'bisect-drb'
|
215
|
+
BisectDRbFormatter
|
216
|
+
when 'f', 'failures'
|
217
|
+
FailureListFormatter
|
206
218
|
end
|
207
219
|
end
|
208
220
|
|
@@ -247,9 +259,14 @@ module RSpec::Core::Formatters
|
|
247
259
|
word
|
248
260
|
end
|
249
261
|
|
250
|
-
def
|
251
|
-
RSpec::
|
252
|
-
|
262
|
+
def open_stream(path_or_wrapper)
|
263
|
+
if RSpec::Core::OutputWrapper === path_or_wrapper
|
264
|
+
path_or_wrapper.output = open_stream(path_or_wrapper.output)
|
265
|
+
path_or_wrapper
|
266
|
+
else
|
267
|
+
RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(path_or_wrapper))
|
268
|
+
File.new(path_or_wrapper, 'w')
|
269
|
+
end
|
253
270
|
end
|
254
271
|
end
|
255
272
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
RSpec::Support.require_rspec_core "bisect/utilities"
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Core
|
5
|
+
module Formatters
|
6
|
+
# Contains common logic for formatters used by `--bisect` to communicate results
|
7
|
+
# back to the bisect runner.
|
8
|
+
#
|
9
|
+
# Subclasses must define a `notify_results(all_example_ids, failed_example_ids)`
|
10
|
+
# method.
|
11
|
+
# @private
|
12
|
+
class BaseBisectFormatter
|
13
|
+
def self.inherited(formatter)
|
14
|
+
Formatters.register formatter, :start_dump, :example_failed, :example_finished
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(expected_failures)
|
18
|
+
@all_example_ids = []
|
19
|
+
@failed_example_ids = []
|
20
|
+
@remaining_failures = expected_failures
|
21
|
+
end
|
22
|
+
|
23
|
+
def example_failed(notification)
|
24
|
+
@failed_example_ids << notification.example.id
|
25
|
+
end
|
26
|
+
|
27
|
+
def example_finished(notification)
|
28
|
+
@all_example_ids << notification.example.id
|
29
|
+
return unless @remaining_failures.include?(notification.example.id)
|
30
|
+
@remaining_failures.delete(notification.example.id)
|
31
|
+
|
32
|
+
status = notification.example.execution_result.status
|
33
|
+
return if status == :failed && !@remaining_failures.empty?
|
34
|
+
RSpec.world.wants_to_quit = true
|
35
|
+
end
|
36
|
+
|
37
|
+
def start_dump(_notification)
|
38
|
+
# `notify_results` is defined in the subclass
|
39
|
+
notify_results(Bisect::ExampleSetDescriptor.new(
|
40
|
+
@all_example_ids, @failed_example_ids))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|