rubocop-rspec 1.9.1 → 1.10.0

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