Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/rubocop')
-rw-r--r--spec/rubocop/batched_background_migrations_spec.rb43
-rw-r--r--spec/rubocop/check_graceful_task_spec.rb11
-rw-r--r--spec/rubocop/cop/background_migration/feature_category_spec.rb6
-rw-r--r--spec/rubocop/cop/experiments_test_coverage_spec.rb2
-rw-r--r--spec/rubocop/cop/gemfile/missing_feature_category_spec.rb63
-rw-r--r--spec/rubocop/cop/gitlab/avoid_gitlab_instance_checks_spec.rb45
-rw-r--r--spec/rubocop/cop/gitlab/feature_available_usage_spec.rb4
-rw-r--r--spec/rubocop/cop/migration/prevent_index_creation_spec.rb24
-rw-r--r--spec/rubocop/cop/migration/unfinished_dependencies_spec.rb118
-rw-r--r--spec/rubocop/cop/qa/fabricate_usage_spec.rb35
-rw-r--r--spec/rubocop/cop/rspec/env_mocking_spec.rb12
-rw-r--r--spec/rubocop/cop/rspec/feature_category_spec.rb (renamed from spec/rubocop/cop/rspec/invalid_feature_category_spec.rb)38
-rw-r--r--spec/rubocop/cop/rspec/missing_feature_category_spec.rb31
-rw-r--r--spec/rubocop/cop/style/regexp_literal_mixed_preserve_spec.rb8
-rw-r--r--spec/rubocop/feature_categories_spec.rb102
-rw-r--r--spec/rubocop/formatter/graceful_formatter_spec.rb27
16 files changed, 485 insertions, 84 deletions
diff --git a/spec/rubocop/batched_background_migrations_spec.rb b/spec/rubocop/batched_background_migrations_spec.rb
new file mode 100644
index 00000000000..a9b99bb466b
--- /dev/null
+++ b/spec/rubocop/batched_background_migrations_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+
+require_relative '../../rubocop/batched_background_migrations'
+
+RSpec.describe RuboCop::BatchedBackgroundMigrations, feature_category: :database do
+ let(:bbm_dictionary_file_name) { "#{described_class::DICTIONARY_BASE_DIR}/test_migration.yml" }
+ let(:migration_version) { 20230307160250 }
+ let(:finalized_by_version) { 20230307160255 }
+ let(:bbm_dictionary_data) do
+ {
+ migration_job_name: 'TestMigration',
+ feature_category: :database,
+ introduced_by_url: 'https://test_url',
+ milestone: 16.5,
+ queued_migration_version: migration_version,
+ finalized_by: finalized_by_version
+ }
+ end
+
+ before do
+ File.open(bbm_dictionary_file_name, 'w') do |file|
+ file.write(bbm_dictionary_data.stringify_keys.to_yaml)
+ end
+ end
+
+ after do
+ FileUtils.rm(bbm_dictionary_file_name)
+ end
+
+ subject(:batched_background_migration) { described_class.new(migration_version) }
+
+ describe '#finalized_by' do
+ it 'returns the finalized_by version of the bbm with given version' do
+ expect(batched_background_migration.finalized_by).to eq(finalized_by_version.to_s)
+ end
+
+ it 'returns nothing for non-existing bbm dictionary' do
+ expect(described_class.new('random').finalized_by).to be_nil
+ end
+ end
+end
diff --git a/spec/rubocop/check_graceful_task_spec.rb b/spec/rubocop/check_graceful_task_spec.rb
index 38c2d68a593..aa66643dd8e 100644
--- a/spec/rubocop/check_graceful_task_spec.rb
+++ b/spec/rubocop/check_graceful_task_spec.rb
@@ -1,14 +1,9 @@
# frozen_string_literal: true
-require 'fast_spec_helper'
-require 'stringio'
-
-require_relative '../support/helpers/next_instance_of'
+require 'rubocop_spec_helper'
require_relative '../../rubocop/check_graceful_task'
RSpec.describe RuboCop::CheckGracefulTask do
- include NextInstanceOf
-
let(:output) { StringIO.new }
subject(:task) { described_class.new(output) }
@@ -119,9 +114,9 @@ RSpec.describe RuboCop::CheckGracefulTask do
end
context 'with args' do
- let(:args) { %w[a.rb Lint/EmptyFile b.rb Lint/Syntax] }
+ let(:args) { %w[Lint/EmptyFile Lint/Syntax] }
- it_behaves_like 'rubocop scan', rubocop_args: %w[--only Lint/EmptyFile,Lint/Syntax a.rb b.rb]
+ it_behaves_like 'rubocop scan', rubocop_args: %w[--only Lint/EmptyFile,Lint/Syntax]
it 'does not notify slack' do
expect(Gitlab::Popen).not_to receive(:popen)
diff --git a/spec/rubocop/cop/background_migration/feature_category_spec.rb b/spec/rubocop/cop/background_migration/feature_category_spec.rb
index 1d1b6cfad5a..12794de4f38 100644
--- a/spec/rubocop/cop/background_migration/feature_category_spec.rb
+++ b/spec/rubocop/cop/background_migration/feature_category_spec.rb
@@ -66,4 +66,10 @@ RSpec.describe RuboCop::Cop::BackgroundMigration::FeatureCategory, feature_categ
RUBY
end
end
+
+ describe '#external_dependency_checksum' do
+ it 'returns a SHA256 digest used by RuboCop to invalid cache' do
+ expect(cop.external_dependency_checksum).to match(/^\h{64}$/)
+ end
+ end
end
diff --git a/spec/rubocop/cop/experiments_test_coverage_spec.rb b/spec/rubocop/cop/experiments_test_coverage_spec.rb
index eb1e672ef40..8221d0d6720 100644
--- a/spec/rubocop/cop/experiments_test_coverage_spec.rb
+++ b/spec/rubocop/cop/experiments_test_coverage_spec.rb
@@ -4,7 +4,7 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/experiments_test_coverage'
-RSpec.describe RuboCop::Cop::ExperimentsTestCoverage, feature_category: :experimentation_conversion do
+RSpec.describe RuboCop::Cop::ExperimentsTestCoverage, feature_category: :acquisition do
let(:class_offense) { described_class::CLASS_OFFENSE }
let(:block_offense) { described_class::BLOCK_OFFENSE }
diff --git a/spec/rubocop/cop/gemfile/missing_feature_category_spec.rb b/spec/rubocop/cop/gemfile/missing_feature_category_spec.rb
new file mode 100644
index 00000000000..5f8e32f0c03
--- /dev/null
+++ b/spec/rubocop/cop/gemfile/missing_feature_category_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+
+require_relative '../../../../rubocop/cop/gemfile/missing_feature_category'
+
+RSpec.describe RuboCop::Cop::Gemfile::MissingFeatureCategory, feature_category: :tooling do
+ let(:valid_category) { RuboCop::FeatureCategories.available.first }
+ let(:invalid_category) { :invalid_category }
+
+ it 'flags missing feature category in gem method without keyword argument' do
+ expect_offense(<<~RUBY)
+ gem 'foo', '~> 1.0'
+ ^^^^^^^^^^^^^^^^^^^ Please use a valid feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#gemfile
+ RUBY
+ end
+
+ it 'flags missing feature category in gem method with keyword argument' do
+ expect_offense(<<~RUBY)
+ gem 'foo', '~> 1.0', require: false
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Please use a valid feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#gemfile
+ RUBY
+ end
+
+ it 'flags invalid feature category in gem method as the only keyword argument' do
+ expect_offense(<<~RUBY, invalid: invalid_category)
+ gem 'foo', '~> 1.0', feature_category: :%{invalid}
+ ^^{invalid} Please use a valid feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#gemfile
+ RUBY
+ end
+
+ it 'flags invalid feature category in gem method as the last keyword argument' do
+ expect_offense(<<~RUBY, invalid: invalid_category)
+ gem 'foo', '~> 1.0', require: false, feature_category: :%{invalid}
+ ^^{invalid} Please use a valid feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#gemfile
+ RUBY
+ end
+
+ it 'flags invalid feature category in gem method as the first keyword argument' do
+ expect_offense(<<~RUBY, invalid: invalid_category)
+ gem 'foo', '~> 1.0', feature_category: :%{invalid}, require: false
+ ^^{invalid} Please use a valid feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#gemfile
+ RUBY
+ end
+
+ it 'does not flag in gem method if feature category is valid as the only keyword argument' do
+ expect_no_offenses(<<~RUBY)
+ gem 'foo', '~> 1.0', feature_category: :#{valid_category}
+ RUBY
+ end
+
+ it 'does not flag in gem method if feature category is valid as the last keyword argument' do
+ expect_no_offenses(<<~RUBY)
+ gem 'foo', '~> 1.0', require: false, feature_category: :#{valid_category}
+ RUBY
+ end
+
+ describe '#external_dependency_checksum' do
+ it 'returns a SHA256 digest used by RuboCop to invalid cache' do
+ expect(cop.external_dependency_checksum).to match(/^\h{64}$/)
+ end
+ end
+end
diff --git a/spec/rubocop/cop/gitlab/avoid_gitlab_instance_checks_spec.rb b/spec/rubocop/cop/gitlab/avoid_gitlab_instance_checks_spec.rb
new file mode 100644
index 00000000000..2dba6194d44
--- /dev/null
+++ b/spec/rubocop/cop/gitlab/avoid_gitlab_instance_checks_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+require 'rspec-parameterized'
+require_relative '../../../../rubocop/cop/gitlab/avoid_gitlab_instance_checks'
+
+RSpec.describe RuboCop::Cop::Gitlab::AvoidGitlabInstanceChecks, feature_category: :shared do
+ let(:msg) { described_class::MSG }
+
+ describe 'bad examples' do
+ where(:code) do
+ %w[
+ Gitlab.com?
+ Gitlab.com_except_jh?
+ Gitlab.com_and_canary?
+ Gitlab.com_but_not_canary?
+ Gitlab.org_or_com?
+ ::Gitlab.com?
+ Gitlab::CurrentSettings.should_check_namespace_plan?
+ ::Gitlab::CurrentSettings.should_check_namespace_plan?
+ ]
+ end
+
+ with_them do
+ it 'registers an offense' do
+ expect_offense(<<~CODE, node: code)
+ return if %{node}
+ ^{node} Avoid the use of [...]
+ CODE
+ end
+ end
+ end
+
+ describe 'good examples' do
+ where(:code) do
+ %w[com? com Gitlab.com Gitlab::CurrentSettings.check_namespace_plan?]
+ end
+
+ with_them do
+ it 'does not register an offense' do
+ expect_no_offenses(code)
+ end
+ end
+ end
+end
diff --git a/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb b/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb
index b15c298099d..184f2c3ee92 100644
--- a/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb
+++ b/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb
@@ -16,6 +16,10 @@ RSpec.describe RuboCop::Cop::Gitlab::FeatureAvailableUsage do
expect_no_offenses('License.feature_available?(:push_rules)')
end
+ it 'does not flag the use of Gitlab::Saas.feature_available?' do
+ expect_no_offenses('Gitlab::Saas.feature_available?("some/feature")')
+ end
+
it 'flags the use with a dynamic feature as nil' do
expect_offense(<<~SOURCE)
feature_available?(nil)
diff --git a/spec/rubocop/cop/migration/prevent_index_creation_spec.rb b/spec/rubocop/cop/migration/prevent_index_creation_spec.rb
index 9d886467a48..088edfedfc9 100644
--- a/spec/rubocop/cop/migration/prevent_index_creation_spec.rb
+++ b/spec/rubocop/cop/migration/prevent_index_creation_spec.rb
@@ -4,7 +4,7 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/prevent_index_creation'
RSpec.describe RuboCop::Cop::Migration::PreventIndexCreation do
- let(:forbidden_tables) { %w(ci_builds) }
+ let(:forbidden_tables) { %w(ci_builds namespaces) }
let(:forbidden_tables_list) { forbidden_tables.join(', ') }
context 'when in migration' do
@@ -12,14 +12,26 @@ RSpec.describe RuboCop::Cop::Migration::PreventIndexCreation do
allow(cop).to receive(:in_migration?).and_return(true)
end
+ let(:offense) { "Adding new index to #{forbidden_tables_list} is forbidden. [...]" }
+
context 'when adding an index to a forbidden table' do
+ it 'does not register an offense when direction is down' do
+ forbidden_tables.each do |table_name|
+ expect_no_offenses(<<~RUBY)
+ def down
+ add_concurrent_index :#{table_name}, :runners_token, unique: true, name: INDEX_NAME
+ end
+ RUBY
+ end
+ end
+
context 'when table_name is a symbol' do
it "registers an offense when add_index is used", :aggregate_failures do
forbidden_tables.each do |table_name|
expect_offense(<<~RUBY)
def change
add_index :#{table_name}, :protected
- ^^^^^^^^^ Adding new index to #{forbidden_tables_list} is forbidden, see https://gitlab.com/gitlab-org/gitlab/-/issues/332886
+ ^^^^^^^^^ #{offense}
end
RUBY
end
@@ -30,7 +42,7 @@ RSpec.describe RuboCop::Cop::Migration::PreventIndexCreation do
expect_offense(<<~RUBY)
def change
add_concurrent_index :#{table_name}, :protected
- ^^^^^^^^^^^^^^^^^^^^ Adding new index to #{forbidden_tables_list} is forbidden, see https://gitlab.com/gitlab-org/gitlab/-/issues/332886
+ ^^^^^^^^^^^^^^^^^^^^ #{offense}
end
RUBY
end
@@ -43,7 +55,7 @@ RSpec.describe RuboCop::Cop::Migration::PreventIndexCreation do
expect_offense(<<~RUBY)
def change
add_index "#{table_name}", :protected
- ^^^^^^^^^ Adding new index to #{forbidden_tables_list} is forbidden, see https://gitlab.com/gitlab-org/gitlab/-/issues/332886
+ ^^^^^^^^^ #{offense}
end
RUBY
end
@@ -54,7 +66,7 @@ RSpec.describe RuboCop::Cop::Migration::PreventIndexCreation do
expect_offense(<<~RUBY)
def change
add_concurrent_index "#{table_name}", :protected
- ^^^^^^^^^^^^^^^^^^^^ Adding new index to #{forbidden_tables_list} is forbidden, see https://gitlab.com/gitlab-org/gitlab/-/issues/332886
+ ^^^^^^^^^^^^^^^^^^^^ #{offense}
end
RUBY
end
@@ -70,7 +82,7 @@ RSpec.describe RuboCop::Cop::Migration::PreventIndexCreation do
def change
add_concurrent_index TABLE_NAME, :protected
- ^^^^^^^^^^^^^^^^^^^^ Adding new index to #{forbidden_tables_list} is forbidden, see https://gitlab.com/gitlab-org/gitlab/-/issues/332886
+ ^^^^^^^^^^^^^^^^^^^^ #{offense}
end
RUBY
end
diff --git a/spec/rubocop/cop/migration/unfinished_dependencies_spec.rb b/spec/rubocop/cop/migration/unfinished_dependencies_spec.rb
new file mode 100644
index 00000000000..cac48871856
--- /dev/null
+++ b/spec/rubocop/cop/migration/unfinished_dependencies_spec.rb
@@ -0,0 +1,118 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+require_relative '../../../../rubocop/cop/migration/unfinished_dependencies'
+
+RSpec.describe RuboCop::Cop::Migration::UnfinishedDependencies, feature_category: :database do
+ let(:version) { 20230307160250 }
+
+ let(:migration) do
+ <<~RUBY
+ class TestMigration < Gitlab::Database::Migration[2.1]
+ def perform; end
+ end
+ RUBY
+ end
+
+ before do
+ allow(cop).to receive(:in_migration?).and_return(true)
+
+ allow(cop).to receive(:version).and_return(version)
+ end
+
+ shared_examples 'migration with rubocop offense' do
+ it 'registers an offense' do
+ expect_offense(migration)
+ end
+ end
+
+ shared_examples 'migration without any rubocop offense' do
+ it 'does not register any offense' do
+ expect_no_offenses(migration)
+ end
+ end
+
+ context 'without any dependent batched background migrations' do
+ it_behaves_like 'migration without any rubocop offense'
+ end
+
+ context 'with dependent batched background migrations' do
+ let(:dependent_migration_versions) { [20230307160240] }
+
+ let(:migration) do
+ <<~RUBY
+ class TestMigration < Gitlab::Database::Migration[2.1]
+ DEPENDENT_BATCHED_BACKGROUND_MIGRATIONS = #{dependent_migration_versions}
+
+ def perform; end
+ end
+ RUBY
+ end
+
+ context 'with unfinished dependent migration' do
+ before do
+ allow(cop).to receive(:fetch_finalized_by)
+ .with(dependent_migration_versions.first)
+ .and_return(nil)
+ end
+
+ it_behaves_like 'migration with rubocop offense' do
+ let(:migration) do
+ <<~RUBY
+ class TestMigration < Gitlab::Database::Migration[2.1]
+ DEPENDENT_BATCHED_BACKGROUND_MIGRATIONS = #{dependent_migration_versions}
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{format(described_class::NOT_FINALIZED_MSG, version: dependent_migration_versions.first)}
+
+ def perform; end
+ end
+ RUBY
+ end
+ end
+ end
+
+ context 'with incorrectly finalized dependent migration' do
+ let(:dependent_migration_versions) { [20230307160240, 20230307160230] }
+
+ before do
+ allow(cop).to receive(:fetch_finalized_by)
+ .with(dependent_migration_versions.first)
+ .and_return(version - 10)
+
+ allow(cop).to receive(:fetch_finalized_by)
+ .with(dependent_migration_versions.last)
+ .and_return(version + 10)
+ end
+
+ it_behaves_like 'migration with rubocop offense' do
+ let(:migration) do
+ <<~RUBY
+ class TestMigration < Gitlab::Database::Migration[2.1]
+ DEPENDENT_BATCHED_BACKGROUND_MIGRATIONS = #{dependent_migration_versions}
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{format(described_class::FINALIZED_BY_LATER_MIGRATION_MSG, version: dependent_migration_versions.last)}
+
+ def perform; end
+ end
+ RUBY
+ end
+ end
+ end
+
+ context 'with properly finalized dependent background migrations' do
+ before do
+ allow_next_instance_of(RuboCop::BatchedBackgroundMigrations) do |bbms|
+ allow(bbms).to receive(:finalized_by).and_return(version - 5)
+ end
+ end
+
+ it_behaves_like 'migration without any rubocop offense'
+ end
+ end
+
+ context 'for non migrations' do
+ before do
+ allow(cop).to receive(:in_migration?).and_return(false)
+ end
+
+ it_behaves_like 'migration without any rubocop offense'
+ end
+end
diff --git a/spec/rubocop/cop/qa/fabricate_usage_spec.rb b/spec/rubocop/cop/qa/fabricate_usage_spec.rb
new file mode 100644
index 00000000000..7c4b42b91e0
--- /dev/null
+++ b/spec/rubocop/cop/qa/fabricate_usage_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+
+require_relative '../../../../rubocop/cop/qa/fabricate_usage'
+
+RSpec.describe RuboCop::Cop::QA::FabricateUsage, feature_category: :quality_management do
+ let(:source_file) { 'qa/qa/specs/spec.rb' }
+
+ it 'registers an offense when using fabricate_via_api! for a valid resource' do
+ expect_offense(<<~RUBY)
+ Resource::Project.fabricate_via_api! do |project|
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer create(:project[, ...]) here.
+ project.name = 'test'
+ end
+ RUBY
+ end
+
+ it 'registers an offense for groups' do
+ expect_offense(<<~RUBY)
+ Resource::Group.fabricate_via_api! do |group|
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer create(:group[, ...]) here.
+ group.path = 'test'
+ end
+ RUBY
+ end
+
+ it 'does not register an offense when using fabricate_via_api! for an unenforced resource' do
+ expect_no_offenses(<<~RUBY)
+ Resource::Invalid.fabricate_via_api! do |project|
+ project.name = 'test'
+ end
+ RUBY
+ end
+end
diff --git a/spec/rubocop/cop/rspec/env_mocking_spec.rb b/spec/rubocop/cop/rspec/env_mocking_spec.rb
index 189fccf483a..fec2000c88b 100644
--- a/spec/rubocop/cop/rspec/env_mocking_spec.rb
+++ b/spec/rubocop/cop/rspec/env_mocking_spec.rb
@@ -34,23 +34,23 @@ RSpec.describe RuboCop::Cop::RSpec::EnvMocking, feature_category: :tooling do
context 'with mocking bracket calls ' do
it_behaves_like 'cop offense mocking the ENV constant correctable with stub_env',
- offense_call_brackets_string_quotes, %(stub_env('FOO', 'bar'))
+ offense_call_brackets_string_quotes, %(stub_env('FOO', 'bar'))
it_behaves_like 'cop offense mocking the ENV constant correctable with stub_env',
- offense_call_brackets_variables, %(stub_env(key, value))
+ offense_call_brackets_variables, %(stub_env(key, value))
end
context 'with mocking fetch calls' do
it_behaves_like 'cop offense mocking the ENV constant correctable with stub_env',
- offense_call_fetch_string_quotes, %(stub_env('FOO', 'bar'))
+ offense_call_fetch_string_quotes, %(stub_env('FOO', 'bar'))
it_behaves_like 'cop offense mocking the ENV constant correctable with stub_env',
- offense_call_fetch_variables, %(stub_env(key, value))
+ offense_call_fetch_variables, %(stub_env(key, value))
end
context 'with other special cases and variations' do
it_behaves_like 'cop offense mocking the ENV constant correctable with stub_env',
- offense_call_root_env_variables, %(stub_env(key, value))
+ offense_call_root_env_variables, %(stub_env(key, value))
it_behaves_like 'cop offense mocking the ENV constant correctable with stub_env',
- offense_call_key_value_method_calls, %(stub_env(fetch_key(object), fetch_value(object)))
+ offense_call_key_value_method_calls, %(stub_env(fetch_key(object), fetch_value(object)))
end
context 'with acceptable cases' do
diff --git a/spec/rubocop/cop/rspec/invalid_feature_category_spec.rb b/spec/rubocop/cop/rspec/feature_category_spec.rb
index e5287f7105e..05e3cae012e 100644
--- a/spec/rubocop/cop/rspec/invalid_feature_category_spec.rb
+++ b/spec/rubocop/cop/rspec/feature_category_spec.rb
@@ -3,14 +3,15 @@
require 'rubocop_spec_helper'
require 'rspec-parameterized'
-require_relative '../../../../rubocop/cop/rspec/invalid_feature_category'
+require_relative '../../../../rubocop/feature_categories'
+require_relative '../../../../rubocop/cop/rspec/feature_category'
-RSpec.describe RuboCop::Cop::RSpec::InvalidFeatureCategory, feature_category: :tooling do
+RSpec.describe RuboCop::Cop::RSpec::FeatureCategory, feature_category: :tooling do
shared_examples 'feature category validation' do |valid_category|
it 'flags invalid feature category in top level example group' do
expect_offense(<<~RUBY, invalid: invalid_category)
RSpec.describe 'foo', feature_category: :%{invalid}, foo: :bar do
- ^^{invalid} Please use a valid feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#rspec-examples.
+ ^^{invalid} Please use a valid feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#rspec-examples
end
RUBY
end
@@ -19,7 +20,7 @@ RSpec.describe RuboCop::Cop::RSpec::InvalidFeatureCategory, feature_category: :t
expect_offense(<<~RUBY, valid: valid_category, invalid: invalid_category)
RSpec.describe 'foo', feature_category: :"%{valid}" do
context 'bar', foo: :bar, feature_category: :%{invalid} do
- ^^{invalid} Please use a valid feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#rspec-examples.
+ ^^{invalid} Please use a valid feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#rspec-examples
end
end
RUBY
@@ -29,7 +30,7 @@ RSpec.describe RuboCop::Cop::RSpec::InvalidFeatureCategory, feature_category: :t
expect_offense(<<~RUBY, valid: valid_category, invalid: invalid_category)
RSpec.describe 'foo', feature_category: :"%{valid}" do
it 'bar', feature_category: :%{invalid} do
- ^^{invalid} Please use a valid feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#rspec-examples.
+ ^^{invalid} Please use a valid feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#rspec-examples
end
end
RUBY
@@ -63,21 +64,14 @@ RSpec.describe RuboCop::Cop::RSpec::InvalidFeatureCategory, feature_category: :t
let(:invalid_category) { :invalid_category }
- context 'with categories defined in config/feature_categories.yml' do
- where(:valid_category) do
- YAML.load_file(rails_root_join('config/feature_categories.yml'))
- end
+ context 'with defined in config/feature_categories.yml and custom categories' do
+ where(:valid_category) { RuboCop::FeatureCategories.available_with_custom.to_a }
with_them do
it_behaves_like 'feature category validation', params[:valid_category]
end
end
- context 'with custom categories' do
- it_behaves_like 'feature category validation', 'tooling'
- it_behaves_like 'feature category validation', 'shared'
- end
-
it 'flags invalid feature category for non-symbols' do
expect_offense(<<~RUBY, invalid: invalid_category)
RSpec.describe 'foo', feature_category: "%{invalid}" do
@@ -91,9 +85,11 @@ RSpec.describe RuboCop::Cop::RSpec::InvalidFeatureCategory, feature_category: :t
end
it 'does not flag use of invalid categories in non-example code' do
+ valid_category = RuboCop::FeatureCategories.available.first
+
# See https://gitlab.com/gitlab-org/gitlab/-/issues/381882#note_1265865125
expect_no_offenses(<<~RUBY)
- RSpec.describe 'A spec' do
+ RSpec.describe 'A spec', feature_category: :#{valid_category} do
let(:api_handler) do
Class.new(described_class) do
namespace '/test' do
@@ -112,6 +108,18 @@ RSpec.describe RuboCop::Cop::RSpec::InvalidFeatureCategory, feature_category: :t
RUBY
end
+ it 'flags missing feature category in top level example group' do
+ expect_offense(<<~RUBY)
+ RSpec.describe 'foo' do
+ ^^^^^^^^^^^^^^^^^^^^^^^ Please use a valid feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#rspec-examples
+ end
+
+ RSpec.describe 'foo', some: :tag do
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Please use a valid feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#rspec-examples
+ end
+ RUBY
+ end
+
describe '#external_dependency_checksum' do
it 'returns a SHA256 digest used by RuboCop to invalid cache' do
expect(cop.external_dependency_checksum).to match(/^\h{64}$/)
diff --git a/spec/rubocop/cop/rspec/missing_feature_category_spec.rb b/spec/rubocop/cop/rspec/missing_feature_category_spec.rb
deleted file mode 100644
index 41b1d2b8580..00000000000
--- a/spec/rubocop/cop/rspec/missing_feature_category_spec.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-require 'rubocop_spec_helper'
-require_relative '../../../../rubocop/cop/rspec/missing_feature_category'
-
-RSpec.describe RuboCop::Cop::RSpec::MissingFeatureCategory, feature_category: :tooling do
- it 'flags missing feature category in top level example group' do
- expect_offense(<<~RUBY)
- RSpec.describe 'foo' do
- ^^^^^^^^^^^^^^^^^^^^ Please add missing feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#rspec-examples.
- end
-
- RSpec.describe 'foo', some: :tag do
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Please add missing feature category. See https://docs.gitlab.com/ee/development/feature_categorization/#rspec-examples.
- end
- RUBY
- end
-
- it 'does not flag if feature category is defined' do
- expect_no_offenses(<<~RUBY)
- RSpec.describe 'foo', feature_category: :foo do
- end
-
- RSpec.describe 'foo', some: :tag, feature_category: :foo do
- end
-
- RSpec.describe 'foo', feature_category: :foo, some: :tag do
- end
- RUBY
- end
-end
diff --git a/spec/rubocop/cop/style/regexp_literal_mixed_preserve_spec.rb b/spec/rubocop/cop/style/regexp_literal_mixed_preserve_spec.rb
index 1d1c0852db2..d2ccd504fcd 100644
--- a/spec/rubocop/cop/style/regexp_literal_mixed_preserve_spec.rb
+++ b/spec/rubocop/cop/style/regexp_literal_mixed_preserve_spec.rb
@@ -10,10 +10,10 @@ require_relative '../../../../rubocop/cop/style/regexp_literal_mixed_preserve'
RSpec.describe RuboCop::Cop::Style::RegexpLiteralMixedPreserve, :config do
let(:config) do
supported_styles = { 'SupportedStyles' => %w[slashes percent_r mixed mixed_preserve] }
- RuboCop::Config.new('Style/PercentLiteralDelimiters' =>
- percent_literal_delimiters_config,
- 'Style/RegexpLiteralMixedPreserve' =>
- cop_config.merge(supported_styles))
+ RuboCop::Config.new(
+ 'Style/PercentLiteralDelimiters' => percent_literal_delimiters_config,
+ 'Style/RegexpLiteralMixedPreserve' => cop_config.merge(supported_styles)
+ )
end
let(:percent_literal_delimiters_config) { { 'PreferredDelimiters' => { '%r' => '{}' } } }
diff --git a/spec/rubocop/feature_categories_spec.rb b/spec/rubocop/feature_categories_spec.rb
new file mode 100644
index 00000000000..ffe7ade82e2
--- /dev/null
+++ b/spec/rubocop/feature_categories_spec.rb
@@ -0,0 +1,102 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+
+require_relative '../../rubocop/feature_categories'
+
+RSpec.describe RuboCop::FeatureCategories, feature_category: :tooling do
+ subject(:feature_categories) { described_class.new(categories) }
+
+ let(:categories) { ['valid_category'] }
+
+ describe '.available' do
+ it 'returns a list of available feature categories in a set of strings' do
+ expect(described_class.available).to be_a(Set)
+ expect(described_class.available).to all(be_a(String))
+ end
+ end
+
+ describe '.available_with_custom' do
+ it 'returns a list of available feature categories' do
+ expect(described_class.available_with_custom).to include(described_class.available)
+ end
+
+ it 'returns a list containing the custom feature categories' do
+ expect(described_class.available_with_custom).to include(described_class::CUSTOM_CATEGORIES)
+ end
+ end
+
+ describe '.config_checksum' do
+ it 'returns a SHA256 digest used by RuboCop to invalid cache' do
+ expect(described_class.config_checksum).to match(/^\h{64}$/)
+ end
+ end
+
+ describe '#check' do
+ let(:value_node) { instance_double(RuboCop::AST::SymbolNode, sym_type?: true) }
+ let(:document_link) { 'https://example.com' }
+
+ def check
+ expect do |block|
+ feature_categories.check(
+ value_node: value_node,
+ document_link: document_link,
+ &block)
+ end
+ end
+
+ context 'when value_node is nil' do
+ let(:value_node) { nil }
+
+ it 'yields a message asking for a feature category with document link only' do
+ check.to yield_with_args(<<~MARKDOWN.chomp)
+ Please use a valid feature category. See https://example.com
+ MARKDOWN
+ end
+ end
+
+ context 'when value_node is not a symbol node' do
+ before do
+ allow(value_node).to receive(:sym_type?).and_return(false)
+ end
+
+ it 'yields a message asking for a symbol value' do
+ check.to yield_with_args(described_class::MSG_SYMBOL)
+ end
+ end
+
+ context 'when category is found' do
+ before do
+ allow(value_node).to receive(:value).and_return(categories.first)
+ end
+
+ it 'returns nil without yielding anything' do
+ check.not_to yield_with_args
+ end
+ end
+
+ context 'when a similar category is found' do
+ before do
+ allow(value_node).to receive(:value).and_return('invalid_category')
+ end
+
+ it 'yields a message asking for a feature category with suggestion and document link' do
+ check.to yield_with_args(<<~MARKDOWN.chomp)
+ Please use a valid feature category. Did you mean `:valid_category`? See https://example.com
+ MARKDOWN
+ end
+ end
+
+ context 'when no similar category is found' do
+ before do
+ allow(value_node).to receive(:value).and_return('something_completely_different')
+ end
+
+ it 'yields a message asking for a feature category with document link only' do
+ check.to yield_with_args(<<~MARKDOWN.chomp)
+ Please use a valid feature category. See https://example.com
+ MARKDOWN
+ end
+ end
+ end
+end
diff --git a/spec/rubocop/formatter/graceful_formatter_spec.rb b/spec/rubocop/formatter/graceful_formatter_spec.rb
index d76e566e2b4..b9a56bec115 100644
--- a/spec/rubocop/formatter/graceful_formatter_spec.rb
+++ b/spec/rubocop/formatter/graceful_formatter_spec.rb
@@ -220,19 +220,20 @@ RSpec.describe RuboCop::Formatter::GracefulFormatter, :isolated_environment do
def fake_offense(cop_name)
# rubocop:disable RSpec/VerifiedDoubles
- double(:offense,
- cop_name: cop_name,
- corrected?: false,
- correctable?: false,
- severity: double(:severity, name: :convention, code: :C),
- line: 5,
- column: 23,
- real_column: 23,
- corrected_with_todo?: false,
- message: "#{cop_name} message",
- location: double(:location, source_line: 'line', first_line: 1, last_line: 1, single_line?: true),
- highlighted_area: double(:highlighted_area, begin_pos: 1, size: 2, source_buffer: 'line', source: 'i')
- )
+ double(
+ :offense,
+ cop_name: cop_name,
+ corrected?: false,
+ correctable?: false,
+ severity: double(:severity, name: :convention, code: :C),
+ line: 5,
+ column: 23,
+ real_column: 23,
+ corrected_with_todo?: false,
+ message: "#{cop_name} message",
+ location: double(:location, source_line: 'line', first_line: 1, last_line: 1, single_line?: true),
+ highlighted_area: double(:highlighted_area, begin_pos: 1, size: 2, source_buffer: 'line', source: 'i')
+ )
# rubocop:enable RSpec/VerifiedDoubles
end
end