Skip to content

Commit

Permalink
Merge pull request #987 from jtannas/Issue-941_ignore-variable-name-c…
Browse files Browse the repository at this point in the history
…onfig

[Fix #941] Add support for ignoring certain variables in RSpec/VariableName
  • Loading branch information
bquorning committed Aug 7, 2020
2 parents 38ef169 + 9759017 commit e1b688e
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 17 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -10,6 +10,7 @@
* Fix `RSpec/EmptyExampleGroup` to ignore examples groups with examples defined inside iterators. ([@pirj][])
* Improve `RSpec/NestedGroups`, `RSpec/FilePath`, `RSpec/DescribeMethod`, `RSpec/MultipleDescribes`, `RSpec/DescribeClass`'s top-level example group detection. ([@pirj][])
* Add detection of `let!` with a block-pass or a string literal to `RSpec/LetSetup`. ([@pirj][])
* Add `IgnoredPatterns` configuration option to `RSpec/VariableName`. ([@jtannas][])

## 1.42.0 (2020-07-09)

Expand Down Expand Up @@ -540,3 +541,4 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
[@harrylewis]: https://github.com/harrylewis
[@elliterate]: https://github.com/elliterate
[@mlarraz]: https://github.com/mlarraz
[@jtannas]: https://github.com/jtannas
2 changes: 2 additions & 0 deletions config/default.yml
Expand Up @@ -558,7 +558,9 @@ RSpec/VariableName:
SupportedStyles:
- snake_case
- camelCase
IgnoredPatterns: []
VersionAdded: '1.40'
VersionChanged: '1.43'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VariableName

RSpec/VerifiedDoubles:
Expand Down
35 changes: 27 additions & 8 deletions lib/rubocop/cop/rspec/variable_name.rb
Expand Up @@ -5,32 +5,51 @@ module Cop
module RSpec
# Checks that memoized helper names use the configured style.
#
# Variables can be excluded from checking using the `IgnoredPatterns`
# option.
#
# @example EnforcedStyle: snake_case (default)
# # bad
# let(:userName) { 'Adam' }
# subject(:userName) { 'Adam' }
# subject(:userName1) { 'Adam' }
# let(:userName2) { 'Adam' }
#
# # good
# let(:user_name) { 'Adam' }
# subject(:user_name) { 'Adam' }
# subject(:user_name_1) { 'Adam' }
# let(:user_name_2) { 'Adam' }
#
# @example EnforcedStyle: camelCase
# # bad
# let(:user_name) { 'Adam' }
# subject(:user_name) { 'Adam' }
# subject(:user_name_1) { 'Adam' }
# let(:user_name_2) { 'Adam' }
#
# # good
# let(:userName) { 'Adam' }
# subject(:userName) { 'Adam' }
# subject(:userName1) { 'Adam' }
# let(:userName2) { 'Adam' }
#
# @example IgnoredPatterns configuration
#
# # rubocop.yml
# # RSpec/VariableName:
# # EnforcedStyle: snake_case
# # IgnoredPatterns:
# # - ^userFood
#
# @example
# # okay because it matches the `^userFood` regex in `IgnoredPatterns`
# subject(:userFood_1) { 'spaghetti' }
# let(:userFood_2) { 'fettuccine' }
#
class VariableName < Base
include ConfigurableNaming
include IgnoredPattern
include RuboCop::RSpec::Variable

MSG = 'Use %<style>s for variable names.'

def on_send(node)
variable_definition?(node) do |variable|
return if variable.dstr_type? || variable.dsym_type?
return if matches_ignored_pattern?(variable.value)

check_name(node, variable.value, variable.loc.expression)
end
Expand Down
36 changes: 27 additions & 9 deletions manual/cops_rspec.md
Expand Up @@ -3075,40 +3075,58 @@ EnforcedStyle | `symbols` | `symbols`, `strings`

Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
--- | --- | --- | --- | ---
Enabled | Yes | No | 1.40 | -
Enabled | Yes | No | 1.40 | 1.43

Checks that memoized helper names use the configured style.

Variables can be excluded from checking using the `IgnoredPatterns`
option.

### Examples

#### EnforcedStyle: snake_case (default)

```ruby
# bad
let(:userName) { 'Adam' }
subject(:userName) { 'Adam' }
subject(:userName1) { 'Adam' }
let(:userName2) { 'Adam' }

# good
let(:user_name) { 'Adam' }
subject(:user_name) { 'Adam' }
subject(:user_name_1) { 'Adam' }
let(:user_name_2) { 'Adam' }
```
#### EnforcedStyle: camelCase

```ruby
# bad
let(:user_name) { 'Adam' }
subject(:user_name) { 'Adam' }
subject(:user_name_1) { 'Adam' }
let(:user_name_2) { 'Adam' }

# good
let(:userName) { 'Adam' }
subject(:userName) { 'Adam' }
subject(:userName1) { 'Adam' }
let(:userName2) { 'Adam' }
```
#### IgnoredPatterns configuration

```ruby
# rubocop.yml
# RSpec/VariableName:
# EnforcedStyle: snake_case
# IgnoredPatterns:
# - ^userFood
```
```ruby
# okay because it matches the `^userFood` regex in `IgnoredPatterns`
subject(:userFood_1) { 'spaghetti' }
let(:userFood_2) { 'fettuccine' }
```

### Configurable attributes

Name | Default value | Configurable values
--- | --- | ---
EnforcedStyle | `snake_case` | `snake_case`, `camelCase`
IgnoredPatterns | `[]` | Array

### References

Expand Down
20 changes: 20 additions & 0 deletions spec/rubocop/cop/rspec/variable_name_spec.rb
Expand Up @@ -188,4 +188,24 @@
end
end
end

context 'when configured to ignore certain patterns' do
let(:cop_config) do
{ 'EnforcedStyle' => 'snake_case',
'IgnoredPatterns' => ['^userFood$', '^userPet$'] }
end

it 'registers an offense when not matching any ignored patterns' do
expect_offense(<<~RUBY)
let(:userName) { 'Adam' }
^^^^^^^^^ Use snake_case for variable names.
RUBY
end

it 'does not register an offense when matching any ignored pattern' do
expect_no_offenses(<<~RUBY)
let(:userFood) { 'Adam' }
RUBY
end
end
end

0 comments on commit e1b688e

Please sign in to comment.