Skip to content

Commit e012af8

Browse files
authored
Merge pull request #1310 from fatkodima/compact_blank-select_present
Change `Rails/CompactBlank` to handle `select(&:present?)`
2 parents 3e91c03 + df47686 commit e012af8

File tree

3 files changed

+92
-3
lines changed

3 files changed

+92
-3
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#1308](https://github.com/rubocop/rubocop-rails/issues/1308): Change `Rails/CompactBlank` to handle `select(&:present?)`. ([@fatkodima][])

lib/rubocop/cop/rails/compact_blank.rb

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ module Rails
2424
# # bad
2525
# collection.reject(&:blank?)
2626
# collection.reject { |_k, v| v.blank? }
27+
# collection.select(&:present?)
28+
# collection.select { |_k, v| v.present? }
2729
#
2830
# # good
2931
# collection.compact_blank
@@ -33,6 +35,8 @@ module Rails
3335
# collection.delete_if { |_k, v| v.blank? } # Same behavior as `Array#compact_blank!` and `Hash#compact_blank!`
3436
# collection.reject!(&:blank?) # Same behavior as `ActionController::Parameters#compact_blank!`
3537
# collection.reject! { |_k, v| v.blank? } # Same behavior as `ActionController::Parameters#compact_blank!`
38+
# collection.keep_if(&:present?) # Same behavior as `Array#compact_blank!` and `Hash#compact_blank!`
39+
# collection.keep_if { |_k, v| v.present? } # Same behavior as `Array#compact_blank!` and `Hash#compact_blank!`
3640
#
3741
# # good
3842
# collection.compact_blank!
@@ -43,7 +47,7 @@ class CompactBlank < Base
4347
extend TargetRailsVersion
4448

4549
MSG = 'Use `%<preferred_method>s` instead.'
46-
RESTRICT_ON_SEND = %i[reject delete_if reject!].freeze
50+
RESTRICT_ON_SEND = %i[reject delete_if reject! select keep_if].freeze
4751

4852
minimum_target_rails_version 6.1
4953

@@ -61,6 +65,20 @@ class CompactBlank < Base
6165
(sym :blank?)))
6266
PATTERN
6367

68+
def_node_matcher :select_with_block?, <<~PATTERN
69+
(block
70+
(send _ {:select :keep_if})
71+
$(args ...)
72+
(send
73+
$(lvar _) :present?))
74+
PATTERN
75+
76+
def_node_matcher :select_with_block_pass?, <<~PATTERN
77+
(send _ {:select :keep_if}
78+
(block-pass
79+
(sym :present?)))
80+
PATTERN
81+
6482
def on_send(node)
6583
return unless bad_method?(node)
6684

@@ -75,8 +93,10 @@ def on_send(node)
7593

7694
def bad_method?(node)
7795
return true if reject_with_block_pass?(node)
96+
return true if select_with_block_pass?(node)
7897

79-
if (arguments, receiver_in_block = reject_with_block?(node.parent))
98+
arguments, receiver_in_block = reject_with_block?(node.parent) || select_with_block?(node.parent)
99+
if arguments
80100
return use_single_value_block_argument?(arguments, receiver_in_block) ||
81101
use_hash_value_block_argument?(arguments, receiver_in_block)
82102
end
@@ -103,7 +123,7 @@ def offense_range(node)
103123
end
104124

105125
def preferred_method(node)
106-
node.method?(:reject) ? 'compact_blank' : 'compact_blank!'
126+
node.method?(:reject) || node.method?(:select) ? 'compact_blank' : 'compact_blank!'
107127
end
108128
end
109129
end

spec/rubocop/cop/rails/compact_blank_spec.rb

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,62 @@
7979
RUBY
8080
end
8181

82+
it 'registers and corrects an offense when using `select { |e| e.present? }`' do
83+
expect_offense(<<~RUBY)
84+
collection.select { |e| e.present? }
85+
^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact_blank` instead.
86+
RUBY
87+
88+
expect_correction(<<~RUBY)
89+
collection.compact_blank
90+
RUBY
91+
end
92+
93+
it 'registers and corrects an offense when using `select(&:present?)`' do
94+
expect_offense(<<~RUBY)
95+
collection.select(&:present?)
96+
^^^^^^^^^^^^^^^^^^ Use `compact_blank` instead.
97+
RUBY
98+
99+
expect_correction(<<~RUBY)
100+
collection.compact_blank
101+
RUBY
102+
end
103+
104+
it 'registers and corrects an offense when using `keep_if { |e| e.present? }`' do
105+
expect_offense(<<~RUBY)
106+
collection.keep_if { |e| e.present? }
107+
^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact_blank!` instead.
108+
RUBY
109+
110+
expect_correction(<<~RUBY)
111+
collection.compact_blank!
112+
RUBY
113+
end
114+
115+
it 'registers and corrects an offense when using `keep_if(&:present?)`' do
116+
expect_offense(<<~RUBY)
117+
collection.keep_if(&:present?)
118+
^^^^^^^^^^^^^^^^^^^ Use `compact_blank!` instead.
119+
RUBY
120+
121+
expect_correction(<<~RUBY)
122+
collection.compact_blank!
123+
RUBY
124+
end
125+
126+
it 'does not register an offense when using `select! { |e| e.present? }`' do
127+
expect_no_offenses(<<~RUBY)
128+
collection.select! { |e| e.present? }
129+
RUBY
130+
end
131+
132+
it 'does not register an offense when using `select!(&:present?)`' do
133+
expect_no_offenses(<<~RUBY)
134+
collection.select!(&:present?)
135+
RUBY
136+
end
137+
82138
it 'does not register an offense when using `compact_blank`' do
83139
expect_no_offenses(<<~RUBY)
84140
collection.compact_blank
@@ -110,6 +166,12 @@ def foo(arg)
110166
collection.reject { |e| e.empty? }
111167
RUBY
112168
end
169+
170+
it 'does not register an offense when using `select { |e| e.blank? }`' do
171+
expect_no_offenses(<<~RUBY)
172+
collection.select { |e| e.blank? }
173+
RUBY
174+
end
113175
end
114176

115177
context 'Rails <= 6.0', :rails60 do
@@ -124,5 +186,11 @@ def foo(arg)
124186
collection.reject { |e| e.empty? }
125187
RUBY
126188
end
189+
190+
it 'does not register an offense when using `select { |e| e.present? }`' do
191+
expect_no_offenses(<<~RUBY)
192+
collection.select { |e| e.present? }
193+
RUBY
194+
end
127195
end
128196
end

0 commit comments

Comments
 (0)