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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: dfc313a9688827e1869e5e7f8a77c48e4de3dae1e5c482ff025ff1ab10d8a5f9
|
4
|
+
data.tar.gz: 778eadf545aad964419c6726a1528d437270b271e144406e0bafe66dea7145ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e3079c080a916da726c6f5fc09d72a80c0f91273ef2cbbe1301708eb458b86773cf336c8f1aa297c819f882ee0b55952f86692c9db0fe2c0a62af5b7a8abf2e
|
7
|
+
data.tar.gz: 90d9fb02c3de9af80b516bf2b3b76520281a0926e16ba383e9384a86a7843be0f20268daba0dd0baa9ca2cb135e58e1bc123b15f5dffd3f0a269ab854b5e3316
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Changelog.md
CHANGED
@@ -1,3 +1,166 @@
|
|
1
|
+
### 3.9.0 / 2019-10-07
|
2
|
+
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.8.2...v3.9.0)
|
3
|
+
|
4
|
+
Enhancements:
|
5
|
+
* Improve the handling of errors during loading support files, if a file
|
6
|
+
errors before loading specs, RSpec will now skip loading the specs.
|
7
|
+
(David Rodríguez, #2568)
|
8
|
+
* Add support for --example-matches to run examples by regular expression.
|
9
|
+
(Sam Joseph, Matt Rider, @okothkongo1, #2586)
|
10
|
+
* Add `did_you_mean` suggestions for file names encountering a `LoadError`
|
11
|
+
outside of examples. (@obromios, #2601)
|
12
|
+
* Add a minimalist quick fix style formatter, only outputs failures as
|
13
|
+
`file:line:message`. (Romain Tartière, #2614)
|
14
|
+
* Convert string number values to integer when used for `RSpec::Configuration#fail_fast`
|
15
|
+
(Viktor Fonic, #2634)
|
16
|
+
* Issue warning when invalid values are used for `RSpec::Configuration#fail_fast`
|
17
|
+
(Viktor Fonic, #2634)
|
18
|
+
* Add support for running the Rake task in a clean environment.
|
19
|
+
(Jon Rowe, #2632)
|
20
|
+
* Indent messages by there example group / example in the documentation formatter.
|
21
|
+
(Samuel Williams, #2649)
|
22
|
+
|
23
|
+
### 3.8.2 / 2019-06-29
|
24
|
+
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.8.1...v3.8.2)
|
25
|
+
|
26
|
+
Bug Fixes:
|
27
|
+
|
28
|
+
* Fix `config.define_derived_metadata` so that cascades are not triggered
|
29
|
+
until metadata has been assigned to the example or example group
|
30
|
+
(Myron Marston, #2635).
|
31
|
+
|
32
|
+
### 3.8.1 / 2019-06-13
|
33
|
+
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.8.0...v3.8.1)
|
34
|
+
|
35
|
+
Bug Fixes:
|
36
|
+
|
37
|
+
* Handle RSpec description(s) with japanese chars in CP932 encoded files.
|
38
|
+
(Benoit Tigeot, #2575)
|
39
|
+
* When defining `let` methods that overwrite an existing method, prevent
|
40
|
+
a warning being issued by removing the old definition. (Jon Rowe, #2593)
|
41
|
+
* Prevent warning on Ruby 2.6.0-rc1 (Keiji Yoshimi, #2582)
|
42
|
+
* Fix `config.define_derived_metadata` so that it supports cascades.
|
43
|
+
(Myron Marston, #2630).
|
44
|
+
|
45
|
+
### 3.8.0 / 2018-08-04
|
46
|
+
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.7.1...v3.8.0)
|
47
|
+
|
48
|
+
Enhancements:
|
49
|
+
|
50
|
+
* Improve shell escaping used by `RSpec::Core::RakeTask` and `--bisect` so
|
51
|
+
that it works on `Pathname` objects. (Andrew Vit, #2479)
|
52
|
+
* Nicely format errors encountered while loading files specified
|
53
|
+
by `--require` option. (Myron Marston, #2504)
|
54
|
+
* Significantly improve the performance of `--bisect` on platforms that
|
55
|
+
support forking by replacing the shell-based runner with one that uses
|
56
|
+
forking so that RSpec and the application environment can be booted only
|
57
|
+
once, instead of once per spec run. (Myron Marston, #2511)
|
58
|
+
* Provide a configuration API to pick which bisect runner is used for
|
59
|
+
`--bisect`. Pick a runner via `config.bisect_runner = :shell` or
|
60
|
+
`config.bisect_runner = :fork` in a file loaded by a `--require`
|
61
|
+
option passed at the command line or set in `.rspec`. (Myron Marston, #2511)
|
62
|
+
* Support the [XDG Base Directory
|
63
|
+
Specification](https://specifications.freedesktop.org/basedir-spec/latest/)
|
64
|
+
for the global options file. `~/.rspec` is still supported when no
|
65
|
+
options file is found in `$XDG_CONFIG_HOME/rspec/options` (Magnus Bergmark, #2538)
|
66
|
+
* Extract `RSpec.world.prepare_example_filtering` that sets up the
|
67
|
+
example filtering for custom RSpec runners. (Oleg Pudeyev, #2552)
|
68
|
+
|
69
|
+
Bug Fixes:
|
70
|
+
|
71
|
+
* Prevent an `ArgumentError` when truncating backtraces with two identical
|
72
|
+
backtraces. (Systho, #2515, Benoit Tigeot, #2539)
|
73
|
+
|
74
|
+
### 3.7.1 / 2018-01-02
|
75
|
+
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.7.0...v3.7.1)
|
76
|
+
|
77
|
+
Bug Fixes:
|
78
|
+
|
79
|
+
* Work around duplicate config hook regression introduced
|
80
|
+
by Ruby 2.5's lazy proc allocation. (Myron Marston, #2497)
|
81
|
+
|
82
|
+
### 3.7.0 / 2017-10-17
|
83
|
+
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0...v3.7.0)
|
84
|
+
|
85
|
+
Enhancements:
|
86
|
+
|
87
|
+
* Add `-n` alias for `--next-failure`. (Ian Ker-Seymer, #2434)
|
88
|
+
* Improve compatibility with `--enable-frozen-string-literal` option
|
89
|
+
on Ruby 2.3+. (Pat Allan, #2425, #2427, #2437)
|
90
|
+
* Do not run `:context` hooks for example groups that have been skipped.
|
91
|
+
(Devon Estes, #2442)
|
92
|
+
* Add `errors_outside_of_examples_count` to the JSON formatter.
|
93
|
+
(Takeshi Arabiki, #2448)
|
94
|
+
|
95
|
+
Bug Fixes:
|
96
|
+
|
97
|
+
* Improve compatibility with frozen string literal flag. (#2425, Pat Allan)
|
98
|
+
|
99
|
+
### 3.6.0 / 2017-05-04
|
100
|
+
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0.beta2...v3.6.0)
|
101
|
+
|
102
|
+
Enhancements:
|
103
|
+
|
104
|
+
* Add seed information to JSON formatter output. (#2388, Mitsutaka Mimura)
|
105
|
+
* Include example id in the JSON formatter output. (#2369, Xavier Shay)
|
106
|
+
* Respect changes to `config.output_stream` after formatters have been
|
107
|
+
setup. (#2401, #2419, Ilya Lavrov)
|
108
|
+
|
109
|
+
Bug Fixes:
|
110
|
+
|
111
|
+
* Delay formatter loading until the last minute to allow accessing the reporter
|
112
|
+
without triggering formatter setup. (Jon Rowe, #2243)
|
113
|
+
* Ensure context hook failures running before an example can access the
|
114
|
+
reporter. (Jon Jensen, #2387)
|
115
|
+
* Multiple fixes to allow using the runner multiple times within the same
|
116
|
+
process: `RSpec.clear_examples` resets the formatter and no longer clears
|
117
|
+
shared examples, and streams can be used across multiple runs rather than
|
118
|
+
being closed after the first. (#2368, Xavier Shay)
|
119
|
+
* Prevent unexpected `example_group_finished` notifications causing an error.
|
120
|
+
(#2396, VTJamie)
|
121
|
+
* Fix bugs where `config.when_first_matching_example_defined` hooks would fire
|
122
|
+
multiple times in some cases. (Yuji Nakayama, #2400)
|
123
|
+
* Default `last_run_status` to "unknown" when the `status` field in the
|
124
|
+
persistence file contains an unrecognized value. (#2360, matrinox)
|
125
|
+
* Prevent `let` from defining an `initialize` method. (#2414, Jon Rowe)
|
126
|
+
|
127
|
+
### 3.6.0.beta2 / 2016-12-12
|
128
|
+
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0.beta1...v3.6.0.beta2)
|
129
|
+
|
130
|
+
Enhancements:
|
131
|
+
|
132
|
+
* Include count of errors occurring outside examples in default summaries.
|
133
|
+
(#2351, Jon Rowe)
|
134
|
+
* Warn when including shared example groups recursively. (#2356, Jon Rowe)
|
135
|
+
* Improve failure snippet syntax highlighting with CodeRay to highlight
|
136
|
+
RSpec "keywords" like `expect`. (#2358, Myron Marston)
|
137
|
+
|
138
|
+
### 3.6.0.beta1 / 2016-10-09
|
139
|
+
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.4...v3.6.0.beta1)
|
140
|
+
|
141
|
+
Enhancements:
|
142
|
+
|
143
|
+
* Warn when duplicate shared examples definitions are loaded due to being
|
144
|
+
defined in files matching the spec pattern (e.g. `_spec.rb`) (#2278, Devon Estes)
|
145
|
+
* Improve metadata filtering so that it can match against any object
|
146
|
+
that implements `===` instead of treating regular expressions as
|
147
|
+
special. (Myron Marston, #2294)
|
148
|
+
* Improve `rspec -v` so that it prints out the versions of each part of
|
149
|
+
RSpec to prevent confusion. (Myron Marston, #2304)
|
150
|
+
* Add `config.fail_if_no_examples` option which causes RSpec to fail if
|
151
|
+
no examples are found. (Ewa Czechowska, #2302)
|
152
|
+
* Nicely format errors encountered while loading spec files.
|
153
|
+
(Myron Marston, #2323)
|
154
|
+
* Improve the API for enabling and disabling color output (Josh
|
155
|
+
Justice, #2321):
|
156
|
+
* Automatically enable color if the output is a TTY, since color is
|
157
|
+
nearly always desirable if the output can handle it.
|
158
|
+
* Introduce new CLI flag to force color on (`--force-color`), even
|
159
|
+
if the output is not a TTY. `--no-color` continues to work as well.
|
160
|
+
* Introduce `config.color_mode` for configuring the color from Ruby.
|
161
|
+
`:automatic` is the default and will produce color if the output is
|
162
|
+
a TTY. `:on` forces it on and `:off` forces it off.
|
163
|
+
|
1
164
|
### 3.5.4 / 2016-09-30
|
2
165
|
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.3...v3.5.4)
|
3
166
|
|
@@ -1863,7 +2026,7 @@ project's root directory or in your home directory:
|
|
1863
2026
|
|
1864
2027
|
require "autotest/bundler"
|
1865
2028
|
|
1866
|
-
Now you can just type 'autotest' on the
|
2029
|
+
Now you can just type 'autotest' on the command line and it will work as you expect.
|
1867
2030
|
|
1868
2031
|
If you don't want 'bundle exec', there is nothing you have to do.
|
1869
2032
|
|
@@ -2051,7 +2214,7 @@ Bug fixes
|
|
2051
2214
|
Enhancements
|
2052
2215
|
|
2053
2216
|
* implicitly require unknown formatters so you don't have to require the file
|
2054
|
-
explicitly on the
|
2217
|
+
explicitly on the command line (Michael Grosser)
|
2055
2218
|
* add --out/-o option to assign output target
|
2056
2219
|
* added fail_fast configuration option to abort on first failure
|
2057
2220
|
* support a Hash subject (its([:key]) { should == value }) (Josep M. Bach)
|
data/README.md
CHANGED
@@ -15,24 +15,10 @@ RSpec repos as well. Add the following to your `Gemfile`:
|
|
15
15
|
|
16
16
|
```ruby
|
17
17
|
%w[rspec rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
|
18
|
-
gem lib, :git => "
|
18
|
+
gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'master'
|
19
19
|
end
|
20
20
|
```
|
21
21
|
|
22
|
-
## Contributing
|
23
|
-
|
24
|
-
Once you've set up the environment, you'll need to cd into the working
|
25
|
-
directory of whichever repo you want to work in. From there you can run the
|
26
|
-
specs and cucumber features, and make patches.
|
27
|
-
|
28
|
-
NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You
|
29
|
-
can treat each RSpec repo as an independent project.
|
30
|
-
|
31
|
-
* [Build details](BUILD_DETAIL.md)
|
32
|
-
* [Code of Conduct](CODE_OF_CONDUCT.md)
|
33
|
-
* [Detailed contributing guide](CONTRIBUTING.md)
|
34
|
-
* [Development setup guide](DEVELOPMENT.md)
|
35
|
-
|
36
22
|
## Basic Structure
|
37
23
|
|
38
24
|
RSpec uses the words "describe" and "it" so we can express concepts like a conversation:
|
@@ -67,7 +53,7 @@ context of an _instance_ of that class.
|
|
67
53
|
|
68
54
|
## Nested Groups
|
69
55
|
|
70
|
-
You can also declare nested
|
56
|
+
You can also declare nested groups using the `describe` or `context`
|
71
57
|
methods:
|
72
58
|
|
73
59
|
```ruby
|
@@ -376,6 +362,20 @@ Finished in 0.000379 seconds
|
|
376
362
|
1 example, 0 failures
|
377
363
|
```
|
378
364
|
|
365
|
+
## Contributing
|
366
|
+
|
367
|
+
Once you've set up the environment, you'll need to cd into the working
|
368
|
+
directory of whichever repo you want to work in. From there you can run the
|
369
|
+
specs and cucumber features, and make patches.
|
370
|
+
|
371
|
+
NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You
|
372
|
+
can treat each RSpec repo as an independent project.
|
373
|
+
|
374
|
+
* [Build details](BUILD_DETAIL.md)
|
375
|
+
* [Code of Conduct](CODE_OF_CONDUCT.md)
|
376
|
+
* [Detailed contributing guide](CONTRIBUTING.md)
|
377
|
+
* [Development setup guide](DEVELOPMENT.md)
|
378
|
+
|
379
379
|
## Also see
|
380
380
|
|
381
381
|
* [https://github.com/rspec/rspec](https://github.com/rspec/rspec)
|
data/lib/rspec/core.rb
CHANGED
@@ -69,7 +69,7 @@ module RSpec
|
|
69
69
|
# same process.
|
70
70
|
def self.clear_examples
|
71
71
|
world.reset
|
72
|
-
configuration.
|
72
|
+
configuration.reset_reporter
|
73
73
|
configuration.start_time = ::RSpec::Core::Time.now
|
74
74
|
configuration.reset_filters
|
75
75
|
end
|
@@ -139,6 +139,7 @@ module RSpec
|
|
139
139
|
module Core
|
140
140
|
autoload :ExampleStatusPersister, "rspec/core/example_status_persister"
|
141
141
|
autoload :Profiler, "rspec/core/profiler"
|
142
|
+
autoload :DidYouMean, "rspec/core/did_you_mean"
|
142
143
|
|
143
144
|
# @private
|
144
145
|
# This avoids issues with reporting time caused by examples that
|
@@ -1,62 +1,58 @@
|
|
1
|
-
RSpec::Support.require_rspec_core "bisect/
|
2
|
-
RSpec::Support.require_rspec_core "bisect/runner"
|
1
|
+
RSpec::Support.require_rspec_core "bisect/shell_command"
|
3
2
|
RSpec::Support.require_rspec_core "bisect/example_minimizer"
|
3
|
+
RSpec::Support.require_rspec_core "bisect/utilities"
|
4
4
|
RSpec::Support.require_rspec_core "formatters/bisect_progress_formatter"
|
5
5
|
|
6
6
|
module RSpec
|
7
7
|
module Core
|
8
8
|
module Bisect
|
9
|
-
# @private
|
10
9
|
# The main entry point into the bisect logic. Coordinates among:
|
11
|
-
# - Bisect::
|
12
|
-
# - Bisect::Runner: Runs a set of examples and directs the results
|
13
|
-
# to the server.
|
10
|
+
# - Bisect::ShellCommand: Generates shell commands to run spec subsets
|
14
11
|
# - Bisect::ExampleMinimizer: Contains the core bisect logic.
|
15
|
-
# -
|
16
|
-
#
|
12
|
+
# - A bisect runner: runs a set of examples and returns the results.
|
13
|
+
# - A bisect formatter: provides progress updates to the user.
|
14
|
+
# @private
|
17
15
|
class Coordinator
|
18
|
-
def self.bisect_with(
|
19
|
-
new(
|
16
|
+
def self.bisect_with(spec_runner, original_cli_args, formatter)
|
17
|
+
new(spec_runner, original_cli_args, formatter).bisect
|
20
18
|
end
|
21
19
|
|
22
|
-
def initialize(
|
23
|
-
@
|
24
|
-
@
|
25
|
-
@
|
20
|
+
def initialize(spec_runner, original_cli_args, formatter)
|
21
|
+
@spec_runner = spec_runner
|
22
|
+
@shell_command = ShellCommand.new(original_cli_args)
|
23
|
+
@notifier = Bisect::Notifier.new(formatter)
|
26
24
|
end
|
27
25
|
|
28
26
|
def bisect
|
29
|
-
|
30
|
-
|
31
|
-
reporter.close_after do
|
32
|
-
repro = Server.run do |server|
|
33
|
-
runner = Runner.new(server, @original_cli_args)
|
34
|
-
minimizer = ExampleMinimizer.new(runner, reporter)
|
27
|
+
repro = start_bisect_runner do |runner|
|
28
|
+
minimizer = ExampleMinimizer.new(@shell_command, runner, @notifier)
|
35
29
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
reporter.publish(:bisect_repro_command, :repro => repro)
|
30
|
+
gracefully_abort_on_sigint(minimizer)
|
31
|
+
minimizer.find_minimal_repro
|
32
|
+
minimizer.repro_command_for_currently_needed_ids
|
42
33
|
end
|
43
34
|
|
35
|
+
@notifier.publish(:bisect_repro_command, :repro => repro)
|
36
|
+
|
44
37
|
true
|
45
38
|
rescue BisectFailedError => e
|
46
|
-
|
39
|
+
@notifier.publish(:bisect_failed, :failure_explanation => e.message)
|
47
40
|
false
|
41
|
+
ensure
|
42
|
+
@notifier.publish(:close)
|
48
43
|
end
|
49
44
|
|
50
45
|
private
|
51
46
|
|
52
|
-
def
|
53
|
-
@configuration.
|
47
|
+
def start_bisect_runner(&block)
|
48
|
+
klass = @spec_runner.configuration.bisect_runner_class
|
49
|
+
klass.start(@shell_command, @spec_runner, &block)
|
54
50
|
end
|
55
51
|
|
56
52
|
def gracefully_abort_on_sigint(minimizer)
|
57
53
|
trap('INT') do
|
58
54
|
repro = minimizer.repro_command_for_currently_needed_ids
|
59
|
-
|
55
|
+
@notifier.publish(:bisect_aborted, :repro => repro)
|
60
56
|
exit(1)
|
61
57
|
end
|
62
58
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
RSpec::Support.require_rspec_core "bisect/utilities"
|
2
|
+
|
1
3
|
module RSpec
|
2
4
|
module Core
|
3
5
|
module Bisect
|
@@ -5,12 +7,13 @@ module RSpec
|
|
5
7
|
# Contains the core bisect logic. Searches for examples we can ignore by
|
6
8
|
# repeatedly running different subsets of the suite.
|
7
9
|
class ExampleMinimizer
|
8
|
-
attr_reader :
|
10
|
+
attr_reader :shell_command, :runner, :all_example_ids, :failed_example_ids
|
9
11
|
attr_accessor :remaining_ids
|
10
12
|
|
11
|
-
def initialize(runner,
|
12
|
-
@
|
13
|
-
@
|
13
|
+
def initialize(shell_command, runner, notifier)
|
14
|
+
@shell_command = shell_command
|
15
|
+
@runner = runner
|
16
|
+
@notifier = notifier
|
14
17
|
end
|
15
18
|
|
16
19
|
def find_minimal_repro
|
@@ -82,7 +85,7 @@ module RSpec
|
|
82
85
|
end
|
83
86
|
|
84
87
|
def repro_command_for_currently_needed_ids
|
85
|
-
return
|
88
|
+
return shell_command.repro_command_from(currently_needed_ids) if remaining_ids
|
86
89
|
"(Not yet enough information to provide any repro command)"
|
87
90
|
end
|
88
91
|
|
@@ -108,7 +111,8 @@ module RSpec
|
|
108
111
|
end
|
109
112
|
|
110
113
|
def prep
|
111
|
-
notify(:bisect_starting, :original_cli_args =>
|
114
|
+
notify(:bisect_starting, :original_cli_args => shell_command.original_cli_args,
|
115
|
+
:bisect_runner => runner.class.name)
|
112
116
|
|
113
117
|
_, duration = track_duration do
|
114
118
|
original_results = runner.original_results
|
@@ -135,7 +139,7 @@ module RSpec
|
|
135
139
|
ids_to_run = ids + failed_example_ids
|
136
140
|
notify(
|
137
141
|
:bisect_individual_run_start,
|
138
|
-
:command =>
|
142
|
+
:command => shell_command.repro_command_from(ids_to_run),
|
139
143
|
:ids_to_run => ids_to_run
|
140
144
|
)
|
141
145
|
|
@@ -161,7 +165,7 @@ module RSpec
|
|
161
165
|
end
|
162
166
|
|
163
167
|
def notify(*args)
|
164
|
-
|
168
|
+
@notifier.publish(*args)
|
165
169
|
end
|
166
170
|
end
|
167
171
|
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
RSpec::Support.require_rspec_core "formatters/base_bisect_formatter"
|
3
|
+
RSpec::Support.require_rspec_core "bisect/utilities"
|
4
|
+
|
5
|
+
module RSpec
|
6
|
+
module Core
|
7
|
+
module Bisect
|
8
|
+
# A Bisect runner that runs requested subsets of the suite by forking
|
9
|
+
# sub-processes. The master process bootstraps RSpec and the application
|
10
|
+
# environment (including preloading files specified via `--require`) so
|
11
|
+
# that the individual spec runs do not have to re-pay that cost. Each
|
12
|
+
# spec run happens in a forked process, ensuring that the spec files are
|
13
|
+
# not loaded in the main process.
|
14
|
+
#
|
15
|
+
# For most projects, bisections that use `ForkRunner` instead of
|
16
|
+
# `ShellRunner` will finish significantly faster, because the `ShellRunner`
|
17
|
+
# pays the cost of booting RSpec and the app environment on _every_ run of
|
18
|
+
# a subset. In contrast, `ForkRunner` pays that cost only once.
|
19
|
+
#
|
20
|
+
# However, not all projects can use `ForkRunner`. Obviously, on platforms
|
21
|
+
# that do not support forking (e.g. Windows), it cannot be used. In addition,
|
22
|
+
# it can cause problems for some projects that put side-effectful spec
|
23
|
+
# bootstrapping logic that should run on every spec run directly at the top
|
24
|
+
# level in a file loaded by `--require`, rather than in a `before(:suite)`
|
25
|
+
# hook. For example, consider a project that relies on some top-level logic
|
26
|
+
# in `spec_helper` to boot a Redis server for the test suite, intending the
|
27
|
+
# Redis bootstrapping to happen on every spec run. With `ShellRunner`, the
|
28
|
+
# bootstrapping logic will happen for each run of any subset of the suite,
|
29
|
+
# but for `ForkRunner`, such logic will only get run once, when the
|
30
|
+
# `RunDispatcher` boots the application environment. This might cause
|
31
|
+
# problems. The solution is for users to move the bootstrapping logic into
|
32
|
+
# a `before(:suite)` hook, or use the slower `ShellRunner`.
|
33
|
+
#
|
34
|
+
# @private
|
35
|
+
class ForkRunner
|
36
|
+
def self.start(shell_command, spec_runner)
|
37
|
+
instance = new(shell_command, spec_runner)
|
38
|
+
yield instance
|
39
|
+
ensure
|
40
|
+
instance.shutdown
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.name
|
44
|
+
:fork
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize(shell_command, spec_runner)
|
48
|
+
@shell_command = shell_command
|
49
|
+
@channel = Channel.new
|
50
|
+
@run_dispatcher = RunDispatcher.new(spec_runner, @channel)
|
51
|
+
end
|
52
|
+
|
53
|
+
def run(locations)
|
54
|
+
run_descriptor = ExampleSetDescriptor.new(locations, original_results.failed_example_ids)
|
55
|
+
dispatch_run(run_descriptor)
|
56
|
+
end
|
57
|
+
|
58
|
+
def original_results
|
59
|
+
@original_results ||= dispatch_run(ExampleSetDescriptor.new(
|
60
|
+
@shell_command.original_locations, []))
|
61
|
+
end
|
62
|
+
|
63
|
+
def shutdown
|
64
|
+
@channel.close
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def dispatch_run(run_descriptor)
|
70
|
+
@run_dispatcher.dispatch_specs(run_descriptor)
|
71
|
+
@channel.receive.tap do |result|
|
72
|
+
if result.is_a?(String)
|
73
|
+
raise BisectFailedError.for_failed_spec_run(result)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# @private
|
79
|
+
class RunDispatcher
|
80
|
+
def initialize(runner, channel)
|
81
|
+
@runner = runner
|
82
|
+
@channel = channel
|
83
|
+
|
84
|
+
@spec_output = StringIO.new
|
85
|
+
|
86
|
+
runner.configuration.tap do |c|
|
87
|
+
c.reset_reporter
|
88
|
+
c.output_stream = @spec_output
|
89
|
+
c.error_stream = @spec_output
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def dispatch_specs(run_descriptor)
|
94
|
+
pid = fork { run_specs(run_descriptor) }
|
95
|
+
Process.waitpid(pid)
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def run_specs(run_descriptor)
|
101
|
+
$stdout = $stderr = @spec_output
|
102
|
+
formatter = CaptureFormatter.new(run_descriptor.failed_example_ids)
|
103
|
+
|
104
|
+
@runner.configuration.tap do |c|
|
105
|
+
c.files_or_directories_to_run = run_descriptor.all_example_ids
|
106
|
+
c.formatter = formatter
|
107
|
+
c.load_spec_files
|
108
|
+
end
|
109
|
+
|
110
|
+
# `announce_filters` has the side effect of implementing the logic
|
111
|
+
# that honors `config.run_all_when_everything_filtered` so we need
|
112
|
+
# to call it here. When we remove `run_all_when_everything_filtered`
|
113
|
+
# (slated for RSpec 4), we can remove this call to `announce_filters`.
|
114
|
+
@runner.world.announce_filters
|
115
|
+
|
116
|
+
@runner.run_specs(@runner.world.ordered_example_groups)
|
117
|
+
latest_run_results = formatter.results
|
118
|
+
|
119
|
+
if latest_run_results.nil? || latest_run_results.all_example_ids.empty?
|
120
|
+
@channel.send(@spec_output.string)
|
121
|
+
else
|
122
|
+
@channel.send(latest_run_results)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
class CaptureFormatter < Formatters::BaseBisectFormatter
|
128
|
+
attr_accessor :results
|
129
|
+
alias_method :notify_results, :results=
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|