Skip to content

Commit

Permalink
Merge pull request #97 from santib/fix-enum-uniqueness
Browse files Browse the repository at this point in the history
Fix false negatives for Rails/EnumUniqueness cop
  • Loading branch information
koic committed Aug 9, 2019
2 parents 3902899 + 4ec7f5a commit 83cdf0d
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -9,6 +9,7 @@
### Bug fixes

* [#53](https://github.com/rubocop-hq/rubocop-rails/issues/53): Fix a false positive for `Rails/SaveBang` when implicitly return using finder method and creation method connected by `||`. ([@koic][])
* [#97](https://github.com/rubocop-hq/rubocop-rails/pull/97): Fix two false negatives for `Rails/EnumUniqueness`. 1. When `enum` name is not a literal. 2. When `enum` has multiple definitions. ([@santib][])

### Changes

Expand Down
36 changes: 28 additions & 8 deletions lib/rubocop/cop/rails/enum_uniqueness.rb
Expand Up @@ -23,22 +23,42 @@ class EnumUniqueness < Cop
MSG = 'Duplicate value `%<value>s` found in `%<enum>s` ' \
'enum declaration.'

def_node_matcher :enum_declaration, <<-PATTERN
(send nil? :enum (hash (pair (_ $_) ${array hash})))
def_node_matcher :enum?, <<~PATTERN
(send nil? :enum (hash $...))
PATTERN

def_node_matcher :enum_values, <<~PATTERN
(pair $_ ${array hash})
PATTERN

def on_send(node)
enum_declaration(node) do |name, args|
items = args.values
enum?(node) do |pairs|
pairs.each do |pair|
enum_values(pair) do |key, args|
items = args.values

return unless duplicates?(items)
next unless duplicates?(items)

consecutive_duplicates(items).each do |item|
add_offense(item, message: format(MSG, value: item.source,
enum: name))
consecutive_duplicates(items).each do |item|
add_offense(item, message: format(
MSG, value: item.source, enum: enum_name(key)
))
end
end
end
end
end

private

def enum_name(key)
case key.type
when :sym, :str
key.value
else
key.source
end
end
end
end
end
Expand Down
29 changes: 29 additions & 0 deletions spec/rubocop/cop/rails/enum_uniqueness_spec.rb
Expand Up @@ -85,4 +85,33 @@
end
end
end

context 'when the enum name is a string' do
it 'registers an offense' do
expect_offense(<<~RUBY)
enum "status" => [:active, :archived, :active]
^^^^^^^ Duplicate value `:active` found in `status` enum declaration.
RUBY
end
end

context 'when the enum name is not a literal' do
it 'registers an offense' do
expect_offense(<<~RUBY)
enum KEY => [:active, :archived, :active]
^^^^^^^ Duplicate value `:active` found in `KEY` enum declaration.
RUBY
end
end

context 'with multiple enum definition for a `enum` method call' do
it 'registers an offense' do
expect_offense(<<~RUBY)
enum status: [:active, :archived, :active],
^^^^^^^ Duplicate value `:active` found in `status` enum declaration.
role: [:owner, :member, :guest, :member]
^^^^^^^ Duplicate value `:member` found in `role` enum declaration.
RUBY
end
end
end

0 comments on commit 83cdf0d

Please sign in to comment.