Skip to content

Commit

Permalink
[Fix rubocop#10857] Add AllowedPatterns to Style/NumericLiterals.
Browse files Browse the repository at this point in the history
  • Loading branch information
dvandersluis committed Aug 6, 2022
1 parent 8ccd832 commit 3a267fe
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 2 deletions.
1 change: 1 addition & 0 deletions changelog/change_add_allowedpatterns_to.md
@@ -0,0 +1 @@
* [#10857](https://github.com/rubocop/rubocop/issues/10857): Add `AllowedPatterns` to `Style/NumericLiterals`. ([@dvandersluis][])
1 change: 1 addition & 0 deletions config/default.yml
Expand Up @@ -4405,6 +4405,7 @@ Style/NumericLiterals:
Strict: false
# You can specify allowed numbers. (e.g. port number 3000, 8080, and etc)
AllowedNumbers: []
AllowedPatterns: []

Style/NumericPredicate:
Description: >-
Expand Down
17 changes: 16 additions & 1 deletion lib/rubocop/cop/style/numeric_literals.rb
Expand Up @@ -3,9 +3,17 @@
module RuboCop
module Cop
module Style
# Checks for big numeric literals without _ between groups
# Checks for big numeric literals without `_` between groups
# of digits in them.
#
# Additional allowed patterns can be added by adding regexps to
# the `AllowedPatterns` configuration. All regexps are treated
# as anchored even if the patterns do not contain anchors (so
# `\d{4}_\d{4}` will allow `1234_5678` but not `1234_5678_9012`).
#
# NOTE: Even if `AllowedPatterns` are given, autocorrection will
# only correct to the standard pattern of an `_` every 3 digits.
#
# @example
#
# # bad
Expand Down Expand Up @@ -34,6 +42,7 @@ module Style
#
class NumericLiterals < Base
include IntegerNode
include AllowedPattern
extend AutoCorrector

MSG = 'Use underscores(_) as thousands separator and separate every 3 digits with them.'
Expand All @@ -59,6 +68,7 @@ def check(node)
# TODO: handle non-decimal literals as well
return if int.start_with?('0')
return if allowed_numbers.include?(int)
return if matches_allowed_pattern?(int)
return unless int.size >= min_digits

case int
Expand Down Expand Up @@ -108,6 +118,11 @@ def min_digits
def allowed_numbers
cop_config.fetch('AllowedNumbers', []).map(&:to_s)
end

def allowed_patterns
# Convert the patterns to be anchored
super.map { |regexp| Regexp.new(/\A#{regexp}\z/) }
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cli/auto_gen_config_spec.rb
Expand Up @@ -379,7 +379,7 @@ def f
'',
'# Offense count: 1',
'# This cop supports safe autocorrection (--autocorrect).',
'# Configuration parameters: Strict, AllowedNumbers.',
'# Configuration parameters: Strict, AllowedNumbers, AllowedPatterns.',
'Style/NumericLiterals:',
' MinDigits: 7',
'',
Expand Down
38 changes: 38 additions & 0 deletions spec/rubocop/cop/style/numeric_literals_spec.rb
Expand Up @@ -253,4 +253,42 @@
RUBY
end
end

context 'AllowedPatterns' do
let(:cop_config) { { 'AllowedPatterns' => [/\d{2}_\d{2}_\d{4}/] } }

it 'does not register an offense for numbers that exactly match the pattern' do
expect_no_offenses(<<~RUBY)
12_34_5678
RUBY
end

it 'registers an offense for numbers that do not exactly match the pattern' do
expect_offense(<<~RUBY)
1234_56_78_9012
^^^^^^^^^^^^^^^ Use underscores(_) as thousands separator and separate every 3 digits with them.
RUBY
end

it 'corrects by inserting underscores every 3 digits' do
expect_offense(<<~RUBY)
12345678
^^^^^^^^ Use underscores(_) as thousands separator and separate every 3 digits with them.
RUBY

expect_correction(<<~RUBY)
12_345_678
RUBY
end

context 'AllowedPatterns with repetition' do
let(:cop_config) { { 'AllowedPatterns' => [/\d{4}(_\d{4})+/] } }

it 'does not register an offense for numbers that match the pattern' do
expect_no_offenses(<<~RUBY)
1234_5678_9012_3456
RUBY
end
end
end
end

0 comments on commit 3a267fe

Please sign in to comment.