From c4646ff66d3944e890c2b4f75a5384ce6a6de96f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Topalovi=C4=87?= Date: Wed, 9 Jun 2021 13:06:29 +0200 Subject: [PATCH] Make FilePath check suffix when given a non-const top-level node This helps with the standard feature format: RSpec.feature "Some feature" do; end --- CHANGELOG.md | 2 ++ lib/rubocop/cop/rspec/file_path.rb | 22 ++++++++++++---------- spec/rubocop/cop/rspec/file_path_spec.rb | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc79a1567..c9391aa1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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][]) @@ -621,3 +622,4 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features. [@Tietew]: https://github.com/Tietew [@rrosenblum]: https://github.com/rrosenblum [@paydaylight]: https://github.com/paydaylight +[@topalovic]: https://github.com/topalovic diff --git a/lib/rubocop/cop/rspec/file_path.rb b/lib/rubocop/cop/rspec/file_path.rb index 4bf70ae89..c2ab8f584 100644 --- a/lib/rubocop/cop/rspec/file_path.rb +++ b/lib/rubocop/cop/rspec/file_path.rb @@ -61,10 +61,10 @@ class FilePath < Base MSG = 'Spec path should end with `%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 @@ -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 @@ -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 diff --git a/spec/rubocop/cop/rspec/file_path_spec.rb b/spec/rubocop/cop/rspec/file_path_spec.rb index eaae94a5d..68dfeb2e4 100644 --- a/spec/rubocop/cop/rspec/file_path_spec.rb +++ b/spec/rubocop/cop/rspec/file_path_spec.rb @@ -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 @@ -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