guard-rspec 2.1.0 → 4.7.3

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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.hound.yml +3 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +5 -0
  6. data/.rubocop_todo.yml +40 -0
  7. data/.travis.yml +14 -0
  8. data/CONTRIBUTING.md +38 -0
  9. data/Gemfile +25 -0
  10. data/Guardfile +28 -0
  11. data/{LICENSE → LICENSE.txt} +4 -2
  12. data/README.md +99 -114
  13. data/Rakefile +38 -0
  14. data/gemfiles/Gemfile.rspec-2.99 +6 -0
  15. data/gemfiles/Gemfile.rspec-3.4 +6 -0
  16. data/gemfiles/common +9 -0
  17. data/guard-rspec.gemspec +25 -0
  18. data/lib/guard/rspec/command.rb +71 -0
  19. data/lib/guard/rspec/deprecator.rb +86 -0
  20. data/lib/guard/rspec/dsl.rb +72 -0
  21. data/lib/guard/rspec/inspectors/base_inspector.rb +73 -0
  22. data/lib/guard/rspec/inspectors/factory.rb +23 -0
  23. data/lib/guard/rspec/inspectors/focused_inspector.rb +39 -0
  24. data/lib/guard/rspec/inspectors/keeping_inspector.rb +97 -0
  25. data/lib/guard/rspec/inspectors/simple_inspector.rb +21 -0
  26. data/lib/guard/rspec/notifier.rb +55 -0
  27. data/lib/guard/rspec/options.rb +37 -0
  28. data/lib/guard/rspec/results.rb +23 -0
  29. data/lib/guard/rspec/rspec_process.rb +93 -0
  30. data/lib/guard/rspec/runner.rb +71 -174
  31. data/lib/guard/rspec/templates/Guardfile +49 -17
  32. data/lib/guard/rspec/version.rb +1 -1
  33. data/lib/guard/rspec.rb +30 -59
  34. data/lib/guard/rspec_defaults.rb +5 -0
  35. data/lib/guard/rspec_formatter.rb +147 -0
  36. data/lib/guard/rspec_formatter_results_path.rb +29 -0
  37. data/spec/acceptance/fixtures/succeeding_spec.rb +4 -0
  38. data/spec/acceptance/formatter_spec.rb +46 -0
  39. data/spec/lib/guard/rspec/command_spec.rb +95 -0
  40. data/spec/lib/guard/rspec/deprecator_spec.rb +101 -0
  41. data/spec/lib/guard/rspec/inspectors/base_inspector_spec.rb +144 -0
  42. data/spec/lib/guard/rspec/inspectors/factory_spec.rb +45 -0
  43. data/spec/lib/guard/rspec/inspectors/focused_inspector_spec.rb +140 -0
  44. data/spec/lib/guard/rspec/inspectors/keeping_inspector_spec.rb +200 -0
  45. data/spec/lib/guard/rspec/inspectors/shared_examples.rb +121 -0
  46. data/spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb +59 -0
  47. data/spec/lib/guard/rspec/notifier_spec.rb +90 -0
  48. data/spec/lib/guard/rspec/results_spec.rb +66 -0
  49. data/spec/lib/guard/rspec/rspec_process_spec.rb +152 -0
  50. data/spec/lib/guard/rspec/runner_spec.rb +372 -0
  51. data/spec/lib/guard/rspec/template_spec.rb +78 -0
  52. data/spec/lib/guard/rspec_formatter_spec.rb +277 -0
  53. data/spec/lib/guard/rspec_spec.rb +91 -0
  54. data/spec/spec_helper.rb +145 -0
  55. metadata +103 -42
  56. data/lib/guard/rspec/formatter.rb +0 -56
  57. data/lib/guard/rspec/inspector.rb +0 -72
@@ -0,0 +1,200 @@
1
+ require "guard/compat/test/helper"
2
+
3
+ require "lib/guard/rspec/inspectors/shared_examples"
4
+
5
+ require "guard/rspec/inspectors/keeping_inspector"
6
+
7
+ klass = Guard::RSpec::Inspectors::KeepingInspector
8
+
9
+ RSpec.describe klass do
10
+ include_examples "inspector", klass
11
+
12
+ # Use real paths because BaseInspector#_clean will be used to clean them
13
+ let(:other_paths) do
14
+ [
15
+ "spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb",
16
+ "spec/lib/guard/rspec/runner_spec.rb"
17
+ ]
18
+ end
19
+ let(:other_failed_locations) do
20
+ [
21
+ "./spec/lib/guard/rspec/runner_spec.rb:12",
22
+ "./spec/lib/guard/rspec/runner_spec.rb:100",
23
+ "./spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb:12"
24
+ ]
25
+ end
26
+
27
+ it "remembers failed paths and returns them along with new paths" do
28
+ allow(File).to receive(:directory?).
29
+ with("spec/lib/guard/rspec/inspectors/base_inspector_spec.rb").
30
+ and_return(false)
31
+
32
+ allow(File).to receive(:directory?).
33
+ with("spec/lib/guard/rspec/runner_spec.rb").
34
+ and_return(false)
35
+
36
+ allow(File).to receive(:directory?).
37
+ with("spec/lib/guard/rspec/deprecator_spec.rb").
38
+ and_return(false)
39
+
40
+ allow(File).to receive(:directory?).
41
+ with("spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb").
42
+ and_return(false)
43
+
44
+ allow(Dir).to receive(:[]).with("spec/**{,/*/**}/*[_.]spec.rb").
45
+ and_return(paths + other_paths)
46
+
47
+ allow(Dir).to receive(:[]).with("myspec/**{,/*/**}/*[_.]spec.rb").
48
+ and_return([])
49
+
50
+ allow(Dir).to receive(:[]).with("myspec/**{,/*/**}/*.feature").
51
+ and_return([])
52
+
53
+ allow(Dir).to receive(:[]).with("spec/**{,/*/**}/*.feature").
54
+ and_return([])
55
+
56
+ expect(inspector.paths(paths)).to eq(paths)
57
+ inspector.failed(failed_locations)
58
+
59
+ # Line numbers in failed_locations needs to be omitted because of
60
+ # https://github.com/rspec/rspec-core/issues/952
61
+ expect(inspector.paths(other_paths)).to match_array(
62
+ [
63
+ "spec/lib/guard/rspec/deprecator_spec.rb",
64
+ "spec/lib/guard/rspec/runner_spec.rb",
65
+ "spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb"
66
+ ]
67
+ )
68
+ inspector.failed(other_failed_locations)
69
+
70
+ # Now it returns other failed locations
71
+ expect(
72
+ inspector.paths(
73
+ %w(spec/lib/guard/rspec/inspectors/base_inspector_spec.rb)
74
+ )
75
+ ).to match_array(
76
+ [
77
+ "spec/lib/guard/rspec/runner_spec.rb",
78
+ "spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb",
79
+ "spec/lib/guard/rspec/inspectors/base_inspector_spec.rb"
80
+ ]
81
+ )
82
+ inspector.failed(other_failed_locations)
83
+
84
+ expect(
85
+ inspector.paths(%w(spec/lib/guard/rspec/runner_spec.rb))
86
+ ).to match_array(
87
+ [
88
+ "spec/lib/guard/rspec/runner_spec.rb",
89
+ "spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb"
90
+ ]
91
+ )
92
+
93
+ inspector.failed([])
94
+
95
+ # Now there is no failed locations
96
+ expect(inspector.paths(paths)).to match_array(paths)
97
+ end
98
+
99
+ describe "#reload" do
100
+ it "force to forget about failed locations" do
101
+ allow(File).to receive(:directory?).
102
+ with("spec/lib/guard/rspec/inspectors/base_inspector_spec.rb").
103
+ and_return(false)
104
+
105
+ allow(File).to receive(:directory?).
106
+ with("spec/lib/guard/rspec/runner_spec.rb").
107
+ and_return(false)
108
+
109
+ allow(File).to receive(:directory?).
110
+ with("spec/lib/guard/rspec/deprecator_spec.rb").
111
+ and_return(false)
112
+
113
+ allow(File).to receive(:directory?).
114
+ with("spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb").
115
+ and_return(false)
116
+
117
+ allow(Dir).to receive(:[]).with("spec/**{,/*/**}/*[_.]spec.rb").
118
+ and_return(paths + other_paths)
119
+
120
+ allow(Dir).to receive(:[]).with("myspec/**{,/*/**}/*[_.]spec.rb").
121
+ and_return([])
122
+
123
+ allow(Dir).to receive(:[]).with("myspec/**{,/*/**}/*.feature").
124
+ and_return([])
125
+
126
+ allow(Dir).to receive(:[]).with("spec/**{,/*/**}/*.feature").
127
+ and_return([])
128
+
129
+ expect(inspector.paths(paths)).to eq(paths)
130
+ inspector.failed(failed_locations)
131
+
132
+ inspector.reload
133
+ expect(inspector.paths(other_paths)).to match_array(other_paths)
134
+ end
135
+ end
136
+ end
137
+
138
+ #
139
+ # FIXME uncomment when RSpec #952 will be resolved
140
+ #
141
+ # This is correct spec for KeepingInspector class,
142
+ # bit it doesn't work because of bug with RSpec
143
+ # https://github.com/rspec/rspec-core/issues/952
144
+ #
145
+ # describe klass do
146
+ # include_examples 'inspector', klass
147
+ #
148
+ # # Use real paths because BaseInspector#_clean will be used to clean them
149
+ # let(:other_paths) { [
150
+ # 'spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb',
151
+ # 'spec/lib/guard/rspec/runner_spec.rb'
152
+ # ] }
153
+ # let(:other_failed_locations) { [
154
+ # './spec/lib/guard/rspec/runner_spec.rb:12',
155
+ # './spec/lib/guard/rspec/runner_spec.rb:100',
156
+ # './spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb:12'
157
+ # ] }
158
+ #
159
+ # it 'remembers failed paths and returns them along with new paths' do
160
+ # expect(inspector.paths(paths)).to eq(paths)
161
+ # inspector.failed(failed_locations)
162
+ #
163
+ # # other_paths and failed_locations contain the same spec (runner_spec.rb)
164
+ # # so #paths should return that spec only once (omit location)
165
+ # expect(inspector.paths(other_paths)).to match_array(
166
+ # other_paths +
167
+ # %w[./spec/lib/guard/rspec/deprecator_spec.rb:55]
168
+ # )
169
+ # inspector.failed(other_failed_locations)
170
+ #
171
+ # # Now it returns other failed locations
172
+ # expect(inspector.paths(%w[spec/lib/guard/rspec/deprecator_spec.rb])).to
173
+ # match_array(
174
+ # other_failed_locations +
175
+ # %w[spec/lib/guard/rspec/deprecator_spec.rb]
176
+ # )
177
+ # inspector.failed(other_failed_locations)
178
+ #
179
+ # # It returns runner_spec.rb without locations in that spec
180
+ # expect(inspector.paths(%w[spec/lib/guard/rspec/runner_spec.rb])).
181
+ # to match_array([
182
+ # './spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb:12',
183
+ # 'spec/lib/guard/rspec/runner_spec.rb'
184
+ # ])
185
+ # inspector.failed([])
186
+ #
187
+ # # Now there is no failed locations
188
+ # expect(inspector.paths(paths)).to match_array(paths)
189
+ # end
190
+ #
191
+ # describe '#reload' do
192
+ # it 'force to forget about failed locations' do
193
+ # expect(inspector.paths(paths)).to eq(paths)
194
+ # inspector.failed(failed_locations)
195
+ #
196
+ # inspector.reload
197
+ # expect(inspector.paths(other_paths)).to match_array(other_paths)
198
+ # end
199
+ # end
200
+ # end
@@ -0,0 +1,121 @@
1
+ RSpec.shared_examples "inspector" do |klass|
2
+ let(:spec_paths) { %w(spec myspec) }
3
+ let(:options) { { custom: "value", spec_paths: spec_paths } }
4
+ let(:inspector) { klass.new(options) }
5
+
6
+ # Use real paths because BaseInspector#_clean will be used to clean them
7
+ let(:paths) do
8
+ [
9
+ "spec/lib/guard/rspec/inspectors/base_inspector_spec.rb",
10
+ "spec/lib/guard/rspec/runner_spec.rb",
11
+ "spec/lib/guard/rspec/deprecator_spec.rb"
12
+ ]
13
+ end
14
+ let(:failed_locations) do
15
+ [
16
+ "./spec/lib/guard/rspec/runner_spec.rb:12",
17
+ "./spec/lib/guard/rspec/deprecator_spec.rb:55"
18
+ ]
19
+ end
20
+
21
+ describe ".initialize" do
22
+ it "sets options and spec_paths" do
23
+ expect(inspector.options).to include(:custom, :spec_paths)
24
+ expect(inspector.options[:custom]).to eq("value")
25
+ expect(inspector.spec_paths).to eq(spec_paths)
26
+ end
27
+ end
28
+
29
+ describe "#paths" do
30
+ before do
31
+ allow(Dir).to receive(:[]).with("myspec/**{,/*/**}/*[_.]spec.rb").
32
+ and_return([])
33
+
34
+ allow(Dir).to receive(:[]).with("myspec/**{,/*/**}/*.feature").
35
+ and_return([])
36
+
37
+ allow(Dir).to receive(:[]).with("spec/**{,/*/**}/*.feature").
38
+ and_return([])
39
+ end
40
+
41
+ it "returns paths when called first time" do
42
+ allow(File).to receive(:directory?).
43
+ with("spec/lib/guard/rspec/inspectors/base_inspector_spec.rb").
44
+ and_return(false)
45
+
46
+ allow(File).to receive(:directory?).
47
+ with("spec/lib/guard/rspec/runner_spec.rb").
48
+ and_return(false)
49
+
50
+ allow(File).to receive(:directory?).
51
+ with("spec/lib/guard/rspec/deprecator_spec.rb").
52
+ and_return(false)
53
+
54
+ allow(Dir).to receive(:[]).with("spec/**{,/*/**}/*[_.]spec.rb").
55
+ and_return(paths)
56
+
57
+ expect(inspector.paths(paths)).to match_array(paths)
58
+ end
59
+
60
+ it "does not return non-spec paths" do
61
+ paths = %w(not_a_spec_path.rb spec/not_exist_spec.rb)
62
+
63
+ allow(File).to receive(:directory?).with("not_a_spec_path.rb").
64
+ and_return(false)
65
+
66
+ allow(File).to receive(:directory?).with("spec/not_exist_spec.rb").
67
+ and_return(false)
68
+
69
+ allow(Dir).to receive(:[]).with("spec/**{,/*/**}/*[_.]spec.rb").
70
+ and_return([])
71
+
72
+ expect(inspector.paths(paths)).to eq([])
73
+ end
74
+
75
+ it "uniq and compact paths" do
76
+ allow(File).to receive(:directory?).
77
+ with("spec/lib/guard/rspec/inspectors/base_inspector_spec.rb").
78
+ and_return(false)
79
+
80
+ allow(File).to receive(:directory?).
81
+ with("spec/lib/guard/rspec/runner_spec.rb").
82
+ and_return(false)
83
+
84
+ allow(File).to receive(:directory?).
85
+ with("spec/lib/guard/rspec/deprecator_spec.rb").
86
+ and_return(false)
87
+
88
+ allow(Dir).to receive(:[]).with("spec/**{,/*/**}/*[_.]spec.rb").
89
+ and_return(paths)
90
+
91
+ expect(inspector.paths(paths + paths + [nil, nil, nil])).
92
+ to match_array(paths)
93
+ end
94
+
95
+ # NOTE: I'm not sure that it is totally correct behaviour
96
+ it "return spec_paths and directories too" do
97
+ allow(File).to receive(:directory?).with("myspec").and_return(true)
98
+ allow(File).to receive(:directory?).with("lib/guard").and_return(true)
99
+ allow(File).to receive(:directory?).
100
+ with("not_exist_dir").and_return(false)
101
+
102
+ allow(Dir).to receive(:[]).with("spec/**{,/*/**}/*[_.]spec.rb").
103
+ and_return([])
104
+
105
+ paths = %w(myspec lib/guard not_exist_dir)
106
+ expect(inspector.paths(paths)).to match_array(paths - ["not_exist_dir"])
107
+ end
108
+ end
109
+
110
+ describe "#failed" do
111
+ it "is callable" do
112
+ expect { inspector.failed(failed_locations) }.not_to raise_error
113
+ end
114
+ end
115
+
116
+ describe "#reload" do
117
+ it "is callable" do
118
+ expect { inspector.reload }.not_to raise_error
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,59 @@
1
+ require "guard/compat/test/helper"
2
+
3
+ require "lib/guard/rspec/inspectors/shared_examples"
4
+
5
+ require "guard/rspec/inspectors/simple_inspector"
6
+
7
+ klass = Guard::RSpec::Inspectors::SimpleInspector
8
+
9
+ RSpec.describe klass do
10
+ include_examples "inspector", klass
11
+
12
+ # Use real paths because BaseInspector#_clean will be used to clean them
13
+ let(:other_paths) do
14
+ [
15
+ "spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb",
16
+ "spec/lib/guard/rspec/runner_spec.rb"
17
+ ]
18
+ end
19
+
20
+ it "returns paths and do not bothers about failed locations" do
21
+ allow(File).to receive(:directory?).
22
+ with("spec/lib/guard/rspec/inspectors/base_inspector_spec.rb").
23
+ and_return(false)
24
+
25
+ allow(File).to receive(:directory?).
26
+ with("spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb").
27
+ and_return(false)
28
+
29
+ allow(File).to receive(:directory?).
30
+ with("spec/lib/guard/rspec/runner_spec.rb").
31
+ and_return(false)
32
+
33
+ allow(File).to receive(:directory?).
34
+ with("spec/lib/guard/rspec/deprecator_spec.rb").
35
+ and_return(false)
36
+
37
+ allow(Dir).to receive(:[]).with("spec/**{,/*/**}/*[_.]spec.rb").
38
+ and_return(paths + other_paths)
39
+
40
+ allow(Dir).to receive(:[]).with("spec/**{,/*/**}/*.feature").
41
+ and_return([])
42
+
43
+ allow(Dir).to receive(:[]).with("myspec/**{,/*/**}/*[_.]spec.rb").
44
+ and_return([])
45
+
46
+ allow(Dir).to receive(:[]).with("myspec/**{,/*/**}/*.feature").
47
+ and_return([])
48
+
49
+ expect(inspector.paths(paths)).to eq(paths)
50
+ inspector.failed(failed_locations)
51
+ expect(inspector.paths(other_paths)).to eq(other_paths)
52
+ inspector.failed([])
53
+
54
+ expect(inspector.paths(paths)).to eq(paths)
55
+ inspector.failed(failed_locations)
56
+ expect(inspector.paths(other_paths)).to eq(other_paths)
57
+ inspector.failed([])
58
+ end
59
+ end
@@ -0,0 +1,90 @@
1
+ require "guard/compat/test/helper"
2
+
3
+ require "guard/rspec/notifier"
4
+
5
+ RSpec.describe Guard::RSpec::Notifier do
6
+ let(:options) { { notification: true, title: "RSpec results" } }
7
+ let(:notifier) { Guard::RSpec::Notifier.new(options) }
8
+
9
+ def expect_notification(message, image, priority, title = "RSpec results")
10
+ expect(Guard::Compat::UI).to receive(:notify).
11
+ with(message, title: title, image: image, priority: priority)
12
+ end
13
+
14
+ describe "#notify_failure" do
15
+ it "notifies about failure" do
16
+ expect_notification("Failed", :failed, 2)
17
+ notifier.notify_failure
18
+ end
19
+
20
+ context "with a custom title" do
21
+ let(:options) { { notification: true, title: "Failure title" } }
22
+
23
+ it "notifies with the title" do
24
+ expect_notification("Failed", :failed, 2, "Failure title")
25
+ notifier.notify_failure
26
+ end
27
+ end
28
+ end
29
+
30
+ describe "#notify" do
31
+ it "notifies about success" do
32
+ expect_notification("This is summary", :success, -2)
33
+ notifier.notify("This is summary")
34
+ end
35
+
36
+ context "with pendings" do
37
+ let(:summary) { "5 examples, 0 failures (1 pending) in 4.0000 seconds" }
38
+
39
+ it "notifies about pendings" do
40
+ expect_notification(summary, :pending, -1)
41
+ notifier.notify(summary)
42
+ end
43
+ end
44
+
45
+ context "with failures" do
46
+ let(:summary) { "5 examples, 1 failures in 4.0000 seconds" }
47
+
48
+ it "notifies about failures" do
49
+ expect_notification(summary, :failed, 2)
50
+ notifier.notify(summary)
51
+ end
52
+
53
+ context "even if there is pendings" do
54
+ let(:summary) { "5 examples, 1 failures (1 pending) in 4.0000 seconds" }
55
+
56
+ it "still notifies about failures" do
57
+ expect_notification(summary, :failed, 2)
58
+ notifier.notify(summary)
59
+ end
60
+ end
61
+ end
62
+
63
+ context "with a custom title" do
64
+ let(:options) { { notification: true, title: "Custom title" } }
65
+
66
+ it "notifies with the title" do
67
+ expect_notification("This is summary", :success, -2, "Custom title")
68
+ notifier.notify("This is summary")
69
+ end
70
+ end
71
+ end
72
+
73
+ context "with notifications turned off" do
74
+ let(:options) { { notification: false } }
75
+
76
+ describe "#notify_failure" do
77
+ it "keeps quiet" do
78
+ expect(Guard::Compat::UI).not_to receive(:notify)
79
+ notifier.notify_failure
80
+ end
81
+ end
82
+
83
+ describe "#notify" do
84
+ it "keeps quiet" do
85
+ expect(Guard::Compat::UI).not_to receive(:notify)
86
+ notifier.notify("Summary")
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,66 @@
1
+ require "guard/compat/test/helper"
2
+
3
+ require "guard/rspec/results"
4
+
5
+ RSpec.describe Guard::RSpec::Results do
6
+ subject do
7
+ described_class.new("foo/bar.txt")
8
+ end
9
+
10
+ before do
11
+ allow(File).to receive(:readlines).with("foo/bar.txt").and_return(data)
12
+ end
13
+
14
+ context "with valid data" do
15
+ let(:data) do
16
+ [
17
+ "5 examples, 2 failures (3 pending)\n",
18
+ "foo1/bar1_spec.rb\n",
19
+ "foo1/bar2_spec.rb\n"
20
+ ]
21
+ end
22
+
23
+ describe "#summary" do
24
+ it "sets a summary" do
25
+ expect(subject.summary).to eq("5 examples, 2 failures (3 pending)")
26
+ end
27
+ end
28
+
29
+ describe "#failures" do
30
+ it "sets a list of failures" do
31
+ expect(subject.failed_paths).
32
+ to eq(%w(foo1/bar1_spec.rb foo1/bar2_spec.rb))
33
+ end
34
+ end
35
+ end
36
+
37
+ context "with no data" do
38
+ let(:data) do
39
+ []
40
+ end
41
+
42
+ it "crashes" do
43
+ expect do
44
+ subject.load
45
+ end.to raise_error(
46
+ Guard::RSpec::Results::InvalidData,
47
+ "Invalid results in: foo/bar.txt, lines:\n[]\n"
48
+ )
49
+ end
50
+ end
51
+
52
+ context "with invalid data" do
53
+ let(:data) do
54
+ [""]
55
+ end
56
+
57
+ it "crashes" do
58
+ expect do
59
+ subject.load
60
+ end.to raise_error(
61
+ Guard::RSpec::Results::InvalidData,
62
+ "Invalid results in: foo/bar.txt, lines:\n[\"\"]\n"
63
+ )
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,152 @@
1
+ require "guard/compat/test/helper"
2
+
3
+ require "guard/rspec/rspec_process"
4
+
5
+ RSpec.describe Guard::RSpec::RSpecProcess do
6
+ let(:results) { instance_double(Guard::RSpec::Results) }
7
+
8
+ let(:cmd) { "foo" }
9
+ let(:file) { "/tmp/foobar.txt" }
10
+ let(:pid) { 1234 }
11
+ let(:exit_code) { 0 }
12
+ let(:status) { instance_double(Process::Status, exitstatus: exit_code) }
13
+ let(:wait_result) { [pid, status] }
14
+
15
+ subject do
16
+ described_class.new(cmd, file)
17
+ end
18
+
19
+ before do
20
+ allow(Kernel).to receive(:spawn).
21
+ with({ "GUARD_RSPEC_RESULTS_FILE" => file }, cmd).and_return(pid)
22
+
23
+ allow(Guard::RSpec::Results).to receive(:new).
24
+ with(file).and_return(results)
25
+
26
+ allow(Guard::Compat::UI).to receive(:debug)
27
+ end
28
+
29
+ context "with an non-existing command" do
30
+ before do
31
+ allow(Kernel).to receive(:spawn).
32
+ and_raise(Errno::ENOENT, "No such file or directory - foo")
33
+ end
34
+
35
+ it "fails" do
36
+ expect { subject }.
37
+ to raise_error(Guard::RSpec::RSpecProcess::Failure, /Failed: /)
38
+ end
39
+ end
40
+
41
+ context "with an existing command" do
42
+ before do
43
+ allow(Process).to receive(:wait2).with(pid).and_return(wait_result)
44
+ end
45
+
46
+ context "with an unknown failure" do
47
+ let(:exit_code) { 100 }
48
+
49
+ it "fails" do
50
+ expect { subject }.
51
+ to raise_error(Guard::RSpec::RSpecProcess::Failure, /Failed: /)
52
+ end
53
+ end
54
+
55
+ context "without any exit code" do
56
+ let(:exit_code) { nil }
57
+
58
+ it "fails" do
59
+ expect { subject }.
60
+ to raise_error(Guard::RSpec::RSpecProcess::Failure, /Failed: /)
61
+ end
62
+ end
63
+
64
+ context "with the failure code for normal test failures" do
65
+ let(:exit_code) { Guard::RSpec::Command::FAILURE_EXIT_CODE }
66
+
67
+ it "fails" do
68
+ expect { subject }.to_not raise_error
69
+ end
70
+
71
+ it { is_expected.to_not be_all_green }
72
+ end
73
+
74
+ context "with no failures" do
75
+ it "waits for process to end" do
76
+ expect(Process).to receive(:wait2).with(pid).and_return(wait_result)
77
+ subject
78
+ end
79
+
80
+ it { is_expected.to be_all_green }
81
+
82
+ context "with a relative results file path" do
83
+ before do
84
+ allow(Guard::Compat::UI).to receive(:warning)
85
+ end
86
+ let(:file) { "foobar.txt" }
87
+
88
+ it "shows a warning" do
89
+ expect(Guard::Compat::UI).to receive(:warning).
90
+ with(/is not an absolute path/)
91
+ subject
92
+ end
93
+ end
94
+
95
+ context "with a missing results file" do
96
+ before do
97
+ allow(Guard::Compat::UI).to receive(:error)
98
+ end
99
+ before do
100
+ allow(Guard::RSpec::Results).to receive(:new).
101
+ with(file).and_raise(Errno::ENOENT, "foobar.txt")
102
+ end
103
+
104
+ it "shows a message" do
105
+ expect(Guard::Compat::UI).to receive(:error).
106
+ with(/cannot open results file/)
107
+
108
+ begin
109
+ subject
110
+ rescue Errno::ENOENT
111
+ nil
112
+ end
113
+ end
114
+
115
+ it "fails with an error" do
116
+ expect { subject }.to raise_error(
117
+ Errno::ENOENT,
118
+ /No such file or directory - foobar/
119
+ )
120
+ end
121
+ end
122
+ end
123
+
124
+ context "with bundler_env option" do
125
+ it "runs without Bunder changes when :inherit" do
126
+ expect(Bundler).to_not receive(:with_clean_env)
127
+ expect(Bundler).to_not receive(:with_original_env)
128
+
129
+ described_class.new(cmd, file, bundler_env: :inherit)
130
+ end
131
+
132
+ it "runs on clean Bunder changes when :clean_env" do
133
+ expect(Bundler).to receive(:with_clean_env)
134
+
135
+ described_class.new(cmd, file, bundler_env: :clean_env)
136
+ end
137
+
138
+ it "runs on original Bunder changes when :original_env" do
139
+ expect(Bundler).to receive(:with_original_env)
140
+
141
+ described_class.new(cmd, file, bundler_env: :original_env)
142
+ end
143
+ end
144
+
145
+ context "without bundler_env option" do
146
+ it "runs on original Bunder" do
147
+ expect(Bundler).to receive(:with_original_env)
148
+ subject
149
+ end
150
+ end
151
+ end
152
+ end