diff --git a/.rubocop_todo/rspec/shared_groups_metadata.yml b/.rubocop_todo/rspec/shared_groups_metadata.yml new file mode 100644 index 0000000000000000000000000000000000000000..a9e4e6defec9916a695089a47d419b3343a35b6e --- /dev/null +++ b/.rubocop_todo/rspec/shared_groups_metadata.yml @@ -0,0 +1,9 @@ +--- +RSpec/SharedGroupsMetadata: + Details: grace period + Exclude: + - 'ee/spec/requests/ee/admin/plan_limits_controller_spec.rb' + - 'ee/spec/support/shared_contexts/saas_registration_settings_context.rb' + - 'spec/lib/gitlab/ci/config/entry/retry_spec.rb' + - 'spec/lib/gitlab/git/merge_base_spec.rb' + - 'spec/models/container_repository_spec.rb' diff --git a/rubocop/cop/rspec/feature_category_on_shared_examples.rb b/rubocop/cop/rspec/feature_category_on_shared_examples.rb deleted file mode 100644 index acb2ae79d123d7bc7ccbef7bb9fbfc505a24b9bf..0000000000000000000000000000000000000000 --- a/rubocop/cop/rspec/feature_category_on_shared_examples.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -require 'rubocop/cop/rspec/base' - -module RuboCop - module Cop - module RSpec - # Ensures that shared examples don't have feature category. - # - # @example - # - # # bad - # RSpec.shared_examples 'an external link with rel attribute', feature_category: :team_planning do - # end - # - # # good - # RSpec.shared_examples 'an external link with rel attribute' do - # end - # - # it 'adds rel="nofollow" to external links', feature_category: :team_planning do - # end - class FeatureCategoryOnSharedExamples < RuboCop::Cop::RSpec::Base - MSG = 'Shared examples should not have feature category set' - - # @!method feature_category_value(node) - def_node_matcher :feature_category_value, <<~PATTERN - (block - (send #rspec? {#SharedGroups.all} ... - $(hash <(pair (sym :feature_category) _) ...>) - ) - ... - ) - PATTERN - - def on_block(node) - value_node = feature_category_value(node) - - return unless value_node - - add_offense(value_node, message: MSG) - end - end - end - end -end diff --git a/rubocop/cop/rspec/shared_groups_metadata.rb b/rubocop/cop/rspec/shared_groups_metadata.rb new file mode 100644 index 0000000000000000000000000000000000000000..ac2406e54d26f2fef3847480f29987198027f005 --- /dev/null +++ b/rubocop/cop/rspec/shared_groups_metadata.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'rubocop/cop/rspec/base' + +module RuboCop + module Cop + module RSpec + # Ensures that shared examples and shared context don't have any metadata. + # + # @example + # + # # bad + # RSpec.shared_examples 'an external link with rel attribute', feature_category: :team_planning do + # end + # + # RSpec.shared_examples 'an external link with rel attribute', :aggregate_failures do + # end + # + # RSpec.shared_context 'an external link with rel attribute', :aggregate_failures do + # end + # + # # good + # RSpec.shared_examples 'an external link with rel attribute' do + # end + # + # shared_examples 'an external link with rel attribute' do + # end + # + # it 'adds rel="nofollow" to external links', feature_category: :team_planning do + # end + class SharedGroupsMetadata < RuboCop::Cop::RSpec::Base + MSG = 'Avoid using metadata on shared examples and shared context. They might cause flaky tests. See https://gitlab.com/gitlab-org/gitlab/-/issues/404388' + + # @!method metadata_value(node) + def_node_matcher :metadata_value, <<~PATTERN + (block + (send #rspec? {#SharedGroups.all} _description $_ ...) + ... + ) + PATTERN + + def on_block(node) + value_node = metadata_value(node) + + return unless value_node + + add_offense(value_node, message: MSG) + end + end + end + end +end diff --git a/spec/rubocop/cop/rspec/feature_category_on_shared_examples_spec.rb b/spec/rubocop/cop/rspec/feature_category_on_shared_examples_spec.rb deleted file mode 100644 index 6b337471f0a8276387f76048868dbc10b70d2652..0000000000000000000000000000000000000000 --- a/spec/rubocop/cop/rspec/feature_category_on_shared_examples_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -require 'rubocop_spec_helper' -require 'rspec-parameterized' - -require_relative '../../../../rubocop/cop/rspec/feature_category_on_shared_examples' - -RSpec.describe RuboCop::Cop::RSpec::FeatureCategoryOnSharedExamples, feature_category: :tooling do - it 'flags feature category in shared example' do - expect_offense(<<~RUBY) - RSpec.shared_examples 'foo', feature_category: :shared do - ^^^^^^^^^^^^^^^^^^^^^^^^^ Shared examples should not have feature category set - end - - shared_examples 'foo', feature_category: :shared do - ^^^^^^^^^^^^^^^^^^^^^^^^^ Shared examples should not have feature category set - end - RUBY - end - - it 'does not flag if feature category is missing' do - expect_no_offenses(<<~RUBY) - RSpec.shared_examples 'foo' do - end - - shared_examples 'foo', some: :tag do - end - RUBY - end -end diff --git a/spec/rubocop/cop/rspec/shared_groups_metadata_spec.rb b/spec/rubocop/cop/rspec/shared_groups_metadata_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..3dd568e7dcd36ef78fb50a69ce4fcb47643a394e --- /dev/null +++ b/spec/rubocop/cop/rspec/shared_groups_metadata_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +require 'rubocop_spec_helper' +require 'rspec-parameterized' + +require_relative '../../../../rubocop/cop/rspec/shared_groups_metadata' + +RSpec.describe RuboCop::Cop::RSpec::SharedGroupsMetadata, feature_category: :tooling do + context 'with hash metadata' do + it 'flags metadata in shared example' do + expect_offense(<<~RUBY) + RSpec.shared_examples 'foo', feature_category: :shared do + ^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid using metadata on shared examples and shared context. They might cause flaky tests. See https://gitlab.com/gitlab-org/gitlab/-/issues/404388 + end + + shared_examples 'foo', feature_category: :shared do + ^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid using metadata on shared examples and shared context. They might cause flaky tests. See https://gitlab.com/gitlab-org/gitlab/-/issues/404388 + end + RUBY + end + + it 'flags metadata in shared context' do + expect_offense(<<~RUBY) + RSpec.shared_context 'foo', feature_category: :shared do + ^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid using metadata on shared examples and shared context. They might cause flaky tests. See https://gitlab.com/gitlab-org/gitlab/-/issues/404388 + end + + shared_context 'foo', feature_category: :shared do + ^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid using metadata on shared examples and shared context. They might cause flaky tests. See https://gitlab.com/gitlab-org/gitlab/-/issues/404388 + end + RUBY + end + end + + context 'with symbol metadata' do + it 'flags metadata in shared example' do + expect_offense(<<~RUBY) + RSpec.shared_examples 'foo', :aggregate_failures do + ^^^^^^^^^^^^^^^^^^^ Avoid using metadata on shared examples and shared context. They might cause flaky tests. See https://gitlab.com/gitlab-org/gitlab/-/issues/404388 + end + + shared_examples 'foo', :aggregate_failures do + ^^^^^^^^^^^^^^^^^^^ Avoid using metadata on shared examples and shared context. They might cause flaky tests. See https://gitlab.com/gitlab-org/gitlab/-/issues/404388 + end + RUBY + end + + it 'flags metadata in shared context' do + expect_offense(<<~RUBY) + RSpec.shared_context 'foo', :aggregate_failures do + ^^^^^^^^^^^^^^^^^^^ Avoid using metadata on shared examples and shared context. They might cause flaky tests. See https://gitlab.com/gitlab-org/gitlab/-/issues/404388 + end + + shared_context 'foo', :aggregate_failures do + ^^^^^^^^^^^^^^^^^^^ Avoid using metadata on shared examples and shared context. They might cause flaky tests. See https://gitlab.com/gitlab-org/gitlab/-/issues/404388 + end + RUBY + end + end + + it 'does not flag if feature category is missing' do + expect_no_offenses(<<~RUBY) + RSpec.shared_examples 'foo' do + end + + shared_examples 'foo' do + end + RUBY + end +end