Skip to content

Commit

Permalink
Add configuration option IgnoreMetadata
Browse files Browse the repository at this point in the history
  • Loading branch information
ydah committed Aug 25, 2023
1 parent cc4beae commit 40467ef
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 46 deletions.
2 changes: 2 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,8 @@ RSpec/SpecFilePathFormat:
RuboCop: rubocop
RSpec: rspec
IgnoreMethods: false
IgnoreMetadata:
type: routing
VersionAdded: "<<next>>"
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SpecFilePathFormat

Expand Down
12 changes: 12 additions & 0 deletions docs/modules/ROOT/pages/cops_rspec.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5078,6 +5078,14 @@ my_class_spec.rb # describe MyClass, '#method'
my_class_spec.rb # describe MyClass, '#method'
----

==== `IgnoreMetadata: {type=>routing}` (default)

[source,ruby]
----
# good
whatever_spec.rb # describe MyClass, type: :routing do; end
----

=== Configurable attributes

|===
Expand All @@ -5098,6 +5106,10 @@ my_class_spec.rb # describe MyClass, '#method'
| IgnoreMethods
| `false`
| Boolean

| IgnoreMetadata
| `{"type"=>"routing"}`
|
|===

=== References
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop-rspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# Dependent on `RuboCop::RSpec::Language::NodePattern`.
require_relative 'rubocop/rspec/language'

require_relative 'rubocop/cop/rspec/mixin/file_help'
require_relative 'rubocop/cop/rspec/mixin/final_end_location'
require_relative 'rubocop/cop/rspec/mixin/inside_example_group'
require_relative 'rubocop/cop/rspec/mixin/location_help'
Expand Down
14 changes: 14 additions & 0 deletions lib/rubocop/cop/rspec/mixin/file_help.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module RuboCop
module Cop
module RSpec
# Help methods for file.
module FileHelp
def expanded_file_path
File.expand_path(processed_source.file_path)
end
end
end
end
end
29 changes: 19 additions & 10 deletions lib/rubocop/cop/rspec/spec_file_path_format.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@ module RSpec
# # good
# my_class_spec.rb # describe MyClass, '#method'
#
# @example `IgnoreMetadata: {type=>routing}` (default)
# # good
# whatever_spec.rb # describe MyClass, type: :routing do; end
#
class SpecFilePathFormat < Base
include TopLevelGroup
include Namespace
include FileHelp

MSG = 'Spec path should end with `%<suffix>s`.'

Expand All @@ -39,22 +44,22 @@ class SpecFilePathFormat < Base
(block (send #rspec? #ExampleGroups.all $_ $...) ...)
PATTERN

# @!method routing_metadata?(node)
def_node_search :routing_metadata?, '(pair (sym :type) (sym :routing))'
# @!method metadata_key_value(node)
def_node_search :metadata_key_value, '(pair (sym $_key) (sym $_value))'

def on_top_level_example_group(node)
return unless top_level_groups.one?

example_group_arguments(node) do |class_name, arguments|
next if !class_name.const_type? || ignore_metadata?(arguments)

ensure_correct_file_path(class_name, arguments)
end
end

private

def ensure_correct_file_path(class_name, arguments)
return if !class_name.const_type? || routing_spec?(arguments)

pattern = correct_path_pattern(class_name, arguments)
return if filename_ends_with?(pattern)

Expand All @@ -65,8 +70,12 @@ def ensure_correct_file_path(class_name, arguments)
add_global_offense(format(MSG, suffix: suffix))
end

def routing_spec?(arguments)
arguments.any?(&method(:routing_metadata?))
def ignore_metadata?(arguments)
arguments.any? do |argument|
metadata_key_value(argument).any? do |key, value|
ignore_metadata.values_at(key.to_s).include?(value.to_s)
end
end
end

def correct_path_pattern(class_name, arguments)
Expand Down Expand Up @@ -111,12 +120,12 @@ def ignore_methods?
cop_config['IgnoreMethods']
end

def filename_ends_with?(pattern)
expanded_file_path.match?("#{pattern}$")
def ignore_metadata
cop_config.fetch('IgnoreMetadata', {})
end

def expanded_file_path
File.expand_path(processed_source.file_path)
def filename_ends_with?(pattern)
expanded_file_path.match?("#{pattern}$")
end
end
end
Expand Down
5 changes: 1 addition & 4 deletions lib/rubocop/cop/rspec/spec_file_path_suffix.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module RSpec
#
class SpecFilePathSuffix < Base
include TopLevelGroup
include FileHelp

MSG = 'Spec path should end with `_spec.rb`.'

Expand All @@ -33,10 +34,6 @@ def on_top_level_example_group(node)
def correct_path?
expanded_file_path.end_with?('_spec.rb')
end

def expanded_file_path
File.expand_path(processed_source.file_path)
end
end
end
end
Expand Down
29 changes: 10 additions & 19 deletions spec/rubocop/cop/rspec/spec_file_path_format_spec.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::SpecFilePathFormat, :config do
def expect_global_offense(source, file = nil, message = '')
processed_source = parse_source(source, file)
offenses = _investigate(cop, processed_source)
expect(offenses.size).to eq(1)
expect(offenses.first.message).to eq(message)
end

def expect_no_global_offenses(source, file = nil)
processed_source = parse_source(source, file)
offenses = _investigate(cop, processed_source)
expect(offenses.size).to eq(0)
end

let(:message) { "Spec path should end with `#{suffix}`." }
let(:suffix) { 'my_class*foo*_spec.rb' }

Expand Down Expand Up @@ -320,12 +307,6 @@ class Foo
describe FooFoo::Some::Class, '#bar' do; end
RUBY
end

it 'does not register an offense for routing specs' do
expect_no_global_offenses(<<-RUBY, 'foofoo/some/class/bar_spec.rb')
describe MyController, "#foo", type: :routing do; end
RUBY
end
end

context 'when configured with `IgnoreMethods: false`' do
Expand All @@ -352,4 +333,14 @@ class Foo
end
end
end

context 'when configured with `IgnoreMetadata: { "foo" => "bar" }`' do
let(:cop_config) { { 'IgnoreMetadata' => { 'foo' => 'bar' } } }

it 'does not register an offense' do
expect_no_global_offenses(<<-RUBY, 'wrong_class_spec.rb')
describe MyClass, foo: :bar do; end
RUBY
end
end
end
13 changes: 0 additions & 13 deletions spec/rubocop/cop/rspec/spec_file_path_suffix_spec.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::SpecFilePathSuffix do
def expect_global_offense(source, file = nil, message = '')
processed_source = parse_source(source, file)
offenses = _investigate(cop, processed_source)
expect(offenses.size).to eq(1)
expect(offenses.first.message).to eq(message)
end

def expect_no_global_offenses(source, file = nil)
processed_source = parse_source(source, file)
offenses = _investigate(cop, processed_source)
expect(offenses.size).to eq(0)
end

let(:message) { 'Spec path should end with `_spec.rb`.' }

it 'registers an offense for a repeated .rb' do
Expand Down
13 changes: 13 additions & 0 deletions spec/support/expect_offense.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,17 @@ def expect_no_offenses(source, filename = inspected_source_filename)
def inspected_source_filename
DEFAULT_FILENAME
end

def expect_global_offense(source, file = nil, message = '')
processed_source = parse_source(source, file)
offenses = _investigate(cop, processed_source)
expect(offenses.size).to eq(1)
expect(offenses.first.message).to eq(message)
end

def expect_no_global_offenses(source, file = nil)
processed_source = parse_source(source, file)
offenses = _investigate(cop, processed_source)
expect(offenses.size).to eq(0)
end
end

0 comments on commit 40467ef

Please sign in to comment.