rubocop-rspec 1.9.1 → 1.10.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/Gemfile +2 -1
  4. data/config/default.yml +13 -1
  5. data/lib/rubocop-rspec.rb +5 -0
  6. data/lib/rubocop/cop/rspec/any_instance.rb +1 -1
  7. data/lib/rubocop/cop/rspec/cop.rb +1 -2
  8. data/lib/rubocop/cop/rspec/described_class.rb +1 -1
  9. data/lib/rubocop/cop/rspec/expect_output.rb +52 -0
  10. data/lib/rubocop/cop/rspec/implicit_expect.rb +3 -2
  11. data/lib/rubocop/cop/rspec/message_chain.rb +1 -1
  12. data/lib/rubocop/cop/rspec/message_spies.rb +2 -2
  13. data/lib/rubocop/cop/rspec/multiple_expectations.rb +2 -4
  14. data/lib/rubocop/cop/rspec/named_subject.rb +1 -1
  15. data/lib/rubocop/cop/rspec/nested_groups.rb +16 -1
  16. data/lib/rubocop/cop/rspec/repeated_example.rb +41 -0
  17. data/lib/rubocop/cop/rspec/scattered_setup.rb +49 -0
  18. data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +17 -5
  19. data/lib/rubocop/rspec.rb +1 -1
  20. data/lib/rubocop/rspec/concept.rb +33 -0
  21. data/lib/rubocop/rspec/example.rb +1 -25
  22. data/lib/rubocop/rspec/example_group.rb +28 -12
  23. data/lib/rubocop/rspec/hook.rb +49 -0
  24. data/lib/rubocop/rspec/language/node_pattern.rb +1 -0
  25. data/lib/rubocop/rspec/version.rb +1 -1
  26. data/spec/rubocop/cop/rspec/cop_spec.rb +4 -1
  27. data/spec/rubocop/cop/rspec/expect_output_spec.rb +62 -0
  28. data/spec/rubocop/cop/rspec/message_spies_spec.rb +74 -2
  29. data/spec/rubocop/cop/rspec/multiple_expectations_spec.rb +2 -2
  30. data/spec/rubocop/cop/rspec/nested_groups_spec.rb +14 -2
  31. data/spec/rubocop/cop/rspec/repeated_example_spec.rb +65 -0
  32. data/spec/rubocop/cop/rspec/scattered_setup_spec.rb +96 -0
  33. data/spec/rubocop/cop/rspec/single_argument_message_chain_spec.rb +27 -3
  34. data/spec/rubocop/rspec/description_extractor_spec.rb +1 -1
  35. data/spec/rubocop/rspec/example_group_spec.rb +1 -1
  36. data/spec/rubocop/rspec/example_spec.rb +2 -2
  37. data/spec/rubocop/rspec/hook_spec.rb +53 -0
  38. metadata +15 -2
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe RuboCop::Cop::RSpec::RepeatedExample do
4
+ subject(:cop) { described_class.new }
5
+
6
+ it 'registers an offense for repeated example' do
7
+ expect_violation(<<-RUBY)
8
+ describe 'doing x' do
9
+ it "does x" do
10
+ ^^^^^^^^^^^^^^ Don't repeat examples within an example group.
11
+ expect(foo).to be(bar)
12
+ end
13
+
14
+ it "does y" do
15
+ ^^^^^^^^^^^^^^ Don't repeat examples within an example group.
16
+ expect(foo).to be(bar)
17
+ end
18
+ end
19
+ RUBY
20
+ end
21
+
22
+ it 'does not register a violation if rspec tag magic is involved' do
23
+ expect_no_violations(<<-RUBY)
24
+ describe 'doing x' do
25
+ it "does x" do
26
+ expect(foo).to be(bar)
27
+ end
28
+
29
+ it "does y", :focus do
30
+ expect(foo).to be(bar)
31
+ end
32
+ end
33
+ RUBY
34
+ end
35
+
36
+ it 'does not flag examples with different implementations' do
37
+ expect_no_violations(<<-RUBY)
38
+ describe 'doing x' do
39
+ it "does x" do
40
+ expect(foo).to have_attribute(foo: 1)
41
+ end
42
+
43
+ it "does y" do
44
+ expect(foo).to have_attribute(bar: 2)
45
+ end
46
+ end
47
+ RUBY
48
+ end
49
+
50
+ it 'does not flag repeated examples in different scopes' do
51
+ expect_no_violations(<<-RUBY)
52
+ describe 'doing x' do
53
+ it "does x" do
54
+ expect(foo).to be(bar)
55
+ end
56
+
57
+ context 'when the scope changes' do
58
+ it 'does not flag anything' do
59
+ expect(foo).to be(bar)
60
+ end
61
+ end
62
+ end
63
+ RUBY
64
+ end
65
+ end
@@ -0,0 +1,96 @@
1
+ describe RuboCop::Cop::RSpec::ScatteredSetup do
2
+ subject(:cop) { described_class.new }
3
+
4
+ it 'flags multiple hooks in the same example group' do
5
+ expect_violation(<<-RUBY)
6
+ describe Foo do
7
+ before { bar }
8
+ ^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
9
+ before { baz }
10
+ ^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
11
+ end
12
+ RUBY
13
+ end
14
+
15
+ it 'flags multiple hooks of the same scope with different symbols' do
16
+ expect_violation(<<-RUBY)
17
+ describe Foo do
18
+ before { bar }
19
+ ^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
20
+ before(:each) { baz }
21
+ ^^^^^^^^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
22
+ before(:example) { baz }
23
+ ^^^^^^^^^^^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
24
+ end
25
+ RUBY
26
+ end
27
+
28
+ it 'flags multiple before(:all) hooks in the same example group' do
29
+ expect_violation(<<-RUBY)
30
+ describe Foo do
31
+ before(:all) { bar }
32
+ ^^^^^^^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
33
+ before(:all) { baz }
34
+ ^^^^^^^^^^^^^^^^^^^^ Do not define multiple hooks in the same example group.
35
+ end
36
+ RUBY
37
+ end
38
+
39
+ it 'does not flag different hooks' do
40
+ expect_no_violations(<<-RUBY)
41
+ describe Foo do
42
+ before { bar }
43
+ after { baz }
44
+ around { qux }
45
+ end
46
+ RUBY
47
+ end
48
+
49
+ it 'does not flag different hook types' do
50
+ expect_no_violations(<<-RUBY)
51
+ describe Foo do
52
+ before { bar }
53
+ before(:all) { baz }
54
+ before(:suite) { baz }
55
+ end
56
+ RUBY
57
+ end
58
+
59
+ it 'does not flag hooks in different example groups' do
60
+ expect_no_violations(<<-RUBY)
61
+ describe Foo do
62
+ before { bar }
63
+
64
+ describe '.baz' do
65
+ before { baz }
66
+ end
67
+ end
68
+ RUBY
69
+ end
70
+
71
+ it 'does not flag hooks in different shared contexts' do
72
+ expect_no_violations(<<-RUBY)
73
+ describe Foo do
74
+ shared_context 'one' do
75
+ before { bar }
76
+ end
77
+
78
+ shared_context 'two' do
79
+ before { baz }
80
+ end
81
+ end
82
+ RUBY
83
+ end
84
+
85
+ it 'does not flag similar method names inside of examples' do
86
+ expect_no_violations(<<-RUBY)
87
+ describe Foo do
88
+ before { bar }
89
+
90
+ it 'uses an instance method called before' do
91
+ expect(before { tricky }).to_not confuse_rubocop_rspec
92
+ end
93
+ end
94
+ RUBY
95
+ end
96
+ end
@@ -11,6 +11,12 @@ describe RuboCop::Cop::RSpec::SingleArgumentMessageChain do
11
11
  RUBY
12
12
  end
13
13
 
14
+ include_examples(
15
+ 'autocorrect',
16
+ 'before { allow(foo).to receive_message_chain(:one) { :two } }',
17
+ 'before { allow(foo).to receive(:one) { :two } }'
18
+ )
19
+
14
20
  it 'accepts multi-argument calls' do
15
21
  expect_no_violations(<<-RUBY)
16
22
  before do
@@ -28,6 +34,12 @@ describe RuboCop::Cop::RSpec::SingleArgumentMessageChain do
28
34
  RUBY
29
35
  end
30
36
 
37
+ include_examples(
38
+ 'autocorrect',
39
+ 'before { allow(foo).to receive_message_chain("one") { :two } }',
40
+ 'before { allow(foo).to receive("one") { :two } }'
41
+ )
42
+
31
43
  it 'accepts multi-argument string calls' do
32
44
  expect_no_violations(<<-RUBY)
33
45
  before do
@@ -47,6 +59,12 @@ describe RuboCop::Cop::RSpec::SingleArgumentMessageChain do
47
59
  RUBY
48
60
  end
49
61
 
62
+ include_examples(
63
+ 'autocorrect',
64
+ 'before { foo.stub_chain(:one) { :two } }',
65
+ 'before { foo.stub(:one) { :two } }'
66
+ )
67
+
50
68
  it 'accepts multi-argument calls' do
51
69
  expect_no_violations(<<-RUBY)
52
70
  before do
@@ -58,16 +76,22 @@ describe RuboCop::Cop::RSpec::SingleArgumentMessageChain do
58
76
  it 'reports single-argument string calls' do
59
77
  expect_violation(<<-RUBY)
60
78
  before do
61
- allow(foo).to stub_chain("one") { :two }
62
- ^^^^^^^^^^ Use `stub` instead of calling `stub_chain` with a single argument
79
+ foo.stub_chain("one") { :two }
80
+ ^^^^^^^^^^ Use `stub` instead of calling `stub_chain` with a single argument
63
81
  end
64
82
  RUBY
65
83
  end
66
84
 
85
+ include_examples(
86
+ 'autocorrect',
87
+ 'before { foo.stub_chain("one") { :two } }',
88
+ 'before { foo.stub("one") { :two } }'
89
+ )
90
+
67
91
  it 'accepts multi-argument string calls' do
68
92
  expect_no_violations(<<-RUBY)
69
93
  before do
70
- allow(foo).to stub_chain("one.two") { :three }
94
+ foo.stub_chain("one.two") { :three }
71
95
  end
72
96
  RUBY
73
97
  end
@@ -39,7 +39,7 @@ RSpec.describe RuboCop::RSpec::DescriptionExtractor do
39
39
  def stub_cop_const(name)
40
40
  stub_const(
41
41
  "RuboCop::Cop::RSpec::#{name}",
42
- Class.new(RuboCop::Cop::Cop)
42
+ Class.new(RuboCop::Cop.const_get(:WorkaroundCop))
43
43
  )
44
44
  end
45
45
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe RuboCop::RSpec::ExampleGroup do
4
- include RuboCop::Sexp
4
+ include RuboCop::AST::Sexp
5
5
 
6
6
  subject(:group) { described_class.new(parse_source(source).ast) }
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe RuboCop::RSpec::Example do
4
- include RuboCop::Sexp
4
+ include RuboCop::AST::Sexp
5
5
 
6
6
  def example(source)
7
7
  described_class.new(parse_source(source).ast)
@@ -23,7 +23,7 @@ RSpec.describe RuboCop::RSpec::Example do
23
23
 
24
24
  it 'extracts keywords' do
25
25
  expect(example("it('foo', :bar, baz: :qux) { a }").metadata)
26
- .to eql([s(:sym, :bar), s(:hash, s(:pair, s(:sym, :baz), s(:sym, :qux)))])
26
+ .to eq([s(:sym, :bar), s(:hash, s(:pair, s(:sym, :baz), s(:sym, :qux)))])
27
27
  end
28
28
 
29
29
  it 'extracts implementation' do
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe RuboCop::RSpec::Hook do
4
+ include RuboCop::AST::Sexp
5
+
6
+ def hook(source)
7
+ described_class.new(parse_source(source).ast)
8
+ end
9
+
10
+ it 'extracts name' do
11
+ expect(hook('around(:each) { }').name).to be(:around)
12
+ end
13
+
14
+ it 'does not break if a hook is not given a symbol literal' do
15
+ expect(hook('before(scope) { example_setup }').knowable_scope?).to be(false)
16
+ end
17
+
18
+ it 'knows the scope of a hook with a symbol literal' do
19
+ expect(hook('before { example_setup }').knowable_scope?).to be(true)
20
+ end
21
+
22
+ it 'ignores other arguments to hooks' do
23
+ expect(hook('before(:each, :metadata) { example_setup }').scope)
24
+ .to be(:each)
25
+ end
26
+
27
+ it 'classifies nonstandard hook arguments as invalid' do
28
+ expect(hook('before(:nothing) { example_setup }').valid_scope?).to be(false)
29
+ end
30
+
31
+ it 'classifies :each as a valid hook argument' do
32
+ expect(hook('before(:each) { example_setup }').valid_scope?).to be(true)
33
+ end
34
+
35
+ it 'classifies :each as an example hook' do
36
+ expect(hook('before(:each) { }').example?).to be(true)
37
+ end
38
+
39
+ shared_examples 'standardizes scope' do |source, scope|
40
+ it "interprets #{source} as having scope #{scope}" do
41
+ expect(hook(source).scope).to equal(scope)
42
+ end
43
+ end
44
+
45
+ include_examples 'standardizes scope', 'before(:each) { }', :each
46
+ include_examples 'standardizes scope', 'around(:example) { }', :each
47
+ include_examples 'standardizes scope', 'after { }', :each
48
+
49
+ include_examples 'standardizes scope', 'before(:all) { }', :context
50
+ include_examples 'standardizes scope', 'around(:context) { }', :context
51
+
52
+ include_examples 'standardizes scope', 'after(:suite) { }', :suite
53
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.1
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Backus
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-01-03 00:00:00.000000000 Z
13
+ date: 2017-01-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -154,6 +154,7 @@ files:
154
154
  - lib/rubocop/cop/rspec/example_length.rb
155
155
  - lib/rubocop/cop/rspec/example_wording.rb
156
156
  - lib/rubocop/cop/rspec/expect_actual.rb
157
+ - lib/rubocop/cop/rspec/expect_output.rb
157
158
  - lib/rubocop/cop/rspec/file_path.rb
158
159
  - lib/rubocop/cop/rspec/focus.rb
159
160
  - lib/rubocop/cop/rspec/hook_argument.rb
@@ -170,14 +171,18 @@ files:
170
171
  - lib/rubocop/cop/rspec/nested_groups.rb
171
172
  - lib/rubocop/cop/rspec/not_to_not.rb
172
173
  - lib/rubocop/cop/rspec/repeated_description.rb
174
+ - lib/rubocop/cop/rspec/repeated_example.rb
175
+ - lib/rubocop/cop/rspec/scattered_setup.rb
173
176
  - lib/rubocop/cop/rspec/single_argument_message_chain.rb
174
177
  - lib/rubocop/cop/rspec/subject_stub.rb
175
178
  - lib/rubocop/cop/rspec/verified_doubles.rb
176
179
  - lib/rubocop/rspec.rb
180
+ - lib/rubocop/rspec/concept.rb
177
181
  - lib/rubocop/rspec/config_formatter.rb
178
182
  - lib/rubocop/rspec/description_extractor.rb
179
183
  - lib/rubocop/rspec/example.rb
180
184
  - lib/rubocop/rspec/example_group.rb
185
+ - lib/rubocop/rspec/hook.rb
181
186
  - lib/rubocop/rspec/inject.rb
182
187
  - lib/rubocop/rspec/language.rb
183
188
  - lib/rubocop/rspec/language/node_pattern.rb
@@ -200,6 +205,7 @@ files:
200
205
  - spec/rubocop/cop/rspec/example_length_spec.rb
201
206
  - spec/rubocop/cop/rspec/example_wording_spec.rb
202
207
  - spec/rubocop/cop/rspec/expect_actual_spec.rb
208
+ - spec/rubocop/cop/rspec/expect_output_spec.rb
203
209
  - spec/rubocop/cop/rspec/file_path_spec.rb
204
210
  - spec/rubocop/cop/rspec/focus_spec.rb
205
211
  - spec/rubocop/cop/rspec/hook_argument_spec.rb
@@ -216,6 +222,8 @@ files:
216
222
  - spec/rubocop/cop/rspec/nested_groups_spec.rb
217
223
  - spec/rubocop/cop/rspec/not_to_not_spec.rb
218
224
  - spec/rubocop/cop/rspec/repeated_description_spec.rb
225
+ - spec/rubocop/cop/rspec/repeated_example_spec.rb
226
+ - spec/rubocop/cop/rspec/scattered_setup_spec.rb
219
227
  - spec/rubocop/cop/rspec/single_argument_message_chain_spec.rb
220
228
  - spec/rubocop/cop/rspec/subject_stub_spec.rb
221
229
  - spec/rubocop/cop/rspec/verified_doubles_spec.rb
@@ -223,6 +231,7 @@ files:
223
231
  - spec/rubocop/rspec/description_extractor_spec.rb
224
232
  - spec/rubocop/rspec/example_group_spec.rb
225
233
  - spec/rubocop/rspec/example_spec.rb
234
+ - spec/rubocop/rspec/hook_spec.rb
226
235
  - spec/rubocop/rspec/language/selector_set_spec.rb
227
236
  - spec/rubocop/rspec/util/one_spec.rb
228
237
  - spec/rubocop/rspec/wording_spec.rb
@@ -269,6 +278,7 @@ test_files:
269
278
  - spec/rubocop/cop/rspec/example_length_spec.rb
270
279
  - spec/rubocop/cop/rspec/example_wording_spec.rb
271
280
  - spec/rubocop/cop/rspec/expect_actual_spec.rb
281
+ - spec/rubocop/cop/rspec/expect_output_spec.rb
272
282
  - spec/rubocop/cop/rspec/file_path_spec.rb
273
283
  - spec/rubocop/cop/rspec/focus_spec.rb
274
284
  - spec/rubocop/cop/rspec/hook_argument_spec.rb
@@ -285,6 +295,8 @@ test_files:
285
295
  - spec/rubocop/cop/rspec/nested_groups_spec.rb
286
296
  - spec/rubocop/cop/rspec/not_to_not_spec.rb
287
297
  - spec/rubocop/cop/rspec/repeated_description_spec.rb
298
+ - spec/rubocop/cop/rspec/repeated_example_spec.rb
299
+ - spec/rubocop/cop/rspec/scattered_setup_spec.rb
288
300
  - spec/rubocop/cop/rspec/single_argument_message_chain_spec.rb
289
301
  - spec/rubocop/cop/rspec/subject_stub_spec.rb
290
302
  - spec/rubocop/cop/rspec/verified_doubles_spec.rb
@@ -292,6 +304,7 @@ test_files:
292
304
  - spec/rubocop/rspec/description_extractor_spec.rb
293
305
  - spec/rubocop/rspec/example_group_spec.rb
294
306
  - spec/rubocop/rspec/example_spec.rb
307
+ - spec/rubocop/rspec/hook_spec.rb
295
308
  - spec/rubocop/rspec/language/selector_set_spec.rb
296
309
  - spec/rubocop/rspec/util/one_spec.rb
297
310
  - spec/rubocop/rspec/wording_spec.rb