rspec-core 3.7.0 → 3.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +80 -2
- data/README.md +16 -16
- data/lib/rspec/core.rb +1 -0
- 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 +5 -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 +219 -62
- data/lib/rspec/core/configuration_options.rb +41 -4
- data/lib/rspec/core/did_you_mean.rb +46 -0
- data/lib/rspec/core/example.rb +8 -5
- data/lib/rspec/core/example_group.rb +8 -3
- data/lib/rspec/core/formatters.rb +13 -6
- data/lib/rspec/core/formatters/base_bisect_formatter.rb +45 -0
- 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/deprecation_formatter.rb +3 -1
- data/lib/rspec/core/formatters/documentation_formatter.rb +35 -3
- data/lib/rspec/core/formatters/exception_presenter.rb +13 -1
- data/lib/rspec/core/formatters/failure_list_formatter.rb +23 -0
- data/lib/rspec/core/formatters/html_printer.rb +0 -2
- data/lib/rspec/core/formatters/protocol.rb +17 -17
- data/lib/rspec/core/formatters/syntax_highlighter.rb +19 -19
- data/lib/rspec/core/hooks.rb +15 -9
- data/lib/rspec/core/invocations.rb +8 -6
- data/lib/rspec/core/memoized_helpers.rb +33 -14
- data/lib/rspec/core/metadata.rb +2 -3
- data/lib/rspec/core/option_parser.rb +8 -0
- data/lib/rspec/core/profiler.rb +3 -1
- data/lib/rspec/core/rake_task.rb +21 -1
- data/lib/rspec/core/reporter.rb +11 -6
- data/lib/rspec/core/runner.rb +25 -14
- data/lib/rspec/core/shared_example_group.rb +2 -4
- data/lib/rspec/core/shell_escape.rb +2 -2
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/world.rb +11 -0
- metadata +22 -13
- metadata.gz.sig +0 -0
- data/lib/rspec/core/formatters/bisect_formatter.rb +0 -69
@@ -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,6 +193,17 @@ 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
|
189
209
|
# :nocov:
|
@@ -191,6 +211,23 @@ module RSpec
|
|
191
211
|
nil
|
192
212
|
# :nocov:
|
193
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:
|
230
|
+
end
|
194
231
|
end
|
195
232
|
end
|
196
233
|
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/example.rb
CHANGED
@@ -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
|
@@ -393,7 +396,7 @@ module RSpec
|
|
393
396
|
end
|
394
397
|
end
|
395
398
|
|
396
|
-
# rubocop:disable
|
399
|
+
# rubocop:disable Naming/AccessorMethodName
|
397
400
|
|
398
401
|
# @private
|
399
402
|
#
|
@@ -420,7 +423,7 @@ module RSpec
|
|
420
423
|
self.display_exception = exception
|
421
424
|
end
|
422
425
|
|
423
|
-
# rubocop:enable
|
426
|
+
# rubocop:enable Naming/AccessorMethodName
|
424
427
|
|
425
428
|
# @private
|
426
429
|
#
|
@@ -642,12 +645,12 @@ module RSpec
|
|
642
645
|
@reporter = reporter
|
643
646
|
end
|
644
647
|
|
645
|
-
# rubocop:disable
|
648
|
+
# rubocop:disable Naming/AccessorMethodName
|
646
649
|
def set_exception(exception)
|
647
650
|
reporter.notify_non_example_exception(exception, "An error occurred in #{description}.")
|
648
651
|
RSpec.world.wants_to_quit = true
|
649
652
|
end
|
650
|
-
# rubocop:enable
|
653
|
+
# rubocop:enable Naming/AccessorMethodName
|
651
654
|
end
|
652
655
|
end
|
653
656
|
end
|
@@ -7,7 +7,7 @@ module RSpec
|
|
7
7
|
# ExampleGroup and {Example} are the main structural elements of
|
8
8
|
# rspec-core. Consider this example:
|
9
9
|
#
|
10
|
-
# describe Thing do
|
10
|
+
# RSpec.describe Thing do
|
11
11
|
# it "does something" do
|
12
12
|
# end
|
13
13
|
# end
|
@@ -90,7 +90,7 @@ module RSpec
|
|
90
90
|
# Returns the class or module passed to the `describe` method (or alias).
|
91
91
|
# Returns nil if the subject is not a class or module.
|
92
92
|
# @example
|
93
|
-
# describe Thing do
|
93
|
+
# RSpec.describe Thing do
|
94
94
|
# it "does something" do
|
95
95
|
# described_class == Thing
|
96
96
|
# end
|
@@ -107,6 +107,7 @@ module RSpec
|
|
107
107
|
# @private
|
108
108
|
# @macro [attach] define_example_method
|
109
109
|
# @!scope class
|
110
|
+
# @method $1
|
110
111
|
# @overload $1
|
111
112
|
# @overload $1(&example_implementation)
|
112
113
|
# @param example_implementation [Block] The implementation of the example.
|
@@ -423,11 +424,15 @@ module RSpec
|
|
423
424
|
superclass.method(:next_runnable_index_for),
|
424
425
|
description, *args, &example_group_block
|
425
426
|
)
|
427
|
+
|
428
|
+
config = RSpec.configuration
|
429
|
+
config.apply_derived_metadata_to(@metadata)
|
430
|
+
|
426
431
|
ExampleGroups.assign_const(self)
|
427
432
|
|
428
433
|
@currently_executing_a_context_hook = false
|
429
434
|
|
430
|
-
|
435
|
+
config.configure_group(self)
|
431
436
|
end
|
432
437
|
|
433
438
|
# @private
|
@@ -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
|
@@ -133,9 +134,6 @@ module RSpec::Core::Formatters
|
|
133
134
|
end
|
134
135
|
|
135
136
|
return unless RSpec.configuration.profile_examples?
|
136
|
-
|
137
|
-
@reporter.setup_profiler
|
138
|
-
|
139
137
|
return if existing_formatter_implements?(:dump_profile)
|
140
138
|
|
141
139
|
add RSpec::Core::Formatters::ProfileFormatter, output_stream
|
@@ -143,6 +141,13 @@ module RSpec::Core::Formatters
|
|
143
141
|
|
144
142
|
# @private
|
145
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
|
+
|
146
151
|
formatter_class = find_formatter(formatter_to_use)
|
147
152
|
|
148
153
|
args = paths.map { |p| p.respond_to?(:puts) ? p : open_stream(p) }
|
@@ -206,8 +211,10 @@ module RSpec::Core::Formatters
|
|
206
211
|
ProgressFormatter
|
207
212
|
when 'j', 'json'
|
208
213
|
JsonFormatter
|
209
|
-
when 'bisect'
|
210
|
-
|
214
|
+
when 'bisect-drb'
|
215
|
+
BisectDRbFormatter
|
216
|
+
when 'f', 'failures'
|
217
|
+
FailureListFormatter
|
211
218
|
end
|
212
219
|
end
|
213
220
|
|
@@ -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
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'drb/drb'
|
2
|
+
RSpec::Support.require_rspec_core "formatters/base_bisect_formatter"
|
3
|
+
|
4
|
+
module RSpec
|
5
|
+
module Core
|
6
|
+
module Formatters
|
7
|
+
# Used by `--bisect`. When it shells out and runs a portion of the suite, it uses
|
8
|
+
# this formatter as a means to have the status reported back to it, via DRb.
|
9
|
+
#
|
10
|
+
# Note that since DRb calls carry considerable overhead compared to normal
|
11
|
+
# method calls, we try to minimize the number of DRb calls for perf reasons,
|
12
|
+
# opting to communicate only at the start and the end of the run, rather than
|
13
|
+
# after each example.
|
14
|
+
# @private
|
15
|
+
class BisectDRbFormatter < BaseBisectFormatter
|
16
|
+
def initialize(_output)
|
17
|
+
drb_uri = "druby://localhost:#{RSpec.configuration.drb_port}"
|
18
|
+
@bisect_server = DRbObject.new_with_uri(drb_uri)
|
19
|
+
RSpec.configuration.files_or_directories_to_run = @bisect_server.files_or_directories_to_run
|
20
|
+
super(Set.new(@bisect_server.expected_failures))
|
21
|
+
end
|
22
|
+
|
23
|
+
def notify_results(results)
|
24
|
+
@bisect_server.latest_run_results = results
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -6,19 +6,14 @@ module RSpec
|
|
6
6
|
# @private
|
7
7
|
# Produces progress output while bisecting.
|
8
8
|
class BisectProgressFormatter < BaseTextFormatter
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
:bisect_failed, :bisect_aborted,
|
14
|
-
:bisect_round_ignoring_ids, :bisect_round_detected_multiple_culprits,
|
15
|
-
:bisect_dependency_check_started, :bisect_dependency_check_passed,
|
16
|
-
:bisect_dependency_check_failed
|
9
|
+
def initialize(output, bisect_runner)
|
10
|
+
super(output)
|
11
|
+
@bisect_runner = bisect_runner
|
12
|
+
end
|
17
13
|
|
18
14
|
def bisect_starting(notification)
|
19
15
|
@round_count = 0
|
20
|
-
|
21
|
-
output.puts "Bisect started using options: #{options.inspect}"
|
16
|
+
output.puts bisect_started_message(notification)
|
22
17
|
output.print "Running suite to find failures..."
|
23
18
|
end
|
24
19
|
|
@@ -40,6 +35,16 @@ module RSpec
|
|
40
35
|
|
41
36
|
def bisect_dependency_check_failed(_notification)
|
42
37
|
output.puts " failure(s) do not require any non-failures to run first"
|
38
|
+
|
39
|
+
if @bisect_runner == :fork
|
40
|
+
output.puts
|
41
|
+
output.puts "=" * 80
|
42
|
+
output.puts "NOTE: this bisect run used `config.bisect_runner = :fork`, which generally"
|
43
|
+
output.puts "provides significantly faster bisection runs than the old shell-based runner,"
|
44
|
+
output.puts "but may inaccurately report that no non-failures are required. If this result"
|
45
|
+
output.puts "is unexpected, consider setting `config.bisect_runner = :shell` and trying again."
|
46
|
+
output.puts "=" * 80
|
47
|
+
end
|
43
48
|
end
|
44
49
|
|
45
50
|
def bisect_round_started(notification, include_trailing_space=true)
|
@@ -85,16 +90,20 @@ module RSpec
|
|
85
90
|
output.puts "\n\nBisect aborted!"
|
86
91
|
output.puts "\nThe most minimal reproduction command discovered so far is:\n #{notification.repro}"
|
87
92
|
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def bisect_started_message(notification)
|
97
|
+
options = notification.original_cli_args.join(' ')
|
98
|
+
"Bisect started using options: #{options.inspect}"
|
99
|
+
end
|
88
100
|
end
|
89
101
|
|
90
102
|
# @private
|
91
|
-
# Produces detailed debug output while bisecting. Used when
|
92
|
-
#
|
93
|
-
#
|
103
|
+
# Produces detailed debug output while bisecting. Used when bisect is
|
104
|
+
# performed with `--bisect=verbose`. Designed to provide details for
|
105
|
+
# us when we need to troubleshoot bisect bugs.
|
94
106
|
class BisectDebugFormatter < BisectProgressFormatter
|
95
|
-
Formatters.register self, :bisect_original_run_complete, :bisect_individual_run_start,
|
96
|
-
:bisect_individual_run_complete, :bisect_round_ignoring_ids
|
97
|
-
|
98
107
|
def bisect_original_run_complete(notification)
|
99
108
|
output.puts " (#{Helpers.format_duration(notification.duration)})"
|
100
109
|
|
@@ -138,6 +147,10 @@ module RSpec
|
|
138
147
|
formatted_ids = organized_ids.map { |id| " - #{id}" }.join("\n")
|
139
148
|
"#{description} (#{ids.size}):\n#{formatted_ids}"
|
140
149
|
end
|
150
|
+
|
151
|
+
def bisect_started_message(notification)
|
152
|
+
"#{super} and bisect runner: #{notification.bisect_runner.inspect}"
|
153
|
+
end
|
141
154
|
end
|
142
155
|
end
|
143
156
|
end
|
@@ -62,6 +62,7 @@ module RSpec
|
|
62
62
|
TOO_MANY_WARNINGS_NOTICE = "Too many similar deprecation messages " \
|
63
63
|
"reported, disregarding further reports. #{DEPRECATION_STREAM_NOTICE}"
|
64
64
|
|
65
|
+
# @private
|
65
66
|
SpecifiedDeprecationMessage = Struct.new(:type) do
|
66
67
|
def initialize(data)
|
67
68
|
@message = data.message
|
@@ -80,7 +81,7 @@ module RSpec
|
|
80
81
|
|
81
82
|
def output_formatted(str)
|
82
83
|
return str unless str.lines.count > 1
|
83
|
-
separator =
|
84
|
+
separator = '-' * 80
|
84
85
|
"#{separator}\n#{str.chomp}\n#{separator}"
|
85
86
|
end
|
86
87
|
|
@@ -89,6 +90,7 @@ module RSpec
|
|
89
90
|
end
|
90
91
|
end
|
91
92
|
|
93
|
+
# @private
|
92
94
|
GeneratedDeprecationMessage = Struct.new(:type) do
|
93
95
|
def initialize(data)
|
94
96
|
@data = data
|
@@ -6,12 +6,19 @@ module RSpec
|
|
6
6
|
module Formatters
|
7
7
|
# @private
|
8
8
|
class DocumentationFormatter < BaseTextFormatter
|
9
|
-
Formatters.register self, :example_group_started, :example_group_finished,
|
9
|
+
Formatters.register self, :example_started, :example_group_started, :example_group_finished,
|
10
10
|
:example_passed, :example_pending, :example_failed
|
11
11
|
|
12
12
|
def initialize(output)
|
13
13
|
super
|
14
14
|
@group_level = 0
|
15
|
+
|
16
|
+
@example_running = false
|
17
|
+
@messages = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def example_started(_notification)
|
21
|
+
@example_running = true
|
15
22
|
end
|
16
23
|
|
17
24
|
def example_group_started(notification)
|
@@ -27,19 +34,44 @@ module RSpec
|
|
27
34
|
|
28
35
|
def example_passed(passed)
|
29
36
|
output.puts passed_output(passed.example)
|
37
|
+
|
38
|
+
flush_messages
|
39
|
+
@example_running = false
|
30
40
|
end
|
31
41
|
|
32
42
|
def example_pending(pending)
|
33
43
|
output.puts pending_output(pending.example,
|
34
44
|
pending.example.execution_result.pending_message)
|
45
|
+
|
46
|
+
flush_messages
|
47
|
+
@example_running = false
|
35
48
|
end
|
36
49
|
|
37
50
|
def example_failed(failure)
|
38
51
|
output.puts failure_output(failure.example)
|
52
|
+
|
53
|
+
flush_messages
|
54
|
+
@example_running = false
|
55
|
+
end
|
56
|
+
|
57
|
+
def message(notification)
|
58
|
+
if @example_running
|
59
|
+
@messages << notification.message
|
60
|
+
else
|
61
|
+
output.puts "#{current_indentation}#{notification.message}"
|
62
|
+
end
|
39
63
|
end
|
40
64
|
|
41
65
|
private
|
42
66
|
|
67
|
+
def flush_messages
|
68
|
+
@messages.each do |message|
|
69
|
+
output.puts "#{current_indentation(1)}#{message}"
|
70
|
+
end
|
71
|
+
|
72
|
+
@messages.clear
|
73
|
+
end
|
74
|
+
|
43
75
|
def passed_output(example)
|
44
76
|
ConsoleCodes.wrap("#{current_indentation}#{example.description.strip}", :success)
|
45
77
|
end
|
@@ -61,8 +93,8 @@ module RSpec
|
|
61
93
|
@next_failure_index += 1
|
62
94
|
end
|
63
95
|
|
64
|
-
def current_indentation
|
65
|
-
' ' * @group_level
|
96
|
+
def current_indentation(offset=0)
|
97
|
+
' ' * (@group_level + offset)
|
66
98
|
end
|
67
99
|
end
|
68
100
|
end
|