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

Skip to content

Commit 1c81a96

Browse files
authored
Merge pull request rubocop#853 from pirj/relax-instance_variable-cop-for-custom-matchers
Fix RSpec/InstanceVariable inside custom matcher
2 parents f995853 + 41f3eed commit 1c81a96

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Master (Unreleased)
44

5+
* Fix `RSpec/InstanceVariable` detection inside custom matchers. ([@pirj][])
6+
57
## 1.37.1 (2019-12-16)
68

79
* Improve message and description of `FactoryBot/FactoryClassName`. ([@ybiquitous][])

lib/rubocop/cop/rspec/instance_variable.rb

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ class InstanceVariable < Cop
5858
(block (send (const nil? :Class) :new ...) ...)
5959
PATTERN
6060

61+
def_node_matcher :custom_matcher?, <<-PATTERN
62+
(block {
63+
(send nil? :matcher sym)
64+
(send (const (const nil? :RSpec) :Matchers) :define sym)
65+
} ...)
66+
PATTERN
67+
6168
def_node_search :ivar_usage, '$(ivar $_)'
6269

6370
def_node_search :ivar_assigned?, '(ivasgn % ...)'
@@ -66,17 +73,19 @@ def on_block(node)
6673
return unless spec_group?(node)
6774

6875
ivar_usage(node) do |ivar, name|
69-
return if inside_dynamic_class?(ivar)
70-
return if assignment_only? && !ivar_assigned?(node, name)
76+
next if valid_usage?(ivar)
77+
next if assignment_only? && !ivar_assigned?(node, name)
7178

7279
add_offense(ivar)
7380
end
7481
end
7582

7683
private
7784

78-
def inside_dynamic_class?(node)
79-
node.each_ancestor(:block).any? { |block| dynamic_class?(block) }
85+
def valid_usage?(node)
86+
node.each_ancestor(:block).any? do |block|
87+
dynamic_class?(block) || custom_matcher?(block)
88+
end
8089
end
8190

8291
def assignment_only?

spec/rubocop/cop/rspec/instance_variable_spec.rb

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@
3131
RUBY
3232
end
3333

34+
it 'flags several instance variables inside a describe' do
35+
expect_offense(<<-RUBY)
36+
describe MyClass do
37+
before { @foo = [] }
38+
it { expect(@foo).to be_empty }
39+
^^^^ Avoid instance variables – use let, a method call, or a local variable (if possible).
40+
it { expect(@bar).to be_empty }
41+
^^^^ Avoid instance variables – use let, a method call, or a local variable (if possible).
42+
end
43+
RUBY
44+
end
45+
3446
it 'ignores an instance variable without describe' do
3547
expect_no_offenses(<<-RUBY)
3648
@foo = []
@@ -67,6 +79,57 @@ def serialize
6779
RUBY
6880
end
6981

82+
context 'when used in a custom matcher' do
83+
it 'ignores instance variables inside `matcher`' do
84+
expect_no_offenses(<<~RUBY)
85+
describe MyClass do
86+
matcher :have_color do
87+
match do |object|
88+
@matcher = have_attributes(color: anything)
89+
@matcher.matches?(object)
90+
end
91+
92+
failure_message do
93+
@matcher.failure_message
94+
end
95+
end
96+
end
97+
RUBY
98+
end
99+
100+
it 'flags instance variables outside `matcher`' do
101+
expect_offense(<<~RUBY)
102+
describe MyClass do
103+
matcher :have_color do
104+
match do |object|
105+
@matcher = have_attributes(color: anything)
106+
@matcher.matches?(object)
107+
end
108+
end
109+
110+
it { expect(color: 1).to @matcher }
111+
^^^^^^^^ Avoid instance variables – use let, a method call, or a local variable (if possible).
112+
end
113+
RUBY
114+
end
115+
116+
it 'ignores instance variables inside `RSpec::Matchers.define`' do
117+
expect_no_offenses(<<~RUBY)
118+
describe MyClass do
119+
RSpec::Matchers.define :be_bigger_than do |first|
120+
match do |actual|
121+
(actual > first) && (actual < @second)
122+
end
123+
124+
chain :and_smaller_than do |second|
125+
@second = second
126+
end
127+
end
128+
end
129+
RUBY
130+
end
131+
end
132+
70133
context 'when configured with AssignmentOnly', :config do
71134
subject(:cop) { described_class.new(config) }
72135

0 commit comments

Comments
 (0)