rubocop-rspec 1.31.0 → 1.32.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 +4 -4
- data/CHANGELOG.md +8 -0
- data/config/default.yml +5 -0
- data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +105 -41
- data/lib/rubocop/cop/rspec/focus.rb +2 -2
- data/lib/rubocop/cop/rspec/pending.rb +2 -2
- data/lib/rubocop/cop/rspec/receive_counts.rb +7 -4
- data/lib/rubocop/cop/rspec/yield.rb +77 -0
- data/lib/rubocop/cop/rspec_cops.rb +1 -0
- data/lib/rubocop/rspec/version.rb +1 -1
- data/spec/rubocop/cop/rspec/factory_bot/create_list_spec.rb +30 -0
- data/spec/rubocop/cop/rspec/focus_spec.rb +8 -0
- data/spec/rubocop/cop/rspec/pending_spec.rb +8 -0
- data/spec/rubocop/cop/rspec/receive_counts_spec.rb +11 -0
- data/spec/rubocop/cop/rspec/yield_spec.rb +80 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0fcdb4a1fb882713a667ae92edf352ee496300bd20cbd44c79ec0c79773691f
|
4
|
+
data.tar.gz: 22ed75baf52c414c530edef39ba1a2b361c4e2060711775c093585c7a10ffe53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 597bacb5b6c60657a33532a1d625008030338e16f8fca2e42d1a9b0dc4bf76a6e9296d8fb2948ad0947bb522212bc53ef997fc4155168c89e76c66fda4e6ef87
|
7
|
+
data.tar.gz: 9ecac64a0f6cccba7a794125e0e4bd0bd47722f8e5d2a3efed8828709fdc8c682ca09794a74c33d92f6feec90d70b856d2bf1f544d13c51fc4f63d7c398568e1
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
## Master (Unreleased)
|
4
4
|
|
5
|
+
## 1.32.0 (2019-01-27)
|
6
|
+
|
7
|
+
* Add `RSpec/Yield` cop, suggesting using the `and_yield` method when stubbing a method, accepting a block. ([@Darhazer][])
|
8
|
+
* Fix `FactoryBot/CreateList` autocorrect crashing when the factory is called with a block=. ([@Darhazer][])
|
9
|
+
* Fixed `RSpec/Focus` not flagging some cases of `RSpec.describe` with `focus: true`. ([@Darhazer][])
|
10
|
+
* Fixed `RSpec/Pending` not flagging some cases of `RSpec.describe` with `:skip`. ([@Darhazer][])
|
11
|
+
* Fix false positive in `RSpec/ReceiveCounts` when method name `exactly`, `at_least` or `at_most` is used along with `times`, without being an RSpec API. ([@Darhazer][])
|
12
|
+
|
5
13
|
## 1.31.0 (2019-01-02)
|
6
14
|
|
7
15
|
* Add `IgnoreSharedExamples` option for `RSpec/NamedSubject`. ([@RST-J][])
|
data/config/default.yml
CHANGED
@@ -417,6 +417,11 @@ RSpec/VoidExpect:
|
|
417
417
|
Enabled: true
|
418
418
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VoidExpect
|
419
419
|
|
420
|
+
RSpec/Yield:
|
421
|
+
Description: This cop checks for calling a block within a stub.
|
422
|
+
Enabled: true
|
423
|
+
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Yield
|
424
|
+
|
420
425
|
Capybara/CurrentPathExpectation:
|
421
426
|
Description: Checks that no expectations are set on Capybara's `current_path`.
|
422
427
|
Enabled: true
|
@@ -69,9 +69,9 @@ module RuboCop
|
|
69
69
|
|
70
70
|
def autocorrect(node)
|
71
71
|
if style == :create_list
|
72
|
-
|
72
|
+
CreateListCorrector.new(node)
|
73
73
|
else
|
74
|
-
|
74
|
+
TimesCorrector.new(node)
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -85,63 +85,127 @@ module RuboCop
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
replacement = factory_call_replacement(block.body, count)
|
88
|
+
# :nodoc
|
89
|
+
class Corrector
|
90
|
+
private
|
92
91
|
|
93
|
-
|
94
|
-
|
92
|
+
def build_options_string(options)
|
93
|
+
options.map(&:source).join(', ')
|
94
|
+
end
|
95
|
+
|
96
|
+
def format_method_call(node, method, arguments)
|
97
|
+
if node.block_type? || node.parenthesized?
|
98
|
+
"#{method}(#{arguments})"
|
99
|
+
else
|
100
|
+
"#{method} #{arguments}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def format_receiver(receiver)
|
105
|
+
return '' unless receiver
|
106
|
+
|
107
|
+
"#{receiver.source}."
|
95
108
|
end
|
96
109
|
end
|
97
110
|
|
98
|
-
|
99
|
-
|
100
|
-
|
111
|
+
# :nodoc
|
112
|
+
class TimesCorrector < Corrector
|
113
|
+
def initialize(node)
|
114
|
+
@node = node
|
115
|
+
end
|
116
|
+
|
117
|
+
def call(corrector)
|
118
|
+
replacement = generate_n_times_block(node)
|
101
119
|
corrector.replace(node.loc.expression, replacement)
|
102
120
|
end
|
103
|
-
end
|
104
121
|
|
105
|
-
|
106
|
-
receiver, factory, count, options = *factory_list_call(node)
|
122
|
+
private
|
107
123
|
|
108
|
-
|
109
|
-
options = build_options_string(options)
|
110
|
-
arguments += ", #{options}" unless options.empty?
|
124
|
+
attr_reader :node
|
111
125
|
|
112
|
-
|
113
|
-
|
114
|
-
|
126
|
+
def generate_n_times_block(node)
|
127
|
+
factory, count, *options = node.arguments
|
128
|
+
|
129
|
+
arguments = factory.source
|
130
|
+
options = build_options_string(options)
|
131
|
+
arguments += ", #{options}" unless options.empty?
|
132
|
+
|
133
|
+
replacement = format_receiver(node.receiver)
|
134
|
+
replacement += format_method_call(node, 'create', arguments)
|
135
|
+
"#{count.source}.times { #{replacement} }"
|
136
|
+
end
|
115
137
|
end
|
116
138
|
|
117
|
-
|
118
|
-
|
139
|
+
# :nodoc:
|
140
|
+
class CreateListCorrector < Corrector
|
141
|
+
def initialize(node)
|
142
|
+
@node = node.parent
|
143
|
+
end
|
119
144
|
|
120
|
-
|
121
|
-
|
122
|
-
|
145
|
+
def call(corrector)
|
146
|
+
replacement = if node.body.block_type?
|
147
|
+
call_with_block_replacement(node)
|
148
|
+
else
|
149
|
+
call_replacement(node)
|
150
|
+
end
|
123
151
|
|
124
|
-
|
125
|
-
|
126
|
-
replacement
|
127
|
-
end
|
152
|
+
corrector.replace(node.loc.expression, replacement)
|
153
|
+
end
|
128
154
|
|
129
|
-
|
130
|
-
options.map(&:source).join(', ')
|
131
|
-
end
|
155
|
+
private
|
132
156
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
157
|
+
attr_reader :node
|
158
|
+
|
159
|
+
def call_with_block_replacement(node)
|
160
|
+
block = node.body
|
161
|
+
arguments = build_arguments(block, node.receiver.source)
|
162
|
+
replacement = format_receiver(block.send_node.receiver)
|
163
|
+
replacement += format_method_call(block, 'create_list', arguments)
|
164
|
+
replacement += format_block(block)
|
165
|
+
replacement
|
138
166
|
end
|
139
|
-
end
|
140
167
|
|
141
|
-
|
142
|
-
|
168
|
+
def build_arguments(node, count)
|
169
|
+
factory, *options = *node.send_node.arguments
|
170
|
+
|
171
|
+
arguments = ":#{factory.value}, #{count}"
|
172
|
+
options = build_options_string(options)
|
173
|
+
arguments += ", #{options}" unless options.empty?
|
174
|
+
arguments
|
175
|
+
end
|
176
|
+
|
177
|
+
def call_replacement(node)
|
178
|
+
block = node.body
|
179
|
+
factory, *options = *block.arguments
|
180
|
+
|
181
|
+
arguments = "#{factory.source}, #{node.receiver.source}"
|
182
|
+
options = build_options_string(options)
|
183
|
+
arguments += ", #{options}" unless options.empty?
|
143
184
|
|
144
|
-
|
185
|
+
replacement = format_receiver(block.receiver)
|
186
|
+
replacement += format_method_call(block, 'create_list', arguments)
|
187
|
+
replacement
|
188
|
+
end
|
189
|
+
|
190
|
+
def format_block(node)
|
191
|
+
if node.body.begin_type?
|
192
|
+
format_multiline_block(node)
|
193
|
+
else
|
194
|
+
format_singeline_block(node)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def format_multiline_block(node)
|
199
|
+
indent = ' ' * node.body.loc.column
|
200
|
+
indent_end = ' ' * node.parent.loc.column
|
201
|
+
" do #{node.arguments.source}\n" \
|
202
|
+
"#{indent}#{node.body.source}\n" \
|
203
|
+
"#{indent_end}end"
|
204
|
+
end
|
205
|
+
|
206
|
+
def format_singeline_block(node)
|
207
|
+
" { #{node.arguments.source} #{node.body.source} }"
|
208
|
+
end
|
145
209
|
end
|
146
210
|
end
|
147
211
|
end
|
@@ -36,8 +36,8 @@ module RuboCop
|
|
36
36
|
FOCUS_TRUE = s(:pair, FOCUS_SYMBOL, s(:true))
|
37
37
|
|
38
38
|
def_node_matcher :metadata, <<-PATTERN
|
39
|
-
{(send nil? #{FOCUSABLE_SELECTORS} ... (hash $...))
|
40
|
-
(send nil? #{FOCUSABLE_SELECTORS} $...)}
|
39
|
+
{(send {(const nil? :RSpec) nil?} #{FOCUSABLE_SELECTORS} ... (hash $...))
|
40
|
+
(send {(const nil? :RSpec) nil?} #{FOCUSABLE_SELECTORS} $...)}
|
41
41
|
PATTERN
|
42
42
|
|
43
43
|
def_node_matcher :focused_block?, focused.send_pattern
|
@@ -37,8 +37,8 @@ module RuboCop
|
|
37
37
|
PENDING_SYMBOL = s(:sym, :pending)
|
38
38
|
|
39
39
|
def_node_matcher :metadata, <<-PATTERN
|
40
|
-
{(send nil? #{SKIPPABLE_SELECTORS} ... (hash $...))
|
41
|
-
(send nil? #{SKIPPABLE_SELECTORS} $...)}
|
40
|
+
{(send {(const nil? :RSpec) nil?} #{SKIPPABLE_SELECTORS} ... (hash $...))
|
41
|
+
(send {(const nil? :RSpec) nil?} #{SKIPPABLE_SELECTORS} $...)}
|
42
42
|
PATTERN
|
43
43
|
|
44
44
|
def_node_matcher :pending_block?, PENDING_EXAMPLES.send_pattern
|
@@ -30,8 +30,12 @@ module RuboCop
|
|
30
30
|
(send $(send _ {:exactly :at_least :at_most} (int {1 2})) :times)
|
31
31
|
PATTERN
|
32
32
|
|
33
|
+
def_node_search :stub?, '(send nil? :receive ...)'
|
34
|
+
|
33
35
|
def on_send(node)
|
34
36
|
receive_counts(node) do |offending_node|
|
37
|
+
return unless stub?(offending_node.receiver)
|
38
|
+
|
35
39
|
offending_range = range(node, offending_node)
|
36
40
|
|
37
41
|
add_offense(
|
@@ -48,10 +52,9 @@ module RuboCop
|
|
48
52
|
node.method_name,
|
49
53
|
node.first_argument.source.to_i
|
50
54
|
)
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
)
|
55
|
+
|
56
|
+
original = range(node.parent, node)
|
57
|
+
corrector.replace(original, replacement)
|
55
58
|
end
|
56
59
|
end
|
57
60
|
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# This cop checks for calling a block within a stub.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# allow(foo).to receive(:bar) { |&block| block.call(1) }
|
11
|
+
#
|
12
|
+
# # good
|
13
|
+
# expect(foo).to be(:bar).and_yield(1)
|
14
|
+
class Yield < Cop
|
15
|
+
include RangeHelp
|
16
|
+
|
17
|
+
MSG = 'Use `.and_yield`.'.freeze
|
18
|
+
|
19
|
+
def_node_search :method_on_stub?, '(send nil? :receive ...)'
|
20
|
+
|
21
|
+
def_node_matcher :block_arg, '(args (blockarg $_))'
|
22
|
+
|
23
|
+
def_node_matcher :block_call?, '(send (lvar %) :call ...)'
|
24
|
+
|
25
|
+
def on_block(node)
|
26
|
+
return unless method_on_stub?(node.send_node)
|
27
|
+
|
28
|
+
block_arg(node.arguments) do |block|
|
29
|
+
if calling_block?(node.body, block)
|
30
|
+
add_offense(node, location: block_range(node))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def autocorrect(node)
|
36
|
+
lambda do |corrector|
|
37
|
+
node_range = range_with_surrounding_space(
|
38
|
+
range: block_range(node), side: :left
|
39
|
+
)
|
40
|
+
corrector.replace(node_range, generate_replacement(node.body))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def calling_block?(node, block)
|
47
|
+
if node.begin_type?
|
48
|
+
node.each_child_node.all? { |child| block_call?(child, block) }
|
49
|
+
else
|
50
|
+
block_call?(node, block)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def block_range(node)
|
55
|
+
block_start = node.loc.begin.begin_pos
|
56
|
+
block_end = node.loc.end.end_pos
|
57
|
+
range_between(block_start, block_end)
|
58
|
+
end
|
59
|
+
|
60
|
+
def generate_replacement(node)
|
61
|
+
if node.begin_type?
|
62
|
+
node.children.map { |child| convert_block_to_yield(child) }.join
|
63
|
+
else
|
64
|
+
convert_block_to_yield(node)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def convert_block_to_yield(node)
|
69
|
+
args = node.arguments
|
70
|
+
replacement = '.and_yield'
|
71
|
+
replacement += "(#{args.map(&:source).join(', ')})" if args.any?
|
72
|
+
replacement
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -88,6 +88,36 @@ RSpec.describe RuboCop::Cop::RSpec::FactoryBot::CreateList, :config do
|
|
88
88
|
include_examples 'autocorrect',
|
89
89
|
'5.times { FactoryGirl.create :user }',
|
90
90
|
'FactoryGirl.create_list :user, 5'
|
91
|
+
|
92
|
+
bad_code = <<-RUBY
|
93
|
+
3.times do
|
94
|
+
create(:user, :trait) { |user| create :account, user: user }
|
95
|
+
end
|
96
|
+
RUBY
|
97
|
+
|
98
|
+
good_code = <<-RUBY
|
99
|
+
create_list(:user, 3, :trait) { |user| create :account, user: user }
|
100
|
+
RUBY
|
101
|
+
|
102
|
+
include_examples 'autocorrect', bad_code, good_code
|
103
|
+
|
104
|
+
bad_code = <<-RUBY
|
105
|
+
3.times do
|
106
|
+
create(:user, :trait) do |user|
|
107
|
+
create :account, user: user
|
108
|
+
create :profile, user: user
|
109
|
+
end
|
110
|
+
end
|
111
|
+
RUBY
|
112
|
+
|
113
|
+
good_code = <<-RUBY
|
114
|
+
create_list(:user, 3, :trait) do |user|
|
115
|
+
create :account, user: user
|
116
|
+
create :profile, user: user
|
117
|
+
end
|
118
|
+
RUBY
|
119
|
+
|
120
|
+
include_examples 'autocorrect', bad_code, good_code
|
91
121
|
end
|
92
122
|
|
93
123
|
context 'when EnforcedStyle is :n_times' do
|
@@ -10,6 +10,8 @@ RSpec.describe RuboCop::Cop::RSpec::Focus do
|
|
10
10
|
^^^^^^^^^^^ Focused spec found.
|
11
11
|
describe 'test', meta: true, focus: true do; end
|
12
12
|
^^^^^^^^^^^ Focused spec found.
|
13
|
+
RSpec.describe 'test', meta: true, focus: true do; end
|
14
|
+
^^^^^^^^^^^ Focused spec found.
|
13
15
|
it 'test', meta: true, focus: true do; end
|
14
16
|
^^^^^^^^^^^ Focused spec found.
|
15
17
|
xspecify 'test', meta: true, focus: true do; end
|
@@ -61,6 +63,8 @@ RSpec.describe RuboCop::Cop::RSpec::Focus do
|
|
61
63
|
^^^^^^ Focused spec found.
|
62
64
|
describe 'test', :focus do; end
|
63
65
|
^^^^^^ Focused spec found.
|
66
|
+
RSpec.describe 'test', :focus do; end
|
67
|
+
^^^^^^ Focused spec found.
|
64
68
|
xit 'test', :focus do; end
|
65
69
|
^^^^^^ Focused spec found.
|
66
70
|
context 'test', :focus do; end
|
@@ -108,10 +112,13 @@ RSpec.describe RuboCop::Cop::RSpec::Focus do
|
|
108
112
|
RUBY
|
109
113
|
end
|
110
114
|
|
115
|
+
# rubocop:disable RSpec/ExampleLength
|
111
116
|
it 'flags focused block types' do
|
112
117
|
expect_offense(<<-RUBY)
|
113
118
|
fdescribe 'test' do; end
|
114
119
|
^^^^^^^^^^^^^^^^ Focused spec found.
|
120
|
+
RSpec.fdescribe 'test' do; end
|
121
|
+
^^^^^^^^^^^^^^^^^^^^^^ Focused spec found.
|
115
122
|
ffeature 'test' do; end
|
116
123
|
^^^^^^^^^^^^^^^ Focused spec found.
|
117
124
|
fcontext 'test' do; end
|
@@ -128,4 +135,5 @@ RSpec.describe RuboCop::Cop::RSpec::Focus do
|
|
128
135
|
^^^^^^^^^^^^ Focused spec found.
|
129
136
|
RUBY
|
130
137
|
end
|
138
|
+
# rubocop:enable RSpec/ExampleLength
|
131
139
|
end
|
@@ -82,6 +82,14 @@ RSpec.describe RuboCop::Cop::RSpec::Pending do
|
|
82
82
|
RUBY
|
83
83
|
end
|
84
84
|
|
85
|
+
it 'flags describe with skip symbol metadata' do
|
86
|
+
expect_offense(<<-RUBY)
|
87
|
+
RSpec.describe 'test', :skip do
|
88
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Pending spec found.
|
89
|
+
end
|
90
|
+
RUBY
|
91
|
+
end
|
92
|
+
|
85
93
|
it 'flags blocks with pending symbol metadata' do
|
86
94
|
expect_offense(<<-RUBY)
|
87
95
|
it 'test', :pending do
|
@@ -78,6 +78,12 @@ RSpec.describe RuboCop::Cop::RSpec::ReceiveCounts do
|
|
78
78
|
RUBY
|
79
79
|
end
|
80
80
|
|
81
|
+
it 'allows exactly(1).times when not called on `receive`' do
|
82
|
+
expect_no_offenses(<<-RUBY)
|
83
|
+
expect(action).to have_published_event.exactly(1).times
|
84
|
+
RUBY
|
85
|
+
end
|
86
|
+
|
81
87
|
include_examples 'autocorrect',
|
82
88
|
'expect(foo).to receive(:bar).exactly(1).times { true }',
|
83
89
|
'expect(foo).to receive(:bar).once { true }'
|
@@ -85,4 +91,9 @@ RSpec.describe RuboCop::Cop::RSpec::ReceiveCounts do
|
|
85
91
|
include_examples 'autocorrect',
|
86
92
|
'expect(foo).to receive(:bar).at_least(2).times { true }',
|
87
93
|
'expect(foo).to receive(:bar).at_least(:twice) { true }'
|
94
|
+
|
95
|
+
# Does not auto-correct if not part of the RSpec API
|
96
|
+
include_examples 'autocorrect',
|
97
|
+
'expect(foo).to have_published_event(:bar).exactly(2).times',
|
98
|
+
'expect(foo).to have_published_event(:bar).exactly(2).times'
|
88
99
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
RSpec.describe RuboCop::Cop::RSpec::Yield do
|
2
|
+
subject(:cop) { described_class.new }
|
3
|
+
|
4
|
+
it 'flags `block.call`' do
|
5
|
+
expect_offense(<<-RUBY)
|
6
|
+
allow(foo).to receive(:bar) { |&block| block.call }
|
7
|
+
^^^^^^^^^^^^^^^^^^^^^^^ Use `.and_yield`.
|
8
|
+
RUBY
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'flags multiple `block.call`' do
|
12
|
+
expect_offense(<<-RUBY)
|
13
|
+
allow(foo).to receive(:bar) do |&block|
|
14
|
+
^^^^^^^^^^^ Use `.and_yield`.
|
15
|
+
block.call
|
16
|
+
block.call
|
17
|
+
end
|
18
|
+
RUBY
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'flags `block.call` with arguments' do
|
22
|
+
expect_offense(<<-RUBY)
|
23
|
+
allow(foo).to receive(:bar) { |&block| block.call(1, 2) }
|
24
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `.and_yield`.
|
25
|
+
RUBY
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'flags multiple `block.call` with arguments' do
|
29
|
+
expect_offense(<<-RUBY)
|
30
|
+
allow(foo).to receive(:bar) do |&block|
|
31
|
+
^^^^^^^^^^^ Use `.and_yield`.
|
32
|
+
block.call(1)
|
33
|
+
block.call(2)
|
34
|
+
end
|
35
|
+
RUBY
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'flags `block.call` when `receive` is chained' do
|
39
|
+
expect_offense(<<-RUBY)
|
40
|
+
allow(foo).to receive(:bar).with(anything) { |&block| block.call }
|
41
|
+
^^^^^^^^^^^^^^^^^^^^^^^ Use `.and_yield`.
|
42
|
+
RUBY
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'ignores `receive` with no block arguments' do
|
46
|
+
expect_no_offenses(<<-RUBY)
|
47
|
+
allow(foo).to receive(:bar) { |block| block.call }
|
48
|
+
RUBY
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'ignores stub when `block.call` is not the only statement' do
|
52
|
+
expect_no_offenses(<<-RUBY)
|
53
|
+
allow(foo).to receive(:bar) do |&block|
|
54
|
+
result = block.call
|
55
|
+
transform(result)
|
56
|
+
end
|
57
|
+
RUBY
|
58
|
+
end
|
59
|
+
|
60
|
+
include_examples 'autocorrect',
|
61
|
+
'allow(foo).to receive(:bar) { |&block| block.call }',
|
62
|
+
'allow(foo).to receive(:bar).and_yield'
|
63
|
+
|
64
|
+
include_examples 'autocorrect',
|
65
|
+
'allow(foo).to receive(:bar) { |&block| block.call(1, 2) }',
|
66
|
+
'allow(foo).to receive(:bar).and_yield(1, 2)'
|
67
|
+
|
68
|
+
bad_code = <<-RUBY
|
69
|
+
allow(foo).to receive(:bar) do |&block|
|
70
|
+
block.call(1)
|
71
|
+
block.call(2)
|
72
|
+
end
|
73
|
+
RUBY
|
74
|
+
|
75
|
+
good_code = <<-RUBY
|
76
|
+
allow(foo).to receive(:bar).and_yield(1).and_yield(2)
|
77
|
+
RUBY
|
78
|
+
|
79
|
+
include_examples 'autocorrect', bad_code, good_code
|
80
|
+
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.
|
4
|
+
version: 1.32.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-01-
|
13
|
+
date: 2019-01-27 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rubocop
|
@@ -187,6 +187,7 @@ files:
|
|
187
187
|
- lib/rubocop/cop/rspec/unspecified_exception.rb
|
188
188
|
- lib/rubocop/cop/rspec/verified_doubles.rb
|
189
189
|
- lib/rubocop/cop/rspec/void_expect.rb
|
190
|
+
- lib/rubocop/cop/rspec/yield.rb
|
190
191
|
- lib/rubocop/cop/rspec_cops.rb
|
191
192
|
- lib/rubocop/rspec.rb
|
192
193
|
- lib/rubocop/rspec/align_let_brace.rb
|
@@ -281,6 +282,7 @@ files:
|
|
281
282
|
- spec/rubocop/cop/rspec/unspecified_exception_spec.rb
|
282
283
|
- spec/rubocop/cop/rspec/verified_doubles_spec.rb
|
283
284
|
- spec/rubocop/cop/rspec/void_expect_spec.rb
|
285
|
+
- spec/rubocop/cop/rspec/yield_spec.rb
|
284
286
|
- spec/rubocop/rspec/config_formatter_spec.rb
|
285
287
|
- spec/rubocop/rspec/description_extractor_spec.rb
|
286
288
|
- spec/rubocop/rspec/example_group_spec.rb
|
@@ -398,6 +400,7 @@ test_files:
|
|
398
400
|
- spec/rubocop/cop/rspec/unspecified_exception_spec.rb
|
399
401
|
- spec/rubocop/cop/rspec/verified_doubles_spec.rb
|
400
402
|
- spec/rubocop/cop/rspec/void_expect_spec.rb
|
403
|
+
- spec/rubocop/cop/rspec/yield_spec.rb
|
401
404
|
- spec/rubocop/rspec/config_formatter_spec.rb
|
402
405
|
- spec/rubocop/rspec/description_extractor_spec.rb
|
403
406
|
- spec/rubocop/rspec/example_group_spec.rb
|