Skip to content

Commit efd16c2

Browse files
authored
Merge pull request #182 from koic/add_supported_style_refute_for_rails_refute_methods
[Fix #150] Add `EnforcedStyle: refute` for `Rails/RefuteMethods`
2 parents b43a7fe + 8ce0fcd commit efd16c2

File tree

5 files changed

+183
-67
lines changed

5 files changed

+183
-67
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
* [#197](https://github.com/rubocop-hq/rubocop-rails/pull/197): Add `Rails/UniqueValidationWithoutIndex` cop. ([@pocke][])
88
* [#208](https://github.com/rubocop-hq/rubocop-rails/pull/208): Add new `Rails/IndexBy` and `Rails/IndexWith` cops. ([@djudd][], [@eugeneius][])
9+
* [#150](https://github.com/rubocop-hq/rubocop-rails/issues/150): Add `EnforcedStyle: refute` for `Rails/RefuteMethods` cop. ([@koic][])
910

1011
### Bug fixes
1112

config/default.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,10 @@ Rails/RefuteMethods:
393393
Description: 'Use `assert_not` methods instead of `refute` methods.'
394394
Enabled: true
395395
VersionAdded: '0.56'
396+
EnforcedStyle: assert_not
397+
SupportedStyles:
398+
- assert_not
399+
- refute
396400
Include:
397401
- '**/test/**/*'
398402

lib/rubocop/cop/rails/refute_methods.rb

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module Rails
66
#
77
# Use `assert_not` methods instead of `refute` methods.
88
#
9-
# @example
9+
# @example EnforcedStyle: assert_not (default)
1010
# # bad
1111
# refute false
1212
# refute_empty [1, 2, 3]
@@ -17,29 +17,43 @@ module Rails
1717
# assert_not_empty [1, 2, 3]
1818
# assert_not_equal true, false
1919
#
20+
# @example EnforcedStyle: refute
21+
# # bad
22+
# assert_not false
23+
# assert_not_empty [1, 2, 3]
24+
# assert_not_equal true, false
25+
#
26+
# # good
27+
# refute false
28+
# refute_empty [1, 2, 3]
29+
# refute_equal true, false
30+
#
2031
class RefuteMethods < Cop
21-
MSG = 'Prefer `%<assert_method>s` over `%<refute_method>s`.'
32+
include ConfigurableEnforcedStyle
33+
34+
MSG = 'Prefer `%<good_method>s` over `%<bad_method>s`.'
2235

2336
CORRECTIONS = {
24-
refute: 'assert_not',
25-
refute_empty: 'assert_not_empty',
26-
refute_equal: 'assert_not_equal',
27-
refute_in_delta: 'assert_not_in_delta',
28-
refute_in_epsilon: 'assert_not_in_epsilon',
29-
refute_includes: 'assert_not_includes',
30-
refute_instance_of: 'assert_not_instance_of',
31-
refute_kind_of: 'assert_not_kind_of',
32-
refute_nil: 'assert_not_nil',
33-
refute_operator: 'assert_not_operator',
34-
refute_predicate: 'assert_not_predicate',
35-
refute_respond_to: 'assert_not_respond_to',
36-
refute_same: 'assert_not_same',
37-
refute_match: 'assert_no_match'
37+
refute: :assert_not,
38+
refute_empty: :assert_not_empty,
39+
refute_equal: :assert_not_equal,
40+
refute_in_delta: :assert_not_in_delta,
41+
refute_in_epsilon: :assert_not_in_epsilon,
42+
refute_includes: :assert_not_includes,
43+
refute_instance_of: :assert_not_instance_of,
44+
refute_kind_of: :assert_not_kind_of,
45+
refute_nil: :assert_not_nil,
46+
refute_operator: :assert_not_operator,
47+
refute_predicate: :assert_not_predicate,
48+
refute_respond_to: :assert_not_respond_to,
49+
refute_same: :assert_not_same,
50+
refute_match: :assert_no_match
3851
}.freeze
3952

40-
OFFENSIVE_METHODS = CORRECTIONS.keys.freeze
53+
REFUTE_METHODS = CORRECTIONS.keys.freeze
54+
ASSERT_NOT_METHODS = CORRECTIONS.values.freeze
4155

42-
def_node_matcher :offensive?, '(send nil? #refute_method? ...)'
56+
def_node_matcher :offensive?, '(send nil? #bad_method? ...)'
4357

4458
def on_send(node)
4559
return unless offensive?(node)
@@ -49,27 +63,39 @@ def on_send(node)
4963
end
5064

5165
def autocorrect(node)
66+
bad_method = node.method_name
67+
good_method = convert_good_method(bad_method)
68+
5269
lambda do |corrector|
53-
corrector.replace(
54-
node.loc.selector,
55-
CORRECTIONS[node.method_name]
56-
)
70+
corrector.replace(node.loc.selector, good_method.to_s)
5771
end
5872
end
5973

6074
private
6175

62-
def refute_method?(method_name)
63-
OFFENSIVE_METHODS.include?(method_name)
76+
def bad_method?(method_name)
77+
if style == :assert_not
78+
REFUTE_METHODS.include?(method_name)
79+
else
80+
ASSERT_NOT_METHODS.include?(method_name)
81+
end
6482
end
6583

6684
def offense_message(method_name)
6785
format(
6886
MSG,
69-
refute_method: method_name,
70-
assert_method: CORRECTIONS[method_name]
87+
bad_method: method_name,
88+
good_method: convert_good_method(method_name)
7189
)
7290
end
91+
92+
def convert_good_method(bad_method)
93+
if style == :assert_not
94+
CORRECTIONS.fetch(bad_method)
95+
else
96+
CORRECTIONS.invert.fetch(bad_method)
97+
end
98+
end
7399
end
74100
end
75101
end

manual/cops_rails.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,6 +1912,8 @@ Use `assert_not` methods instead of `refute` methods.
19121912

19131913
### Examples
19141914

1915+
#### EnforcedStyle: assert_not (default)
1916+
19151917
```ruby
19161918
# bad
19171919
refute false
@@ -1923,11 +1925,25 @@ assert_not false
19231925
assert_not_empty [1, 2, 3]
19241926
assert_not_equal true, false
19251927
```
1928+
#### EnforcedStyle: refute
1929+
1930+
```ruby
1931+
# bad
1932+
assert_not false
1933+
assert_not_empty [1, 2, 3]
1934+
assert_not_equal true, false
1935+
1936+
# good
1937+
refute false
1938+
refute_empty [1, 2, 3]
1939+
refute_equal true, false
1940+
```
19261941

19271942
### Configurable attributes
19281943

19291944
Name | Default value | Configurable values
19301945
--- | --- | ---
1946+
EnforcedStyle | `assert_not` | `assert_not`, `refute`
19311947
Include | `**/test/**/*` | Array
19321948

19331949
## Rails/RelativeDateConstant
Lines changed: 110 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,122 @@
11
# frozen_string_literal: true
22

3-
RSpec.describe RuboCop::Cop::Rails::RefuteMethods do
4-
subject(:cop) { described_class.new }
5-
6-
it 'registers an offense and correct using `refute` with a single argument' do
7-
expect_offense(<<~RUBY)
8-
refute foo
9-
^^^^^^ Prefer `assert_not` over `refute`.
10-
RUBY
11-
12-
expect_correction(<<~RUBY)
13-
assert_not foo
14-
RUBY
15-
end
3+
RSpec.describe RuboCop::Cop::Rails::RefuteMethods, :config do
4+
subject(:cop) { described_class.new(config) }
165

17-
it 'registers an offense and corrects using `refute` ' \
18-
'with multiple arguments' do
19-
expect_offense(<<~RUBY)
20-
refute foo, bar, baz
21-
^^^^^^ Prefer `assert_not` over `refute`.
22-
RUBY
6+
let(:config) do
7+
RuboCop::Config.new('Rails/RefuteMethods' => cop_config)
8+
end
239

24-
expect_correction(<<~RUBY)
25-
assert_not foo, bar, baz
26-
RUBY
10+
let(:cop_config) do
11+
{
12+
'EnforcedStyle' => enforced_style,
13+
'SupportedStyles' => %w[assert_not refute]
14+
}
2715
end
2816

29-
it 'registers an offense when using `refute_empty`' do
30-
expect_offense(<<~RUBY)
31-
refute_empty foo
32-
^^^^^^^^^^^^ Prefer `assert_not_empty` over `refute_empty`.
33-
RUBY
17+
context 'when EnforcedStyle is `assert_not`' do
18+
let(:enforced_style) { 'assert_not' }
3419

35-
expect_correction(<<~RUBY)
36-
assert_not_empty foo
37-
RUBY
38-
end
20+
it 'registers an offense and correct using `refute` ' \
21+
'with a single argument' do
22+
expect_offense(<<~RUBY)
23+
refute foo
24+
^^^^^^ Prefer `assert_not` over `refute`.
25+
RUBY
26+
27+
expect_correction(<<~RUBY)
28+
assert_not foo
29+
RUBY
30+
end
31+
32+
it 'registers an offense and corrects using `refute` ' \
33+
'with multiple arguments' do
34+
expect_offense(<<~RUBY)
35+
refute foo, bar, baz
36+
^^^^^^ Prefer `assert_not` over `refute`.
37+
RUBY
38+
39+
expect_correction(<<~RUBY)
40+
assert_not foo, bar, baz
41+
RUBY
42+
end
43+
44+
it 'registers an offense when using `refute_empty`' do
45+
expect_offense(<<~RUBY)
46+
refute_empty foo
47+
^^^^^^^^^^^^ Prefer `assert_not_empty` over `refute_empty`.
48+
RUBY
49+
50+
expect_correction(<<~RUBY)
51+
assert_not_empty foo
52+
RUBY
53+
end
54+
55+
it 'does not registers an offense when using `assert_not` ' \
56+
'with a single argument' do
57+
expect_no_offenses(<<~RUBY)
58+
assert_not foo
59+
RUBY
60+
end
3961

40-
it 'does not registers an offense when using `assert_not` ' \
41-
'with a single argument' do
42-
expect_no_offenses(<<~RUBY)
43-
assert_not foo
44-
RUBY
62+
it 'does not registers an offense when using `assert_not` ' \
63+
'with a multiple arguments' do
64+
expect_no_offenses(<<~RUBY)
65+
assert_not foo, bar, baz
66+
RUBY
67+
end
4568
end
4669

47-
it 'does not registers an offense when using `assert_not` ' \
48-
'with a multiple arguments' do
49-
expect_no_offenses(<<~RUBY)
50-
assert_not foo, bar, baz
51-
RUBY
70+
context 'when EnforcedStyle is `refute`' do
71+
let(:enforced_style) { 'refute' }
72+
73+
it 'registers an offense and correct using `assert_not` ' \
74+
'with a single argument' do
75+
expect_offense(<<~RUBY)
76+
assert_not foo
77+
^^^^^^^^^^ Prefer `refute` over `assert_not`.
78+
RUBY
79+
80+
expect_correction(<<~RUBY)
81+
refute foo
82+
RUBY
83+
end
84+
85+
it 'registers an offense and corrects using `assert_not` ' \
86+
'with multiple arguments' do
87+
expect_offense(<<~RUBY)
88+
assert_not foo, bar, baz
89+
^^^^^^^^^^ Prefer `refute` over `assert_not`.
90+
RUBY
91+
92+
expect_correction(<<~RUBY)
93+
refute foo, bar, baz
94+
RUBY
95+
end
96+
97+
it 'registers an offense when using `assert_not_empty`' do
98+
expect_offense(<<~RUBY)
99+
assert_not_empty foo
100+
^^^^^^^^^^^^^^^^ Prefer `refute_empty` over `assert_not_empty`.
101+
RUBY
102+
103+
expect_correction(<<~RUBY)
104+
refute_empty foo
105+
RUBY
106+
end
107+
108+
it 'does not registers an offense when using `refute` ' \
109+
'with a single argument' do
110+
expect_no_offenses(<<~RUBY)
111+
refute foo
112+
RUBY
113+
end
114+
115+
it 'does not registers an offense when using `refute` ' \
116+
'with a multiple arguments' do
117+
expect_no_offenses(<<~RUBY)
118+
refute foo, bar, baz
119+
RUBY
120+
end
52121
end
53122
end

0 commit comments

Comments
 (0)