rspec-core 3.7.1 → 3.8.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 +29 -0
- data/README.md +1 -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 +4 -13
- 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 +133 -53
- data/lib/rspec/core/configuration_options.rb +41 -4
- data/lib/rspec/core/example.rb +4 -4
- data/lib/rspec/core/example_group.rb +1 -0
- data/lib/rspec/core/formatters.rb +10 -6
- data/lib/rspec/core/formatters/base_bisect_formatter.rb +45 -0
- data/lib/rspec/core/formatters/bisect_drb_formatter.rb +29 -0
- data/lib/rspec/core/formatters/bisect_progress_formatter.rb +29 -16
- data/lib/rspec/core/formatters/deprecation_formatter.rb +3 -1
- data/lib/rspec/core/formatters/exception_presenter.rb +1 -0
- data/lib/rspec/core/formatters/html_printer.rb +0 -2
- data/lib/rspec/core/formatters/protocol.rb +17 -17
- data/lib/rspec/core/formatters/syntax_highlighter.rb +19 -19
- data/lib/rspec/core/hooks.rb +1 -3
- data/lib/rspec/core/invocations.rb +8 -6
- data/lib/rspec/core/memoized_helpers.rb +2 -2
- data/lib/rspec/core/profiler.rb +3 -1
- data/lib/rspec/core/reporter.rb +3 -6
- data/lib/rspec/core/runner.rb +20 -14
- data/lib/rspec/core/shared_example_group.rb +1 -3
- data/lib/rspec/core/shell_escape.rb +2 -2
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/world.rb +11 -0
- metadata +12 -8
- metadata.gz.sig +0 -0
- data/lib/rspec/core/formatters/bisect_formatter.rb +0 -69
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 01f0ed2875b8c4e0801d2857936e4a4116ceb309
|
4
|
+
data.tar.gz: 58b9a780de52779ef48a2c510d99c14dd7a22f1d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc81061f5a9badff82a346285c6571447b9884906540c0502aeec96c1d100d4c764e2422f87dadd46148a8db96926b9c1a5e5d57a72adda28d6f05ddceae65e9
|
7
|
+
data.tar.gz: 940193670454593373c80e55c407e31a70b3eb8f9579b108663ec9234e2025149a93aed2d8aec8e2e7eeffd124853bf1a5a068d2a79e4bbcaed551b769d485fd
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Changelog.md
CHANGED
@@ -1,3 +1,32 @@
|
|
1
|
+
### 3.8.0 / 2018-08-04
|
2
|
+
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.7.1...v3.8.0)
|
3
|
+
|
4
|
+
Enhancements:
|
5
|
+
|
6
|
+
* Improve shell escaping used by `RSpec::Core::RakeTask` and `--bisect` so
|
7
|
+
that it works on `Pathname` objects. (Andrew Vit, #2479)
|
8
|
+
* Nicely format errors encountered while loading files specified
|
9
|
+
by `--require` option. (Myron Marston, #2504)
|
10
|
+
* Significantly improve the performance of `--bisect` on platforms that
|
11
|
+
support forking by replacing the shell-based runner with one that uses
|
12
|
+
forking so that RSpec and the application environment can be booted only
|
13
|
+
once, instead of once per spec run. (Myron Marston, #2511)
|
14
|
+
* Provide a configuration API to pick which bisect runner is used for
|
15
|
+
`--bisect`. Pick a runner via `config.bisect_runner = :shell` or
|
16
|
+
`config.bisect_runner = :fork` in a file loaded by a `--require`
|
17
|
+
option passed at the command line or set in `.rspec`. (Myron Marston, #2511)
|
18
|
+
* Support the [XDG Base Directory
|
19
|
+
Specification](https://specifications.freedesktop.org/basedir-spec/latest/)
|
20
|
+
for the global options file. `~/.rspec` is still supported when no
|
21
|
+
options file is found in `$XDG_CONFIG_HOME/rspec/options` (Magnus Bergmark, #2538)
|
22
|
+
* Extract `RSpec.world.prepare_example_filtering` that sets up the
|
23
|
+
example filtering for custom RSpec runners. (Oleg Pudeyev, #2552)
|
24
|
+
|
25
|
+
Bug Fixes:
|
26
|
+
|
27
|
+
* Prevent an `ArgumentError` when truncating backtraces with two identical
|
28
|
+
backtraces. (Systho, #2515, Benoit Tigeot, #2539)
|
29
|
+
|
1
30
|
### 3.7.1 / 2018-01-02
|
2
31
|
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.7.0...v3.7.1)
|
3
32
|
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@ 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
|
|
@@ -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
|
@@ -1,13 +1,11 @@
|
|
1
1
|
require 'drb/drb'
|
2
2
|
require 'drb/acl'
|
3
|
+
RSpec::Support.require_rspec_core "bisect/utilities"
|
3
4
|
|
4
5
|
module RSpec
|
5
6
|
module Core
|
6
7
|
# @private
|
7
8
|
module Bisect
|
8
|
-
# @private
|
9
|
-
BisectFailedError = Class.new(StandardError)
|
10
|
-
|
11
9
|
# @private
|
12
10
|
# A DRb server that receives run results from a separate RSpec process
|
13
11
|
# started by the bisect process.
|
@@ -27,7 +25,7 @@ module RSpec
|
|
27
25
|
run_output = yield
|
28
26
|
|
29
27
|
if latest_run_results.nil? || latest_run_results.all_example_ids.empty?
|
30
|
-
|
28
|
+
raise BisectFailedError.for_failed_spec_run(run_output)
|
31
29
|
end
|
32
30
|
|
33
31
|
latest_run_results
|
@@ -49,21 +47,14 @@ module RSpec
|
|
49
47
|
@drb_port ||= Integer(@drb.uri[/\d+$/])
|
50
48
|
end
|
51
49
|
|
52
|
-
# Fetched via DRb by the
|
50
|
+
# Fetched via DRb by the BisectDRbFormatter to determine when to abort.
|
53
51
|
attr_accessor :expected_failures
|
54
52
|
|
55
|
-
# Set via DRb by the
|
53
|
+
# Set via DRb by the BisectDRbFormatter with the results of the run.
|
56
54
|
attr_accessor :latest_run_results
|
57
55
|
|
58
56
|
# Fetched via DRb to tell clients which files to run
|
59
57
|
attr_accessor :files_or_directories_to_run
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def raise_bisect_failed(run_output)
|
64
|
-
raise BisectFailedError, "Failed to get results from the spec " \
|
65
|
-
"run. Spec run output:\n\n#{run_output}"
|
66
|
-
end
|
67
58
|
end
|
68
59
|
end
|
69
60
|
end
|
@@ -1,36 +1,30 @@
|
|
1
1
|
RSpec::Support.require_rspec_core "shell_escape"
|
2
|
-
require 'open3'
|
3
2
|
require 'shellwords'
|
4
3
|
|
5
4
|
module RSpec
|
6
5
|
module Core
|
7
6
|
module Bisect
|
8
|
-
# Provides an API to run the suite for a
|
9
|
-
# the given bisect server to capture the results.
|
7
|
+
# Provides an API to generate shell commands to run the suite for a
|
8
|
+
# set of locations, using the given bisect server to capture the results.
|
10
9
|
# @private
|
11
|
-
class
|
10
|
+
class ShellCommand
|
12
11
|
attr_reader :original_cli_args
|
13
12
|
|
14
|
-
def initialize(
|
15
|
-
@server = server
|
13
|
+
def initialize(original_cli_args)
|
16
14
|
@original_cli_args = original_cli_args.reject { |arg| arg.start_with?("--bisect") }
|
17
15
|
end
|
18
16
|
|
19
|
-
def
|
20
|
-
run_locations(locations, original_results.failed_example_ids)
|
21
|
-
end
|
22
|
-
|
23
|
-
def command_for(locations)
|
17
|
+
def command_for(locations, server)
|
24
18
|
parts = []
|
25
19
|
|
26
20
|
parts << RUBY << load_path
|
27
21
|
parts << open3_safe_escape(RSpec::Core.path_to_executable)
|
28
22
|
|
29
|
-
parts << "--format" << "bisect"
|
30
|
-
parts << "--drb-port" <<
|
23
|
+
parts << "--format" << "bisect-drb"
|
24
|
+
parts << "--drb-port" << server.drb_port
|
31
25
|
|
32
|
-
parts.concat
|
33
|
-
parts.concat
|
26
|
+
parts.concat(reusable_cli_options)
|
27
|
+
parts.concat(locations.map { |l| open3_safe_escape(l) })
|
34
28
|
|
35
29
|
parts.join(" ")
|
36
30
|
end
|
@@ -46,8 +40,24 @@ module RSpec
|
|
46
40
|
parts.join(" ")
|
47
41
|
end
|
48
42
|
|
49
|
-
def
|
50
|
-
|
43
|
+
def original_locations
|
44
|
+
parsed_original_cli_options.fetch(:files_or_directories_to_run)
|
45
|
+
end
|
46
|
+
|
47
|
+
def bisect_environment_hash
|
48
|
+
if ENV.key?('SPEC_OPTS')
|
49
|
+
{ 'SPEC_OPTS' => spec_opts_without_bisect }
|
50
|
+
else
|
51
|
+
{}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def spec_opts_without_bisect
|
56
|
+
Shellwords.join(
|
57
|
+
Shellwords.split(ENV.fetch('SPEC_OPTS', '')).reject do |arg|
|
58
|
+
arg =~ /^--bisect/
|
59
|
+
end
|
60
|
+
)
|
51
61
|
end
|
52
62
|
|
53
63
|
private
|
@@ -63,61 +73,12 @@ module RSpec
|
|
63
73
|
alias open3_safe_escape escape
|
64
74
|
end
|
65
75
|
|
66
|
-
def run_locations(*capture_args)
|
67
|
-
@server.capture_run_results(*capture_args) do
|
68
|
-
run_command command_for([])
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# `Open3.capture2e` does not work on JRuby:
|
73
|
-
# https://github.com/jruby/jruby/issues/2766
|
74
|
-
if Open3.respond_to?(:capture2e) && !RSpec::Support::Ruby.jruby?
|
75
|
-
def run_command(cmd)
|
76
|
-
Open3.capture2e(bisect_environment_hash, cmd).first
|
77
|
-
end
|
78
|
-
else # for 1.8.7
|
79
|
-
# :nocov:
|
80
|
-
def run_command(cmd)
|
81
|
-
out = err = nil
|
82
|
-
|
83
|
-
original_spec_opts = ENV['SPEC_OPTS']
|
84
|
-
ENV['SPEC_OPTS'] = spec_opts_without_bisect
|
85
|
-
|
86
|
-
Open3.popen3(cmd) do |_, stdout, stderr|
|
87
|
-
# Reading the streams blocks until the process is complete
|
88
|
-
out = stdout.read
|
89
|
-
err = stderr.read
|
90
|
-
end
|
91
|
-
|
92
|
-
"Stdout:\n#{out}\n\nStderr:\n#{err}"
|
93
|
-
ensure
|
94
|
-
ENV['SPEC_OPTS'] = original_spec_opts
|
95
|
-
end
|
96
|
-
# :nocov:
|
97
|
-
end
|
98
|
-
|
99
|
-
def bisect_environment_hash
|
100
|
-
if ENV.key?('SPEC_OPTS')
|
101
|
-
{ 'SPEC_OPTS' => spec_opts_without_bisect }
|
102
|
-
else
|
103
|
-
{}
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
76
|
def environment_repro_parts
|
108
77
|
bisect_environment_hash.map do |k, v|
|
109
78
|
%Q(#{k}="#{v}")
|
110
79
|
end
|
111
80
|
end
|
112
81
|
|
113
|
-
def spec_opts_without_bisect
|
114
|
-
Shellwords.join(
|
115
|
-
Shellwords.split(ENV.fetch('SPEC_OPTS', '')).reject do |arg|
|
116
|
-
arg =~ /^--bisect/
|
117
|
-
end
|
118
|
-
)
|
119
|
-
end
|
120
|
-
|
121
82
|
def reusable_cli_options
|
122
83
|
@reusable_cli_options ||= begin
|
123
84
|
opts = original_cli_args_without_locations
|
@@ -146,10 +107,6 @@ module RSpec
|
|
146
107
|
@parsed_original_cli_options ||= Parser.parse(@original_cli_args)
|
147
108
|
end
|
148
109
|
|
149
|
-
def original_locations
|
150
|
-
parsed_original_cli_options.fetch(:files_or_directories_to_run)
|
151
|
-
end
|
152
|
-
|
153
110
|
def load_path
|
154
111
|
@load_path ||= "-I#{$LOAD_PATH.map { |p| open3_safe_escape(p) }.join(':')}"
|
155
112
|
end
|