Skip to content

Commit

Permalink
[Fix #5022] Fix false negative for Lint/DuplicateMethods inside `cl…
Browse files Browse the repository at this point in the history
…ass << self`.
  • Loading branch information
dvandersluis committed Aug 10, 2021
1 parent bb5d832 commit defdb71
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 9 deletions.
13 changes: 8 additions & 5 deletions lib/rubocop/cop/lint/duplicate_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,14 @@ def message_for_dup(node, method_name)
def found_instance_method(node, name)
return unless (scope = node.parent_module_name)

if scope =~ /\A#<Class:(.*)>\Z/
found_method(node, "#{Regexp.last_match(1)}.#{name}")
else
found_method(node, "#{scope}##{name}")
end
# Humanize the scope
scope = scope.sub(
/(?:(?<name>.*)::)#<Class:\k<name>>|#<Class:(?<name>.*)>(?:::)?/,
'\k<name>.'
)
scope << '#' unless scope.end_with?('.')

found_method(node, "#{scope}#{name}")
end

def found_method(node, method_name)
Expand Down
2 changes: 1 addition & 1 deletion rubocop.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency('rainbow', '>= 2.2.2', '< 4.0')
s.add_runtime_dependency('regexp_parser', '>= 1.8', '< 3.0')
s.add_runtime_dependency('rexml')
s.add_runtime_dependency('rubocop-ast', '>= 1.9.0', '< 2.0')
s.add_runtime_dependency('rubocop-ast', '>= 1.9.1', '< 2.0')
s.add_runtime_dependency('ruby-progressbar', '~> 1.7')
s.add_runtime_dependency('unicode-display_width', '>= 1.4.0', '< 3.0')

Expand Down
41 changes: 38 additions & 3 deletions spec/rubocop/cop/lint/duplicate_methods_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def some_method
RUBY
end

xit 'understands class << self' do
it 'understands class << self' do
expect_offense(<<~RUBY, 'test.rb')
#{opening_line}
class << self
Expand Down Expand Up @@ -424,8 +424,8 @@ def A.some_method
RUBY
end

xit 'registers an offense for duplicate class methods with `<<` and named ' \
"receiver in #{type}" do
it 'registers an offense for duplicate class methods with `<<` and named ' \
"receiver in #{type}" do
expect_offense(<<~RUBY, 'test.rb')
#{type} A
class << self
Expand Down Expand Up @@ -510,6 +510,41 @@ def foo
RUBY
end

it 'does not register for the same method in different scopes within `class << self`' do
expect_no_offenses(<<~RUBY, 'test.rb')
class A
class << self
def foo
end
class B
def foo
end
end
end
end
RUBY
end

it 'properly registers and offense when deeply nested' do
expect_offense(<<~RUBY, 'test.rb')
module A
module B
class C
class << self
def foo
end
def foo
^^^^^^^ Method `A::B::C.foo` is defined at both test.rb:5 and test.rb:8.
end
end
end
end
end
RUBY
end

context 'when path is in the project root' do
before do
allow(Dir).to receive(:pwd).and_return('/path/to/project/root')
Expand Down

0 comments on commit defdb71

Please sign in to comment.