From 1fa9ce3a5a02a0727179b387596a4f4a036ba765 Mon Sep 17 00:00:00 2001 From: ydah Date: Mon, 20 May 2024 00:33:38 +0900 Subject: [PATCH] Remove RSpec/Capybara/FeatureMethods Fix: https://github.com/rubocop/rubocop-rspec/issues/1852 --- CHANGELOG.md | 1 + Rakefile | 3 +- config/default.yml | 17 +- config/obsoletion.yml | 5 + docs/modules/ROOT/pages/cops.adoc | 4 - docs/modules/ROOT/pages/cops_rspec.adoc | 13 ++ .../ROOT/pages/cops_rspec_capybara.adoc | 74 --------- .../cop/rspec/capybara/feature_methods.rb | 104 ------------ lib/rubocop/cop/rspec/dialect.rb | 13 ++ lib/rubocop/cop/rspec_cops.rb | 2 - lib/rubocop/rspec/config_formatter.rb | 2 +- spec/project/default_config_spec.rb | 10 +- .../rspec/capybara/feature_methods_spec.rb | 153 ------------------ tasks/cops_documentation.rake | 2 +- 14 files changed, 39 insertions(+), 364 deletions(-) delete mode 100644 docs/modules/ROOT/pages/cops_rspec_capybara.adoc delete mode 100644 lib/rubocop/cop/rspec/capybara/feature_methods.rb delete mode 100644 spec/rubocop/cop/rspec/capybara/feature_methods_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e72e8a7a..8ead814f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Remove extracted cops in `Capybara`, `FactoryBot` and `Rails` departments. ([@ydah]) - Remove `RuboCop::RSpec::Language::NodePattern`. ([@ydah]) - Remove `RSpec/FilePath` cop. ([@ydah]) +- Remove `RSpec/Capybara/FeatureMethods` cop. If you are using this cop, change it to use `RSpec/Dialect`. ([@ydah]) ## 2.29.2 (2024-05-02) diff --git a/Rakefile b/Rakefile index 6dc3b8f04..f65684797 100644 --- a/Rakefile +++ b/Rakefile @@ -33,8 +33,7 @@ task :build_config do require 'rubocop/rspec/config_formatter' require 'rubocop/rspec/description_extractor' - glob = File.join('lib', 'rubocop', 'cop', 'rspec', - '{,capybara}', '*.rb') + glob = File.join('lib', 'rubocop', 'cop', 'rspec', '*.rb') # Due to YARD's sensitivity to file require order (as of 0.9.25), # we have to prepend the list with our base cop, RuboCop::Cop::RSpec::Base. # Otherwise, cop's parent class for cops loaded before our base cop class diff --git a/config/default.yml b/config/default.yml index 003ab1527..cdfebc8c2 100644 --- a/config/default.yml +++ b/config/default.yml @@ -3,10 +3,10 @@ RSpec: Enabled: true StyleGuideBaseURL: https://rspec.rubystyle.guide DocumentationBaseURL: https://docs.rubocop.org/rubocop-rspec - Include: &1 + Include: - "**/*_spec.rb" - "**/spec/**/*" - Language: &2 + Language: inherit_mode: merge: - Expectations @@ -990,16 +990,3 @@ RSpec/Yield: Enabled: true VersionAdded: '1.32' Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Yield - -RSpec/Capybara: - Enabled: true - Include: *1 - Language: *2 - -RSpec/Capybara/FeatureMethods: - Description: Checks for consistent method usage in feature specs. - Enabled: true - EnabledMethods: [] - VersionAdded: '1.17' - VersionChanged: '2.0' - Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/FeatureMethods diff --git a/config/obsoletion.yml b/config/obsoletion.yml index 989d31f80..5669cc85b 100644 --- a/config/obsoletion.yml +++ b/config/obsoletion.yml @@ -40,3 +40,8 @@ split: alternatives: - RSpec/SpecFilePathFormat - RSpec/SpecFilePathSuffix + +removed: + RSpec/Capybara/FeatureMethods: + reason: > + this cop has migrated to `RSpec/Dialect`. Please use `RSpec/Dialect` instead diff --git a/docs/modules/ROOT/pages/cops.adoc b/docs/modules/ROOT/pages/cops.adoc index f951678c3..dca76e47e 100644 --- a/docs/modules/ROOT/pages/cops.adoc +++ b/docs/modules/ROOT/pages/cops.adoc @@ -111,8 +111,4 @@ * xref:cops_rspec.adoc#rspecvoidexpect[RSpec/VoidExpect] * xref:cops_rspec.adoc#rspecyield[RSpec/Yield] -=== Department xref:cops_rspec_capybara.adoc[RSpec/Capybara] - -* xref:cops_rspec_capybara.adoc#rspeccapybara/featuremethods[RSpec/Capybara/FeatureMethods] - // END_COP_LIST diff --git a/docs/modules/ROOT/pages/cops_rspec.adoc b/docs/modules/ROOT/pages/cops_rspec.adoc index 48da86270..532cadb89 100644 --- a/docs/modules/ROOT/pages/cops_rspec.adoc +++ b/docs/modules/ROOT/pages/cops_rspec.adoc @@ -1073,6 +1073,19 @@ a config like: PreferredMethods: context: describe +If you were previously using the `RSpec/Capybara/FeatureMethods` cop and +want to keep disabling all Capybara-specific methods that have the same +native RSpec method (e.g. are just aliases), use the following config: + + RSpec/Dialect: + PreferredMethods: + background: :before + scenario: :it + xscenario: :xit + given: :let + given!: :let! + feature: :describe + You can expect the following behavior: === Examples diff --git a/docs/modules/ROOT/pages/cops_rspec_capybara.adoc b/docs/modules/ROOT/pages/cops_rspec_capybara.adoc deleted file mode 100644 index 6ea58f2b8..000000000 --- a/docs/modules/ROOT/pages/cops_rspec_capybara.adoc +++ /dev/null @@ -1,74 +0,0 @@ -//// - Do NOT edit this file by hand directly, as it is automatically generated. - - Please make any necessary changes to the cop documentation within the source files themselves. -//// - -= RSpec/Capybara - -== RSpec/Capybara/FeatureMethods - -|=== -| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed - -| Enabled -| Yes -| Always -| 1.17 -| 2.0 -|=== - -Checks for consistent method usage in feature specs. - -By default, the cop disables all Capybara-specific methods that have -the same native RSpec method (e.g. are just aliases). Some teams -however may prefer using some of the Capybara methods (like `feature`) -to make it obvious that the test uses Capybara, while still disable -the rest of the methods, like `given` (alias for `let`), `background` -(alias for `before`), etc. You can configure which of the methods to -be enabled by using the EnabledMethods configuration option. - -=== Examples - -[source,ruby] ----- -# bad -feature 'User logs in' do - given(:user) { User.new } - - background do - visit new_session_path - end - - scenario 'with OAuth' do - # ... - end -end - -# good -describe 'User logs in' do - let(:user) { User.new } - - before do - visit new_session_path - end - - it 'with OAuth' do - # ... - end -end ----- - -=== Configurable attributes - -|=== -| Name | Default value | Configurable values - -| EnabledMethods -| `[]` -| Array -|=== - -=== References - -* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/FeatureMethods diff --git a/lib/rubocop/cop/rspec/capybara/feature_methods.rb b/lib/rubocop/cop/rspec/capybara/feature_methods.rb deleted file mode 100644 index 2b95dc70b..000000000 --- a/lib/rubocop/cop/rspec/capybara/feature_methods.rb +++ /dev/null @@ -1,104 +0,0 @@ -# frozen_string_literal: true - -module RuboCop - module Cop - module RSpec - module Capybara - # Checks for consistent method usage in feature specs. - # - # By default, the cop disables all Capybara-specific methods that have - # the same native RSpec method (e.g. are just aliases). Some teams - # however may prefer using some of the Capybara methods (like `feature`) - # to make it obvious that the test uses Capybara, while still disable - # the rest of the methods, like `given` (alias for `let`), `background` - # (alias for `before`), etc. You can configure which of the methods to - # be enabled by using the EnabledMethods configuration option. - # - # @example - # # bad - # feature 'User logs in' do - # given(:user) { User.new } - # - # background do - # visit new_session_path - # end - # - # scenario 'with OAuth' do - # # ... - # end - # end - # - # # good - # describe 'User logs in' do - # let(:user) { User.new } - # - # before do - # visit new_session_path - # end - # - # it 'with OAuth' do - # # ... - # end - # end - # - class FeatureMethods < Base - extend AutoCorrector - include InsideExampleGroup - - MSG = 'Use `%s` instead of `%s`.' - - # https://github.com/teamcapybara/capybara/blob/e283c1aeaa72441f5403963577e16333bf111a81/lib/capybara/rspec/features.rb#L31-L36 - MAP = { - background: :before, - scenario: :it, - xscenario: :xit, - given: :let, - given!: :let!, - feature: :describe - }.freeze - - # @!method capybara_speak(node) - def_node_matcher :capybara_speak, <<~PATTERN - {#{MAP.keys.map(&:inspect).join(' ')}} - PATTERN - - # @!method feature_method(node) - def_node_matcher :feature_method, <<~PATTERN - (block - $(send #rspec? $#capybara_speak ...) - ...) - PATTERN - - def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler - return unless inside_example_group?(node) - - feature_method(node) do |send_node, match| - next if enabled?(match) - - add_offense(send_node.loc.selector) do |corrector| - corrector.replace(send_node.loc.selector, MAP[match].to_s) - end - end - end - - def message(range) - name = range.source.to_sym - format(MSG, method: name, replacement: MAP[name]) - end - - private - - def enabled?(method_name) - enabled_methods.include?(method_name) - end - - def enabled_methods - cop_config - .fetch('EnabledMethods', []) - .map(&:to_sym) - end - end - end - end - end -end diff --git a/lib/rubocop/cop/rspec/dialect.rb b/lib/rubocop/cop/rspec/dialect.rb index 7140541c4..5bc91f0cc 100644 --- a/lib/rubocop/cop/rspec/dialect.rb +++ b/lib/rubocop/cop/rspec/dialect.rb @@ -29,6 +29,19 @@ module RSpec # PreferredMethods: # context: describe # + # If you were previously using the `RSpec/Capybara/FeatureMethods` cop and + # want to keep disabling all Capybara-specific methods that have the same + # native RSpec method (e.g. are just aliases), use the following config: + # + # RSpec/Dialect: + # PreferredMethods: + # background: :before + # scenario: :it + # xscenario: :xit + # given: :let + # given!: :let! + # feature: :describe + # # You can expect the following behavior: # # @example diff --git a/lib/rubocop/cop/rspec_cops.rb b/lib/rubocop/cop/rspec_cops.rb index aa462cf71..aeb115719 100644 --- a/lib/rubocop/cop/rspec_cops.rb +++ b/lib/rubocop/cop/rspec_cops.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require_relative 'rspec/capybara/feature_methods' - require_relative 'rspec/align_left_let_brace' require_relative 'rspec/align_right_let_brace' require_relative 'rspec/any_instance' diff --git a/lib/rubocop/rspec/config_formatter.rb b/lib/rubocop/rspec/config_formatter.rb index 9a06a7780..9f66ef7ea 100644 --- a/lib/rubocop/rspec/config_formatter.rb +++ b/lib/rubocop/rspec/config_formatter.rb @@ -7,7 +7,7 @@ module RSpec # Builds a YAML config file from two config hashes class ConfigFormatter EXTENSION_ROOT_DEPARTMENT = %r{^(RSpec/)}.freeze - SUBDEPARTMENTS = %(RSpec/Capybara) + SUBDEPARTMENTS = [].freeze AMENDMENTS = %(Metrics/BlockLength) COP_DOC_BASE_URL = 'https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/' diff --git a/spec/project/default_config_spec.rb b/spec/project/default_config_spec.rb index 41b556826..f2e3f7cc1 100644 --- a/spec/project/default_config_spec.rb +++ b/spec/project/default_config_spec.rb @@ -5,16 +5,10 @@ RuboCop::ConfigLoader.load_yaml_configuration('config/default.yml') end - let(:namespaces) do - { - 'rspec' => 'RSpec', - 'capybara' => 'RSpec/Capybara' - } - end + let(:namespaces) { { 'rspec' => 'RSpec' } } let(:cop_names) do - glob = SpecHelper::ROOT.join('lib', 'rubocop', 'cop', 'rspec', - '{,capybara}', '*.rb') + glob = SpecHelper::ROOT.join('lib', 'rubocop', 'cop', 'rspec', '*.rb') cop_names = Pathname.glob(glob).map do |file| file_name = file.basename('.rb').to_s diff --git a/spec/rubocop/cop/rspec/capybara/feature_methods_spec.rb b/spec/rubocop/cop/rspec/capybara/feature_methods_spec.rb deleted file mode 100644 index e535a5641..000000000 --- a/spec/rubocop/cop/rspec/capybara/feature_methods_spec.rb +++ /dev/null @@ -1,153 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe RuboCop::Cop::RSpec::Capybara::FeatureMethods do - it 'flags offenses for `background`' do - expect_offense(<<~RUBY) - describe 'some feature' do - background do; end - ^^^^^^^^^^ Use `before` instead of `background`. - end - RUBY - - expect_correction(<<~RUBY) - describe 'some feature' do - before do; end - end - RUBY - end - - it 'flags offenses for `scenario`' do - expect_offense(<<~RUBY) - RSpec.describe 'some feature' do - scenario 'Foo' do; end - ^^^^^^^^ Use `it` instead of `scenario`. - end - RUBY - - expect_correction(<<~RUBY) - RSpec.describe 'some feature' do - it 'Foo' do; end - end - RUBY - end - - it 'flags offenses for `xscenario`' do - expect_offense(<<~RUBY) - describe 'Foo' do - RSpec.xscenario 'Baz' do; end - ^^^^^^^^^ Use `xit` instead of `xscenario`. - end - RUBY - - expect_correction(<<~RUBY) - describe 'Foo' do - RSpec.xit 'Baz' do; end - end - RUBY - end - - it 'flags offenses for `given`' do - expect_offense(<<~RUBY) - RSpec.describe 'Foo' do - given(:foo) { :foo } - ^^^^^ Use `let` instead of `given`. - end - RUBY - - expect_correction(<<~RUBY) - RSpec.describe 'Foo' do - let(:foo) { :foo } - end - RUBY - end - - it 'flags offenses for `given!`' do - expect_offense(<<~RUBY) - describe 'Foo' do - given!(:foo) { :foo } - ^^^^^^ Use `let!` instead of `given!`. - end - RUBY - - expect_correction(<<~RUBY) - describe 'Foo' do - let!(:foo) { :foo } - end - RUBY - end - - it 'flags offenses for `feature`' do - expect_offense(<<~RUBY) - RSpec.feature 'Foo' do; end - ^^^^^^^ Use `describe` instead of `feature`. - RUBY - - expect_correction(<<~RUBY) - RSpec.describe 'Foo' do; end - RUBY - end - - it 'flags offenses inside shared groups' do - expect_offense(<<~RUBY) - RSpec.shared_examples_for 'common scenarios' do - feature 'Foo' do; end - ^^^^^^^ Use `describe` instead of `feature`. - end - RUBY - - expect_correction(<<~RUBY) - RSpec.shared_examples_for 'common scenarios' do - describe 'Foo' do; end - end - RUBY - end - - it 'ignores variables inside examples' do - expect_no_offenses(<<~RUBY) - it 'is valid code' do - given(feature) - assign(background) - run scenario - end - RUBY - end - - it 'ignores feature calls outside spec' do - expect_no_offenses(<<~RUBY) - FactoryBot.define do - factory :company do - feature { "a company" } - background { Faker::Lorem.sentence } - end - end - RUBY - end - - it 'allows includes before the spec' do - expect_offense(<<~RUBY) - require 'rails_helper' - - RSpec.feature 'Foo' do; end - ^^^^^^^ Use `describe` instead of `feature`. - RUBY - end - - context 'with configured `EnabledMethods`' do - let(:cop_config) { { 'EnabledMethods' => %w[feature] } } - - it 'ignores usage of the enabled method' do - expect_no_offenses(<<~RUBY) - RSpec.feature 'feature is enabled' do; end - RUBY - end - - it 'flags other methods' do - expect_offense(<<~RUBY) - RSpec.feature 'feature is enabled' do - given(:foo) { :foo } - ^^^^^ Use `let` instead of `given`. - end - RUBY - end - end -end diff --git a/tasks/cops_documentation.rake b/tasks/cops_documentation.rake index aa157fe08..510146bd6 100644 --- a/tasks/cops_documentation.rake +++ b/tasks/cops_documentation.rake @@ -13,7 +13,7 @@ end desc 'Generate docs of all cops departments' task generate_cops_documentation: :yard_for_generate_documentation do generator = CopsDocumentationGenerator.new( - departments: %w[RSpec RSpec/Capybara] + departments: %w[RSpec] ) generator.call end