diff --git a/CHANGELOG.md b/CHANGELOG.md index 3266b77bb..82dc18170 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Master (Unreleased) - Fix false-negative and error for `RSpec/MetadataStyle` when non-literal args are used in metadata in `EnforceStyle: hash`. ([@cbliard]) +- Fix false negative for `RSpec/Dialect` when specified Capybara-specific methods. ([@sanfrecce-osaka]) ## 3.0.4 (2024-08-05) @@ -1004,6 +1005,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features. [@rspeicher]: https://github.com/rspeicher [@rst-j]: https://github.com/RST-J [@samrjenkins]: https://github.com/samrjenkins +[@sanfrecce-osaka]: https://github.com/sanfrecce-osaka [@schmijos]: https://github.com/schmijos [@seanpdoyle]: https://github.com/seanpdoyle [@sl4vr]: https://github.com/sl4vr diff --git a/lib/rubocop/cop/rspec/dialect.rb b/lib/rubocop/cop/rspec/dialect.rb index 5bc91f0cc..abd5d6d3e 100644 --- a/lib/rubocop/cop/rspec/dialect.rb +++ b/lib/rubocop/cop/rspec/dialect.rb @@ -58,14 +58,12 @@ module RSpec class Dialect < Base extend AutoCorrector include MethodPreference + include InsideExampleGroup MSG = 'Prefer `%s` over `%s`.' - # @!method rspec_method?(node) - def_node_matcher :rspec_method?, '(send #rspec? #ALL.all ...)' - def on_send(node) - return unless rspec_method?(node) + return unless inside_example_group?(node) return unless preferred_methods[node.method_name] msg = format(MSG, prefer: preferred_method(node.method_name), diff --git a/spec/rubocop/cop/rspec/dialect_spec.rb b/spec/rubocop/cop/rspec/dialect_spec.rb index 75ba063d0..5161a93f3 100644 --- a/spec/rubocop/cop/rspec/dialect_spec.rb +++ b/spec/rubocop/cop/rspec/dialect_spec.rb @@ -1,59 +1,186 @@ # frozen_string_literal: true RSpec.describe RuboCop::Cop::RSpec::Dialect do - let(:cop_config) do - { - 'PreferredMethods' => { - 'context' => 'describe' - } - } - end + context 'with preferred methods' do + context 'when `describe` is preferred to `context`' do + let(:cop_config) do + { + 'PreferredMethods' => { + 'context' => 'describe' + } + } + end - it 'allows describe blocks' do - expect_no_offenses(<<~RUBY) - describe 'display name presence' do + it 'allows describe blocks' do + expect_no_offenses(<<~RUBY) + RSpec.describe 'context' do + describe 'display name presence' do + end + end + RUBY end - RUBY - end - it 'allows calling methods named context in examples' do - expect_no_offenses(<<~RUBY) - it 'tests common context invocations' do - expect(request.context).to be_empty? + it 'registers an offense for context blocks' do + expect_offense(<<~RUBY) + RSpec.describe 'context' do + context 'display name presence' do + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `describe` over `context`. + end + end + RUBY + + expect_correction(<<~RUBY) + RSpec.describe 'context' do + describe 'display name presence' do + end + end + RUBY end - RUBY - end + end - it 'registers an offense for context blocks' do - expect_offense(<<~RUBY) - context 'display name presence' do - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `describe` over `context`. + context 'when `describe` is preferred to `feature`' do + let(:cop_config) do + { + 'PreferredMethods' => { + 'feature' => 'describe' + } + } end - RUBY - expect_correction(<<~RUBY) - describe 'display name presence' do + it 'allows describe blocks' do + expect_no_offenses(<<~RUBY) + RSpec.describe 'context' do + describe 'display name presence' do + end + end + RUBY end - RUBY - end - it 'registers an offense for RSpec.context blocks' do - expect_offense(<<~RUBY) - RSpec.context 'context' do - ^^^^^^^^^^^^^^^^^^^^^^^ Prefer `describe` over `context`. - it 'tests common context invocations' do - expect(request.context).to be_empty? - end + it 'registers an offense for feature blocks' do + expect_offense(<<~RUBY) + RSpec.describe 'context' do + feature 'display name presence' do + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `describe` over `feature`. + end + end + RUBY + + expect_correction(<<~RUBY) + RSpec.describe 'context' do + describe 'display name presence' do + end + end + RUBY end - RUBY + end - expect_correction(<<~RUBY) - RSpec.describe 'context' do - it 'tests common context invocations' do - expect(request.context).to be_empty? - end + context 'when `let` is preferred to `given`' do + let(:cop_config) do + { + 'PreferredMethods' => { + 'given' => 'let' + } + } + end + + it 'allows let blocks' do + expect_no_offenses(<<~RUBY) + RSpec.describe 'context' do + let do + end + end + RUBY end - RUBY + + it 'registers an offense for given blocks' do + expect_offense(<<~RUBY) + RSpec.describe 'context' do + given do + ^^^^^ Prefer `let` over `given`. + end + end + RUBY + + expect_correction(<<~RUBY) + RSpec.describe 'context' do + let do + end + end + RUBY + end + end + + context 'when `let!` is preferred to `given!`' do + let(:cop_config) do + { + 'PreferredMethods' => { + 'given!' => 'let!' + } + } + end + + it 'allows let! blocks' do + expect_no_offenses(<<~RUBY) + RSpec.describe 'context' do + let! do + end + end + RUBY + end + + it 'registers an offense for given! blocks' do + expect_offense(<<~RUBY) + RSpec.describe 'context' do + given! do + ^^^^^^ Prefer `let!` over `given!`. + end + end + RUBY + + expect_correction(<<~RUBY) + RSpec.describe 'context' do + let! do + end + end + RUBY + end + end + + context 'when `before` is preferred to `background`' do + let(:cop_config) do + { + 'PreferredMethods' => { + 'background' => 'before' + } + } + end + + it 'allows before blocks' do + expect_no_offenses(<<~RUBY) + RSpec.describe 'context' do + before do + end + end + RUBY + end + + it 'registers an offense for background blocks' do + expect_offense(<<~RUBY) + RSpec.describe 'context' do + background do + ^^^^^^^^^^ Prefer `before` over `background`. + end + end + RUBY + + expect_correction(<<~RUBY) + RSpec.describe 'context' do + before do + end + end + RUBY + end + end end context 'without preferred methods' do @@ -65,9 +192,11 @@ it 'allows all methods blocks' do expect_no_offenses(<<~RUBY) - context 'is important' do - specify 'for someone to work' do - everyone.should have_some_leeway + RSpec.describe 'context' do + context 'is important' do + specify 'for someone to work' do + everyone.should have_some_leeway + end end end RUBY