rspec-core 3.5.4 → 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 +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
|