guard-rspec 4.0.4 → 4.1.0

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +5 -1
  4. data/README.md +12 -9
  5. data/lib/guard/rspec.rb +3 -6
  6. data/lib/guard/rspec/command.rb +6 -19
  7. data/lib/guard/rspec/deprecator.rb +13 -1
  8. data/lib/guard/rspec/formatter.rb +36 -0
  9. data/lib/guard/rspec/inspectors/base_inspector.rb +52 -0
  10. data/lib/guard/rspec/inspectors/factory.rb +24 -0
  11. data/lib/guard/rspec/inspectors/focused_inspector.rb +39 -0
  12. data/lib/guard/rspec/inspectors/keeping_inspector.rb +96 -0
  13. data/lib/guard/rspec/inspectors/simple_inspector.rb +21 -0
  14. data/lib/guard/rspec/notifier.rb +52 -0
  15. data/lib/guard/rspec/options.rb +34 -0
  16. data/lib/guard/rspec/runner.rb +40 -31
  17. data/lib/guard/rspec/version.rb +1 -1
  18. data/spec/lib/guard/rspec/command_spec.rb +2 -6
  19. data/spec/lib/guard/rspec/deprecator_spec.rb +21 -2
  20. data/spec/lib/guard/rspec/formatter_spec.rb +42 -0
  21. data/spec/lib/guard/rspec/inspectors/base_inspector_spec.rb +34 -0
  22. data/spec/lib/guard/rspec/inspectors/factory_spec.rb +40 -0
  23. data/spec/lib/guard/rspec/inspectors/focused_inspector_spec.rb +74 -0
  24. data/spec/lib/guard/rspec/inspectors/keeping_inspector_spec.rb +122 -0
  25. data/spec/lib/guard/rspec/inspectors/shared_examples.rb +59 -0
  26. data/spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb +23 -0
  27. data/spec/lib/guard/rspec/notifier_spec.rb +69 -0
  28. data/spec/lib/guard/rspec/runner_spec.rb +75 -66
  29. data/spec/lib/guard/rspec_spec.rb +8 -3
  30. metadata +25 -12
  31. data/lib/guard/rspec/formatters/focuser.rb +0 -29
  32. data/lib/guard/rspec/formatters/notifier.rb +0 -48
  33. data/lib/guard/rspec/inspector.rb +0 -78
  34. data/spec/lib/guard/rspec/formatters/focuser_spec.rb +0 -25
  35. data/spec/lib/guard/rspec/formatters/notifier_spec.rb +0 -44
  36. data/spec/lib/guard/rspec/inspector_spec.rb +0 -107
@@ -0,0 +1,122 @@
1
+ require 'spec_helper'
2
+ require 'lib/guard/rspec/inspectors/shared_examples'
3
+
4
+ klass = Guard::RSpec::Inspectors::KeepingInspector
5
+
6
+ describe klass do
7
+ include_examples 'inspector', klass
8
+
9
+ # Use real paths because BaseInspector#_clean will be used to clean them
10
+ let(:other_paths) { [
11
+ 'spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb',
12
+ 'spec/lib/guard/rspec/runner_spec.rb'
13
+ ] }
14
+ let(:other_failed_locations) { [
15
+ './spec/lib/guard/rspec/runner_spec.rb:12',
16
+ './spec/lib/guard/rspec/runner_spec.rb:100',
17
+ './spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb:12'
18
+ ] }
19
+
20
+ it 'remembers failed paths and returns them along with new paths' do
21
+ expect(inspector.paths(paths)).to eq(paths)
22
+ inspector.failed(failed_locations)
23
+
24
+ # Line numbers in failed_locations needs to be omitted because of
25
+ # https://github.com/rspec/rspec-core/issues/952
26
+ expect(inspector.paths(other_paths)).to match_array([
27
+ 'spec/lib/guard/rspec/deprecator_spec.rb',
28
+ 'spec/lib/guard/rspec/runner_spec.rb',
29
+ 'spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb'
30
+ ])
31
+ inspector.failed(other_failed_locations)
32
+
33
+ # Now it returns other failed locations
34
+ expect(inspector.paths(%w[spec/lib/guard/rspec/inspectors/base_inspector_spec.rb])).to match_array([
35
+ 'spec/lib/guard/rspec/runner_spec.rb',
36
+ 'spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb',
37
+ 'spec/lib/guard/rspec/inspectors/base_inspector_spec.rb'
38
+ ])
39
+ inspector.failed(other_failed_locations)
40
+
41
+ expect(inspector.paths(%w[spec/lib/guard/rspec/runner_spec.rb])).to match_array([
42
+ 'spec/lib/guard/rspec/runner_spec.rb',
43
+ 'spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb'
44
+ ])
45
+ inspector.failed([])
46
+
47
+ # Now there is no failed locations
48
+ expect(inspector.paths(paths)).to match_array(paths)
49
+ end
50
+
51
+ describe '#reload' do
52
+ it 'force to forget about failed locations' do
53
+ expect(inspector.paths(paths)).to eq(paths)
54
+ inspector.failed(failed_locations)
55
+
56
+ inspector.reload
57
+ expect(inspector.paths(other_paths)).to match_array(other_paths)
58
+ end
59
+ end
60
+ end
61
+
62
+ #
63
+ # FIXME uncomment when RSpec #952 will be resolved
64
+ #
65
+ # This is correct spec for KeepingInspector class,
66
+ # bit it doesn't work because of bug with RSpec
67
+ # https://github.com/rspec/rspec-core/issues/952
68
+ #
69
+ #describe klass do
70
+ # include_examples 'inspector', klass
71
+ #
72
+ # # Use real paths because BaseInspector#_clean will be used to clean them
73
+ # let(:other_paths) { [
74
+ # 'spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb',
75
+ # 'spec/lib/guard/rspec/runner_spec.rb'
76
+ # ] }
77
+ # let(:other_failed_locations) { [
78
+ # './spec/lib/guard/rspec/runner_spec.rb:12',
79
+ # './spec/lib/guard/rspec/runner_spec.rb:100',
80
+ # './spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb:12'
81
+ # ] }
82
+ #
83
+ # it 'remembers failed paths and returns them along with new paths' do
84
+ # expect(inspector.paths(paths)).to eq(paths)
85
+ # inspector.failed(failed_locations)
86
+ #
87
+ # # other_paths and failed_locations contain the same spec (runner_spec.rb)
88
+ # # so #paths should return that spec only once (omit location)
89
+ # expect(inspector.paths(other_paths)).to match_array(
90
+ # other_paths +
91
+ # %w[./spec/lib/guard/rspec/deprecator_spec.rb:55]
92
+ # )
93
+ # inspector.failed(other_failed_locations)
94
+ #
95
+ # # Now it returns other failed locations
96
+ # expect(inspector.paths(%w[spec/lib/guard/rspec/deprecator_spec.rb])).to match_array(
97
+ # other_failed_locations +
98
+ # %w[spec/lib/guard/rspec/deprecator_spec.rb]
99
+ # )
100
+ # inspector.failed(other_failed_locations)
101
+ #
102
+ # # It returns runner_spec.rb without locations in that spec
103
+ # expect(inspector.paths(%w[spec/lib/guard/rspec/runner_spec.rb])).to match_array([
104
+ # './spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb:12',
105
+ # 'spec/lib/guard/rspec/runner_spec.rb'
106
+ # ])
107
+ # inspector.failed([])
108
+ #
109
+ # # Now there is no failed locations
110
+ # expect(inspector.paths(paths)).to match_array(paths)
111
+ # end
112
+ #
113
+ # describe '#reload' do
114
+ # it 'force to forget about failed locations' do
115
+ # expect(inspector.paths(paths)).to eq(paths)
116
+ # inspector.failed(failed_locations)
117
+ #
118
+ # inspector.reload
119
+ # expect(inspector.paths(other_paths)).to match_array(other_paths)
120
+ # end
121
+ # end
122
+ #end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples 'inspector' do |klass|
4
+ let(:spec_paths) { %w[spec myspec] }
5
+ let(:options) { { custom: 'value', spec_paths: spec_paths } }
6
+ let(:inspector) { klass.new(options) }
7
+
8
+ # Use real paths because BaseInspector#_clean will be used to clean them
9
+ let(:paths) { [
10
+ 'spec/lib/guard/rspec/inspectors/base_inspector_spec.rb',
11
+ 'spec/lib/guard/rspec/runner_spec.rb',
12
+ 'spec/lib/guard/rspec/deprecator_spec.rb'
13
+ ] }
14
+ let(:failed_locations) { [
15
+ './spec/lib/guard/rspec/runner_spec.rb:12',
16
+ './spec/lib/guard/rspec/deprecator_spec.rb:55'
17
+ ] }
18
+
19
+ describe '.initialize' do
20
+ it 'sets options and spec_paths' do
21
+ expect(inspector.options).to include(:custom, :spec_paths)
22
+ expect(inspector.options[:custom]).to eq('value')
23
+ expect(inspector.spec_paths).to eq(spec_paths)
24
+ end
25
+ end
26
+
27
+ describe '#paths' do
28
+ it 'returns paths when called first time' do
29
+ expect(inspector.paths(paths)).to match_array(paths)
30
+ end
31
+
32
+ it 'does not return non-spec paths' do
33
+ paths = %w[not_a_spec_path.rb spec/not_exist_spec.rb]
34
+ expect(inspector.paths(paths)).to eq([])
35
+ end
36
+
37
+ it 'uniq and compact paths' do
38
+ expect(inspector.paths(paths + paths + [nil, nil, nil])).to match_array(paths)
39
+ end
40
+
41
+ # NOTE: I'm not sure that it is totally correct behaviour
42
+ it 'return spec_paths and directories too' do
43
+ paths = %w[myspec lib/guard not_exist_dir]
44
+ expect(inspector.paths(paths)).to match_array(paths - ['not_exist_dir'])
45
+ end
46
+ end
47
+
48
+ describe '#failed' do
49
+ it 'is callable' do
50
+ expect { inspector.failed(failed_locations) }.not_to raise_error
51
+ end
52
+ end
53
+
54
+ describe '#reload' do
55
+ it 'is callable' do
56
+ expect { inspector.reload }.not_to raise_error
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+ require 'lib/guard/rspec/inspectors/shared_examples'
3
+
4
+ klass = Guard::RSpec::Inspectors::SimpleInspector
5
+
6
+ describe klass do
7
+ include_examples 'inspector', klass
8
+
9
+ # Use real paths because BaseInspector#_clean will be used to clean them
10
+ let(:other_paths) { [
11
+ 'spec/lib/guard/rspec/inspectors/simple_inspector_spec.rb',
12
+ 'spec/lib/guard/rspec/runner_spec.rb'
13
+ ] }
14
+
15
+ it 'returns paths and do not bothers about failed locations' do
16
+ 2.times do
17
+ expect(inspector.paths(paths)).to eq(paths)
18
+ inspector.failed(failed_locations)
19
+ expect(inspector.paths(other_paths)).to eq(other_paths)
20
+ inspector.failed([])
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe Guard::RSpec::Notifier do
4
+ let(:options) { { notification: true } }
5
+ let(:notifier) { Guard::RSpec::Notifier.new(options) }
6
+
7
+ def expect_notification(message, image, priority)
8
+ expect(Guard::Notifier).to receive(:notify).with(message, { title: 'RSpec results', image: image, priority: priority })
9
+ end
10
+
11
+ describe '#notify_failure' do
12
+ it 'notifies about failure' do
13
+ expect_notification('Failed', :failed, 2)
14
+ notifier.notify_failure
15
+ end
16
+ end
17
+
18
+ describe '#notify' do
19
+ it 'notifies about success' do
20
+ expect_notification('This is summary', :success, -2)
21
+ notifier.notify('This is summary')
22
+ end
23
+
24
+ context 'with pendings' do
25
+ let(:summary) { '5 examples, 0 failures (1 pending) in 4.0000 seconds' }
26
+
27
+ it 'notifies about pendings' do
28
+ expect_notification(summary, :pending, -1)
29
+ notifier.notify(summary)
30
+ end
31
+ end
32
+
33
+ context 'with failures' do
34
+ let(:summary) { '5 examples, 1 failures in 4.0000 seconds' }
35
+
36
+ it 'notifies about failures' do
37
+ expect_notification(summary, :failed, 2)
38
+ notifier.notify(summary)
39
+ end
40
+
41
+ context 'even if there is pendings' do
42
+ let(:summary) { '5 examples, 1 failures (1 pending) in 4.0000 seconds' }
43
+
44
+ it 'still notifies about failures' do
45
+ expect_notification(summary, :failed, 2)
46
+ notifier.notify(summary)
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ context 'with notifications turned off' do
53
+ let(:options) { { notification: false } }
54
+
55
+ describe '#notify_failure' do
56
+ it 'keeps quiet' do
57
+ expect(Guard::Notifier).not_to receive(:notify)
58
+ notifier.notify_failure
59
+ end
60
+ end
61
+
62
+ describe '#notify' do
63
+ it 'keeps quiet' do
64
+ expect(Guard::Notifier).not_to receive(:notify)
65
+ notifier.notify('Summary')
66
+ end
67
+ end
68
+ end
69
+ end
@@ -2,135 +2,144 @@ require 'spec_helper'
2
2
  require 'launchy'
3
3
 
4
4
  describe Guard::RSpec::Runner do
5
- let(:default_options) { {
6
- all_after_pass: false,
7
- notification: true,
8
- run_all: { message: 'Running all specs' },
9
- launchy: nil,
10
- } }
11
5
  let(:options) { {} }
12
6
  let(:runner) { Guard::RSpec::Runner.new(options) }
13
- let(:inspector) { double(Guard::RSpec::Inspector) }
7
+ let(:inspector) { double(Guard::RSpec::Inspectors::SimpleInspector) }
8
+ let(:notifier) { double(Guard::RSpec::Notifier) }
9
+ let(:formatter_tmp_file) { Guard::RSpec::Formatter::TEMPORARY_FILE_PATH }
14
10
  before {
15
11
  Guard::UI.stub(:info)
16
12
  Kernel.stub(:system) { true }
17
- Guard::RSpec::Inspector.stub(:new) { inspector }
13
+ Guard::RSpec::Inspectors::Factory.stub(:create) { inspector }
14
+ Guard::RSpec::Notifier.stub(:new) { notifier }
18
15
  Guard::RSpec::Command.stub(:new) { 'rspec' }
16
+ notifier.stub(:notify)
17
+ notifier.stub(:notify_failure)
19
18
  }
20
19
 
21
20
  describe '.initialize' do
22
- it 'instanciates inspector with options' do
23
- expect(Guard::RSpec::Inspector).to receive(:new).with(default_options.merge(foo: :bar))
24
- Guard::RSpec::Runner.new(foo: :bar)
21
+ context 'with custom options' do
22
+ let(:options) { { foo: :bar } }
23
+
24
+ it 'instanciates inspector via Inspectors::Factory with custom options' do
25
+ expect(Guard::RSpec::Inspectors::Factory).to receive(:create).with(foo: :bar)
26
+ runner
27
+ end
28
+
29
+ it 'instanciates notifier with custom options' do
30
+ expect(Guard::RSpec::Notifier).to receive(:new).with(foo: :bar)
31
+ runner
32
+ end
25
33
  end
26
34
  end
27
35
 
28
- describe "#reloads" do
29
- it "clears inspector failed_paths" do
30
- expect(inspector).to receive(:clear_paths)
36
+ describe '#reload' do
37
+ it 'calls inspector\'s #reload' do
38
+ expect(inspector).to receive(:reload)
31
39
  runner.reload
32
40
  end
33
41
  end
34
42
 
35
- describe "#run_all" do
36
- before {
37
- inspector.stub(:paths) { %w[spec1 spec2] }
38
- inspector.stub(:clear_paths) { true }
39
- }
43
+ describe '#run_all' do
44
+ let(:options) { {
45
+ spec_paths: %w[spec1 spec2],
46
+ run_all: { message: 'Custom message' }
47
+ } }
40
48
 
41
- it "prints default message" do
42
- expect(Guard::UI).to receive(:info).with(default_options[:run_all][:message], reset: true)
49
+ it 'builds commands with spec paths' do
50
+ expect(Guard::RSpec::Command).to receive(:new).with(%w[spec1 spec2], kind_of(Hash))
43
51
  runner.run_all
44
52
  end
45
53
 
46
- context "with custom message" do
47
- let(:options) { { run_all: { message: 'Custom message' } } }
48
-
49
- it "prints custom message" do
50
- expect(Guard::UI).to receive(:info).with('Custom message', reset: true)
51
- runner.run_all
52
- end
54
+ it 'prints message' do
55
+ expect(Guard::UI).to receive(:info).with('Custom message', reset: true)
56
+ runner.run_all
53
57
  end
54
58
 
55
- context "with custom cmd" do
56
- let(:options) { { run_all: { cmd: 'rspec -t ~slow' } } }
59
+ context 'with custom cmd' do
60
+ before {
61
+ options[:run_all][:cmd] = 'rspec -t ~slow'
62
+ }
57
63
 
58
- it "builds command with custom options" do
64
+ it 'builds command with custom cmd' do
59
65
  expect(Guard::RSpec::Command).to receive(:new).with(kind_of(Array), hash_including(cmd: 'rspec -t ~slow'))
60
66
  runner.run_all
61
67
  end
62
68
  end
63
-
64
- it "builds commands with all spec paths" do
65
- expect(Guard::RSpec::Command).to receive(:new).with(%w[spec1 spec2], kind_of(Hash))
66
- runner.run_all
67
- end
68
-
69
- it "clears inspector paths if run is success" do
70
- expect(inspector).to receive(:clear_paths)
71
- runner.run_all
72
- end
73
69
  end
74
70
 
75
- describe "#run" do
71
+ describe '#run' do
76
72
  let(:paths) { %w[spec_path1 spec_path2] }
77
73
  before {
78
- inspector.stub(:failed_paths) { [] }
74
+ File.stub(:readlines).with(formatter_tmp_file) { %W{Summary\n} }
79
75
  inspector.stub(:paths) { paths }
80
76
  inspector.stub(:clear_paths) { true }
77
+ inspector.stub(:failed)
81
78
  }
82
79
 
83
- it "prints running message" do
80
+ it 'prints running message' do
84
81
  expect(Guard::UI).to receive(:info).with('Running: spec_path1 spec_path2', reset: true)
85
82
  runner.run(paths)
86
83
  end
87
84
 
88
- it "returns if no paths are given" do
85
+ it 'returns if no paths are given' do
89
86
  inspector.stub(:paths) { [] }
90
87
  expect(Guard::UI).to_not receive(:info)
91
88
  runner.run([])
92
89
  end
93
90
 
94
- it "builds commands with spec paths" do
91
+ it 'builds commands with spec paths' do
95
92
  expect(Guard::RSpec::Command).to receive(:new).with(%w[spec_path1 spec_path2], kind_of(Hash))
96
93
  runner.run(paths)
97
94
  end
98
95
 
99
- it "clears inspector paths if run is success" do
100
- expect(inspector).to receive(:clear_paths).with(paths)
101
- runner.run(paths)
102
- end
103
-
104
- it "notifies failure" do
105
- Kernel.stub(:system) { false }
106
- expect(Guard::Notifier).to receive(:notify).with('Failed', title: 'RSpec results', image: :failed, priority: 2)
107
- runner.run(paths)
108
- end
109
-
110
- context "with all_after_pass option and old failed spec paths" do
96
+ context 'with all_after_pass option' do
111
97
  let(:options) { { all_after_pass: true } }
112
- before {
113
- inspector.stub(:failed_paths) { %w[failed_path] }
114
- inspector.stub(:paths).with(paths) { paths }
115
- }
116
98
 
117
- it "re-runs all if run is success" do
99
+ it 're-runs all if run is success' do
118
100
  expect(runner).to receive(:run_all)
119
101
  runner.run(paths)
120
102
  end
121
103
  end
122
104
 
123
- context "with launchy option" do
105
+ context 'with launchy option' do
124
106
  let(:options) { { launchy: 'launchy_path' } }
107
+
125
108
  before {
126
109
  Pathname.stub(:new).with('launchy_path') { double(exist?: true) }
127
110
  }
128
111
 
129
- it "opens Launchy" do
112
+ it 'opens Launchy' do
130
113
  expect(Launchy).to receive(:open).with('launchy_path')
131
114
  runner.run(paths)
132
115
  end
133
116
  end
134
- end
135
117
 
118
+ it 'notifies inspector about failed paths' do
119
+ expect(inspector).to receive(:failed).with([])
120
+ runner.run(paths)
121
+ end
122
+
123
+ context 'with failed paths' do
124
+ before {
125
+ File.stub(:readlines).with(formatter_tmp_file) { %W{Summary\n ./failed_spec.rb:123\n ./other/failed_spec.rb:77\n} }
126
+ }
127
+
128
+ it 'notifies inspector about failed paths' do
129
+ expect(inspector).to receive(:failed).with(%w[./failed_spec.rb:123 ./other/failed_spec.rb:77])
130
+ runner.run(paths)
131
+ end
132
+ end
133
+
134
+ it 'notifies success' do
135
+ expect(notifier).to receive(:notify).with('Summary')
136
+ runner.run(paths)
137
+ end
138
+
139
+ it 'notifies failure' do
140
+ Kernel.stub(:system) { nil }
141
+ expect(notifier).to receive(:notify_failure)
142
+ runner.run(paths)
143
+ end
144
+ end
136
145
  end