rspec-core 3.7.1 → 3.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Changelog.md +116 -0
  5. data/README.md +18 -18
  6. data/lib/rspec/core.rb +1 -0
  7. data/lib/rspec/core/bisect/coordinator.rb +26 -30
  8. data/lib/rspec/core/bisect/example_minimizer.rb +12 -8
  9. data/lib/rspec/core/bisect/fork_runner.rb +138 -0
  10. data/lib/rspec/core/bisect/server.rb +5 -14
  11. data/lib/rspec/core/bisect/{runner.rb → shell_command.rb} +27 -70
  12. data/lib/rspec/core/bisect/shell_runner.rb +73 -0
  13. data/lib/rspec/core/bisect/utilities.rb +58 -0
  14. data/lib/rspec/core/configuration.rb +236 -79
  15. data/lib/rspec/core/configuration_options.rb +41 -4
  16. data/lib/rspec/core/did_you_mean.rb +46 -0
  17. data/lib/rspec/core/example.rb +18 -8
  18. data/lib/rspec/core/example_group.rb +33 -16
  19. data/lib/rspec/core/filter_manager.rb +1 -1
  20. data/lib/rspec/core/formatters.rb +14 -6
  21. data/lib/rspec/core/formatters/base_bisect_formatter.rb +45 -0
  22. data/lib/rspec/core/formatters/bisect_drb_formatter.rb +29 -0
  23. data/lib/rspec/core/formatters/bisect_progress_formatter.rb +29 -16
  24. data/lib/rspec/core/formatters/deprecation_formatter.rb +3 -1
  25. data/lib/rspec/core/formatters/documentation_formatter.rb +35 -3
  26. data/lib/rspec/core/formatters/exception_presenter.rb +29 -6
  27. data/lib/rspec/core/formatters/failure_list_formatter.rb +23 -0
  28. data/lib/rspec/core/formatters/html_printer.rb +0 -2
  29. data/lib/rspec/core/formatters/protocol.rb +17 -17
  30. data/lib/rspec/core/formatters/syntax_highlighter.rb +19 -19
  31. data/lib/rspec/core/hooks.rb +44 -24
  32. data/lib/rspec/core/invocations.rb +9 -7
  33. data/lib/rspec/core/memoized_helpers.rb +33 -14
  34. data/lib/rspec/core/metadata.rb +2 -3
  35. data/lib/rspec/core/option_parser.rb +10 -3
  36. data/lib/rspec/core/profiler.rb +3 -1
  37. data/lib/rspec/core/rake_task.rb +22 -2
  38. data/lib/rspec/core/reporter.rb +11 -6
  39. data/lib/rspec/core/runner.rb +25 -14
  40. data/lib/rspec/core/shared_example_group.rb +5 -5
  41. data/lib/rspec/core/shell_escape.rb +2 -2
  42. data/lib/rspec/core/version.rb +1 -1
  43. data/lib/rspec/core/world.rb +14 -1
  44. metadata +25 -15
  45. metadata.gz.sig +0 -0
  46. 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
- # We've named all events with a `bisect_` prefix to prevent naming collisions.
10
- Formatters.register self, :bisect_starting, :bisect_original_run_complete,
11
- :bisect_round_started, :bisect_individual_run_complete,
12
- :bisect_complete, :bisect_repro_command,
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
- options = notification.original_cli_args.join(' ')
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
- # bisect is performed while the `DEBUG_RSPEC_BISECT` ENV var is used.
93
- # Designed to provide details for us when we need to troubleshoot bisect bugs.
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 = "#{'-' * 80}"
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.message.to_s).split("\n").each do |line|
54
+ encoded_string(exception_message_string(last_cause)).split("\n").each do |line|
55
55
  cause << " #{line}"
56
56
  end
57
57
 
58
- cause << (" #{backtrace_formatter.format_backtrace(last_cause.backtrace, example.metadata).first}")
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
- if cause && !previous.include?(cause)
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.message.to_s).split("\n").each do |line|
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
  #