Skip to content

Commit 9b0765e

Browse files
committed
Add test cop
1 parent 5431a42 commit 9b0765e

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# frozen_string_literal: true
2+
3+
module RuboCop
4+
module Cop
5+
module Rails
6+
# Looks for enums written with keyword arguments.
7+
#
8+
# Defining enums with keyword arguments is deprecated
9+
# and will be removed in Rails 7.3.
10+
#
11+
# Positional arguments should be used instead:
12+
#
13+
# @example
14+
# # bad
15+
# enum status: { active: 0, archived: 1 }, _prefix: true
16+
#
17+
# # good
18+
# enum :status, { active: 0, archived: 1 }, prefix: true
19+
#
20+
class EnumKeywordArgs < Base
21+
extend AutoCorrector
22+
23+
MSG_ARGS = 'Enum defined with keyword arguments found in `%<enum>s` enum declaration. Use positional arguments instead.'
24+
MSG_OPTS = 'Enum defined with deprecated options found in `%<enum>s` enum declaration. Use options without the `_` prefix.'
25+
RESTRICT_ON_SEND = %i[enum].freeze
26+
27+
def_node_matcher :enum?, <<~PATTERN
28+
(send nil? :enum (hash $...))
29+
PATTERN
30+
31+
def_node_matcher :enum_with_keyword_args?, <<~PATTERN
32+
(send nil? :enum $_ ${array hash} $_)
33+
PATTERN
34+
35+
def_node_matcher :enum_values, <<~PATTERN
36+
(pair $_ ${array hash})
37+
PATTERN
38+
39+
def_node_matcher :enum_options, <<~PATTERN
40+
(pair $_ $_)
41+
PATTERN
42+
43+
def on_send(node)
44+
enum?(node) do |pairs|
45+
pairs.each do |pair|
46+
key, array = enum_values(pair)
47+
if key
48+
add_offense(array, message: format(MSG_ARGS, enum: enum_name(key))) do |corrector|
49+
corrected_options = pairs[1..].map do |pair|
50+
name = if pair.key.source[0] == "_"
51+
pair.key.source[1..]
52+
else
53+
pair.key.source
54+
end
55+
56+
"#{name}: #{pair.value.source}"
57+
end.join(", ")
58+
corrected_options = ", " + corrected_options unless corrected_options.empty?
59+
60+
corrector.replace(node, "enum #{source(key)}, #{array.source}#{corrected_options}")
61+
end
62+
end
63+
end
64+
end
65+
66+
enum_with_keyword_args?(node) do |key, _, options|
67+
options.children.each do |option|
68+
name, value = enum_options(option)
69+
if name.source[0] == "_"
70+
add_offense(name, message: format(MSG_OPTS, enum: enum_name(key)))
71+
end
72+
end
73+
end
74+
end
75+
76+
private
77+
78+
def enum_name(key)
79+
case key.type
80+
when :sym, :str
81+
key.value
82+
else
83+
key.source
84+
end
85+
end
86+
87+
def source(elem)
88+
case elem.type
89+
when :str
90+
elem.value.dump
91+
when :sym
92+
elem.value.inspect
93+
else
94+
elem.source
95+
end
96+
end
97+
end
98+
end
99+
end
100+
end

0 commit comments

Comments
 (0)