Skip to content

Commit

Permalink
Add SpecSuffixOnly option to RSpec/FilePath cop
Browse files Browse the repository at this point in the history
which ensures spec files end with *_spec.rb but does not care about the path, described class, or described method leading up to it.
  • Loading branch information
zdennis committed May 19, 2020
1 parent 1a9af87 commit bffe20f
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Add new `RSpec/VariableName` cop. ([@tejasbubane][])
* Add new `RSpec/VariableDefinition` cop. ([@tejasbubane][])
* Expand `Capybara/VisibilityMatcher` to support more than just `have_selector`. ([@twalpole][])
* Add new `SpecSuffixOnly` option to `RSpec/FilePath` cop. ([@zdennis][])

## 1.39.0 (2020-05-01)

Expand Down Expand Up @@ -508,3 +509,4 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
[@AlexWayfer]: https://github.com/AlexWayfer
[@tejasbubane]: https://github.com/tejasbubane
[@twalpole]: https://github.com/twalpole
[@zdennis]: https://github.com/zdennis
3 changes: 2 additions & 1 deletion config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,13 @@ RSpec/ExpectOutput:
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExpectOutput

RSpec/FilePath:
Description: Checks that spec file paths are consistent with the test subject.
Description: Checks that spec file paths are consistent and well-formed.
Enabled: true
CustomTransform:
RuboCop: rubocop
RSpec: rspec
IgnoreMethods: false
SpecSuffixOnly: false
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FilePath

RSpec/Focus:
Expand Down
31 changes: 28 additions & 3 deletions lib/rubocop/cop/rspec/file_path.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
module RuboCop
module Cop
module RSpec
# Checks that spec file paths are consistent with the test subject.
# Checks that spec file paths are consistent and well-formed.
#
# Checks the path of the spec file and enforces that it reflects the
# described class/module and its optionally called out method.
# By default, this checks that spec file paths are consistent with the
# test subject and and enforces that it reflects the described
# class/module and its optionally called out method.
#
# With the configuration option `IgnoreMethods` the called out method will
# be ignored when determining the enforced path.
Expand All @@ -15,6 +16,10 @@ module RSpec
# be specified that should not as usual be transformed from CamelCase to
# snake_case (e.g. 'RuboCop' => 'rubocop' ).
#
# With the configuration option `SpecSuffixOnly` test files will only
# be checked to ensure they end in '_spec.rb'. This option disables
# checking for consistency in the test subject or test methods.
#
# @example
# # bad
# whatever_spec.rb # describe MyClass
Expand All @@ -41,6 +46,16 @@ module RSpec
# # good
# my_class_spec.rb # describe MyClass, '#method'
#
# @example when configuration is `SpecSuffixOnly: true`
# # good
# whatever_spec.rb # describe MyClass
#
# # good
# my_class_spec.rb # describe MyClass
#
# # good
# my_class_spec.rb # describe MyClass, '#method'
#
class FilePath < Cop
include RuboCop::RSpec::TopLevelDescribe

Expand Down Expand Up @@ -70,9 +85,15 @@ def routing_spec?(args)
end

def glob_for((described_class, method_name))
return glob_for_spec_suffix_only? if spec_suffix_only?

"#{expected_path(described_class)}#{name_glob(method_name)}*_spec.rb"
end

def glob_for_spec_suffix_only?
'*_spec.rb'
end

def name_glob(name)
return unless name&.str_type?

Expand Down Expand Up @@ -111,6 +132,10 @@ def filename_ends_with?(glob)
def relevant_rubocop_rspec_file?(_file)
true
end

def spec_suffix_only?
cop_config['SpecSuffixOnly']
end
end
end
end
Expand Down
24 changes: 21 additions & 3 deletions manual/cops_rspec.md
Original file line number Diff line number Diff line change
Expand Up @@ -1164,10 +1164,11 @@ Enabled by default | Supports autocorrection
--- | ---
Enabled | No

Checks that spec file paths are consistent with the test subject.
Checks that spec file paths are consistent and well-formed.

Checks the path of the spec file and enforces that it reflects the
described class/module and its optionally called out method.
By default, this checks that spec file paths are consistent with the
test subject and and enforces that it reflects the described
class/module and its optionally called out method.

With the configuration option `IgnoreMethods` the called out method will
be ignored when determining the enforced path.
Expand All @@ -1176,6 +1177,10 @@ With the configuration option `CustomTransform` modules or classes can
be specified that should not as usual be transformed from CamelCase to
snake_case (e.g. 'RuboCop' => 'rubocop' ).

With the configuration option `SpecSuffixOnly` test files will only
be checked to ensure they end in '_spec.rb'. This option disables
checking for consistency in the test subject or test methods.

### Examples

```ruby
Expand Down Expand Up @@ -1203,6 +1208,18 @@ whatever_spec.rb # describe MyClass
# good
my_class_spec.rb # describe MyClass

# good
my_class_spec.rb # describe MyClass, '#method'
```
#### when configuration is `SpecSuffixOnly: true`

```ruby
# good
whatever_spec.rb # describe MyClass

# good
my_class_spec.rb # describe MyClass

# good
my_class_spec.rb # describe MyClass, '#method'
```
Expand All @@ -1213,6 +1230,7 @@ Name | Default value | Configurable values
--- | --- | ---
CustomTransform | `{"RuboCop"=>"rubocop", "RSpec"=>"rspec"}` |
IgnoreMethods | `false` | Boolean
SpecSuffixOnly | `false` | Boolean

### References

Expand Down
17 changes: 17 additions & 0 deletions spec/rubocop/cop/rspec/file_path_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,21 @@
RUBY
end
end

context 'when configured with SpecSuffixOnly' do
let(:cop_config) { { 'SpecSuffixOnly' => true } }

it 'does not care about the described class' do
expect_no_offenses(<<-RUBY, 'whatever_spec.rb')
describe MyClass do; end
RUBY
end

it 'registers an offense when _spec.rb suffix is missing' do
expect_offense(<<-RUBY, 'whatever.rb')
describe MyClass do; end
^^^^^^^^^^^^^^^^ Spec path should end with `*_spec.rb`.
RUBY
end
end
end

0 comments on commit bffe20f

Please sign in to comment.