Skip to content

Commit 7758046

Browse files
authored
Merge pull request #504 from lovro-bikic/performance-count-multiline-call
Fix autocorrection syntax error for `Performance/Count` with multiline calls
2 parents 8176097 + 804d614 commit 7758046

File tree

3 files changed

+153
-6
lines changed

3 files changed

+153
-6
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#504](https://github.com/rubocop/rubocop-performance/pull/504): Fix autocorrection syntax error for `Performance/Count` with multiline calls. ([@lovro-bikic][])

lib/rubocop/cop/performance/count.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def autocorrect(corrector, node, selector_node, selector)
8181

8282
range = source_starting_at(node) { |n| n.loc.dot.begin_pos }
8383

84-
corrector.remove(range)
84+
corrector.remove(range_with_surrounding_space(range, side: :left))
8585
corrector.replace(selector_loc, 'count')
8686
negate_reject(corrector, node) if selector == :reject
8787
end

spec/rubocop/cop/performance/count_spec.rb

Lines changed: 151 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,124 @@
11
# frozen_string_literal: true
22

33
RSpec.describe RuboCop::Cop::Performance::Count, :config do
4-
shared_examples 'selectors' do |selector|
4+
shared_examples 'selectors' do |selector, negate_condition|
55
it "registers an offense for using array.#{selector}...size" do
66
expect_offense(<<~RUBY, selector: selector)
77
[1, 2, 3].#{selector} { |e| e.even? }.size
88
^{selector}^^^^^^^^^^^^^^^^^^^^^ Use `count` instead of `#{selector}...size`.
99
RUBY
10+
11+
if negate_condition
12+
expect_correction(<<~RUBY)
13+
[1, 2, 3].count { |e| !(e.even?) }
14+
RUBY
15+
else
16+
expect_correction(<<~RUBY)
17+
[1, 2, 3].count { |e| e.even? }
18+
RUBY
19+
end
1020
end
1121

1222
it "registers an offense for using array&.#{selector}...size" do
1323
expect_offense(<<~RUBY, selector: selector)
1424
[1, 2, 3]&.#{selector} { |e| e.even? }&.size
1525
^{selector}^^^^^^^^^^^^^^^^^^^^^^ Use `count` instead of `#{selector}...size`.
1626
RUBY
27+
28+
if negate_condition
29+
expect_correction(<<~RUBY)
30+
[1, 2, 3]&.count { |e| !(e.even?) }
31+
RUBY
32+
else
33+
expect_correction(<<~RUBY)
34+
[1, 2, 3]&.count { |e| e.even? }
35+
RUBY
36+
end
1737
end
1838

1939
it "registers an offense for using hash.#{selector}...size" do
2040
expect_offense(<<~RUBY, selector: selector)
2141
{a: 1, b: 2, c: 3}.#{selector} { |e| e == :a }.size
2242
^{selector}^^^^^^^^^^^^^^^^^^^^^ Use `count` instead of `#{selector}...size`.
2343
RUBY
44+
45+
if negate_condition
46+
expect_correction(<<~RUBY)
47+
{a: 1, b: 2, c: 3}.count { |e| !(e == :a) }
48+
RUBY
49+
else
50+
expect_correction(<<~RUBY)
51+
{a: 1, b: 2, c: 3}.count { |e| e == :a }
52+
RUBY
53+
end
2454
end
2555

2656
it "registers an offense for using array.#{selector}...length" do
2757
expect_offense(<<~RUBY, selector: selector)
2858
[1, 2, 3].#{selector} { |e| e.even? }.length
2959
^{selector}^^^^^^^^^^^^^^^^^^^^^^^ Use `count` instead of `#{selector}...length`.
3060
RUBY
61+
62+
if negate_condition
63+
expect_correction(<<~RUBY)
64+
[1, 2, 3].count { |e| !(e.even?) }
65+
RUBY
66+
else
67+
expect_correction(<<~RUBY)
68+
[1, 2, 3].count { |e| e.even? }
69+
RUBY
70+
end
3171
end
3272

3373
it "registers an offense for using hash.#{selector}...length" do
3474
expect_offense(<<~RUBY, selector: selector)
3575
{a: 1, b: 2}.#{selector} { |e| e == :a }.length
3676
^{selector}^^^^^^^^^^^^^^^^^^^^^^^ Use `count` instead of `#{selector}...length`.
3777
RUBY
78+
79+
if negate_condition
80+
expect_correction(<<~RUBY)
81+
{a: 1, b: 2}.count { |e| !(e == :a) }
82+
RUBY
83+
else
84+
expect_correction(<<~RUBY)
85+
{a: 1, b: 2}.count { |e| e == :a }
86+
RUBY
87+
end
3888
end
3989

4090
it "registers an offense for using array.#{selector}...count" do
4191
expect_offense(<<~RUBY, selector: selector)
4292
[1, 2, 3].#{selector} { |e| e.even? }.count
4393
^{selector}^^^^^^^^^^^^^^^^^^^^^^ Use `count` instead of `#{selector}...count`.
4494
RUBY
95+
96+
if negate_condition
97+
expect_correction(<<~RUBY)
98+
[1, 2, 3].count { |e| !(e.even?) }
99+
RUBY
100+
else
101+
expect_correction(<<~RUBY)
102+
[1, 2, 3].count { |e| e.even? }
103+
RUBY
104+
end
45105
end
46106

47107
it "registers an offense for using hash.#{selector}...count" do
48108
expect_offense(<<~RUBY, selector: selector)
49109
{a: 1, b: 2}.#{selector} { |e| e == :a }.count
50110
^{selector}^^^^^^^^^^^^^^^^^^^^^^ Use `count` instead of `#{selector}...count`.
51111
RUBY
112+
113+
if negate_condition
114+
expect_correction(<<~RUBY)
115+
{a: 1, b: 2}.count { |e| !(e == :a) }
116+
RUBY
117+
else
118+
expect_correction(<<~RUBY)
119+
{a: 1, b: 2}.count { |e| e == :a }
120+
RUBY
121+
end
52122
end
53123

54124
it "allows usage of #{selector}...count with a block on an array" do
@@ -70,20 +140,78 @@
70140
puts array.#{selector}(&:value).count
71141
^{selector}^^^^^^^^^^^^^^^ Use `count` instead of `#{selector}...count`.
72142
RUBY
143+
144+
if negate_condition
145+
expect_correction(<<~RUBY)
146+
Data = Struct.new(:value)
147+
array = [Data.new(2), Data.new(3), Data.new(2)]
148+
puts array.count { |element| !element.value }
149+
RUBY
150+
else
151+
expect_correction(<<~RUBY)
152+
Data = Struct.new(:value)
153+
array = [Data.new(2), Data.new(3), Data.new(2)]
154+
puts array.count(&:value)
155+
RUBY
156+
end
73157
end
74158

75159
it "registers an offense for #{selector}(&:something).count" do
76160
expect_offense(<<~RUBY, selector: selector)
77161
foo.#{selector}(&:something).count
78162
^{selector}^^^^^^^^^^^^^^^^^^^ Use `count` instead of `#{selector}...count`.
79163
RUBY
164+
165+
if negate_condition
166+
expect_correction(<<~RUBY)
167+
foo.count { |element| !element.something }
168+
RUBY
169+
else
170+
expect_correction(<<~RUBY)
171+
foo.count(&:something)
172+
RUBY
173+
end
174+
end
175+
176+
it "registers an offense for multiline #{selector}(&:something).count.positive?" do
177+
expect_offense(<<~RUBY, selector: selector)
178+
foo
179+
.#{selector}(&:something)
180+
^{selector}^^^^^^^^^^^^^ Use `count` instead of `#{selector}...count`.
181+
.count
182+
.positive?
183+
RUBY
184+
185+
if negate_condition
186+
expect_correction(<<~RUBY)
187+
foo
188+
.count { |element| !element.something }
189+
.positive?
190+
RUBY
191+
else
192+
expect_correction(<<~RUBY)
193+
foo
194+
.count(&:something)
195+
.positive?
196+
RUBY
197+
end
80198
end
81199

82200
it "registers an offense for #{selector}(&:something)&.count" do
83201
expect_offense(<<~RUBY, selector: selector)
84202
foo&.#{selector}(&:something)&.count
85203
^{selector}^^^^^^^^^^^^^^^^^^^^ Use `count` instead of `#{selector}...count`.
86204
RUBY
205+
206+
if negate_condition
207+
expect_correction(<<~RUBY)
208+
foo&.count { |element| !element.something }
209+
RUBY
210+
else
211+
expect_correction(<<~RUBY)
212+
foo&.count(&:something)
213+
RUBY
214+
end
87215
end
88216

89217
it "registers an offense for #{selector}(&:something).count " \
@@ -96,6 +224,24 @@ def count(&block)
96224
end
97225
end
98226
RUBY
227+
228+
if negate_condition
229+
expect_correction(<<~RUBY)
230+
class A < Array
231+
def count(&block)
232+
count { !block.call }
233+
end
234+
end
235+
RUBY
236+
else
237+
expect_correction(<<~RUBY)
238+
class A < Array
239+
def count(&block)
240+
count(&block)
241+
end
242+
end
243+
RUBY
244+
end
99245
end
100246

101247
it "allows usage of #{selector} without getting the size" do
@@ -117,10 +263,10 @@ def count(&block)
117263
end
118264
end
119265

120-
it_behaves_like('selectors', 'select')
121-
it_behaves_like('selectors', 'find_all')
122-
it_behaves_like('selectors', 'filter')
123-
it_behaves_like('selectors', 'reject')
266+
it_behaves_like('selectors', 'select', false)
267+
it_behaves_like('selectors', 'find_all', false)
268+
it_behaves_like('selectors', 'filter', false)
269+
it_behaves_like('selectors', 'reject', true)
124270

125271
context 'Active Record select' do
126272
it 'allows usage of select with a string' do

0 commit comments

Comments
 (0)