Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Commit 80b6be1

Browse files
1.8.7/Jruby: handle --bisect in SPEC_OPTS by mutating environment
Open3.popen3 doesn't support passing a modified environment hash like .capture2e. We can therefore either build a command string with an explicit environment in it, or modify the current environment before invoking the command. While not mutating the current env would normally be preferable, I wasn't confident I could do so correctly while accounting for shell escaping, spaces etc. I've therefore tried modifying the environment, and have provided a new custom matcher that switches on the Open3 command in use.
1 parent 7cc8630 commit 80b6be1

File tree

2 files changed

+53
-24
lines changed

2 files changed

+53
-24
lines changed

lib/rspec/core/bisect/runner.rb

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,36 +72,43 @@ def run_locations(*capture_args)
7272
# https://github.com/jruby/jruby/issues/2766
7373
if Open3.respond_to?(:capture2e) && !RSpec::Support::Ruby.jruby?
7474
def run_command(cmd)
75-
Open3.capture2e(spec_opts_without_bisect, cmd).first
75+
Open3.capture2e(bisect_environment_hash, cmd).first
7676
end
7777
else # for 1.8.7
7878
# :nocov:
7979
def run_command(cmd)
8080
out = err = nil
8181

82-
Open3.popen3(spec_opts_without_bisect, cmd) do |_, stdout, stderr|
82+
original_spec_opts = ENV['SPEC_OPTS']
83+
ENV['SPEC_OPTS'] = spec_opts_without_bisect
84+
85+
Open3.popen3(cmd) do |_, stdout, stderr|
8386
# Reading the streams blocks until the process is complete
8487
out = stdout.read
8588
err = stderr.read
8689
end
8790

8891
"Stdout:\n#{out}\n\nStderr:\n#{err}"
92+
ensure
93+
ENV['SPEC_OPTS'] = original_spec_opts
8994
end
9095
# :nocov:
9196
end
9297

93-
def spec_opts_without_bisect
98+
def bisect_environment_hash
9499
if ENV.key?('SPEC_OPTS')
95-
{ 'SPEC_OPTS' => spec_opts_args_without_bisect.join(" ") }
100+
{ 'SPEC_OPTS' => spec_opts_without_bisect }
96101
else
97102
{}
98103
end
99104
end
100105

101-
def spec_opts_args_without_bisect
102-
Shellwords.split(ENV.fetch('SPEC_OPTS', '')).reject do |arg|
103-
arg =~ /^--bisect/
104-
end
106+
def spec_opts_without_bisect
107+
Shellwords.join(
108+
Shellwords.split(ENV.fetch('SPEC_OPTS', '')).reject do |arg|
109+
arg =~ /^--bisect/
110+
end
111+
)
105112
end
106113

107114
def reusable_cli_options

spec/rspec/core/bisect/runner_spec.rb

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,27 @@ def repro_command_from(ids)
213213
open3_method = Open3.respond_to?(:capture2e) ? :capture2e : :popen3
214214
open3_method = :popen3 if RSpec::Support::Ruby.jruby?
215215

216+
RSpec::Matchers.define :invoke_command_with_env do |command, environment|
217+
match do |actual|
218+
if open3_method == :capture2e
219+
actual.call
220+
expect(Open3).to have_received(open3_method).with(environment, command)
221+
elsif open3_method == :popen3
222+
called_environment = nil
223+
allow(Open3).to receive(open3_method) do
224+
called_environment = ENV.to_hash.dup
225+
end
226+
actual.call
227+
expect(Open3).to have_received(open3_method).with(command)
228+
expect(called_environment).to include(environment)
229+
end
230+
end
231+
232+
def supports_block_expectations?
233+
true
234+
end
235+
end
236+
216237
before do
217238
allow(Open3).to receive(open3_method).and_return(
218239
[double("Exit Status"), double("Stdout/err")]
@@ -224,32 +245,33 @@ def repro_command_from(ids)
224245
end
225246

226247
it "runs the suite with the original CLI options" do
227-
runner.original_results
228-
expect(Open3).to have_received(open3_method).with({}, a_string_including("--seed 1234"))
248+
expect {
249+
runner.original_results
250+
}.to invoke_command_with_env(a_string_including("--seed 1234"), {})
229251
end
230252

231253
context 'when --bisect is present in SPEC_OPTS' do
232254
it "runs the suite with --bisect removed from the environment" do
233-
with_env_vars 'SPEC_OPTS' => '--bisect --fail-fast' do
234-
runner.original_results
235-
end
236-
237-
expect(Open3).to have_received(open3_method).with(
238-
{ 'SPEC_OPTS' => '--fail-fast' },
239-
a_string_including("--seed 1234")
255+
expect {
256+
with_env_vars 'SPEC_OPTS' => '--bisect --fail-fast' do
257+
runner.original_results
258+
end
259+
}.to invoke_command_with_env(
260+
a_string_including("--seed 1234"),
261+
{ 'SPEC_OPTS' => '--fail-fast' }
240262
)
241263
end
242264
end
243265

244266
context 'when --bisect=verbose is present in SPEC_OPTS' do
245267
it "runs the suite with --bisect removed from the environment" do
246-
with_env_vars 'SPEC_OPTS' => '--bisect=verbose --fail-fast' do
247-
runner.original_results
248-
end
249-
250-
expect(Open3).to have_received(open3_method).with(
251-
{ 'SPEC_OPTS' => '--fail-fast' },
252-
a_string_including("--seed 1234")
268+
expect {
269+
with_env_vars 'SPEC_OPTS' => '--bisect=verbose --fail-fast' do
270+
runner.original_results
271+
end
272+
}.to invoke_command_with_env(
273+
a_string_including("--seed 1234"),
274+
{ 'SPEC_OPTS' => '--fail-fast' }
253275
)
254276
end
255277
end

0 commit comments

Comments
 (0)