summaryrefslogtreecommitdiff
path: root/spec/rubocop/cop
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-11-17 11:33:21 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-11-17 11:33:21 +0000
commit7021455bd1ed7b125c55eb1b33c5a01f2bc55ee0 (patch)
tree5bdc2229f5198d516781f8d24eace62fc7e589e9 /spec/rubocop/cop
parent185b095e93520f96e9cfc31d9c3e69b498cdab7c (diff)
downloadgitlab-ce-7021455bd1ed7b125c55eb1b33c5a01f2bc55ee0.tar.gz
Add latest changes from gitlab-org/gitlab@15-6-stable-eev15.6.0-rc42
Diffstat (limited to 'spec/rubocop/cop')
-rw-r--r--spec/rubocop/cop/api/ensure_string_detail_spec.rb136
-rw-r--r--spec/rubocop/cop/gitlab/json_spec.rb45
-rw-r--r--spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb4
-rw-r--r--spec/rubocop/cop/gitlab/rspec/avoid_setup_spec.rb36
-rw-r--r--spec/rubocop/cop/graphql/enum_names_spec.rb52
-rw-r--r--spec/rubocop/cop/graphql/enum_values_spec.rb79
-rw-r--r--spec/rubocop/cop/migration/schema_addition_methods_no_post_spec.rb24
-rw-r--r--spec/rubocop/cop/rake/require_spec.rb60
-rw-r--r--spec/rubocop/cop/rspec/duplicate_spec_location_spec.rb (renamed from spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb)18
-rw-r--r--spec/rubocop/cop/rspec/factory_bot/strategy_in_callback_spec.rb71
10 files changed, 512 insertions, 13 deletions
diff --git a/spec/rubocop/cop/api/ensure_string_detail_spec.rb b/spec/rubocop/cop/api/ensure_string_detail_spec.rb
new file mode 100644
index 00000000000..d4f68711e78
--- /dev/null
+++ b/spec/rubocop/cop/api/ensure_string_detail_spec.rb
@@ -0,0 +1,136 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+require_relative '../../../../rubocop/cop/api/ensure_string_detail'
+
+RSpec.describe RuboCop::Cop::API::EnsureStringDetail do
+ context "when in_api? == true" do
+ before do
+ allow(cop).to receive(:in_api?).and_return(true)
+ end
+
+ context "when detail field uses a string" do
+ it "does not add an offense" do
+ expect_no_offenses(<<~CODE)
+ class SomeAPI
+ resource :projects do
+ desc 'Some API thing related to a project' do
+ detail "foo bar"
+ end
+ end
+ end
+ CODE
+ end
+ end
+
+ context "when detail field uses interpolation in a string" do
+ it "does not add an offense" do
+ baz = "bat"
+
+ expect_no_offenses(<<~CODE)
+ class SomeAPI
+ resource :projects do
+ desc 'Some API thing related to a project' do
+ detail "foo bar #{baz}"
+ end
+ end
+ end
+ CODE
+ end
+ end
+
+ context "when detail field uses a multiline string" do
+ it "does not add an offense" do
+ expect_no_offenses(<<~CODE)
+ class SomeAPI
+ resource :projects do
+ desc 'Some API thing related to a project' do
+ detail "foo bar"\
+ "baz bat"
+ end
+ end
+ end
+ CODE
+ end
+ end
+
+ context "when detail field uses a constant" do
+ it "does not add an offense" do
+ pending
+
+ expect_no_offenses(<<~CODE)
+ class SomeAPI
+ resource :projects do
+ DESCRIPTION = 'A string'
+
+ desc 'Some API thing related to a project' do
+ detail DESCRIPTION
+ end
+ end
+ end
+ CODE
+ end
+ end
+
+ context "when detail field uses a HEREDOC string" do
+ it "does not add an offense" do
+ expect_no_offenses(<<~CODE)
+ class SomeAPI
+ resource :projects do
+ desc 'Some API thing related to a project' do
+ detail <<~END
+ foo bar
+ baz bat
+ END
+ end
+ end
+ end
+ CODE
+ end
+ end
+
+ context "when detail field uses an array" do
+ it "adds an offense" do
+ expect_offense(<<~CODE)
+ class SomeAPI
+ resource :projects do
+ desc 'Some API thing related to a project' do
+ something 'else'
+ detail ["foo", "bar"]
+ ^^^^^^^^^^^^^^^^^^^^^ Only String objects are permitted in API detail field.
+ end
+ end
+ end
+ CODE
+ end
+ end
+
+ context "when detail field is outside of desc block" do
+ it "does not add an offense" do
+ expect_no_offenses(<<~CODE)
+ class Foo
+ detail ["foo", "bar"]
+ end
+ CODE
+ end
+ end
+ end
+
+ context "when in_api? == false" do
+ before do
+ allow(cop).to receive(:in_api?).and_return(false)
+ end
+
+ it "does not add an offense" do
+ expect_no_offenses(<<~CODE)
+ class SomeAPI
+ resource :projects do
+ desc 'Some API thing related to a project' do
+ detail ["foo", "bar"]
+ end
+ end
+ end
+ CODE
+ end
+ end
+end
diff --git a/spec/rubocop/cop/gitlab/json_spec.rb b/spec/rubocop/cop/gitlab/json_spec.rb
index e4ec107747d..70f63a78dd1 100644
--- a/spec/rubocop/cop/gitlab/json_spec.rb
+++ b/spec/rubocop/cop/gitlab/json_spec.rb
@@ -5,12 +5,41 @@ require_relative '../../../../rubocop/cop/gitlab/json'
RSpec.describe RuboCop::Cop::Gitlab::Json do
context 'when ::JSON is called' do
- it 'registers an offense' do
+ it 'registers an offense and autocorrects' do
expect_offense(<<~RUBY)
class Foo
def bar
JSON.parse('{ "foo": "bar" }')
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid calling `JSON` directly. [...]
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Gitlab::Json` over calling `JSON` directly. [...]
+ end
+ end
+ RUBY
+
+ expect_correction(<<~RUBY)
+ class Foo
+ def bar
+ Gitlab::Json.parse('{ "foo": "bar" }')
+ end
+ end
+ RUBY
+ end
+ end
+
+ context 'when ::JSON is called in EE' do
+ it 'registers an offense and autocorrects' do
+ expect_offense(<<~RUBY, '/path/to/ee/foo.rb')
+ class Foo
+ def bar
+ JSON.parse('{ "foo": "bar" }')
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Gitlab::Json` over calling `JSON` directly. [...]
+ end
+ end
+ RUBY
+
+ expect_correction(<<~RUBY)
+ class Foo
+ def bar
+ ::Gitlab::Json.parse('{ "foo": "bar" }')
end
end
RUBY
@@ -18,12 +47,20 @@ RSpec.describe RuboCop::Cop::Gitlab::Json do
end
context 'when ActiveSupport::JSON is called' do
- it 'registers an offense' do
+ it 'registers an offense and autocorrects' do
expect_offense(<<~RUBY)
class Foo
def bar
ActiveSupport::JSON.parse('{ "foo": "bar" }')
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid calling `JSON` directly. [...]
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Gitlab::Json` over calling `JSON` directly. [...]
+ end
+ end
+ RUBY
+
+ expect_correction(<<~RUBY)
+ class Foo
+ def bar
+ Gitlab::Json.parse('{ "foo": "bar" }')
end
end
RUBY
diff --git a/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb b/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb
index a3c9ae8916e..6e60889f737 100644
--- a/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb
+++ b/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb
@@ -194,6 +194,10 @@ RSpec.describe RuboCop::Cop::Gitlab::MarkUsedFeatureFlags do
include_examples 'sets flag as used', 'FEATURE_FLAG = :foo', 'foo'
end
+ describe 'ROUTING_FEATURE_FLAG = :foo' do
+ include_examples 'sets flag as used', 'ROUTING_FEATURE_FLAG = :foo', 'foo'
+ end
+
describe 'Worker `data_consistency` method' do
include_examples 'sets flag as used', 'data_consistency :delayed, feature_flag: :foo', 'foo'
include_examples 'does not set any flags as used', 'data_consistency :delayed'
diff --git a/spec/rubocop/cop/gitlab/rspec/avoid_setup_spec.rb b/spec/rubocop/cop/gitlab/rspec/avoid_setup_spec.rb
new file mode 100644
index 00000000000..f9226649f65
--- /dev/null
+++ b/spec/rubocop/cop/gitlab/rspec/avoid_setup_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+
+require_relative '../../../../../rubocop/cop/gitlab/rspec/avoid_setup'
+
+RSpec.describe RuboCop::Cop::Gitlab::RSpec::AvoidSetup do
+ context 'when calling let_it_be' do
+ let(:source) do
+ <<~SRC
+ let_it_be(:user) { create(:user) }
+ ^^^^^^^^^^^^^^^^ Avoid the use of `let_it_be` [...]
+ SRC
+ end
+
+ it 'registers an offense' do
+ expect_offense(source)
+ end
+ end
+
+ context 'without readability issues' do
+ let(:source) do
+ <<~SRC
+ it 'registers the user and sends them to a project listing page' do
+ user_signs_up
+
+ expect_to_see_account_confirmation_page
+ end
+ SRC
+ end
+
+ it 'does not register an offense' do
+ expect_no_offenses(source)
+ end
+ end
+end
diff --git a/spec/rubocop/cop/graphql/enum_names_spec.rb b/spec/rubocop/cop/graphql/enum_names_spec.rb
new file mode 100644
index 00000000000..f45df068381
--- /dev/null
+++ b/spec/rubocop/cop/graphql/enum_names_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+require_relative '../../../../rubocop/cop/graphql/enum_names'
+
+RSpec.describe RuboCop::Cop::Graphql::EnumNames do
+ describe 'class name' do
+ it 'adds an offense when class name does not end with `Enum`' do
+ expect_offense(<<~ENUM)
+ module Types
+ class Fake < BaseEnum
+ ^^^^ #{described_class::CLASS_NAME_SUFFIX_MSG}
+ graphql_name 'Fake'
+ end
+ end
+ ENUM
+ end
+ end
+
+ describe 'graphql_name' do
+ it 'adds an offense when `graphql_name` is not set' do
+ expect_offense(<<~ENUM)
+ module Types
+ class FakeEnum < BaseEnum
+ ^^^^^^^^^^^^^^^^^^^^^^^^^ #{described_class::GRAPHQL_NAME_MISSING_MSG}
+ end
+ end
+ ENUM
+ end
+
+ it 'adds no offense when `declarative_enum` is used' do
+ expect_no_offenses(<<~ENUM)
+ module Types
+ class FakeEnum < BaseEnum
+ declarative_enum ::FakeModule::FakeDeclarativeEnum
+ end
+ end
+ ENUM
+ end
+
+ it 'adds an offense when `graphql_name` includes `enum`' do
+ expect_offense(<<~ENUM)
+ module Types
+ class FakeEnum < BaseEnum
+ graphql_name 'FakeEnum'
+ ^^^^^^^^^^ #{described_class::GRAPHQL_NAME_WITH_ENUM_MSG}
+ end
+ end
+ ENUM
+ end
+ end
+end
diff --git a/spec/rubocop/cop/graphql/enum_values_spec.rb b/spec/rubocop/cop/graphql/enum_values_spec.rb
new file mode 100644
index 00000000000..5609c86d9ec
--- /dev/null
+++ b/spec/rubocop/cop/graphql/enum_values_spec.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+require_relative '../../../../rubocop/cop/graphql/enum_values'
+
+RSpec.describe RuboCop::Cop::Graphql::EnumValues do
+ it 'adds an offense when enum value is not uppercase' do
+ expect_offense(<<~ENUM)
+ module Types
+ class FakeEnum < BaseEnum
+ graphql_name 'Fake'
+
+ value 'downcase', description: "Downcase."
+ ^^^^^^^^^^ #{described_class::MSG}
+ end
+ end
+ ENUM
+ end
+
+ context 'when values are set dynamically' do
+ it 'adds an offense when enum value is set without `:upcase`' do
+ expect_offense(<<~ENUM)
+ VALUES = ['FOO', 'bar']
+
+ module Types
+ class FakeEnum < BaseEnum
+ graphql_name 'Fake'
+
+ VALUES.each do |val|
+ value val, description: "Dynamic value."
+ ^^^ #{described_class::MSG}
+ end
+ end
+ end
+ ENUM
+ end
+
+ it 'adds no offense when enum value is deprecated' do
+ expect_no_offenses(<<~ENUM)
+ module Types
+ class FakeEnum < BaseEnum
+ graphql_name 'Fake'
+
+ value 'foo', deprecated: { reason: 'Use something else' }
+ end
+ end
+ ENUM
+ end
+
+ it 'adds no offense when enum value is uppercased literally' do
+ expect_no_offenses(<<~'ENUM')
+ module Types
+ class FakeEnum < BaseEnum
+ graphql_name 'Fake'
+
+ value 'FOO'
+ end
+ end
+ ENUM
+ end
+
+ it 'adds no offense when enum value is calling upcased' do
+ expect_no_offenses(<<~'ENUM')
+ VALUES = ['FOO', 'bar']
+
+ module Types
+ class FakeEnum < BaseEnum
+ graphql_name 'Fake'
+
+ VALUES.each do |val|
+ value val.underscore.upcase, description: "Dynamic value."
+ value "#{field.upcase.tr(' ', '_')}_ASC"
+ end
+ end
+ end
+ ENUM
+ end
+ end
+end
diff --git a/spec/rubocop/cop/migration/schema_addition_methods_no_post_spec.rb b/spec/rubocop/cop/migration/schema_addition_methods_no_post_spec.rb
new file mode 100644
index 00000000000..fb087269e2d
--- /dev/null
+++ b/spec/rubocop/cop/migration/schema_addition_methods_no_post_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+require_relative '../../../../rubocop/cop/migration/schema_addition_methods_no_post'
+
+RSpec.describe RuboCop::Cop::Migration::SchemaAdditionMethodsNoPost do
+ before do
+ allow(cop).to receive(:time_enforced?).and_return true
+ end
+
+ it "does not allow 'add_column' to be called" do
+ expect_offense(<<~CODE)
+ add_column
+ ^^^^^^^^^^ #{described_class::MSG}
+ CODE
+ end
+
+ it "does not allow 'create_table' to be called" do
+ expect_offense(<<~CODE)
+ create_table
+ ^^^^^^^^^^^^ #{described_class::MSG}
+ CODE
+ end
+end
diff --git a/spec/rubocop/cop/rake/require_spec.rb b/spec/rubocop/cop/rake/require_spec.rb
new file mode 100644
index 00000000000..bb8c6a1f063
--- /dev/null
+++ b/spec/rubocop/cop/rake/require_spec.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+
+require_relative '../../../../rubocop/cop/rake/require'
+
+RSpec.describe RuboCop::Cop::Rake::Require do
+ let(:msg) { described_class::MSG }
+
+ it 'registers an offenses for require methods' do
+ expect_offense(<<~RUBY)
+ require 'json'
+ ^^^^^^^^^^^^^^ #{msg}
+ require_relative 'gitlab/json'
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg}
+ RUBY
+ end
+
+ it 'does not register offense inside `task` definition' do
+ expect_no_offenses(<<~RUBY)
+ task :parse do
+ require 'json'
+ end
+
+ namespace :some do
+ task parse: :env do
+ require_relative 'gitlab/json'
+ end
+ end
+ RUBY
+ end
+
+ it 'does not register offense inside a block definition' do
+ expect_no_offenses(<<~RUBY)
+ RSpec::Core::RakeTask.new(:parse_json) do |t, args|
+ require 'json'
+ end
+ RUBY
+ end
+
+ it 'does not register offense inside a method definition' do
+ expect_no_offenses(<<~RUBY)
+ def load_deps
+ require 'json'
+ end
+
+ task :parse do
+ load_deps
+ end
+ RUBY
+ end
+
+ it 'does not register offense when require task related files' do
+ expect_no_offenses(<<~RUBY)
+ require 'rubocop/rake_tasks'
+ require 'gettext_i18n_rails/tasks'
+ require_relative '../../rubocop/check_graceful_task'
+ RUBY
+ end
+end
diff --git a/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb b/spec/rubocop/cop/rspec/duplicate_spec_location_spec.rb
index 0a121a495c9..f209ae81661 100644
--- a/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb
+++ b/spec/rubocop/cop/rspec/duplicate_spec_location_spec.rb
@@ -2,16 +2,16 @@
require 'rubocop_spec_helper'
-require_relative '../../../../rubocop/cop/gitlab/duplicate_spec_location'
+require_relative '../../../../rubocop/cop/rspec/duplicate_spec_location'
-RSpec.describe RuboCop::Cop::Gitlab::DuplicateSpecLocation, type: :rubocop_rspec do
+RSpec.describe RuboCop::Cop::RSpec::DuplicateSpecLocation do
let(:rails_root) { '../../../../' }
def full_path(path)
File.expand_path(File.join(rails_root, path), __dir__)
end
- context 'Non-EE spec file' do
+ context 'for a non-EE spec file' do
it 'registers no offenses' do
expect_no_offenses(<<~SOURCE, full_path('spec/foo_spec.rb'))
describe 'Foo' do
@@ -20,7 +20,7 @@ RSpec.describe RuboCop::Cop::Gitlab::DuplicateSpecLocation, type: :rubocop_rspec
end
end
- context 'Non-EE application file' do
+ context 'for a non-EE application file' do
it 'registers no offenses' do
expect_no_offenses(<<~SOURCE, full_path('app/models/blog_post.rb'))
class BlogPost
@@ -29,7 +29,7 @@ RSpec.describe RuboCop::Cop::Gitlab::DuplicateSpecLocation, type: :rubocop_rspec
end
end
- context 'EE application file' do
+ context 'for an EE application file' do
it 'registers no offenses' do
expect_no_offenses(<<~SOURCE, full_path('ee/app/models/blog_post.rb'))
class BlogPost
@@ -38,7 +38,7 @@ RSpec.describe RuboCop::Cop::Gitlab::DuplicateSpecLocation, type: :rubocop_rspec
end
end
- context 'EE spec file for EE only code' do
+ context 'for an EE spec file for EE only code' do
let(:spec_file_path) { full_path('ee/spec/controllers/foo_spec.rb') }
it 'registers no offenses' do
@@ -48,7 +48,7 @@ RSpec.describe RuboCop::Cop::Gitlab::DuplicateSpecLocation, type: :rubocop_rspec
SOURCE
end
- context 'there is a duplicate file' do
+ context 'when there is a duplicate file' do
before do
allow(File).to receive(:exist?).and_call_original
@@ -67,7 +67,7 @@ RSpec.describe RuboCop::Cop::Gitlab::DuplicateSpecLocation, type: :rubocop_rspec
end
end
- context 'EE spec file for EE extension' do
+ context 'for an EE spec file for EE extension' do
let(:spec_file_path) { full_path('ee/spec/controllers/ee/foo_spec.rb') }
it 'registers no offenses' do
@@ -77,7 +77,7 @@ RSpec.describe RuboCop::Cop::Gitlab::DuplicateSpecLocation, type: :rubocop_rspec
SOURCE
end
- context 'there is a duplicate file' do
+ context 'when there is a duplicate file' do
before do
allow(File).to receive(:exist?).and_call_original
diff --git a/spec/rubocop/cop/rspec/factory_bot/strategy_in_callback_spec.rb b/spec/rubocop/cop/rspec/factory_bot/strategy_in_callback_spec.rb
new file mode 100644
index 00000000000..9dcfebc7c1d
--- /dev/null
+++ b/spec/rubocop/cop/rspec/factory_bot/strategy_in_callback_spec.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+
+require_relative '../../../../../rubocop/cop/rspec/factory_bot/strategy_in_callback'
+
+RSpec.describe RuboCop::Cop::RSpec::FactoryBot::StrategyInCallback do
+ shared_examples 'an offensive factory call' do |namespace|
+ described_class::FORBIDDEN_METHODS.each do |forbidden_method|
+ namespaced_forbidden_method = "#{namespace}#{forbidden_method}(:ci_job_artifact, :archive)"
+
+ it "registers an offence for multiple #{namespaced_forbidden_method} calls" do
+ expect_offense(<<-RUBY)
+ FactoryBot.define do
+ factory :ci_build, class: 'Ci::Build', parent: :ci_processable do
+ trait :artifacts do
+ before(:create) do
+ #{namespaced_forbidden_method}
+ #{'^' * namespaced_forbidden_method.size} Prefer inline `association` over `#{forbidden_method}`. See https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#factories
+ end
+
+ after(:create) do |build|
+ #{namespaced_forbidden_method}
+ #{'^' * namespaced_forbidden_method.size} Prefer inline `association` over `#{forbidden_method}`. See https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#factories
+ #{namespaced_forbidden_method}
+ #{'^' * namespaced_forbidden_method.size} Prefer inline `association` over `#{forbidden_method}`. See https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#factories
+ end
+ end
+ end
+ end
+ RUBY
+ end
+
+ it "registers an offense for #{namespaced_forbidden_method} when is a send node" do
+ expect_offense(<<-RUBY)
+ FactoryBot.define do
+ factory :ci_build, class: 'Ci::Build', parent: :ci_processable do
+ trait :artifacts do
+ after(:create) do |build|
+ #{namespaced_forbidden_method}
+ #{'^' * namespaced_forbidden_method.size} Prefer inline `association` over `#{forbidden_method}`. See https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#factories
+ end
+ end
+ end
+ end
+ RUBY
+ end
+
+ it "registers an offense for #{namespaced_forbidden_method} when is assigned" do
+ expect_offense(<<-RUBY)
+ FactoryBot.define do
+ factory :ci_build, class: 'Ci::Build', parent: :ci_processable do
+ trait :artifacts do
+ after(:create) do |build|
+ ci_build = #{namespaced_forbidden_method}
+ #{'^' * namespaced_forbidden_method.size} Prefer inline `association` over `#{forbidden_method}`. See https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#factories
+
+ ci_build
+ end
+ end
+ end
+ end
+ RUBY
+ end
+ end
+ end
+
+ it_behaves_like 'an offensive factory call', ''
+ it_behaves_like 'an offensive factory call', 'FactoryBot.'
+ it_behaves_like 'an offensive factory call', '::FactoryBot.'
+end