Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
162 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# frozen_string_literal: true | ||
|
||
module RuboCop | ||
module Cop | ||
module Lint | ||
# This cop checks for duplicate `require`s and `require_relative`s. | ||
# | ||
# @example | ||
# # bad | ||
# require 'foo' | ||
# require 'bar' | ||
# require 'foo' | ||
# | ||
# # good | ||
# require 'foo' | ||
# require 'bar' | ||
# | ||
class DuplicateRequire < Base | ||
MSG = 'Duplicate `%<method>s` detected.' | ||
REQUIRE_METHODS = %i[require require_relative].freeze | ||
|
||
def_node_matcher :require_call?, <<~PATTERN | ||
(send {nil? (const _ :Kernel)} {:#{REQUIRE_METHODS.join(' :')}} _) | ||
PATTERN | ||
|
||
def on_new_investigation | ||
# Holds the known required files for a given parent node (used as key) | ||
@required = Hash.new { |h, k| h[k] = Set.new }.compare_by_identity | ||
super | ||
end | ||
|
||
def on_send(node) | ||
return unless REQUIRE_METHODS.include?(node.method_name) && require_call?(node) | ||
return if @required[node.parent].add?(node.first_argument) | ||
|
||
add_offense(node, message: format(MSG, method: node.method_name)) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# frozen_string_literal: true | ||
|
||
RSpec.describe RuboCop::Cop::Lint::DuplicateRequire do | ||
subject(:cop) { described_class.new } | ||
|
||
it 'registers an offense when duplicate `require` is detected' do | ||
expect_offense(<<~RUBY) | ||
require 'foo' | ||
require 'foo' | ||
^^^^^^^^^^^^^ Duplicate `require` detected. | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when duplicate `require_relative` is detected' do | ||
expect_offense(<<~RUBY) | ||
require_relative '../bar' | ||
require_relative '../bar' | ||
^^^^^^^^^^^^^^^^^^^^^^^^^ Duplicate `require_relative` detected. | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when duplicate `require` through `Kernel` is detected' do | ||
expect_offense(<<~RUBY) | ||
require 'foo' | ||
Kernel.require 'foo' | ||
^^^^^^^^^^^^^^^^^^^^ Duplicate `require` detected. | ||
RUBY | ||
end | ||
|
||
it 'registers an offense for multiple duplicate requires' do | ||
expect_offense(<<~RUBY) | ||
require 'foo' | ||
require_relative '../bar' | ||
require 'foo/baz' | ||
require_relative '../bar' | ||
^^^^^^^^^^^^^^^^^^^^^^^^^ Duplicate `require_relative` detected. | ||
Kernel.require 'foo' | ||
^^^^^^^^^^^^^^^^^^^^ Duplicate `require` detected. | ||
require 'quux' | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when duplicate requires are interleaved with some other code' do | ||
expect_offense(<<~RUBY) | ||
require 'foo' | ||
def m | ||
end | ||
require 'foo' | ||
^^^^^^^^^^^^^ Duplicate `require` detected. | ||
RUBY | ||
end | ||
|
||
it 'registers an offense for duplicate non top-level requires' do | ||
expect_offense(<<~RUBY) | ||
def m | ||
require 'foo' | ||
require 'foo' | ||
^^^^^^^^^^^^^ Duplicate `require` detected. | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when there are no duplicate `require`s' do | ||
expect_no_offenses(<<~RUBY) | ||
require 'foo' | ||
require 'bar' | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using single `require`' do | ||
expect_no_offenses(<<~RUBY) | ||
require 'foo' | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when calling user-defined `require` method' do | ||
expect_no_offenses(<<~RUBY) | ||
params.require(:user) | ||
params.require(:user) | ||
RUBY | ||
end | ||
end |