Skip to content

Commit

Permalink
Add new option to Naming/VariableNumber snake_case
Browse files Browse the repository at this point in the history
Fix rubocop#10539

Adds a new integer option called `MaxAllowedLettersBeforeNumber` to
allow a positive number of non-digits before the digits in a snake_case
style that would otherwise require separation between them, e.g. `_v1`.
  • Loading branch information
henrahmagix committed Apr 15, 2022
1 parent 523ccba commit e8643c3
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog/new_add_new_option_to_namingvariablenumber.md
@@ -0,0 +1 @@
* [#10539](https://github.com/rubocop/rubocop/issues/10539): Add new MaxAllowedLettersBeforeNumber option to Naming/VariableNumber snake_case. ([@henrahmagix][])
1 change: 1 addition & 0 deletions config/default.yml
Expand Up @@ -2787,6 +2787,7 @@ Naming/VariableNumber:
- rfc822 # Time#rfc822
- rfc2822 # Time#rfc2822
- rfc3339 # DateTime.rfc3339
MaxAllowedLettersBeforeNumber: 0

#################### Security ##############################

Expand Down
13 changes: 13 additions & 0 deletions lib/rubocop/cop/naming/variable_number.rb
Expand Up @@ -102,6 +102,19 @@ class VariableNumber < Base

MSG = 'Use %<style>s for %<identifier_type>s numbers.'

def max_allowed_letters_before_number
cop_config.fetch('MaxAllowedLettersBeforeNumber', 0)
end

def valid_name?(node, name, given_style = style)
return true if super

return false unless given_style == :snake_case
return false unless max_allowed_letters_before_number.to_i.positive?

name.match?(/(?:_|\b)\D{0,#{max_allowed_letters_before_number}}\d+\z/)
end

def on_arg(node)
@node = node
name, = *node
Expand Down
103 changes: 103 additions & 0 deletions spec/rubocop/cop/naming/variable_number_spec.rb
Expand Up @@ -33,6 +33,14 @@
end
end

shared_examples 'accepts_array' do |style, variables|
it "accepts #{variables} in #{style}" do
lines = variables.map { |v| "#{v} = 1" }

expect_no_offenses(lines.join("\n"), first_variable: variables.first)
end
end

shared_examples 'accepts integer symbols' do
it 'accepts integer symbol' do
expect_no_offenses(':"42"')
Expand All @@ -54,6 +62,70 @@
it_behaves_like 'offense', 'snake_case', '_unused1', :normalcase
it_behaves_like 'offense', 'snake_case', 'aB1', :normalcase
it_behaves_like 'offense_array', 'snake_case', %w[a1 a_2]
it_behaves_like 'offense', 'snake_case', 'v1', :normalcase
it_behaves_like 'offense', 'snake_case', '_v1', :normalcase

it_behaves_like 'accepts', 'snake_case', 'local_1'
it_behaves_like 'accepts', 'snake_case', 'local_12'
it_behaves_like 'accepts', 'snake_case', 'local_123'
it_behaves_like 'accepts', 'snake_case', 'local_'
it_behaves_like 'accepts', 'snake_case', 'aB_1'
it_behaves_like 'accepts', 'snake_case', 'a_1_b'
it_behaves_like 'accepts', 'snake_case', 'a_1_b_1'
it_behaves_like 'accepts', 'snake_case', '_'
it_behaves_like 'accepts', 'snake_case', '_foo'
it_behaves_like 'accepts', 'snake_case', '@foo'
it_behaves_like 'accepts', 'snake_case', '@__foo__'
it_behaves_like 'accepts', 'snake_case', 'emparejó'
it_behaves_like 'accepts', 'snake_case', '_1'

it_behaves_like 'accepts integer symbols'

it 'registers an offense for normal case numbering in symbol' do
expect_offense(<<~RUBY)
:sym1
^^^^^ Use snake_case for symbol numbers.
RUBY
end

it 'does not register an offense for snake case numbering in symbol' do
expect_no_offenses(<<~RUBY)
:sym_1
RUBY
end

it 'registers an offense for normal case numbering in method parameter' do
expect_offense(<<~RUBY)
def method(arg1); end
^^^^ Use snake_case for variable numbers.
RUBY
end

it 'registers an offense for normal case numbering in method camel case parameter' do
expect_offense(<<~RUBY)
def method(funnyArg1); end
^^^^^^^^^ Use snake_case for variable numbers.
RUBY
end

it 'registers an offense for normal case numbering in method name' do
expect_offense(<<~RUBY)
def method1; end
^^^^^^^ Use snake_case for method name numbers.
RUBY
end
end

context 'when configured for snake_case and MaxAllowedLettersBeforeNumber is set to 1' do
let(:cop_config) { { 'EnforcedStyle' => 'snake_case', 'MaxAllowedLettersBeforeNumber' => 1 } }

it_behaves_like 'offense', 'snake_case', 'local1', :normalcase
it_behaves_like 'offense', 'snake_case', '@local1', :normalcase
it_behaves_like 'offense', 'snake_case', '@@local1', :normalcase
it_behaves_like 'offense', 'snake_case', 'camelCase1', :normalcase
it_behaves_like 'offense', 'snake_case', '@camelCase1', :normalcase
it_behaves_like 'offense', 'snake_case', '_unused1', :normalcase
it_behaves_like 'offense', 'snake_case', 'aB1', :normalcase

it_behaves_like 'accepts', 'snake_case', 'local_1'
it_behaves_like 'accepts', 'snake_case', 'local_12'
Expand All @@ -68,6 +140,9 @@
it_behaves_like 'accepts', 'snake_case', '@__foo__'
it_behaves_like 'accepts', 'snake_case', 'emparejó'
it_behaves_like 'accepts', 'snake_case', '_1'
it_behaves_like 'accepts_array', 'snake_case', %w[a1 a_2]
it_behaves_like 'accepts', 'snake_case', 'v1'
it_behaves_like 'accepts', 'snake_case', '_v1'

it_behaves_like 'accepts integer symbols'

Expand All @@ -78,6 +153,12 @@
RUBY
end

it 'does not register an offense for normal case numbering in symbol with only 1 letter before the numbering' do
expect_no_offenses(<<~RUBY)
:s1
RUBY
end

it 'does not register an offense for snake case numbering in symbol' do
expect_no_offenses(<<~RUBY)
:sym_1
Expand All @@ -91,6 +172,12 @@ def method(arg1); end
RUBY
end

it 'does not register an offense for normal case numbering in method parameter with only 1 letter before the numbering' do
expect_no_offenses(<<~RUBY)
def method(a1); end
RUBY
end

it 'registers an offense for normal case numbering in method camel case parameter' do
expect_offense(<<~RUBY)
def method(funnyArg1); end
Expand All @@ -104,6 +191,22 @@ def method1; end
^^^^^^^ Use snake_case for method name numbers.
RUBY
end

it 'does not register an offense for normal case numbering in method name with only 1 letter before the numbering' do
expect_no_offenses(<<~RUBY)
def m1; end
RUBY
end
end

context 'when configured for snake_case and MaxAllowedLettersBeforeNumber is set to 8' do
let(:cop_config) { { 'EnforcedStyle' => 'snake_case', 'MaxAllowedLettersBeforeNumber' => 8 } }

it 'does not register an offense for normal case numbering in method camel case parameter with only 8 letters before the numbering' do
expect_no_offenses(<<~RUBY)
def method(funnyArg1); end
RUBY
end
end

context 'when configured for normal' do
Expand Down

0 comments on commit e8643c3

Please sign in to comment.