guard-rspec 2.1.0 → 4.7.3

Sign up to get free protection for your applications and to get access to all the features.
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,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