Skip to content

Commit 1796fda

Browse files
committed
Merge pull request #331 from guard/e2-support_custom_results_file
Support custom result files
2 parents 5c4a004 + 6e26645 commit 1796fda

File tree

8 files changed

+99
-35
lines changed

8 files changed

+99
-35
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ notification: false # Display notification after the specs are done running,
9595
run_all: { cmd: 'custom rspec command', message: 'custom message' } # Custom options to use when running all specs
9696
title: 'My project' # Display a custom title for the notification, default: 'RSpec results'
9797
chdir: 'directory' # run rspec from within a given subdirectory (useful if project has separate specs for submodules)
98+
results_file: 'some/path' # use the given file for storing results (instead of default relative path)
9899
```
99100

100101
### Using Launchy to view rspec results

lib/guard/rspec/rspec_process.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ def _run
3434
end
3535

3636
def _really_run
37-
pid = Kernel.spawn(command) # use spawn to stub in JRuby
37+
env = { "GUARD_RSPEC_RESULTS_FILE" => formatter_tmp_file }
38+
pid = Kernel.spawn(env, command) # use spawn to stub in JRuby
3839
result = Process.wait2(pid)
3940
result.last.exitstatus
4041
rescue Errno::ENOENT => ex

lib/guard/rspec/runner.rb

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,20 @@ def reload
4949

5050
def _run(paths, options, &block)
5151
fail NoCmdOptionError unless options[:cmd]
52-
_really_run(paths, options, &block)
52+
command = Command.new(paths, options)
53+
_really_run(command, options, &block)
5354
true
5455
rescue RSpecProcess::Failure, NoCmdOptionError => ex
5556
Compat::UI.error(ex.to_s)
5657
notifier.notify_failure
5758
false
5859
end
5960

60-
def _really_run(paths, options)
61+
def _really_run(cmd, options)
6162
# TODO: add option to specify the file
62-
file = _tmp_file(options[:chdir])
63+
file = _results_file(options[:results_file], options[:chdir])
6364

64-
process = RSpecProcess.new(Command.new(paths, options), file)
65+
process = RSpecProcess.new(cmd, file)
6566
results = process.results
6667

6768
inspector.failed(results.failed_paths)
@@ -78,8 +79,10 @@ def _open_launchy
7879
::Launchy.open(options[:launchy]) if pn.exist?
7980
end
8081

81-
def _tmp_file(chdir)
82-
chdir ? File.join(chdir, TEMPORARY_FILE_PATH) : TEMPORARY_FILE_PATH
82+
def _results_file(results_file, chdir)
83+
results_file ||= TEMPORARY_FILE_PATH
84+
return results_file unless Pathname(results_file).relative?
85+
chdir ? File.join(chdir, results_file) : results_file
8386
end
8487
end
8588
end

lib/guard/rspec_formatter.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
module Guard
1111
class RSpecFormatter < ::RSpec::Core::Formatters::BaseFormatter
12-
TEMPORARY_FILE_PATH ||= "tmp/rspec_guard_result"
13-
1412
def self.rspec_3?
1513
::RSpec::Core::Version::STRING.split(".").first == "3"
1614
end
@@ -82,7 +80,7 @@ def write_summary(duration, total, failures, pending)
8280
end
8381

8482
def _write(&block)
85-
file = File.expand_path(TEMPORARY_FILE_PATH)
83+
file = _results_file
8684
FileUtils.mkdir_p(File.dirname(file))
8785
File.open(file, "w", &block)
8886
end
@@ -109,5 +107,11 @@ def _status_failed?(example)
109107
example.execution_result[:status].to_s == "failed"
110108
end
111109
end
110+
111+
def _results_file
112+
path = ENV["GUARD_RSPEC_RESULTS_FILE"]
113+
fail "Fatal: No output file given for Guard::RSpec formatter!" unless path
114+
File.expand_path(path)
115+
end
112116
end
113117
end

spec/lib/guard/rspec/command_spec.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@
4646
end
4747

4848
context "with no RSpec defined formatter" do
49+
before do
50+
allow(RSpec::Core::ConfigurationOptions).to receive(:new) do
51+
instance_double(RSpec::Core::ConfigurationOptions,
52+
options: { formatters: nil })
53+
end
54+
end
55+
4956
it "sets default progress formatter" do
5057
expect(command).to match %r{-f progress}
5158
end

spec/lib/guard/rspec/rspec_process_spec.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@
2323
end
2424

2525
before do
26+
allow(Kernel).to receive(:spawn).
27+
with({ "GUARD_RSPEC_RESULTS_FILE" => file }, cmd).and_return(pid)
28+
2629
allow(Guard::RSpec::Results).to receive(:new).
27-
with("foobar.txt").and_return(results)
30+
with(file).and_return(results)
2831
end
2932

3033
context "with an non-existing command" do
@@ -41,7 +44,6 @@
4144

4245
context "with an existing command" do
4346
before do
44-
allow(Kernel).to receive(:spawn).with(cmd).and_return(pid)
4547
allow(Process).to receive(:wait2).with(pid).and_return(wait_result)
4648
end
4749

@@ -65,8 +67,7 @@
6567
end
6668

6769
context "with no failures" do
68-
it "spawns and waits" do
69-
expect(Kernel).to receive(:spawn).with(cmd).and_return(pid)
70+
it "waits for process to end" do
7071
expect(Process).to receive(:wait2).with(pid).and_return(wait_result)
7172
subject
7273
end

spec/lib/guard/rspec/runner_spec.rb

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,66 @@
191191
end
192192
end
193193

194+
context "with a custom results file" do
195+
let(:options) do
196+
{ cmd: "rspec", results_file: results_file }.merge(chdir_options)
197+
end
198+
199+
context "with no chdir option" do
200+
let(:chdir_options) { {} }
201+
202+
context "when the path is relative" do
203+
let(:results_file) { "foobar.txt" }
204+
it "uses the given file" do
205+
expect(Guard::RSpec::RSpecProcess).to receive(:new).
206+
with(anything, results_file).and_return(process)
207+
runner.run(paths)
208+
end
209+
end
210+
211+
context "when the path is absolute" do
212+
let(:results_file) { "/foo/foobar.txt" }
213+
it "uses the given path" do
214+
expect(Guard::RSpec::RSpecProcess).to receive(:new).
215+
with(anything, results_file).and_return(process)
216+
runner.run(paths)
217+
end
218+
end
219+
end
220+
221+
context "with chdir option" do
222+
let(:chdir_options) { { chdir: "moduleA" } }
223+
224+
context "when the path is relative" do
225+
let(:results_file) { "foobar.txt" }
226+
227+
it "uses a path relative to chdir" do
228+
expect(Guard::RSpec::RSpecProcess).to receive(:new).
229+
with(anything, "moduleA/foobar.txt").and_return(process)
230+
runner.run(paths)
231+
end
232+
end
233+
234+
context "when the path is absolute" do
235+
let(:results_file) { "/foo/foobar.txt" }
236+
it "uses the full given path anyway" do
237+
expect(Guard::RSpec::RSpecProcess).to receive(:new).
238+
with(anything, results_file).and_return(process)
239+
runner.run(paths)
240+
end
241+
end
242+
end
243+
end
244+
245+
context "with no custom results file" do
246+
let(:options) { { cmd: "rspec" } }
247+
it "uses the default" do
248+
expect(Guard::RSpec::RSpecProcess).to receive(:new).
249+
with(anything, "tmp/rspec_guard_result").and_return(process)
250+
runner.run(paths)
251+
end
252+
end
253+
194254
it "notifies inspector about failed paths" do
195255
expect(inspector).to receive(:failed).with([])
196256
runner.run(paths)
@@ -225,19 +285,4 @@
225285
runner.run(paths)
226286
end
227287
end
228-
229-
# TODO: remove / cleanup
230-
describe "_tmp_file" do
231-
subject { described_class.new.send(:_tmp_file, chdir) }
232-
233-
context "with no chdir option" do
234-
let(:chdir) { nil }
235-
it { is_expected.to eq("tmp/rspec_guard_result") }
236-
end
237-
238-
context "chdir option" do
239-
let(:chdir) { "moduleA" }
240-
it { is_expected.to eq("moduleA/tmp/rspec_guard_result") }
241-
end
242-
end
243288
end

spec/lib/guard/rspec_formatter_spec.rb

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
require "guard/rspec_formatter"
22

33
RSpec.describe Guard::RSpecFormatter do
4-
describe "::TEMPORARY_FILE_PATH" do
5-
subject { Pathname.new(described_class::TEMPORARY_FILE_PATH) }
6-
it { is_expected.to be_relative }
7-
end
8-
94
describe "#dump_summary" do
105
def rspec_summary_args(*args)
116
return args unless ::RSpec::Core::Version::STRING.start_with?("3.")
@@ -53,8 +48,15 @@ def rspec_summary_args(*args)
5348
context "without stubbed IO" do
5449
let(:stub_formatter) { false }
5550

51+
around do |example|
52+
env_var = "GUARD_RSPEC_RESULTS_FILE"
53+
old, ENV[env_var] = ENV[env_var], "foobar.txt"
54+
example.run
55+
ENV[env_var] = old
56+
end
57+
5658
it "creates temporary file and and writes to it" do
57-
file = File.expand_path(described_class::TEMPORARY_FILE_PATH)
59+
file = File.expand_path("foobar.txt")
5860

5961
expect(FileUtils).to receive(:mkdir_p).
6062
with(File.dirname(file)) {}

0 commit comments

Comments
 (0)