Skip to content

Commit

Permalink
Merge pull request #9363 from uplus/add-new-cop-or_assignment_to_cons…
Browse files Browse the repository at this point in the history
…tant

Add new cop `Lint/OrAssignmentToConstant`
  • Loading branch information
dvandersluis committed Jan 15, 2021
2 parents be0ff6a + 93a7e0d commit b72ae11
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -5366,3 +5366,4 @@
[@ohbarye]: https://github.com/ohbarye
[@magneland]: https://github.com/magneland
[@k-karen]: https://github.com/k-karen
[@uplus]: https://github.com/uplus
1 change: 1 addition & 0 deletions changelog/new_add_new_cop_lintorassignmenttoconstant.md
@@ -0,0 +1 @@
* [#9363](https://github.com/rubocop-hq/rubocop/pull/9363): Add new cop `Lint/OrAssignmentToConstant`. ([@uplus][])
6 changes: 6 additions & 0 deletions config/default.yml
Expand Up @@ -1811,6 +1811,12 @@ Lint/NumberedParameterAssignment:
Enabled: pending
VersionAdded: '<<next>>'

Lint/OrAssignmentToConstant:
Description: 'Checks unintended or-assignment to constant.'
Enabled: pending
Safe: false
VersionAdded: '<<next>>'

Lint/OrderedMagicComments:
Description: 'Checks the proper ordering of magic comments and whether a magic comment is not placed before a shebang.'
Enabled: true
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop.rb
Expand Up @@ -313,6 +313,7 @@
require_relative 'rubocop/cop/lint/non_local_exit_from_iterator'
require_relative 'rubocop/cop/lint/number_conversion'
require_relative 'rubocop/cop/lint/numbered_parameter_assignment'
require_relative 'rubocop/cop/lint/or_assignment_to_constant'
require_relative 'rubocop/cop/lint/ordered_magic_comments'
require_relative 'rubocop/cop/lint/out_of_range_regexp_ref'
require_relative 'rubocop/cop/lint/parentheses_as_grouped_expression'
Expand Down
39 changes: 39 additions & 0 deletions lib/rubocop/cop/lint/or_assignment_to_constant.rb
@@ -0,0 +1,39 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Lint
# This cop checks for unintended or-assignment to a constant.
#
# Constants should always be assigned in the same location. And its value
# should always be the same. If constants are assigned in multiple
# locations, the result may vary depending on the order of `require`.
#
# Also, if you already have such an implementation, auto-correction may
# change the result.
#
# @example
#
# # bad
# CONST ||= 1
#
# # good
# CONST = 1
#
class OrAssignmentToConstant < Base
extend AutoCorrector

MSG = 'Avoid using or-assignment with constants.'

def on_or_asgn(node)
lhs, _rhs = *node
return unless lhs&.casgn_type?

add_offense(node.loc.operator) do |corrector|
corrector.replace(node.loc.operator, '=')
end
end
end
end
end
end
36 changes: 36 additions & 0 deletions spec/rubocop/cop/lint/or_assignment_to_constant_spec.rb
@@ -0,0 +1,36 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Lint::OrAssignmentToConstant, :config do
subject(:cop) { described_class.new(config) }

it 'registers an offense with or-assignment to a constant' do
expect_offense(<<~RUBY)
CONST ||= 1
^^^ Avoid using or-assignment with constants.
RUBY

expect_correction(<<~RUBY)
CONST = 1
RUBY
end

it 'does not register an offense with plain assignment to a constant' do
expect_no_offenses(<<~RUBY)
CONST = 1
RUBY
end

[
['a local variable', 'var'],
['an instance variable', '@var'],
['a class variable', '@@var'],
['a global variable', '$var'],
['an attribute', 'self.var']
].each do |type, var|
it "does not register an offense with or-assignment to #{type}" do
expect_no_offenses(<<~RUBY)
#{var} ||= 1
RUBY
end
end
end

0 comments on commit b72ae11

Please sign in to comment.