rspec-core 3.7.1 → 3.9.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +116 -0
- data/README.md +18 -18
- 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 +138 -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 +236 -79
- 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 +18 -8
- data/lib/rspec/core/example_group.rb +33 -16
- data/lib/rspec/core/filter_manager.rb +1 -1
- data/lib/rspec/core/formatters.rb +14 -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 +29 -6
- 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 +44 -24
- data/lib/rspec/core/invocations.rb +9 -7
- data/lib/rspec/core/memoized_helpers.rb +33 -14
- data/lib/rspec/core/metadata.rb +2 -3
- data/lib/rspec/core/option_parser.rb +10 -3
- data/lib/rspec/core/profiler.rb +3 -1
- data/lib/rspec/core/rake_task.rb +22 -2
- data/lib/rspec/core/reporter.rb +11 -6
- data/lib/rspec/core/runner.rb +25 -14
- data/lib/rspec/core/shared_example_group.rb +5 -5
- data/lib/rspec/core/shell_escape.rb +2 -2
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/world.rb +14 -1
- metadata +25 -15
- metadata.gz.sig +0 -0
- data/lib/rspec/core/formatters/bisect_formatter.rb +0 -69
@@ -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
|
@@ -43,7 +43,7 @@ module RSpec
|
|
43
43
|
|
44
44
|
if RSpec::Support::RubyFeatures.supports_exception_cause?
|
45
45
|
def formatted_cause(exception)
|
46
|
-
last_cause = final_exception(exception)
|
46
|
+
last_cause = final_exception(exception, [exception])
|
47
47
|
cause = []
|
48
48
|
|
49
49
|
if exception.cause
|
@@ -51,11 +51,13 @@ module RSpec
|
|
51
51
|
cause << '--- Caused by: ---'
|
52
52
|
cause << "#{exception_class_name(last_cause)}:" unless exception_class_name(last_cause) =~ /RSpec/
|
53
53
|
|
54
|
-
encoded_string(last_cause
|
54
|
+
encoded_string(exception_message_string(last_cause)).split("\n").each do |line|
|
55
55
|
cause << " #{line}"
|
56
56
|
end
|
57
57
|
|
58
|
-
|
58
|
+
unless last_cause.backtrace.empty?
|
59
|
+
cause << (" #{backtrace_formatter.format_backtrace(last_cause.backtrace, example.metadata).first}")
|
60
|
+
end
|
59
61
|
end
|
60
62
|
|
61
63
|
cause
|
@@ -81,7 +83,7 @@ module RSpec
|
|
81
83
|
|
82
84
|
def fully_formatted_lines(failure_number, colorizer)
|
83
85
|
lines = [
|
84
|
-
description,
|
86
|
+
encoded_description(description),
|
85
87
|
detail_formatter.call(example, colorizer),
|
86
88
|
formatted_message_and_backtrace(colorizer),
|
87
89
|
extra_detail_formatter.call(failure_number, colorizer),
|
@@ -96,7 +98,8 @@ module RSpec
|
|
96
98
|
|
97
99
|
def final_exception(exception, previous=[])
|
98
100
|
cause = exception.cause
|
99
|
-
|
101
|
+
|
102
|
+
if cause && Exception === cause && !previous.include?(cause)
|
100
103
|
previous << cause
|
101
104
|
final_exception(cause, previous)
|
102
105
|
else
|
@@ -171,10 +174,18 @@ module RSpec
|
|
171
174
|
lines
|
172
175
|
end
|
173
176
|
|
177
|
+
# 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}."
|
182
|
+
end
|
183
|
+
# rubocop:enable Lint/RescueException
|
184
|
+
|
174
185
|
def exception_lines
|
175
186
|
lines = []
|
176
187
|
lines << "#{exception_class_name}:" unless exception_class_name =~ /RSpec/
|
177
|
-
encoded_string(exception
|
188
|
+
encoded_string(exception_message_string(exception)).split("\n").each do |line|
|
178
189
|
lines << (line.empty? ? line : " #{line}")
|
179
190
|
end
|
180
191
|
lines
|
@@ -244,6 +255,17 @@ module RSpec
|
|
244
255
|
end
|
245
256
|
end
|
246
257
|
|
258
|
+
if String.method_defined?(:encoding)
|
259
|
+
def encoded_description(description)
|
260
|
+
return if description.nil?
|
261
|
+
encoded_string(description)
|
262
|
+
end
|
263
|
+
else # for 1.8.7
|
264
|
+
def encoded_description(description)
|
265
|
+
description
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
247
269
|
def exception_backtrace
|
248
270
|
exception.backtrace || []
|
249
271
|
end
|
@@ -379,6 +401,7 @@ module RSpec
|
|
379
401
|
parent_bt[index] != child_bt[index]
|
380
402
|
end
|
381
403
|
|
404
|
+
return child if index_before_first_common_frame.nil?
|
382
405
|
return child if index_before_first_common_frame == -1
|
383
406
|
|
384
407
|
child = child.dup
|
@@ -0,0 +1,23 @@
|
|
1
|
+
RSpec::Support.require_rspec_core "formatters/base_formatter"
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Core
|
5
|
+
module Formatters
|
6
|
+
# @private
|
7
|
+
class FailureListFormatter < BaseFormatter
|
8
|
+
Formatters.register self, :example_failed, :dump_profile, :message
|
9
|
+
|
10
|
+
def example_failed(failure)
|
11
|
+
output.puts "#{failure.example.location}:#{failure.example.description}"
|
12
|
+
end
|
13
|
+
|
14
|
+
# Discard profile and messages
|
15
|
+
#
|
16
|
+
# These outputs are not really relevant in the context of this failure
|
17
|
+
# list formatter.
|
18
|
+
def dump_profile(_profile); end
|
19
|
+
def message(_message); end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -115,7 +115,6 @@ module RSpec
|
|
115
115
|
"style=\"margin-left: #{(number_of_parents - 1) * 15}px;\""
|
116
116
|
end
|
117
117
|
|
118
|
-
# rubocop:disable LineLength
|
119
118
|
REPORT_HEADER = <<-EOF
|
120
119
|
<div class="rspec-report">
|
121
120
|
|
@@ -139,7 +138,6 @@ module RSpec
|
|
139
138
|
|
140
139
|
<div class="results">
|
141
140
|
EOF
|
142
|
-
# rubocop:enable LineLength
|
143
141
|
|
144
142
|
GLOBAL_SCRIPTS = <<-EOF
|
145
143
|
|
@@ -17,12 +17,12 @@ module RSpec
|
|
17
17
|
# @see RSpec::Core::Formatters::BaseTextFormatter
|
18
18
|
# @see RSpec::Core::Reporter
|
19
19
|
class Protocol
|
20
|
-
# @method initialize
|
20
|
+
# @method initialize(output)
|
21
21
|
# @api public
|
22
22
|
#
|
23
23
|
# @param output [IO] the formatter output
|
24
24
|
|
25
|
-
# @method start
|
25
|
+
# @method start(notification)
|
26
26
|
# @api public
|
27
27
|
# @group Suite Notifications
|
28
28
|
#
|
@@ -35,7 +35,7 @@ module RSpec
|
|
35
35
|
#
|
36
36
|
# @param notification [Notifications::StartNotification]
|
37
37
|
|
38
|
-
# @method example_group_started
|
38
|
+
# @method example_group_started(notification)
|
39
39
|
# @api public
|
40
40
|
# @group Group Notifications
|
41
41
|
#
|
@@ -48,7 +48,7 @@ module RSpec
|
|
48
48
|
# @param notification [Notifications::GroupNotification] containing example_group
|
49
49
|
# subclass of {ExampleGroup}
|
50
50
|
|
51
|
-
# @method example_group_finished
|
51
|
+
# @method example_group_finished(notification)
|
52
52
|
# @api public
|
53
53
|
# @group Group Notifications
|
54
54
|
#
|
@@ -57,7 +57,7 @@ module RSpec
|
|
57
57
|
# @param notification [Notifications::GroupNotification] containing example_group
|
58
58
|
# subclass of {ExampleGroup}
|
59
59
|
|
60
|
-
# @method example_started
|
60
|
+
# @method example_started(notification)
|
61
61
|
# @api public
|
62
62
|
# @group Example Notifications
|
63
63
|
#
|
@@ -66,7 +66,7 @@ module RSpec
|
|
66
66
|
# @param notification [Notifications::ExampleNotification] containing example subclass
|
67
67
|
# of {Example}
|
68
68
|
|
69
|
-
# @method example_finished
|
69
|
+
# @method example_finished(notification)
|
70
70
|
# @api public
|
71
71
|
# @group Example Notifications
|
72
72
|
#
|
@@ -75,7 +75,7 @@ module RSpec
|
|
75
75
|
# @param notification [Notifications::ExampleNotification] containing example subclass
|
76
76
|
# of {Example}
|
77
77
|
|
78
|
-
# @method example_passed
|
78
|
+
# @method example_passed(notification)
|
79
79
|
# @api public
|
80
80
|
# @group Example Notifications
|
81
81
|
#
|
@@ -84,7 +84,7 @@ module RSpec
|
|
84
84
|
# @param notification [Notifications::ExampleNotification] containing example subclass
|
85
85
|
# of {Example}
|
86
86
|
|
87
|
-
# @method example_pending
|
87
|
+
# @method example_pending(notification)
|
88
88
|
# @api public
|
89
89
|
# @group Example Notifications
|
90
90
|
#
|
@@ -93,7 +93,7 @@ module RSpec
|
|
93
93
|
# @param notification [Notifications::ExampleNotification] containing example subclass
|
94
94
|
# of {Example}
|
95
95
|
|
96
|
-
# @method example_failed
|
96
|
+
# @method example_failed(notification)
|
97
97
|
# @api public
|
98
98
|
# @group Example Notifications
|
99
99
|
#
|
@@ -102,7 +102,7 @@ module RSpec
|
|
102
102
|
# @param notification [Notifications::ExampleNotification] containing example subclass
|
103
103
|
# of {Example}
|
104
104
|
|
105
|
-
# @method message
|
105
|
+
# @method message(notification)
|
106
106
|
# @api public
|
107
107
|
# @group Suite Notifications
|
108
108
|
#
|
@@ -110,7 +110,7 @@ module RSpec
|
|
110
110
|
#
|
111
111
|
# @param notification [Notifications::MessageNotification] containing message
|
112
112
|
|
113
|
-
# @method stop
|
113
|
+
# @method stop(notification)
|
114
114
|
# @api public
|
115
115
|
# @group Suite Notifications
|
116
116
|
#
|
@@ -119,7 +119,7 @@ module RSpec
|
|
119
119
|
#
|
120
120
|
# @param notification [Notifications::NullNotification]
|
121
121
|
|
122
|
-
# @method start_dump
|
122
|
+
# @method start_dump(notification)
|
123
123
|
# @api public
|
124
124
|
# @group Suite Notifications
|
125
125
|
#
|
@@ -130,7 +130,7 @@ module RSpec
|
|
130
130
|
#
|
131
131
|
# @param notification [Notifications::NullNotification]
|
132
132
|
|
133
|
-
# @method dump_failures
|
133
|
+
# @method dump_failures(notification)
|
134
134
|
# @api public
|
135
135
|
# @group Suite Notifications
|
136
136
|
#
|
@@ -138,7 +138,7 @@ module RSpec
|
|
138
138
|
#
|
139
139
|
# @param notification [Notifications::NullNotification]
|
140
140
|
|
141
|
-
# @method dump_summary
|
141
|
+
# @method dump_summary(summary)
|
142
142
|
# @api public
|
143
143
|
# @group Suite Notifications
|
144
144
|
#
|
@@ -148,7 +148,7 @@ module RSpec
|
|
148
148
|
# @param summary [Notifications::SummaryNotification] containing duration,
|
149
149
|
# example_count, failure_count and pending_count
|
150
150
|
|
151
|
-
# @method dump_profile
|
151
|
+
# @method dump_profile(profile)
|
152
152
|
# @api public
|
153
153
|
# @group Suite Notifications
|
154
154
|
#
|
@@ -158,7 +158,7 @@ module RSpec
|
|
158
158
|
# @param profile [Notifications::ProfileNotification] containing duration,
|
159
159
|
# slowest_examples and slowest_example_groups
|
160
160
|
|
161
|
-
# @method dump_pending
|
161
|
+
# @method dump_pending(notification)
|
162
162
|
# @api public
|
163
163
|
# @group Suite Notifications
|
164
164
|
#
|
@@ -167,7 +167,7 @@ module RSpec
|
|
167
167
|
#
|
168
168
|
# @param notification [Notifications::NullNotification]
|
169
169
|
|
170
|
-
# @method close
|
170
|
+
# @method close(notification)
|
171
171
|
# @api public
|
172
172
|
# @group Suite Notifications
|
173
173
|
#
|