rspec-core 3.0.4 → 3.12.2
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/.document +1 -1
- data/.yardopts +2 -1
- data/Changelog.md +888 -2
- data/{License.txt → LICENSE.md} +6 -5
- data/README.md +165 -24
- data/lib/rspec/autorun.rb +1 -0
- data/lib/rspec/core/backtrace_formatter.rb +19 -20
- data/lib/rspec/core/bisect/coordinator.rb +62 -0
- data/lib/rspec/core/bisect/example_minimizer.rb +173 -0
- data/lib/rspec/core/bisect/fork_runner.rb +138 -0
- data/lib/rspec/core/bisect/server.rb +61 -0
- data/lib/rspec/core/bisect/shell_command.rb +126 -0
- data/lib/rspec/core/bisect/shell_runner.rb +73 -0
- data/lib/rspec/core/bisect/utilities.rb +69 -0
- data/lib/rspec/core/configuration.rb +1287 -246
- data/lib/rspec/core/configuration_options.rb +95 -35
- data/lib/rspec/core/did_you_mean.rb +46 -0
- data/lib/rspec/core/drb.rb +21 -12
- data/lib/rspec/core/dsl.rb +10 -6
- data/lib/rspec/core/example.rb +305 -113
- data/lib/rspec/core/example_group.rb +431 -223
- data/lib/rspec/core/example_status_persister.rb +235 -0
- data/lib/rspec/core/filter_manager.rb +86 -115
- data/lib/rspec/core/flat_map.rb +6 -4
- data/lib/rspec/core/formatters/base_bisect_formatter.rb +45 -0
- data/lib/rspec/core/formatters/base_formatter.rb +14 -116
- data/lib/rspec/core/formatters/base_text_formatter.rb +18 -21
- data/lib/rspec/core/formatters/bisect_drb_formatter.rb +29 -0
- data/lib/rspec/core/formatters/bisect_progress_formatter.rb +157 -0
- data/lib/rspec/core/formatters/console_codes.rb +29 -18
- data/lib/rspec/core/formatters/deprecation_formatter.rb +16 -16
- data/lib/rspec/core/formatters/documentation_formatter.rb +49 -16
- data/lib/rspec/core/formatters/exception_presenter.rb +525 -0
- data/lib/rspec/core/formatters/failure_list_formatter.rb +23 -0
- data/lib/rspec/core/formatters/fallback_message_formatter.rb +28 -0
- data/lib/rspec/core/formatters/helpers.rb +45 -15
- data/lib/rspec/core/formatters/html_formatter.rb +33 -28
- data/lib/rspec/core/formatters/html_printer.rb +30 -20
- data/lib/rspec/core/formatters/html_snippet_extractor.rb +120 -0
- data/lib/rspec/core/formatters/json_formatter.rb +18 -9
- data/lib/rspec/core/formatters/profile_formatter.rb +10 -9
- data/lib/rspec/core/formatters/progress_formatter.rb +5 -4
- data/lib/rspec/core/formatters/protocol.rb +182 -0
- data/lib/rspec/core/formatters/snippet_extractor.rb +113 -82
- data/lib/rspec/core/formatters/syntax_highlighter.rb +91 -0
- data/lib/rspec/core/formatters.rb +81 -41
- data/lib/rspec/core/hooks.rb +314 -244
- data/lib/rspec/core/invocations.rb +87 -0
- data/lib/rspec/core/memoized_helpers.rb +161 -51
- data/lib/rspec/core/metadata.rb +132 -61
- data/lib/rspec/core/metadata_filter.rb +224 -64
- data/lib/rspec/core/minitest_assertions_adapter.rb +6 -3
- data/lib/rspec/core/mocking_adapters/flexmock.rb +4 -2
- data/lib/rspec/core/mocking_adapters/mocha.rb +11 -9
- data/lib/rspec/core/mocking_adapters/null.rb +2 -0
- data/lib/rspec/core/mocking_adapters/rr.rb +3 -1
- data/lib/rspec/core/mocking_adapters/rspec.rb +3 -1
- data/lib/rspec/core/notifications.rb +192 -206
- data/lib/rspec/core/option_parser.rb +174 -69
- data/lib/rspec/core/ordering.rb +48 -35
- data/lib/rspec/core/output_wrapper.rb +29 -0
- data/lib/rspec/core/pending.rb +25 -33
- data/lib/rspec/core/profiler.rb +34 -0
- data/lib/rspec/core/project_initializer/.rspec +0 -2
- data/lib/rspec/core/project_initializer/spec/spec_helper.rb +59 -39
- data/lib/rspec/core/project_initializer.rb +5 -3
- data/lib/rspec/core/rake_task.rb +99 -55
- data/lib/rspec/core/reporter.rb +128 -15
- data/lib/rspec/core/ruby_project.rb +14 -6
- data/lib/rspec/core/runner.rb +96 -45
- data/lib/rspec/core/sandbox.rb +37 -0
- data/lib/rspec/core/set.rb +54 -0
- data/lib/rspec/core/shared_example_group.rb +133 -43
- data/lib/rspec/core/shell_escape.rb +49 -0
- data/lib/rspec/core/test_unit_assertions_adapter.rb +4 -4
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/warnings.rb +6 -6
- data/lib/rspec/core/world.rb +172 -68
- data/lib/rspec/core.rb +66 -21
- data.tar.gz.sig +0 -0
- metadata +93 -69
- metadata.gz.sig +0 -0
- data/lib/rspec/core/backport_random.rb +0 -336
|
@@ -4,23 +4,22 @@ require 'stringio'
|
|
|
4
4
|
module RSpec
|
|
5
5
|
module Core
|
|
6
6
|
module Formatters
|
|
7
|
-
# RSpec's built-in formatters are all subclasses of
|
|
8
|
-
#
|
|
9
|
-
# interface. The reporter will issue these during a normal test suite run, but a formatter will
|
|
10
|
-
# only receive those notifications it has registered itself to receive.
|
|
7
|
+
# RSpec's built-in formatters are all subclasses of
|
|
8
|
+
# RSpec::Core::Formatters::BaseFormatter.
|
|
11
9
|
#
|
|
12
10
|
# @see RSpec::Core::Formatters::BaseTextFormatter
|
|
13
11
|
# @see RSpec::Core::Reporter
|
|
12
|
+
# @see RSpec::Core::Formatters::Protocol
|
|
14
13
|
class BaseFormatter
|
|
15
|
-
|
|
16
|
-
#
|
|
14
|
+
# All formatters inheriting from this formatter will receive these
|
|
15
|
+
# notifications.
|
|
17
16
|
Formatters.register self, :start, :example_group_started, :close
|
|
18
17
|
attr_accessor :example_group
|
|
19
18
|
attr_reader :output
|
|
20
19
|
|
|
21
20
|
# @api public
|
|
22
|
-
#
|
|
23
21
|
# @param output [IO] the formatter output
|
|
22
|
+
# @see RSpec::Core::Formatters::Protocol#initialize
|
|
24
23
|
def initialize(output)
|
|
25
24
|
@output = output || StringIO.new
|
|
26
25
|
@example_group = nil
|
|
@@ -28,14 +27,8 @@ module RSpec
|
|
|
28
27
|
|
|
29
28
|
# @api public
|
|
30
29
|
#
|
|
31
|
-
# This method is invoked before any examples are run, right after
|
|
32
|
-
# they have all been collected. This can be useful for special
|
|
33
|
-
# formatters that need to provide progress on feedback (graphical ones).
|
|
34
|
-
#
|
|
35
|
-
# This will only be invoked once, and the next one to be invoked
|
|
36
|
-
# is {#example_group_started}.
|
|
37
|
-
#
|
|
38
30
|
# @param notification [StartNotification]
|
|
31
|
+
# @see RSpec::Core::Formatters::Protocol#start
|
|
39
32
|
def start(notification)
|
|
40
33
|
start_sync_output
|
|
41
34
|
@example_count = notification.count
|
|
@@ -43,112 +36,18 @@ module RSpec
|
|
|
43
36
|
|
|
44
37
|
# @api public
|
|
45
38
|
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
# {#example_pending}, or {#example_group_finished}.
|
|
50
|
-
#
|
|
51
|
-
# @param notification [GroupNotification] containing example_group subclass of `RSpec::Core::ExampleGroup`
|
|
39
|
+
# @param notification [GroupNotification] containing example_group
|
|
40
|
+
# subclass of `RSpec::Core::ExampleGroup`
|
|
41
|
+
# @see RSpec::Core::Formatters::Protocol#example_group_started
|
|
52
42
|
def example_group_started(notification)
|
|
53
43
|
@example_group = notification.group
|
|
54
44
|
end
|
|
55
45
|
|
|
56
|
-
# @method example_group_finished
|
|
57
|
-
# @api public
|
|
58
|
-
#
|
|
59
|
-
# Invoked at the end of the execution of each example group.
|
|
60
|
-
#
|
|
61
|
-
# @param notification [GroupNotification] containing example_group subclass of `RSpec::Core::ExampleGroup`
|
|
62
|
-
|
|
63
|
-
# @method example_started
|
|
64
|
-
# @api public
|
|
65
|
-
#
|
|
66
|
-
# Invoked at the beginning of the execution of each example.
|
|
67
|
-
#
|
|
68
|
-
# @param notification [ExampleNotification] containing example subclass of `RSpec::Core::Example`
|
|
69
|
-
|
|
70
|
-
# @method example_passed
|
|
71
|
-
# @api public
|
|
72
|
-
#
|
|
73
|
-
# Invoked when an example passes.
|
|
74
|
-
#
|
|
75
|
-
# @param notification [ExampleNotification] containing example subclass of `RSpec::Core::Example`
|
|
76
|
-
|
|
77
|
-
# @method example_pending
|
|
78
|
-
# Invoked when an example is pending.
|
|
79
|
-
#
|
|
80
|
-
# @param notification [ExampleNotification] containing example subclass of `RSpec::Core::Example`
|
|
81
|
-
|
|
82
|
-
# @method example_failed
|
|
83
|
-
# @api public
|
|
84
|
-
#
|
|
85
|
-
# Invoked when an example fails.
|
|
86
|
-
#
|
|
87
|
-
# @param notification [ExampleNotification] containing example subclass of `RSpec::Core::Example`
|
|
88
|
-
|
|
89
|
-
# @method message
|
|
90
|
-
# @api public
|
|
91
|
-
#
|
|
92
|
-
# Used by the reporter to send messages to the output stream.
|
|
93
|
-
#
|
|
94
|
-
# @param notification [MessageNotification] containing message
|
|
95
|
-
|
|
96
|
-
# @method stop
|
|
97
|
-
# @api public
|
|
98
|
-
#
|
|
99
|
-
# Invoked after all examples have executed, before dumping post-run reports.
|
|
100
|
-
#
|
|
101
|
-
# @param notification [NullNotification]
|
|
102
|
-
|
|
103
|
-
# @method start_dump
|
|
104
|
-
# @api public
|
|
105
|
-
#
|
|
106
|
-
# This method is invoked after all of the examples have executed. The next method
|
|
107
|
-
# to be invoked after this one is {#dump_failures}
|
|
108
|
-
# (BaseTextFormatter then calls {#dump_failure} once for each failed example.)
|
|
109
|
-
#
|
|
110
|
-
# @param notification [NullNotification]
|
|
111
|
-
|
|
112
|
-
# @method dump_failures
|
|
113
46
|
# @api public
|
|
114
47
|
#
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
# @method dump_summary
|
|
120
|
-
# @api public
|
|
121
|
-
#
|
|
122
|
-
# This method is invoked after the dumping of examples and failures. Each parameter
|
|
123
|
-
# is assigned to a corresponding attribute.
|
|
124
|
-
#
|
|
125
|
-
# @param summary [SummaryNotification] containing duration, example_count,
|
|
126
|
-
# failure_count and pending_count
|
|
127
|
-
|
|
128
|
-
# @method dump_profile
|
|
129
|
-
# @api public
|
|
130
|
-
#
|
|
131
|
-
# This method is invoked after the dumping the summary if profiling is
|
|
132
|
-
# enabled.
|
|
133
|
-
#
|
|
134
|
-
# @param profile [ProfileNotification] containing duration, slowest_examples
|
|
135
|
-
# and slowest_example_groups
|
|
136
|
-
|
|
137
|
-
# @method dump_pending
|
|
138
|
-
# @api public
|
|
139
|
-
#
|
|
140
|
-
# Outputs a report of pending examples. This gets invoked
|
|
141
|
-
# after the summary if option is set to do so.
|
|
142
|
-
#
|
|
143
|
-
# @param notification [NullNotification]
|
|
144
|
-
|
|
145
|
-
# @api public
|
|
146
|
-
#
|
|
147
|
-
# Invoked at the very end, `close` allows the formatter to clean
|
|
148
|
-
# up resources, e.g. open streams, etc.
|
|
149
|
-
#
|
|
150
|
-
# @param notification [NullNotification]
|
|
151
|
-
def close(notification)
|
|
48
|
+
# @param _notification [NullNotification] (Ignored)
|
|
49
|
+
# @see RSpec::Core::Formatters::Protocol#close
|
|
50
|
+
def close(_notification)
|
|
152
51
|
restore_sync_output
|
|
153
52
|
end
|
|
154
53
|
|
|
@@ -159,13 +58,12 @@ module RSpec
|
|
|
159
58
|
end
|
|
160
59
|
|
|
161
60
|
def restore_sync_output
|
|
162
|
-
output.sync = @old_sync if output_supports_sync
|
|
61
|
+
output.sync = @old_sync if output_supports_sync && !output.closed?
|
|
163
62
|
end
|
|
164
63
|
|
|
165
64
|
def output_supports_sync
|
|
166
65
|
output.respond_to?(:sync=)
|
|
167
66
|
end
|
|
168
|
-
|
|
169
67
|
end
|
|
170
68
|
end
|
|
171
69
|
end
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
RSpec::Support.require_rspec_core "formatters/base_formatter"
|
|
2
|
-
RSpec::Support.require_rspec_core "formatters/console_codes"
|
|
3
2
|
|
|
4
3
|
module RSpec
|
|
5
4
|
module Core
|
|
6
5
|
module Formatters
|
|
7
|
-
|
|
8
|
-
#
|
|
9
|
-
#
|
|
6
|
+
# Base for all of RSpec's built-in formatters. See
|
|
7
|
+
# RSpec::Core::Formatters::BaseFormatter to learn more about all of the
|
|
8
|
+
# methods called by the reporter.
|
|
10
9
|
#
|
|
11
10
|
# @see RSpec::Core::Formatters::BaseFormatter
|
|
12
11
|
# @see RSpec::Core::Reporter
|
|
13
12
|
class BaseTextFormatter < BaseFormatter
|
|
14
|
-
Formatters.register self,
|
|
15
|
-
|
|
13
|
+
Formatters.register self,
|
|
14
|
+
:message, :dump_summary, :dump_failures, :dump_pending, :seed
|
|
16
15
|
|
|
17
|
-
# @method message
|
|
18
16
|
# @api public
|
|
19
17
|
#
|
|
20
18
|
# Used by the reporter to send messages to the output stream.
|
|
@@ -24,7 +22,6 @@ module RSpec
|
|
|
24
22
|
output.puts notification.message
|
|
25
23
|
end
|
|
26
24
|
|
|
27
|
-
# @method dump_failures
|
|
28
25
|
# @api public
|
|
29
26
|
#
|
|
30
27
|
# Dumps detailed information about each example failure.
|
|
@@ -35,14 +32,13 @@ module RSpec
|
|
|
35
32
|
output.puts notification.fully_formatted_failed_examples
|
|
36
33
|
end
|
|
37
34
|
|
|
38
|
-
# @method dump_summary
|
|
39
35
|
# @api public
|
|
40
36
|
#
|
|
41
|
-
# This method is invoked after the dumping of examples and failures.
|
|
42
|
-
# is assigned to a corresponding attribute.
|
|
37
|
+
# This method is invoked after the dumping of examples and failures.
|
|
38
|
+
# Each parameter is assigned to a corresponding attribute.
|
|
43
39
|
#
|
|
44
|
-
# @param summary [SummaryNotification] containing duration,
|
|
45
|
-
#
|
|
40
|
+
# @param summary [SummaryNotification] containing duration,
|
|
41
|
+
# example_count, failure_count and pending_count
|
|
46
42
|
def dump_summary(summary)
|
|
47
43
|
output.puts summary.fully_formatted
|
|
48
44
|
end
|
|
@@ -61,17 +57,18 @@ module RSpec
|
|
|
61
57
|
|
|
62
58
|
# @api public
|
|
63
59
|
#
|
|
64
|
-
# Invoked at the
|
|
65
|
-
# up
|
|
60
|
+
# Invoked at the end of a suite run. Allows the formatter to do any
|
|
61
|
+
# tidying up, but be aware that formatter output streams may be used
|
|
62
|
+
# elsewhere so don't actually close them.
|
|
66
63
|
#
|
|
67
|
-
# @param
|
|
68
|
-
def close(
|
|
69
|
-
return
|
|
70
|
-
return if output.closed? || output == $stdout
|
|
64
|
+
# @param _notification [NullNotification] (Ignored)
|
|
65
|
+
def close(_notification)
|
|
66
|
+
return if output.closed?
|
|
71
67
|
|
|
72
|
-
output.
|
|
73
|
-
end
|
|
68
|
+
output.puts
|
|
74
69
|
|
|
70
|
+
output.flush
|
|
71
|
+
end
|
|
75
72
|
end
|
|
76
73
|
end
|
|
77
74
|
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
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
RSpec::Support.require_rspec_core "formatters/base_text_formatter"
|
|
2
|
+
|
|
3
|
+
module RSpec
|
|
4
|
+
module Core
|
|
5
|
+
module Formatters
|
|
6
|
+
# @private
|
|
7
|
+
# Produces progress output while bisecting.
|
|
8
|
+
class BisectProgressFormatter < BaseTextFormatter
|
|
9
|
+
def initialize(output, bisect_runner)
|
|
10
|
+
super(output)
|
|
11
|
+
@bisect_runner = bisect_runner
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def bisect_starting(notification)
|
|
15
|
+
@round_count = 0
|
|
16
|
+
output.puts bisect_started_message(notification)
|
|
17
|
+
output.print "Running suite to find failures..."
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def bisect_original_run_complete(notification)
|
|
21
|
+
failures = Helpers.pluralize(notification.failed_example_ids.size, "failing example")
|
|
22
|
+
non_failures = Helpers.pluralize(notification.non_failing_example_ids.size, "non-failing example")
|
|
23
|
+
|
|
24
|
+
output.puts " (#{Helpers.format_duration(notification.duration)})"
|
|
25
|
+
output.puts "Starting bisect with #{failures} and #{non_failures}."
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def bisect_dependency_check_started(_notification)
|
|
29
|
+
output.print "Checking that failure(s) are order-dependent.."
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def bisect_dependency_check_passed(_notification)
|
|
33
|
+
output.puts " failure appears to be order-dependent"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def bisect_dependency_check_failed(_notification)
|
|
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
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def bisect_round_started(notification, include_trailing_space=true)
|
|
51
|
+
@round_count += 1
|
|
52
|
+
range_desc = notification.candidate_range.description
|
|
53
|
+
|
|
54
|
+
output.print "\nRound #{@round_count}: bisecting over non-failing #{range_desc}"
|
|
55
|
+
output.print " " if include_trailing_space
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def bisect_round_ignoring_ids(notification)
|
|
59
|
+
range_desc = notification.ignore_range.description
|
|
60
|
+
|
|
61
|
+
output.print " ignoring #{range_desc}"
|
|
62
|
+
output.print " (#{Helpers.format_duration(notification.duration)})"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def bisect_round_detected_multiple_culprits(notification)
|
|
66
|
+
output.print " multiple culprits detected - splitting candidates"
|
|
67
|
+
output.print " (#{Helpers.format_duration(notification.duration)})"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def bisect_individual_run_complete(_)
|
|
71
|
+
output.print '.'
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def bisect_complete(notification)
|
|
75
|
+
output.puts "\nBisect complete! Reduced necessary non-failing examples " \
|
|
76
|
+
"from #{notification.original_non_failing_count} to " \
|
|
77
|
+
"#{notification.remaining_count} in " \
|
|
78
|
+
"#{Helpers.format_duration(notification.duration)}."
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def bisect_repro_command(notification)
|
|
82
|
+
output.puts "\nThe minimal reproduction command is:\n #{notification.repro}"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def bisect_failed(notification)
|
|
86
|
+
output.puts "\nBisect failed! #{notification.failure_explanation}"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def bisect_aborted(notification)
|
|
90
|
+
output.puts "\n\nBisect aborted!"
|
|
91
|
+
output.puts "\nThe most minimal reproduction command discovered so far is:\n #{notification.repro}"
|
|
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
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# @private
|
|
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.
|
|
106
|
+
class BisectDebugFormatter < BisectProgressFormatter
|
|
107
|
+
def bisect_original_run_complete(notification)
|
|
108
|
+
output.puts " (#{Helpers.format_duration(notification.duration)})"
|
|
109
|
+
|
|
110
|
+
output.puts " - #{describe_ids 'Failing examples', notification.failed_example_ids}"
|
|
111
|
+
output.puts " - #{describe_ids 'Non-failing examples', notification.non_failing_example_ids}"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def bisect_individual_run_start(notification)
|
|
115
|
+
output.print "\n - Running: #{notification.command}"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def bisect_individual_run_complete(notification)
|
|
119
|
+
output.print " (#{Helpers.format_duration(notification.duration)})"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def bisect_dependency_check_passed(_notification)
|
|
123
|
+
output.print "\n - Failure appears to be order-dependent"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def bisect_dependency_check_failed(_notification)
|
|
127
|
+
output.print "\n - Failure is not order-dependent"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def bisect_round_started(notification)
|
|
131
|
+
super(notification, false)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def bisect_round_ignoring_ids(notification)
|
|
135
|
+
output.print "\n - #{describe_ids 'Examples we can safely ignore', notification.ids_to_ignore}"
|
|
136
|
+
output.print "\n - #{describe_ids 'Remaining non-failing examples', notification.remaining_ids}"
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def bisect_round_detected_multiple_culprits(_notification)
|
|
140
|
+
output.print "\n - Multiple culprits detected - splitting candidates"
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
private
|
|
144
|
+
|
|
145
|
+
def describe_ids(description, ids)
|
|
146
|
+
organized_ids = Formatters::Helpers.organize_ids(ids)
|
|
147
|
+
formatted_ids = organized_ids.map { |id| " - #{id}" }.join("\n")
|
|
148
|
+
"#{description} (#{ids.size}):\n#{formatted_ids}"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def bisect_started_message(notification)
|
|
152
|
+
"#{super} and bisect runner: #{notification.bisect_runner.inspect}"
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
@@ -7,30 +7,47 @@ module RSpec
|
|
|
7
7
|
# @private
|
|
8
8
|
VT100_CODES =
|
|
9
9
|
{
|
|
10
|
-
:black
|
|
11
|
-
:red
|
|
12
|
-
:green
|
|
13
|
-
:yellow
|
|
14
|
-
:blue
|
|
15
|
-
:magenta
|
|
16
|
-
:cyan
|
|
17
|
-
:white
|
|
18
|
-
:
|
|
10
|
+
:black => 30,
|
|
11
|
+
:red => 31,
|
|
12
|
+
:green => 32,
|
|
13
|
+
:yellow => 33,
|
|
14
|
+
:blue => 34,
|
|
15
|
+
:magenta => 35,
|
|
16
|
+
:cyan => 36,
|
|
17
|
+
:white => 37,
|
|
18
|
+
:bold_black => '1;30',
|
|
19
|
+
:bold_red => '1;31',
|
|
20
|
+
:bold_green => '1;32',
|
|
21
|
+
:bold_yellow => '1;33',
|
|
22
|
+
:bold_blue => '1;34',
|
|
23
|
+
:bold_magenta => '1;35',
|
|
24
|
+
:bold_cyan => '1;36',
|
|
25
|
+
:bold_white => '1;37',
|
|
26
|
+
:bold => 1,
|
|
19
27
|
}
|
|
20
28
|
# @private
|
|
21
29
|
VT100_CODE_VALUES = VT100_CODES.invert
|
|
22
30
|
|
|
23
31
|
module_function
|
|
24
32
|
|
|
33
|
+
# @private
|
|
34
|
+
def config_colors_to_methods
|
|
35
|
+
@config_colors_to_methods ||=
|
|
36
|
+
Configuration.instance_methods.grep(/_color\z/).inject({}) do |hash, method|
|
|
37
|
+
hash[method.to_s.sub(/_color\z/, '').to_sym] = method
|
|
38
|
+
hash
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
25
42
|
# Fetches the correct code for the supplied symbol, or checks
|
|
26
43
|
# that a code is valid. Defaults to white (37).
|
|
27
44
|
#
|
|
28
45
|
# @param code_or_symbol [Symbol, Fixnum] Symbol or code to check
|
|
29
46
|
# @return [Fixnum] a console code
|
|
30
47
|
def console_code_for(code_or_symbol)
|
|
31
|
-
if
|
|
32
|
-
console_code_for
|
|
33
|
-
elsif VT100_CODE_VALUES.
|
|
48
|
+
if (config_method = config_colors_to_methods[code_or_symbol])
|
|
49
|
+
console_code_for RSpec.configuration.__send__(config_method)
|
|
50
|
+
elsif VT100_CODE_VALUES.key?(code_or_symbol)
|
|
34
51
|
code_or_symbol
|
|
35
52
|
else
|
|
36
53
|
VT100_CODES.fetch(code_or_symbol) do
|
|
@@ -53,12 +70,6 @@ module RSpec
|
|
|
53
70
|
text
|
|
54
71
|
end
|
|
55
72
|
end
|
|
56
|
-
|
|
57
|
-
# @private
|
|
58
|
-
def configuration_color(code)
|
|
59
|
-
RSpec.configuration.__send__(:"#{code}_color")
|
|
60
|
-
end
|
|
61
|
-
|
|
62
73
|
end
|
|
63
74
|
end
|
|
64
75
|
end
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
RSpec::Support.require_rspec_core "formatters/helpers"
|
|
2
|
-
require 'set'
|
|
3
2
|
|
|
4
3
|
module RSpec
|
|
5
4
|
module Core
|
|
@@ -21,7 +20,8 @@ module RSpec
|
|
|
21
20
|
def printer
|
|
22
21
|
@printer ||= case deprecation_stream
|
|
23
22
|
when File
|
|
24
|
-
ImmediatePrinter.new(FileStream.new(deprecation_stream),
|
|
23
|
+
ImmediatePrinter.new(FileStream.new(deprecation_stream),
|
|
24
|
+
summary_stream, self)
|
|
25
25
|
when RaiseErrorStream
|
|
26
26
|
ImmediatePrinter.new(deprecation_stream, summary_stream, self)
|
|
27
27
|
else
|
|
@@ -37,7 +37,7 @@ module RSpec
|
|
|
37
37
|
@seen_deprecations << notification
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
def deprecation_summary(
|
|
40
|
+
def deprecation_summary(_notification)
|
|
41
41
|
printer.deprecation_summary
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -57,9 +57,12 @@ module RSpec
|
|
|
57
57
|
|deprecation warnings into errors, giving you the full backtrace.
|
|
58
58
|
EOS
|
|
59
59
|
|
|
60
|
-
DEPRECATION_STREAM_NOTICE = "Pass `--deprecation-out` or set "
|
|
60
|
+
DEPRECATION_STREAM_NOTICE = "Pass `--deprecation-out` or set " \
|
|
61
61
|
"`config.deprecation_stream` to a file for full output."
|
|
62
|
+
TOO_MANY_WARNINGS_NOTICE = "Too many similar deprecation messages " \
|
|
63
|
+
"reported, disregarding further reports. #{DEPRECATION_STREAM_NOTICE}"
|
|
62
64
|
|
|
65
|
+
# @private
|
|
63
66
|
SpecifiedDeprecationMessage = Struct.new(:type) do
|
|
64
67
|
def initialize(data)
|
|
65
68
|
@message = data.message
|
|
@@ -71,16 +74,14 @@ module RSpec
|
|
|
71
74
|
end
|
|
72
75
|
|
|
73
76
|
def too_many_warnings_message
|
|
74
|
-
|
|
75
|
-
msg << DEPRECATION_STREAM_NOTICE
|
|
76
|
-
msg
|
|
77
|
+
TOO_MANY_WARNINGS_NOTICE
|
|
77
78
|
end
|
|
78
79
|
|
|
79
80
|
private
|
|
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
|
|
@@ -96,16 +98,14 @@ module RSpec
|
|
|
96
98
|
end
|
|
97
99
|
|
|
98
100
|
def to_s
|
|
99
|
-
msg =
|
|
101
|
+
msg = String.new("#{@data.deprecated} is deprecated.")
|
|
100
102
|
msg << " Use #{@data.replacement} instead." if @data.replacement
|
|
101
|
-
msg << " Called from #{@data.call_site}."
|
|
103
|
+
msg << " Called from #{@data.call_site}." if @data.call_site
|
|
102
104
|
msg
|
|
103
105
|
end
|
|
104
106
|
|
|
105
107
|
def too_many_warnings_message
|
|
106
|
-
|
|
107
|
-
msg << DEPRECATION_STREAM_NOTICE
|
|
108
|
-
msg
|
|
108
|
+
"Too many uses of deprecated '#{type}'. #{DEPRECATION_STREAM_NOTICE}"
|
|
109
109
|
end
|
|
110
110
|
end
|
|
111
111
|
|
|
@@ -209,15 +209,15 @@ module RSpec
|
|
|
209
209
|
end
|
|
210
210
|
|
|
211
211
|
def summarize(summary_stream, deprecation_count)
|
|
212
|
-
|
|
212
|
+
path = @file.respond_to?(:path) ? @file.path : @file.inspect
|
|
213
|
+
summary_stream.puts "\n#{Helpers.pluralize(deprecation_count, 'deprecation')} logged to #{path}"
|
|
213
214
|
puts RAISE_ERROR_CONFIG_NOTICE
|
|
214
215
|
end
|
|
215
216
|
end
|
|
216
|
-
|
|
217
217
|
end
|
|
218
218
|
end
|
|
219
219
|
|
|
220
|
-
# Deprecation Error
|
|
220
|
+
# Deprecation Error.
|
|
221
221
|
DeprecationError = Class.new(StandardError)
|
|
222
222
|
end
|
|
223
223
|
end
|