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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.hound.yml +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +40 -0
- data/.travis.yml +14 -0
- data/CONTRIBUTING.md +38 -0
- data/Gemfile +25 -0
- data/Guardfile +28 -0
- data/{LICENSE → LICENSE.txt} +4 -2
- data/README.md +99 -114
- data/Rakefile +38 -0
- data/gemfiles/Gemfile.rspec-2.99 +6 -0
- data/gemfiles/Gemfile.rspec-3.4 +6 -0
- data/gemfiles/common +9 -0
- data/guard-rspec.gemspec +25 -0
- data/lib/guard/rspec/command.rb +71 -0
- data/lib/guard/rspec/deprecator.rb +86 -0
- data/lib/guard/rspec/dsl.rb +72 -0
- data/lib/guard/rspec/inspectors/base_inspector.rb +73 -0
- data/lib/guard/rspec/inspectors/factory.rb +23 -0
- data/lib/guard/rspec/inspectors/focused_inspector.rb +39 -0
- data/lib/guard/rspec/inspectors/keeping_inspector.rb +97 -0
- data/lib/guard/rspec/inspectors/simple_inspector.rb +21 -0
- data/lib/guard/rspec/notifier.rb +55 -0
- data/lib/guard/rspec/options.rb +37 -0
- data/lib/guard/rspec/results.rb +23 -0
- data/lib/guard/rspec/rspec_process.rb +93 -0
- data/lib/guard/rspec/runner.rb +71 -174
- data/lib/guard/rspec/templates/Guardfile +49 -17
- data/lib/guard/rspec/version.rb +1 -1
- data/lib/guard/rspec.rb +30 -59
- data/lib/guard/rspec_defaults.rb +5 -0
- data/lib/guard/rspec_formatter.rb +147 -0
- data/lib/guard/rspec_formatter_results_path.rb +29 -0
- data/spec/acceptance/fixtures/succeeding_spec.rb +4 -0
- data/spec/acceptance/formatter_spec.rb +46 -0
- data/spec/lib/guard/rspec/command_spec.rb +95 -0
- data/spec/lib/guard/rspec/deprecator_spec.rb +101 -0
- data/spec/lib/guard/rspec/inspectors/base_inspector_spec.rb +144 -0
- data/spec/lib/guard/rspec/inspectors/factory_spec.rb +45 -0
- data/spec/lib/guard/rspec/inspectors/focused_inspector_spec.rb +140 -0
- data/spec/lib/guard/rspec/inspectors/keeping_inspector_spec.rb +200 -0
- data/spec/lib/guard/rspec/inspectors/shared_examples.rb +121 -0
- data/spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb +59 -0
- data/spec/lib/guard/rspec/notifier_spec.rb +90 -0
- data/spec/lib/guard/rspec/results_spec.rb +66 -0
- data/spec/lib/guard/rspec/rspec_process_spec.rb +152 -0
- data/spec/lib/guard/rspec/runner_spec.rb +372 -0
- data/spec/lib/guard/rspec/template_spec.rb +78 -0
- data/spec/lib/guard/rspec_formatter_spec.rb +277 -0
- data/spec/lib/guard/rspec_spec.rb +91 -0
- data/spec/spec_helper.rb +145 -0
- metadata +103 -42
- data/lib/guard/rspec/formatter.rb +0 -56
- data/lib/guard/rspec/inspector.rb +0 -72
@@ -0,0 +1,372 @@
|
|
1
|
+
require "guard/compat/test/helper"
|
2
|
+
|
3
|
+
require "launchy"
|
4
|
+
|
5
|
+
require "guard/rspec/runner"
|
6
|
+
|
7
|
+
RSpec.describe Guard::RSpec::Runner do
|
8
|
+
let(:options) { { cmd: "rspec" } }
|
9
|
+
let(:runner) { Guard::RSpec::Runner.new(options) }
|
10
|
+
let(:inspector) { instance_double(Guard::RSpec::Inspectors::SimpleInspector) }
|
11
|
+
let(:notifier) { instance_double(Guard::RSpec::Notifier) }
|
12
|
+
let(:results) { instance_double(Guard::RSpec::Results) }
|
13
|
+
let(:process) { instance_double(Guard::RSpec::RSpecProcess) }
|
14
|
+
|
15
|
+
before do
|
16
|
+
allow(Guard::Compat::UI).to receive(:info)
|
17
|
+
allow(Guard::Compat::UI).to receive(:warning)
|
18
|
+
allow(Guard::Compat::UI).to receive(:error)
|
19
|
+
allow(Guard::RSpec::Inspectors::Factory).to receive(:create) { inspector }
|
20
|
+
allow(Guard::RSpec::Notifier).to receive(:new) { notifier }
|
21
|
+
allow(Guard::RSpec::Command).to receive(:new) { "rspec" }
|
22
|
+
allow(notifier).to receive(:notify)
|
23
|
+
allow(notifier).to receive(:notify_failure)
|
24
|
+
|
25
|
+
allow(results).to receive(:summary).and_return("Summary")
|
26
|
+
allow(results).to receive(:failed_paths).and_return([])
|
27
|
+
|
28
|
+
allow(Guard::RSpec::RSpecProcess).to receive(:new).and_return(process)
|
29
|
+
allow(process).to receive(:all_green?).and_return(true)
|
30
|
+
allow(process).to receive(:results).and_return(results)
|
31
|
+
end
|
32
|
+
|
33
|
+
describe ".initialize" do
|
34
|
+
context "with custom options" do
|
35
|
+
let(:options) { { foo: :bar } }
|
36
|
+
|
37
|
+
it "instanciates inspector via Inspectors::Factory with custom options" do
|
38
|
+
expect(Guard::RSpec::Inspectors::Factory).
|
39
|
+
to receive(:create).with(foo: :bar)
|
40
|
+
runner
|
41
|
+
end
|
42
|
+
|
43
|
+
it "instanciates notifier with custom options" do
|
44
|
+
expect(Guard::RSpec::Notifier).to receive(:new).with(foo: :bar)
|
45
|
+
runner
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#reload" do
|
51
|
+
it 'calls inspector\'s #reload' do
|
52
|
+
expect(inspector).to receive(:reload)
|
53
|
+
runner.reload
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
shared_examples "abort" do
|
58
|
+
it "aborts" do
|
59
|
+
expect(Guard::Compat::UI).to_not receive(:info)
|
60
|
+
subject
|
61
|
+
end
|
62
|
+
|
63
|
+
it "returns true" do
|
64
|
+
expect(subject).to be true
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#run_all" do
|
69
|
+
let(:options) do
|
70
|
+
{
|
71
|
+
spec_paths: %w(spec1 spec2),
|
72
|
+
cmd: "rspec",
|
73
|
+
run_all: { message: "Custom message" }
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
before do
|
78
|
+
allow(inspector).to receive(:failed)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "builds commands with spec paths" do
|
82
|
+
expect(Guard::RSpec::Command).to receive(:new).
|
83
|
+
with(%w(spec1 spec2), kind_of(Hash))
|
84
|
+
runner.run_all
|
85
|
+
end
|
86
|
+
|
87
|
+
it "prints message" do
|
88
|
+
expect(Guard::Compat::UI).to receive(:info).
|
89
|
+
with("Custom message", reset: true)
|
90
|
+
|
91
|
+
runner.run_all
|
92
|
+
end
|
93
|
+
|
94
|
+
context "when no paths are given" do
|
95
|
+
subject { runner.run_all }
|
96
|
+
|
97
|
+
let(:options) do
|
98
|
+
{
|
99
|
+
spec_paths: [],
|
100
|
+
run_all: { message: "Custom message" }
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
include_examples "abort"
|
105
|
+
end
|
106
|
+
|
107
|
+
context "with custom cmd" do
|
108
|
+
before do
|
109
|
+
options[:run_all][:cmd] = "rspec -t ~slow"
|
110
|
+
end
|
111
|
+
|
112
|
+
it "builds command with custom cmd" do
|
113
|
+
expect(Guard::RSpec::Command).to receive(:new).
|
114
|
+
with(kind_of(Array), hash_including(cmd: "rspec -t ~slow"))
|
115
|
+
runner.run_all
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "with no cmd" do
|
120
|
+
before do
|
121
|
+
options[:cmd] = nil
|
122
|
+
allow(Guard::RSpec::Command).to receive(:new)
|
123
|
+
allow(Guard::Compat::UI).to receive(:error).with(an_instance_of(String))
|
124
|
+
allow(notifier).to receive(:notify_failure)
|
125
|
+
runner.run_all
|
126
|
+
end
|
127
|
+
|
128
|
+
it "does not build" do
|
129
|
+
expect(Guard::RSpec::Command).to_not have_received(:new)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "issues a warning to the user" do
|
133
|
+
expect(Guard::Compat::UI).to have_received(:error).
|
134
|
+
with(an_instance_of(String))
|
135
|
+
end
|
136
|
+
|
137
|
+
it "notifies the notifer of failure" do
|
138
|
+
expect(notifier).to have_received(:notify_failure)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "return value" do
|
143
|
+
subject { runner.run_all }
|
144
|
+
|
145
|
+
it { is_expected.to be true }
|
146
|
+
|
147
|
+
context "when process is not all green" do
|
148
|
+
before do
|
149
|
+
allow(process).to receive(:all_green?).and_return(false)
|
150
|
+
end
|
151
|
+
|
152
|
+
it { is_expected.to be false }
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "#run" do
|
158
|
+
let(:paths) { %w(spec_path1 spec_path2) }
|
159
|
+
before do
|
160
|
+
allow(inspector).to receive(:paths) { paths }
|
161
|
+
allow(inspector).to receive(:failed)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "prints running message" do
|
165
|
+
expect(Guard::Compat::UI).to receive(:info).
|
166
|
+
with("Running: spec_path1 spec_path2", reset: true)
|
167
|
+
runner.run(paths)
|
168
|
+
end
|
169
|
+
|
170
|
+
context "when no paths are given" do
|
171
|
+
subject { runner.run([]) }
|
172
|
+
|
173
|
+
before do
|
174
|
+
allow(inspector).to receive(:paths) { [] }
|
175
|
+
end
|
176
|
+
|
177
|
+
include_examples "abort"
|
178
|
+
end
|
179
|
+
|
180
|
+
it "builds commands with spec paths" do
|
181
|
+
expect(Guard::RSpec::Command).to receive(:new).
|
182
|
+
with(%w(spec_path1 spec_path2), kind_of(Hash))
|
183
|
+
runner.run(paths)
|
184
|
+
end
|
185
|
+
|
186
|
+
context "with all_after_pass option" do
|
187
|
+
let(:options) { { cmd: "rspec", all_after_pass: true } }
|
188
|
+
|
189
|
+
it "re-runs all if run is success" do
|
190
|
+
expect(runner).to receive(:run_all)
|
191
|
+
runner.run(paths)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "with launchy option" do
|
196
|
+
let(:options) { { cmd: "rspec", launchy: "launchy_path" } }
|
197
|
+
|
198
|
+
before do
|
199
|
+
allow(Pathname).to receive(:new).
|
200
|
+
with("launchy_path") { double(exist?: true) }
|
201
|
+
end
|
202
|
+
|
203
|
+
it "opens Launchy" do
|
204
|
+
expect(Launchy).to receive(:open).with("launchy_path")
|
205
|
+
runner.run(paths)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context "with a custom results file" do
|
210
|
+
let(:options) do
|
211
|
+
{ cmd: "rspec", results_file: results_file }.merge(chdir_options)
|
212
|
+
end
|
213
|
+
|
214
|
+
context "with no chdir option" do
|
215
|
+
let(:chdir_options) { {} }
|
216
|
+
|
217
|
+
context "when the path is relative" do
|
218
|
+
let(:results_file) { File.join(Dir.pwd, "foobar.txt") }
|
219
|
+
it "uses the given file" do
|
220
|
+
expect(Guard::RSpec::RSpecProcess).to receive(:new).
|
221
|
+
with(anything, results_file, options).and_return(process)
|
222
|
+
runner.run(paths)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
context "when the path is absolute" do
|
227
|
+
let(:results_file) { "/foo/foobar.txt" }
|
228
|
+
it "uses the given path" do
|
229
|
+
expect(Guard::RSpec::RSpecProcess).to receive(:new).
|
230
|
+
with(anything, results_file, options).and_return(process)
|
231
|
+
runner.run(paths)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
context "with chdir option" do
|
237
|
+
context "when chdir option is absolute" do
|
238
|
+
let(:chdir_options) { { chdir: "/foo/bar/moduleA" } }
|
239
|
+
|
240
|
+
context "when the path is relative" do
|
241
|
+
let(:results_file) { "foobar.txt" }
|
242
|
+
|
243
|
+
it "uses a path relative to chdir" do
|
244
|
+
expected = "/foo/bar/moduleA/foobar.txt"
|
245
|
+
expect(Guard::RSpec::RSpecProcess).to receive(:new).
|
246
|
+
with(anything, expected, options).and_return(process)
|
247
|
+
runner.run(paths)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
context "when the path is absolute" do
|
252
|
+
let(:results_file) { "/foo/foobar.txt" }
|
253
|
+
it "uses the full given path anyway" do
|
254
|
+
expect(Guard::RSpec::RSpecProcess).to receive(:new).
|
255
|
+
with(anything, results_file, options).and_return(process)
|
256
|
+
runner.run(paths)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
context "when chdir option is relative" do
|
262
|
+
let(:chdir_options) { { chdir: "moduleA" } }
|
263
|
+
before do
|
264
|
+
allow(Guard::Compat::UI).to receive(:warning)
|
265
|
+
end
|
266
|
+
|
267
|
+
context "when the path is relative" do
|
268
|
+
let(:results_file) { "foobar.txt" }
|
269
|
+
|
270
|
+
it "uses a path relative to chdir" do
|
271
|
+
expected = File.join(Dir.pwd, "moduleA/foobar.txt")
|
272
|
+
expect(Guard::RSpec::RSpecProcess).to receive(:new).
|
273
|
+
with(anything, expected, options).and_return(process)
|
274
|
+
runner.run(paths)
|
275
|
+
end
|
276
|
+
|
277
|
+
it "shows a warning" do
|
278
|
+
expect(Guard::Compat::UI).to receive(:warning).
|
279
|
+
with(/is not an absolute path/)
|
280
|
+
runner.run(paths)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
context "when the path is absolute" do
|
285
|
+
let(:results_file) { "/foo/foobar.txt" }
|
286
|
+
it "uses the full given path anyway" do
|
287
|
+
expect(Guard::RSpec::RSpecProcess).to receive(:new).
|
288
|
+
with(anything, results_file, options).and_return(process)
|
289
|
+
runner.run(paths)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
context "with no custom results file" do
|
297
|
+
let(:options) { { cmd: "rspec" } }
|
298
|
+
it "uses the default" do
|
299
|
+
expected_params = [anything, %r{/tmp/rspec_guard_result$}, options]
|
300
|
+
expect(Guard::RSpec::RSpecProcess).to receive(:new).
|
301
|
+
with(*expected_params).and_return(process)
|
302
|
+
runner.run(paths)
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
it "notifies inspector about failed paths" do
|
307
|
+
expect(inspector).to receive(:failed).with([])
|
308
|
+
runner.run(paths)
|
309
|
+
end
|
310
|
+
|
311
|
+
context "with failed paths" do
|
312
|
+
before do
|
313
|
+
allow(results).to receive(:failed_paths).and_return(
|
314
|
+
[
|
315
|
+
"./failed_spec.rb:123",
|
316
|
+
"./other/failed_spec.rb:77"
|
317
|
+
]
|
318
|
+
)
|
319
|
+
end
|
320
|
+
|
321
|
+
it "notifies inspector about failed paths" do
|
322
|
+
expect(inspector).to receive(:failed).
|
323
|
+
with(["./failed_spec.rb:123", "./other/failed_spec.rb:77"])
|
324
|
+
|
325
|
+
runner.run(paths)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
it "notifies success" do
|
330
|
+
expect(notifier).to receive(:notify).with("Summary")
|
331
|
+
runner.run(paths)
|
332
|
+
end
|
333
|
+
|
334
|
+
it "notifies failure" do
|
335
|
+
allow(process).to receive(:all_green?).
|
336
|
+
and_raise(Guard::RSpec::RSpecProcess::Failure, /Failed: /)
|
337
|
+
|
338
|
+
expect(notifier).to receive(:notify_failure)
|
339
|
+
runner.run(paths)
|
340
|
+
end
|
341
|
+
|
342
|
+
describe "return value" do
|
343
|
+
subject { runner.run(paths) }
|
344
|
+
|
345
|
+
it { is_expected.to be true }
|
346
|
+
|
347
|
+
context "with all_after_pass option" do
|
348
|
+
let(:options) do
|
349
|
+
{ cmd: "rspec", all_after_pass: true, run_all: {}, spec_paths: paths }
|
350
|
+
end
|
351
|
+
|
352
|
+
it { is_expected.to be true }
|
353
|
+
|
354
|
+
describe "when all tests fail" do
|
355
|
+
before do
|
356
|
+
allow(process).to receive(:all_green?).and_return(true, false)
|
357
|
+
end
|
358
|
+
|
359
|
+
it { is_expected.to be false }
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
context "when process is not all green" do
|
364
|
+
before do
|
365
|
+
allow(process).to receive(:all_green?).and_return(false)
|
366
|
+
end
|
367
|
+
|
368
|
+
it { is_expected.to be false }
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require "guard/compat/test/template"
|
2
|
+
|
3
|
+
# Do not require to simulate Guardfile loading more accurately
|
4
|
+
# require 'guard/rspec'
|
5
|
+
|
6
|
+
RSpec.describe "Guard::RSpec" do
|
7
|
+
describe "template" do
|
8
|
+
subject { Guard::Compat::Test::Template.new("Guard::RSpec") }
|
9
|
+
|
10
|
+
it "matches spec files by default" do
|
11
|
+
expect(subject.changed("spec/lib/foo_spec.rb")).
|
12
|
+
to eq(%w(spec/lib/foo_spec.rb))
|
13
|
+
|
14
|
+
expect(subject.changed("spec/spec_helper.rb")).to eq(%w(spec))
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "mapping files to specs" do
|
18
|
+
before do
|
19
|
+
allow(Dir).to receive(:exist?).with("spec/lib").and_return(has_spec_lib)
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when spec/lib exists" do
|
23
|
+
let(:has_spec_lib) { true }
|
24
|
+
it "matches Ruby files with files in spec/lib" do
|
25
|
+
expect(subject.changed("lib/foo.rb")).to eq(%w(spec/lib/foo_spec.rb))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when spec/lib does not exist" do
|
30
|
+
let(:has_spec_lib) { false }
|
31
|
+
it "matches Ruby files with files in spec/lib" do
|
32
|
+
expect(subject.changed("lib/foo.rb")).to eq(%w(spec/foo_spec.rb))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "matches Rails files by default" do
|
38
|
+
expect(subject.changed("spec/rails_helper.rb")).to eq(%w(spec))
|
39
|
+
|
40
|
+
expect(subject.changed("app/models/foo.rb")).
|
41
|
+
to eq(%w(spec/models/foo_spec.rb))
|
42
|
+
|
43
|
+
expect(subject.changed("app/views/foo/bar.slim")).to eq(
|
44
|
+
%w(
|
45
|
+
spec/views/foo/bar.slim_spec.rb
|
46
|
+
spec/features/foo_spec.rb
|
47
|
+
)
|
48
|
+
)
|
49
|
+
|
50
|
+
expect(subject.changed("app/controllers/application_controller.rb")).
|
51
|
+
to eq(
|
52
|
+
%w(
|
53
|
+
spec/controllers/application_controller_spec.rb
|
54
|
+
spec/routing/application_routing_spec.rb
|
55
|
+
spec/acceptance/application_spec.rb
|
56
|
+
spec/controllers
|
57
|
+
)
|
58
|
+
)
|
59
|
+
|
60
|
+
expect(subject.changed("app/controllers/foo_controller.rb")).
|
61
|
+
to match_array(
|
62
|
+
%w(
|
63
|
+
spec/controllers/foo_controller_spec.rb
|
64
|
+
spec/routing/foo_routing_spec.rb
|
65
|
+
spec/acceptance/foo_spec.rb
|
66
|
+
)
|
67
|
+
)
|
68
|
+
|
69
|
+
expect(subject.changed("config/routes.rb")).to eq(%w(spec/routing))
|
70
|
+
|
71
|
+
expect(subject.changed("app/layouts/foo/bar.slim")).to eq(
|
72
|
+
%w(
|
73
|
+
spec/features/foo_spec.rb
|
74
|
+
)
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|