Skip to content

Commit

Permalink
Make FilePath check suffix when given a non-const top-level node
Browse files Browse the repository at this point in the history
This helps with the default feature format:

RSpec.feature "Some feature" do
end
  • Loading branch information
topalovic committed Jun 9, 2021
1 parent 0be6148 commit 4398429
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Master (Unreleased)

* Update `RSpec/FilePath` to check suffix when given a non-constant top-level node (e.g. features). ([@topalovic][])
* Add missing documentation for `single_statement_only` style of `RSpec/ImplicitSubject` cop. ([@tejasbubane][])
* Fix an exception in `DescribedClass` when accessing a constant on a variable in a spec that is nested in a namespace. ([@rrosenblum][])
* Add new `RSpec/IdenticalEqualityAssertion` cop. ([@tejasbubane][])
Expand Down
22 changes: 12 additions & 10 deletions lib/rubocop/cop/rspec/file_path.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ class FilePath < Base

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

# @!method const_described(node)
def_node_matcher :const_described, <<~PATTERN
# @!method example_group(node)
def_node_matcher :example_group, <<~PATTERN
(block
$(send #rspec? _example_group $(const ...) $...) ...
$(send #rspec? _example_group $(_ ...) $...) ...
)
PATTERN

Expand All @@ -74,17 +74,17 @@ class FilePath < Base
def on_top_level_example_group(node)
return unless top_level_groups.one?

const_described(node) do |send_node, described_class, arguments|
example_group(node) do |send_node, example_group, arguments|
next if routing_spec?(arguments)

ensure_correct_file_path(send_node, described_class, arguments)
ensure_correct_file_path(send_node, example_group, arguments)
end
end

private

def ensure_correct_file_path(send_node, described_class, arguments)
pattern = pattern_for(described_class, arguments.first)
def ensure_correct_file_path(send_node, example_group, arguments)
pattern = pattern_for(example_group, arguments.first)
return if filename_ends_with?(pattern)

# For the suffix shown in the offense message, modify the regular
Expand All @@ -99,11 +99,13 @@ def routing_spec?(args)
args.any?(&method(:routing_metadata?))
end

def pattern_for(described_class, method_name)
return pattern_for_spec_suffix_only? if spec_suffix_only?
def pattern_for(example_group, method_name)
if spec_suffix_only? || !example_group.const_type?
return pattern_for_spec_suffix_only?
end

[
expected_path(described_class),
expected_path(example_group),
name_pattern(method_name),
'[^/]*_spec\.rb'
].join
Expand Down
14 changes: 14 additions & 0 deletions spec/rubocop/cop/rspec/file_path_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@
RUBY
end

it 'registers an offense for a feature file missing _spec' do
expect_offense(<<-RUBY, 'spec/features/my_feature.rb')
feature "my feature" do; end
^^^^^^^^^^^^^^^^^^^^ Spec path should end with `*_spec.rb`.
RUBY
end

it 'registers an offense for a file without the .rb extension' do
expect_offense(<<-RUBY, 'spec/models/user_specxrb')
describe User do; end
Expand Down Expand Up @@ -265,6 +272,13 @@ class Foo
RUBY
end

it 'registers an offense when a feature file is missing _spec.rb suffix' do
expect_offense(<<-RUBY, 'spec/my_feature.rb')
feature "my feature" do; end
^^^^^^^^^^^^^^^^^^^^ Spec path should end with `*_spec.rb`.
RUBY
end

it 'registers an offense when the file extension is not .rb' do
expect_offense(<<-RUBY, 'whatever_specxrb')
describe MyClass do; end
Expand Down

0 comments on commit 4398429

Please sign in to comment.