rubocop-rspec 1.34.1 → 1.35.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cde39325f1b2c820f9105b689ab70ed80cd0e05bc0255cad156cfd3418e90d33
4
- data.tar.gz: f538c3972f746964aca96015ea16e5553589601defe597d7069cbbc5e1a20e24
3
+ metadata.gz: 47216a8696392108804dfd285875acfdec9857df832fb6270120b29161bcd5d6
4
+ data.tar.gz: 742b3c4e6836a6e7c8aa4d2ca02abd73f09870165f2e10a4eb41ea9d1ef6c859
5
5
  SHA512:
6
- metadata.gz: dd46062a2e229f7f9af5404399eb08762cb18eb30649af6d9b3e6ea12e5ee56bbc13a8971ca951626e5239502faa06992ea2c67be74687dbb909e41b1fcfcbe7
7
- data.tar.gz: 56e6d26667a4c96060fa80cc94795a21db84299272ad0b6ba532bce2e04e3362bbf12c2df53a4ae5db948ef1a1f1441618a201e30eef843aa1463879c0c21809
6
+ metadata.gz: 488afcabe181b6658b73014730194c4a1bab399e096d2fdb230f2d16bee41afa3d71d285fd764a7a6b766117bd68d6702c54cab33503a18ed3f6501428569ff0
7
+ data.tar.gz: a8030e59e2f88880b09621a868f18e8af0b44bca6927822f7e07cfcae9668a3e11d91aab7e4450dffa05d7409043a4e2db9b87373ea9b1316d00e924e52668d1
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## Master (Unreleased)
4
4
 
5
+ ## 1.35.0 (2019-08-02)
6
+
7
+ * Add `RSpec/ImplicitBlockExpectation` cop. ([@pirj][])
8
+
5
9
  ## 1.34.1 (2019-07-31)
6
10
 
7
11
  * Fix `RSpec/DescribedClass`'s error when a local variable is part of the namespace. ([@pirj][])
@@ -197,6 +197,11 @@ RSpec/HooksBeforeExamples:
197
197
  Description: Checks for before/around/after hooks that come after an example.
198
198
  StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/HooksBeforeExamples
199
199
 
200
+ RSpec/ImplicitBlockExpectation:
201
+ Description: Check that implicit block expectation syntax is not used.
202
+ Enabled: true
203
+ StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ImplicitBlockExpectation
204
+
200
205
  RSpec/ImplicitExpect:
201
206
  Description: Check that a consistent implicit expectation style is used.
202
207
  Enabled: true
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Check that implicit block expectation syntax is not used.
7
+ #
8
+ # Prefer using explicit block expectations.
9
+ #
10
+ # @example
11
+ # # bad
12
+ # subject { -> { do_something } }
13
+ # it { is_expected.to change(something).to(new_value) }
14
+ #
15
+ # # good
16
+ # it 'changes something to a new value' do
17
+ # expect { do_something }.to change(something).to(new_value)
18
+ # end
19
+ class ImplicitBlockExpectation < Cop
20
+ MSG = 'Avoid implicit block expectations.'
21
+
22
+ def_node_matcher :lambda?, <<-PATTERN
23
+ {
24
+ (send (const nil? :Proc) :new)
25
+ (send nil? :proc)
26
+ (send nil? :lambda)
27
+ }
28
+ PATTERN
29
+
30
+ def_node_matcher :lambda_subject?, '(block #lambda? ...)'
31
+
32
+ def_node_matcher :implicit_expect, <<-PATTERN
33
+ $(send nil? {:is_expected :should :should_not} ...)
34
+ PATTERN
35
+
36
+ def on_send(node)
37
+ implicit_expect(node) do |implicit_expect|
38
+ subject = nearest_subject(implicit_expect)
39
+ add_offense(implicit_expect) if lambda_subject?(subject&.body)
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def nearest_subject(node)
46
+ node
47
+ .each_ancestor(:block)
48
+ .lazy
49
+ .select { |block_node| multi_statement_example_group?(block_node) }
50
+ .map { |block_node| find_subject(block_node) }
51
+ .find(&:itself)
52
+ end
53
+
54
+ def multi_statement_example_group?(node)
55
+ example_group_with_body?(node) && node.body.begin_type?
56
+ end
57
+
58
+ def find_subject(block_node)
59
+ block_node.body.child_nodes.find { |send_node| subject?(send_node) }
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -41,6 +41,7 @@ require_relative 'rspec/file_path'
41
41
  require_relative 'rspec/focus'
42
42
  require_relative 'rspec/hook_argument'
43
43
  require_relative 'rspec/hooks_before_examples'
44
+ require_relative 'rspec/implicit_block_expectation'
44
45
  require_relative 'rspec/implicit_expect'
45
46
  require_relative 'rspec/implicit_subject'
46
47
  require_relative 'rspec/instance_spy'
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module RSpec
5
5
  # Version information for the RSpec RuboCop plugin.
6
6
  module Version
7
- STRING = '1.34.1'
7
+ STRING = '1.35.0'
8
8
  end
9
9
  end
10
10
  end
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe RuboCop::Cop::RSpec::ImplicitBlockExpectation do
4
+ subject(:cop) { described_class.new }
5
+
6
+ it 'flags lambda in subject' do
7
+ expect_offense(<<-RUBY)
8
+ describe do
9
+ subject { -> { boom } }
10
+ it { is_expected.to change { something }.to(new_value) }
11
+ ^^^^^^^^^^^ Avoid implicit block expectations.
12
+ end
13
+ RUBY
14
+ end
15
+
16
+ it 'ignores non-lambda subject' do
17
+ expect_no_offenses(<<-RUBY)
18
+ describe do
19
+ subject { 'normal' }
20
+ it { is_expected.to eq(something) }
21
+ end
22
+ RUBY
23
+ end
24
+
25
+ it 'flags lambda in subject!' do
26
+ expect_offense(<<-RUBY)
27
+ describe do
28
+ subject! { -> { boom } }
29
+ it { is_expected.to change { something }.to(new_value) }
30
+ ^^^^^^^^^^^ Avoid implicit block expectations.
31
+ end
32
+ RUBY
33
+ end
34
+
35
+ it 'flags literal lambda' do
36
+ expect_offense(<<-RUBY)
37
+ describe do
38
+ subject! { lambda { boom } }
39
+ it { is_expected.to change { something }.to(new_value) }
40
+ ^^^^^^^^^^^ Avoid implicit block expectations.
41
+ end
42
+ RUBY
43
+ end
44
+
45
+ it 'flags proc' do
46
+ expect_offense(<<-RUBY)
47
+ describe do
48
+ subject! { proc { boom } }
49
+ it { is_expected.to change { something }.to(new_value) }
50
+ ^^^^^^^^^^^ Avoid implicit block expectations.
51
+ end
52
+ RUBY
53
+ end
54
+
55
+ it 'flags Proc.new' do
56
+ expect_offense(<<-RUBY)
57
+ describe do
58
+ subject! { Proc.new { boom } }
59
+ it { is_expected.to change { something }.to(new_value) }
60
+ ^^^^^^^^^^^ Avoid implicit block expectations.
61
+ end
62
+ RUBY
63
+ end
64
+
65
+ it 'flags named subject' do
66
+ expect_offense(<<-RUBY)
67
+ describe do
68
+ subject(:name) { -> { boom } }
69
+ it { is_expected.to change { something }.to(new_value) }
70
+ ^^^^^^^^^^^ Avoid implicit block expectations.
71
+ end
72
+ RUBY
73
+ end
74
+
75
+ it 'flags when subject is defined in the outer example group' do
76
+ expect_offense(<<-RUBY)
77
+ describe do
78
+ subject { -> { boom } }
79
+ context do
80
+ it { is_expected.to change { something }.to(new_value) }
81
+ ^^^^^^^^^^^ Avoid implicit block expectations.
82
+ end
83
+ end
84
+ RUBY
85
+ end
86
+
87
+ it 'ignores normal local subject' do
88
+ expect_no_offenses(<<-RUBY)
89
+ describe do
90
+ subject { -> { boom } }
91
+ context do
92
+ subject { 'normal' }
93
+ it { is_expected.to eq(something) }
94
+ end
95
+ end
96
+ RUBY
97
+ end
98
+
99
+ it 'ignores named subject with deeply nested lambda' do
100
+ expect_no_offenses(<<-RUBY)
101
+ describe do
102
+ subject { {hash: -> { boom }} }
103
+ it { is_expected.to be(something) }
104
+ end
105
+ RUBY
106
+ end
107
+
108
+ it 'flags with `should` as implicit subject' do
109
+ expect_offense(<<-RUBY)
110
+ describe do
111
+ subject { -> { boom } }
112
+ it { should change { something }.to(new_value) }
113
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid implicit block expectations.
114
+ end
115
+ RUBY
116
+ end
117
+
118
+ it 'flags with `should_not` as implicit subject' do
119
+ expect_offense(<<-RUBY)
120
+ describe do
121
+ subject { -> { boom } }
122
+ it { should_not change { something }.to(new_value) }
123
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid implicit block expectations.
124
+ end
125
+ RUBY
126
+ end
127
+
128
+ it 'ignores when there is no subject defined' do
129
+ expect_no_offenses(<<-RUBY)
130
+ shared_examples 'subject is defined somewhere else' do
131
+ it { is_expected.to change { something }.to(new_value) }
132
+ end
133
+ RUBY
134
+ end
135
+ 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.34.1
4
+ version: 1.35.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: 2019-07-31 00:00:00.000000000 Z
13
+ date: 2019-08-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -150,6 +150,7 @@ files:
150
150
  - lib/rubocop/cop/rspec/focus.rb
151
151
  - lib/rubocop/cop/rspec/hook_argument.rb
152
152
  - lib/rubocop/cop/rspec/hooks_before_examples.rb
153
+ - lib/rubocop/cop/rspec/implicit_block_expectation.rb
153
154
  - lib/rubocop/cop/rspec/implicit_expect.rb
154
155
  - lib/rubocop/cop/rspec/implicit_subject.rb
155
156
  - lib/rubocop/cop/rspec/instance_spy.rb
@@ -248,6 +249,7 @@ files:
248
249
  - spec/rubocop/cop/rspec/focus_spec.rb
249
250
  - spec/rubocop/cop/rspec/hook_argument_spec.rb
250
251
  - spec/rubocop/cop/rspec/hooks_before_examples_spec.rb
252
+ - spec/rubocop/cop/rspec/implicit_block_expectation_spec.rb
251
253
  - spec/rubocop/cop/rspec/implicit_expect_spec.rb
252
254
  - spec/rubocop/cop/rspec/implicit_subject_spec.rb
253
255
  - spec/rubocop/cop/rspec/instance_spy_spec.rb
@@ -368,6 +370,7 @@ test_files:
368
370
  - spec/rubocop/cop/rspec/focus_spec.rb
369
371
  - spec/rubocop/cop/rspec/hook_argument_spec.rb
370
372
  - spec/rubocop/cop/rspec/hooks_before_examples_spec.rb
373
+ - spec/rubocop/cop/rspec/implicit_block_expectation_spec.rb
371
374
  - spec/rubocop/cop/rspec/implicit_expect_spec.rb
372
375
  - spec/rubocop/cop/rspec/implicit_subject_spec.rb
373
376
  - spec/rubocop/cop/rspec/instance_spy_spec.rb