Skip to content

Commit

Permalink
[Fix #7320] Add support in Naming/MethodName for checking attribute n…
Browse files Browse the repository at this point in the history
…ames (#7372)
  • Loading branch information
denys281 committed Mar 21, 2020
1 parent 99ec41a commit ac577f8
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -228,6 +228,7 @@
* [#7091](https://github.com/rubocop-hq/rubocop/issues/7091): `Style/FormatStringToken` now detects format sequences with flags and modifiers. ([@buehmann][])
* [#7319](https://github.com/rubocop-hq/rubocop/pull/7319): Rename `IgnoredMethodPatterns` option to `IgnoredPatterns` option for `Style/MethodCallWithArgsParentheses`. ([@koic][])
* [#7345](https://github.com/rubocop-hq/rubocop/issues/7345): Mark unsafe for `Style/YodaCondition`. ([@koic][])
* [#7320](https://github.com/rubocop-hq/rubocop/issues/7320): Naming/MethodName doesn't flag attr_reader / attr_writer / attr_accessor. ([@denys281][])

## 0.74.0 (2019-07-31)

Expand Down Expand Up @@ -4406,4 +4407,4 @@
[@jemmaissroff]: https://github.com/jemmaissroff
[@nikitasakov]: https://github.com/nikitasakov
[@dmolesUC]: https://github.com/dmolesUC
[@yuritomanek]: https://github.com/yuritomanek
[@yuritomanek]: https://github.com/yuritomanek
30 changes: 30 additions & 0 deletions lib/rubocop/cop/naming/method_name.rb
Expand Up @@ -31,9 +31,28 @@ module Naming
class MethodName < Cop
include ConfigurableNaming
include IgnoredPattern
include RangeHelp

MSG = 'Use %<style>s for method names.'

def_node_matcher :attr?, <<~PATTERN
(send nil? ${:attr_reader :attr_writer :attr_accessor :attr} $...)
PATTERN

def_node_matcher :sym_name, '(sym $_name)'
def_node_matcher :str_name, '(str $_name)'

def on_send(node)
return unless (attrs = attr?(node))

attrs.last.each do |name_item|
name = attr_name(name_item)
next if !name || matches_ignored_pattern?(name)

check_name(node, name, range_position(node))
end
end

def on_def(node)
return if node.operator_method? ||
matches_ignored_pattern?(node.method_name)
Expand All @@ -44,6 +63,17 @@ def on_def(node)

private

def attr_name(name_item)
sym_name(name_item) || str_name(name_item)
end

def range_position(node)
selector_end_pos = node.loc.selector.end_pos + 1
expr_end_pos = node.loc.expression.end_pos

range_between(selector_end_pos, expr_end_pos)
end

def message(style)
format(MSG, style: style)
end
Expand Down
126 changes: 126 additions & 0 deletions spec/rubocop/cop/naming/method_name_spec.rb
Expand Up @@ -4,6 +4,35 @@
subject(:cop) { described_class.new(config) }

shared_examples 'never accepted' do |enforced_style|
it 'registers an offense for mixed snake case and camel case in attr.' do
expect_offense(<<~RUBY)
attr :visit_Arel_Nodes_SelectStatement
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use #{enforced_style} for method names.
attr_reader :visit_Arel_Nodes_SelectStatement
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use #{enforced_style} for method names.
attr_accessor :visit_Arel_Nodes_SelectStatement
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use #{enforced_style} for method names.
attr_writer :visit_Arel_Nodes_SelectStatement
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use #{enforced_style} for method names.
attr 'visit_Arel_Nodes_SelectStatement'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use #{enforced_style} for method names.
RUBY
end

it 'registers an offense for mixed snake case and camel case in attr.' do
expect_offense(<<~RUBY)
attr_reader :visit_Arel_Nodes_SelectStatement
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use #{enforced_style} for method names.
attr_reader 'visit_Arel_Nodes_SelectStatement'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use #{enforced_style} for method names.
RUBY
end

it 'registers an offense for mixed snake case and camel case' do
expect_offense(<<~RUBY)
def visit_Arel_Nodes_SelectStatement
Expand All @@ -12,6 +41,22 @@ def visit_Arel_Nodes_SelectStatement
RUBY
end

it 'registers an offense for capitalized camel case name in attr.' do
expect_offense(<<~RUBY)
attr :MyMethod
^^^^^^^^^ Use #{enforced_style} for method names.
attr_reader :MyMethod
^^^^^^^^^ Use #{enforced_style} for method names.
attr_accessor :MyMethod
^^^^^^^^^ Use #{enforced_style} for method names.
attr_writer :MyMethod
^^^^^^^^^ Use #{enforced_style} for method names.
RUBY
end

it 'registers an offense for capitalized camel case' do
expect_offense(<<~RUBY)
class MyClass
Expand Down Expand Up @@ -100,6 +145,14 @@ def base.Start(aws_env, *args)
}
end

it 'does not register an offense for camel case method name in attr.' do
expect_no_offenses(<<~RUBY)
attr_reader :onSelectionBulkChange
attr_accessor :onSelectionBulkChange
attr_writer :onSelectionBulkChange
RUBY
end

it 'does not register an offense for camel case method name ' \
' matching `IgnoredPatterns`' do
expect_no_offenses(<<~RUBY)
Expand All @@ -108,6 +161,14 @@ def onSelectionBulkChange(arg)
RUBY
end

it 'does not register an offense for snake case method name in attr.' do
expect_no_offenses(<<~RUBY)
attr_reader :on_selection_cleared
attr_accessor :on_selection_cleared
attr_writer :on_selection_cleared
RUBY
end

it 'does not register an offense for snake case method name ' \
' matching `IgnoredPatterns`' do
expect_no_offenses(<<~RUBY)
Expand All @@ -118,9 +179,40 @@ def on_selection_cleared(arg)
end
end

shared_examples 'multiple attr methods' do |enforced_style|
it 'registers an offense for camel case methods names in attr.' do
expect_offense(<<~RUBY)
attr :my_method, :myMethod
^^^^^^^^^^^^^^^^^^^^^ Use #{enforced_style} for method names.
attr_reader :my_method, :myMethod
^^^^^^^^^^^^^^^^^^^^^ Use #{enforced_style} for method names.
attr_accessor :myMethod, :my_method
^^^^^^^^^^^^^^^^^^^^^ Use #{enforced_style} for method names.
attr_accessor 'myMethod', 'my_method'
^^^^^^^^^^^^^^^^^^^^^^^ Use #{enforced_style} for method names.
RUBY
end
end

context 'when configured for snake_case' do
let(:cop_config) { { 'EnforcedStyle' => 'snake_case' } }

it 'registers an offense for camel case method names in attr.' do
expect_offense(<<~RUBY)
attr_reader :myMethod
^^^^^^^^^ Use snake_case for method names.
attr_accessor :myMethod
^^^^^^^^^ Use snake_case for method names.
attr_writer :myMethod
^^^^^^^^^ Use snake_case for method names.
RUBY
end

it 'registers an offense for camel case in instance method name' do
expect_offense(<<~RUBY)
def myMethod
Expand Down Expand Up @@ -149,6 +241,14 @@ def self.myMethod
RUBY
end

it 'accepts snake case in attr.' do
expect_no_offenses(<<~RUBY)
attr_reader :my_method
attr_accessor :my_method
attr_writer :my_method
RUBY
end

it 'accepts snake case in names' do
expect_no_offenses(<<~RUBY)
def my_method
Expand All @@ -168,11 +268,20 @@ def self.fooBar

include_examples 'never accepted', 'snake_case'
include_examples 'always accepted', 'snake_case'
include_examples 'multiple attr methods', 'snake_case'
end

context 'when configured for camelCase' do
let(:cop_config) { { 'EnforcedStyle' => 'camelCase' } }

it 'accepts camel case names in attr.' do
expect_no_offenses(<<~RUBY)
attr_reader :myMethod
attr_accessor :myMethod
attr_writer :myMethod
RUBY
end

it 'accepts camel case in instance method name' do
expect_no_offenses(<<~RUBY)
def myMethod
Expand All @@ -189,6 +298,22 @@ def self.myMethod
RUBY
end

it 'registers an offense for snake case name in attr.' do
expect_offense(<<~RUBY)
attr_reader :my_method
^^^^^^^^^^ Use camelCase for method names.
attr_accessor :my_method
^^^^^^^^^^ Use camelCase for method names.
attr_writer :my_method
^^^^^^^^^^ Use camelCase for method names.
attr_writer 'my_method'
^^^^^^^^^^^ Use camelCase for method names.
RUBY
end

it 'registers an offense for snake case in names' do
expect_offense(<<~RUBY)
def my_method
Expand Down Expand Up @@ -219,5 +344,6 @@ def self.foo_bar

include_examples 'always accepted', 'camelCase'
include_examples 'never accepted', 'camelCase'
include_examples 'multiple attr methods', 'camelCase'
end
end

0 comments on commit ac577f8

Please sign in to comment.