Skip to content

Commit

Permalink
Add configuration option CustomTransformPatterns to `RSpec/SpecFile…
Browse files Browse the repository at this point in the history
…PathFormat`
  • Loading branch information
ydah committed Dec 6, 2023
1 parent 9d51eb0 commit 3bf2f8b
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Master (Unreleased)

- Add configuration option `CustomTransformPatterns` to `RSpec/SpecFilePathFormat`. ([@ydah])

## 2.25.0 (2023-10-27)

- Add support single quoted string and percent string and heredoc for `RSpec/Rails/HttpStatus`. ([@ydah])
Expand Down
4 changes: 3 additions & 1 deletion config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -863,13 +863,15 @@ RSpec/SpecFilePathFormat:
- "**/*_spec.rb"
Exclude:
- "**/spec/routing/**/*"
CustomTransform:
CustomTransform: {}
CustomTransformPatterns:
RuboCop: rubocop
RSpec: rspec
IgnoreMethods: false
IgnoreMetadata:
type: routing
VersionAdded: '2.24'
VersionChanged: "<<next>>"
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SpecFilePathFormat

RSpec/SpecFilePathSuffix:
Expand Down
24 changes: 23 additions & 1 deletion docs/modules/ROOT/pages/cops_rspec.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5127,7 +5127,7 @@ it 'works', :a, :b, baz: true, foo: 'bar'
| Yes
| No
| 2.24
| -
| <<next>>
|===

Checks that spec file paths are consistent and well-formed.
Expand Down Expand Up @@ -5155,6 +5155,24 @@ rubocop_spec.rb # describe RuboCop
rspec_spec.rb # describe RSpec
----

==== `CustomTransformPatterns: {}` (default)

[source,ruby]
----
# bad
rspec_spec.rb # describe RSpec
rspec_class_spec.rb # describe RSpecClass
----

==== `CustomTransformPatterns: {RSpec=>rspec}`

[source,ruby]
----
# good
rspec_spec.rb # describe RSpec
rspec_class_spec.rb # describe RSpecClass
----

==== `IgnoreMethods: false` (default)

[source,ruby]
Expand Down Expand Up @@ -5196,6 +5214,10 @@ whatever_spec.rb # describe MyClass, type: :routing do; end
| `{"RuboCop"=>"rubocop", "RSpec"=>"rspec"}`
|

| CustomTransformPatterns
| `{}`
|

| IgnoreMethods
| `false`
| Boolean
Expand Down
22 changes: 22 additions & 0 deletions lib/rubocop/cop/rspec/spec_file_path_format.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ module RSpec
# rubocop_spec.rb # describe RuboCop
# rspec_spec.rb # describe RSpec
#
# @example `CustomTransformPatterns: {}` (default)
# # bad
# rspec_spec.rb # describe RSpec
# rspec_class_spec.rb # describe RSpecClass
#
# @example `CustomTransformPatterns: {RSpec=>rspec}`
# # good
# rspec_spec.rb # describe RSpec
# rspec_class_spec.rb # describe RSpecClass
#
# @example `IgnoreMethods: false` (default)
# # bad
# my_class_spec.rb # describe MyClass, '#method'
Expand Down Expand Up @@ -100,11 +110,19 @@ def expected_path(constant)

File.join(
constants.map do |name|
pattern, transformed = transformed_pattern(name)
name.gsub!(pattern, transformed) if transformed
custom_transform.fetch(name) { camel_to_snake_case(name) }
end
)
end

def transformed_pattern(name)
custom_transform_patterns.find do |pattern, _|
name.include?(pattern)
end
end

def camel_to_snake_case(string)
string
.gsub(/([^A-Z])([A-Z]+)/, '\1_\2')
Expand All @@ -116,6 +134,10 @@ def custom_transform
cop_config.fetch('CustomTransform', {})
end

def custom_transform_patterns
cop_config.fetch('CustomTransformPatterns', {})
end

def ignore_methods?
cop_config['IgnoreMethods']
end
Expand Down
59 changes: 53 additions & 6 deletions spec/rubocop/cop/rspec/spec_file_path_format_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -233,19 +233,66 @@ class Foo
RUBY
end

context 'when configured with `CustomTransform: { "FooFoo" => "foofoo" }`' do
let(:cop_config) { { 'CustomTransform' => { 'FooFoo' => 'foofoo' } } }
context 'when configured with `CustomTransform: { "RSpec" => "rspec" }`' do
let(:cop_config) do
{
'CustomTransform' => { 'RSpec' => 'rspec' },
'CustomTransformPatterns' => {}
}
end

it 'registers an offense when not an exact match to custom ' \
'module name transformation' do
expect_offense(<<-RUBY, 'rspec_foo_spec.rb')
RSpec.describe RSpecFoo do; end
^^^^^^^^^^^^^^^^^^^^^^^ Spec path should end with `r_spec_foo*_spec.rb`.
RUBY
end

it 'registers an offense when not an exact match to custom ' \
'module name transformation with nested directories' do
expect_offense(<<-RUBY, 'foo/some/rspec_foo/bar_spec.rb')
describe Foo::Some::RSpecFoo, '#bar' do; end
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Spec path should end with `foo/some/r_spec_foo*bar*_spec.rb`.
RUBY
end

it 'does not register an offense when an exact match to custom ' \
'module name transformation' do
expect_no_offenses(<<-RUBY, 'rspec/some/foo/bar_spec.rb')
describe RSpec::Some::Foo, '#bar' do; end
RUBY
end
end

context 'when configured with `CustomTransformPatterns: ' \
'{ "RSpec" => "rspec" }`' do
let(:cop_config) { { 'CustomTransformPatterns' => { 'RSpec' => 'rspec' } } }

it 'does not register an offense when not an exact match to custom ' \
'module name transformation' do
expect_no_offenses(<<-RUBY, 'foo/some/rspec_foo/bar_spec.rb')
describe Foo::Some::RSpecFoo, '#bar' do; end
RUBY
end

it 'does not register an offense when an exact match to custom ' \
'module name transformation' do
expect_no_offenses(<<-RUBY, 'rspec_foo_spec.rb')
RSpec.describe RSpecFoo do; end
RUBY
end

it 'does not register an offense for custom module name transformation' do
expect_no_offenses(<<-RUBY, 'foofoo/some/class/bar_spec.rb')
describe FooFoo::Some::Class, '#bar' do; end
it 'does not register an offense when an exact match to custom ' \
'module name transformation with nested directories' do
expect_no_offenses(<<-RUBY, 'rspec/some/foo/bar_spec.rb')
describe RSpec::Some::Foo, '#bar' do; end
RUBY
end
end

context 'when configured with `IgnoreMethods: false`' do
let(:cop_config) { { 'IgnoreMethods' => false } }
let(:suffix) { 'my_class*look_here_a_method*_spec.rb' }

it 'registers an offense when file path not include method name' do
expect_offense(<<-RUBY, 'my_class_spec.rb')
Expand Down

0 comments on commit 3bf2f8b

Please sign in to comment.