Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3520077

Browse files
author
Maxim Krizhanovski
committed
[Fix rubocop#719] Allow using arrays, variables and method in receive_message_chain
1 parent f53fa70 commit 3520077

File tree

3 files changed

+69
-5
lines changed

3 files changed

+69
-5
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Add `IgnoreSharedExamples` option for `RSpec/NamedSubject`. ([@RST-J][])
66
* Add autocorrect support for `Capybara/CurrentPathExpectation` cop. ([@ypresto][])
77
* Add support for built-in `exists` matcher for `RSpec/PredicateMatcher` cop. ([@mkenyon][])
8+
* `SingleArgumentMessageChain` no longer reports an array as it's only argument as an offense. ([@Darhazer][])
89

910
## 1.30.1 (2018-11-01)
1011

lib/rubocop/cop/rspec/single_argument_message_chain.rb

+22-3
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ class SingleArgumentMessageChain < Cop
2626

2727
def on_send(node)
2828
message_chain(node) do |arg|
29-
return if arg.to_s.include?('.')
30-
31-
return if arg.hash_type? && !single_key_hash?(arg)
29+
return if valid_usage?(arg)
3230

3331
add_offense(node, location: :selector)
3432
end
@@ -39,12 +37,27 @@ def autocorrect(node)
3937
corrector.replace(node.loc.selector, replacement(node.method_name))
4038
message_chain(node) do |arg|
4139
autocorrect_hash_arg(corrector, arg) if single_key_hash?(arg)
40+
autocorrect_array_arg(corrector, arg) if arg.array_type?
4241
end
4342
end
4443
end
4544

4645
private
4746

47+
def valid_usage?(node)
48+
return true unless node.literal? || node.array_type?
49+
50+
case node.type
51+
when :hash then !single_key_hash?(node)
52+
when :array then !single_element_array?(node)
53+
else node.to_s.include?('.')
54+
end
55+
end
56+
57+
def single_element_array?(node)
58+
node.child_nodes.one?
59+
end
60+
4861
def autocorrect_hash_arg(corrector, arg)
4962
key, value = *arg.children.first
5063

@@ -53,6 +66,12 @@ def autocorrect_hash_arg(corrector, arg)
5366
".and_return(#{value.source})")
5467
end
5568

69+
def autocorrect_array_arg(corrector, arg)
70+
value = arg.children.first
71+
72+
corrector.replace(arg.loc.expression, value.source)
73+
end
74+
5675
def key_to_arg(node)
5776
key, = *node
5877
node.sym_type? ? ":#{key}" : node.source

spec/rubocop/cop/rspec/single_argument_message_chain_spec.rb

+46-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,52 @@
4848
RUBY
4949
end
5050

51+
it 'accepts single-argument calls with variable' do
52+
expect_no_offenses(<<-RUBY)
53+
before do
54+
foo = %i[:one :two]
55+
allow(foo).to receive_message_chain(foo) { :many }
56+
end
57+
RUBY
58+
end
59+
60+
it 'accepts single-argument calls with send node' do
61+
expect_no_offenses(<<-RUBY)
62+
before do
63+
allow(foo).to receive_message_chain(foo) { :many }
64+
end
65+
RUBY
66+
end
67+
68+
context 'with single-element array argument' do
69+
it 'reports an offense' do
70+
expect_offense(<<-RUBY)
71+
before do
72+
allow(foo).to receive_message_chain([:one]) { :two }
73+
^^^^^^^^^^^^^^^^^^^^^ Use `receive` instead of calling `receive_message_chain` with a single argument.
74+
end
75+
RUBY
76+
end
77+
78+
include_examples(
79+
'autocorrect',
80+
'before { allow(foo).to receive_message_chain([:one]) { :two } }',
81+
'before { allow(foo).to receive(:one) { :two } }'
82+
)
83+
end
84+
85+
context 'with multiple-element array argument' do
86+
it "doesn't report an offense" do
87+
expect_no_offenses(<<-RUBY)
88+
before do
89+
allow(foo).to receive_message_chain([:one, :two]) { :many }
90+
end
91+
RUBY
92+
end
93+
end
94+
5195
context 'with single-key hash argument' do
52-
it 'reports an offence' do
96+
it 'reports an offense' do
5397
expect_offense(<<-RUBY)
5498
before do
5599
allow(foo).to receive_message_chain(bar: 42)
@@ -78,7 +122,7 @@
78122
end
79123

80124
context 'with multiple keys hash argument' do
81-
it "doesn't report an offence" do
125+
it "doesn't report an offense" do
82126
expect_no_offenses(<<-RUBY)
83127
before do
84128
allow(foo).to receive_message_chain(bar: 42, baz: 42)

0 commit comments

Comments
 (0)