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:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-03-18 23:02:30 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-18 23:02:30 +0300
commit41fe97390ceddf945f3d967b8fdb3de4c66b7dea (patch)
tree9c8d89a8624828992f06d892cd2f43818ff5dcc8 /spec/rubocop
parent0804d2dc31052fb45a1efecedc8e06ce9bc32862 (diff)
Add latest changes from gitlab-org/gitlab@14-9-stable-eev14.9.0-rc42
Diffstat (limited to 'spec/rubocop')
-rw-r--r--spec/rubocop/cop/database/establish_connection_spec.rb2
-rw-r--r--spec/rubocop/cop/database/multiple_databases_spec.rb10
-rw-r--r--spec/rubocop/cop/graphql/graphql_name_position_spec.rb44
-rw-r--r--spec/rubocop/formatter/todo_formatter_spec.rb284
-rw-r--r--spec/rubocop/todo_dir_spec.rb218
5 files changed, 557 insertions, 1 deletions
diff --git a/spec/rubocop/cop/database/establish_connection_spec.rb b/spec/rubocop/cop/database/establish_connection_spec.rb
index a3c27d33cb0..3919872b5e7 100644
--- a/spec/rubocop/cop/database/establish_connection_spec.rb
+++ b/spec/rubocop/cop/database/establish_connection_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'spec_helper'
+require 'fast_spec_helper'
require_relative '../../../../rubocop/cop/database/establish_connection'
RSpec.describe RuboCop::Cop::Database::EstablishConnection do
diff --git a/spec/rubocop/cop/database/multiple_databases_spec.rb b/spec/rubocop/cop/database/multiple_databases_spec.rb
index 16b916d61db..8bcd4710305 100644
--- a/spec/rubocop/cop/database/multiple_databases_spec.rb
+++ b/spec/rubocop/cop/database/multiple_databases_spec.rb
@@ -12,4 +12,14 @@ RSpec.describe RuboCop::Cop::Database::MultipleDatabases do
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use methods from ActiveRecord::Base, [...]
SOURCE
end
+
+ described_class::ALLOWED_METHODS.each do |method_name|
+ it "does not flag use of ActiveRecord::Base.#{method_name}" do
+ expect_no_offenses(<<~SOURCE)
+ ActiveRecord::Base.#{method_name} do
+ Project.save
+ end
+ SOURCE
+ end
+ end
end
diff --git a/spec/rubocop/cop/graphql/graphql_name_position_spec.rb b/spec/rubocop/cop/graphql/graphql_name_position_spec.rb
new file mode 100644
index 00000000000..42cc398ed84
--- /dev/null
+++ b/spec/rubocop/cop/graphql/graphql_name_position_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+require_relative '../../../../rubocop/cop/graphql/graphql_name_position'
+
+RSpec.describe RuboCop::Cop::Graphql::GraphqlNamePosition do
+ subject(:cop) { described_class.new }
+
+ it 'adds an offense when graphql_name is not on the first line' do
+ expect_offense(<<~TYPE)
+ module Types
+ class AType < BaseObject
+ ^^^^^^^^^^^^^^^^^^^^^^^^ `graphql_name` should be the first line of the class: https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#naming-conventions
+ field :a_thing
+ field :another_thing
+ graphql_name 'ATypeName'
+ end
+ end
+ TYPE
+ end
+
+ it 'does not add an offense for classes that have no call to graphql_name' do
+ expect_no_offenses(<<~TYPE.strip)
+ module Types
+ class AType < BaseObject
+ authorize :an_ability, :second_ability
+
+ field :a_thing
+ end
+ end
+ TYPE
+ end
+
+ it 'does not add an offense for classes that only call graphql_name' do
+ expect_no_offenses(<<~TYPE.strip)
+ module Types
+ class AType < BaseObject
+ graphql_name 'ATypeName'
+ end
+ end
+ TYPE
+ end
+end
diff --git a/spec/rubocop/formatter/todo_formatter_spec.rb b/spec/rubocop/formatter/todo_formatter_spec.rb
new file mode 100644
index 00000000000..e1b1de33bfe
--- /dev/null
+++ b/spec/rubocop/formatter/todo_formatter_spec.rb
@@ -0,0 +1,284 @@
+# frozen_string_literal: true
+# rubocop:disable RSpec/VerifiedDoubles
+
+require 'fast_spec_helper'
+require 'stringio'
+require 'fileutils'
+
+require_relative '../../../rubocop/formatter/todo_formatter'
+require_relative '../../../rubocop/todo_dir'
+
+RSpec.describe RuboCop::Formatter::TodoFormatter do
+ let(:stdout) { StringIO.new }
+ let(:tmp_dir) { Dir.mktmpdir }
+ let(:real_tmp_dir) { File.join(tmp_dir, 'real') }
+ let(:symlink_tmp_dir) { File.join(tmp_dir, 'symlink') }
+ let(:rubocop_todo_dir) { "#{symlink_tmp_dir}/.rubocop_todo" }
+ let(:options) { { rubocop_todo_dir: rubocop_todo_dir } }
+ let(:todo_dir) { RuboCop::TodoDir.new(rubocop_todo_dir) }
+
+ subject(:formatter) { described_class.new(stdout, options) }
+
+ around do |example|
+ FileUtils.mkdir(real_tmp_dir)
+ FileUtils.symlink(real_tmp_dir, symlink_tmp_dir)
+
+ Dir.chdir(symlink_tmp_dir) do
+ example.run
+ end
+ end
+
+ after do
+ FileUtils.remove_entry(tmp_dir)
+ end
+
+ context 'with offenses detected' do
+ let(:offense) { fake_offense('A/Offense') }
+ let(:offense_too_many) { fake_offense('B/TooManyOffenses') }
+ let(:offense_autocorrect) { fake_offense('B/AutoCorrect') }
+
+ before do
+ stub_const("#{described_class}::MAX_OFFENSE_COUNT", 1)
+
+ stub_rubocop_registry(
+ 'A/Offense' => { autocorrectable: false },
+ 'B/AutoCorrect' => { autocorrectable: true }
+ )
+ end
+
+ def run_formatter
+ formatter.started(%w[a.rb b.rb c.rb d.rb])
+ formatter.file_finished('c.rb', [offense_too_many])
+ formatter.file_finished('a.rb', [offense_too_many, offense, offense_too_many])
+ formatter.file_finished('b.rb', [])
+ formatter.file_finished('d.rb', [offense_autocorrect])
+ formatter.finished(%w[a.rb b.rb c.rb d.rb])
+ end
+
+ it 'outputs its actions' do
+ run_formatter
+
+ expect(stdout.string).to eq(<<~OUTPUT)
+ Written to .rubocop_todo/a/offense.yml
+ Written to .rubocop_todo/b/auto_correct.yml
+ Written to .rubocop_todo/b/too_many_offenses.yml
+ OUTPUT
+ end
+
+ it 'creates YAML files', :aggregate_failures do
+ run_formatter
+
+ expect(rubocop_todo_dir_listing).to contain_exactly(
+ 'a/offense.yml', 'b/auto_correct.yml', 'b/too_many_offenses.yml'
+ )
+
+ expect(todo_yml('A/Offense')).to eq(<<~YAML)
+ ---
+ A/Offense:
+ Exclude:
+ - 'a.rb'
+ YAML
+
+ expect(todo_yml('B/AutoCorrect')).to eq(<<~YAML)
+ ---
+ # Cop supports --auto-correct.
+ B/AutoCorrect:
+ Exclude:
+ - 'd.rb'
+ YAML
+
+ expect(todo_yml('B/TooManyOffenses')).to eq(<<~YAML)
+ ---
+ B/TooManyOffenses:
+ Exclude:
+ - 'a.rb'
+ - 'c.rb'
+ YAML
+ end
+
+ context 'when cop previously not explicitly disabled' do
+ before do
+ todo_dir.write('B/TooManyOffenses', <<~YAML)
+ ---
+ B/TooManyOffenses:
+ Exclude:
+ - 'x.rb'
+ YAML
+ end
+
+ it 'does not disable cop' do
+ run_formatter
+
+ expect(todo_yml('B/TooManyOffenses')).to eq(<<~YAML)
+ ---
+ B/TooManyOffenses:
+ Exclude:
+ - 'a.rb'
+ - 'c.rb'
+ YAML
+ end
+ end
+
+ context 'when cop previously explicitly disabled in rubocop_todo/' do
+ before do
+ todo_dir.write('B/TooManyOffenses', <<~YAML)
+ ---
+ B/TooManyOffenses:
+ Enabled: false
+ Exclude:
+ - 'x.rb'
+ YAML
+
+ todo_dir.inspect_all
+ end
+
+ it 'keeps cop disabled' do
+ run_formatter
+
+ expect(todo_yml('B/TooManyOffenses')).to eq(<<~YAML)
+ ---
+ B/TooManyOffenses:
+ # Offense count: 3
+ # Temporarily disabled due to too many offenses
+ Enabled: false
+ Exclude:
+ - 'a.rb'
+ - 'c.rb'
+ YAML
+ end
+ end
+
+ context 'when cop previously explicitly disabled in rubocop_todo.yml' do
+ before do
+ File.write('.rubocop_todo.yml', <<~YAML)
+ ---
+ B/TooManyOffenses:
+ Enabled: false
+ Exclude:
+ - 'x.rb'
+ YAML
+ end
+
+ it 'keeps cop disabled' do
+ run_formatter
+
+ expect(todo_yml('B/TooManyOffenses')).to eq(<<~YAML)
+ ---
+ B/TooManyOffenses:
+ # Offense count: 3
+ # Temporarily disabled due to too many offenses
+ Enabled: false
+ Exclude:
+ - 'a.rb'
+ - 'c.rb'
+ YAML
+ end
+ end
+
+ context 'with cop configuration in both .rubocop_todo/ and .rubocop_todo.yml' do
+ before do
+ todo_dir.write('B/TooManyOffenses', <<~YAML)
+ ---
+ B/TooManyOffenses:
+ Exclude:
+ - 'a.rb'
+ YAML
+
+ todo_dir.write('A/Offense', <<~YAML)
+ ---
+ A/Offense:
+ Exclude:
+ - 'a.rb'
+ YAML
+
+ todo_dir.inspect_all
+
+ File.write('.rubocop_todo.yml', <<~YAML)
+ ---
+ B/TooManyOffenses:
+ Exclude:
+ - 'x.rb'
+ A/Offense:
+ Exclude:
+ - 'y.rb'
+ YAML
+ end
+
+ it 'raises an error' do
+ expect { run_formatter }.to raise_error(RuntimeError, <<~TXT)
+ Multiple configurations found for cops:
+ - A/Offense
+ - B/TooManyOffenses
+ TXT
+ end
+ end
+ end
+
+ context 'without offenses detected' do
+ before do
+ formatter.started(%w[a.rb b.rb])
+ formatter.file_finished('a.rb', [])
+ formatter.file_finished('b.rb', [])
+ formatter.finished(%w[a.rb b.rb])
+ end
+
+ it 'does not output anything' do
+ expect(stdout.string).to eq('')
+ end
+
+ it 'does not write any YAML files' do
+ expect(rubocop_todo_dir_listing).to be_empty
+ end
+ end
+
+ context 'without files to inspect' do
+ before do
+ formatter.started([])
+ formatter.finished([])
+ end
+
+ it 'does not output anything' do
+ expect(stdout.string).to eq('')
+ end
+
+ it 'does not write any YAML files' do
+ expect(rubocop_todo_dir_listing).to be_empty
+ end
+ end
+
+ private
+
+ def rubocop_todo_dir_listing
+ Dir.glob("#{rubocop_todo_dir}/**/*")
+ .select { |path| File.file?(path) }
+ .map { |path| path.delete_prefix("#{rubocop_todo_dir}/") }
+ end
+
+ def todo_yml(cop_name)
+ todo_dir.read(cop_name)
+ end
+
+ def fake_offense(cop_name)
+ double(:offense, cop_name: cop_name)
+ end
+
+ def stub_rubocop_registry(**cops)
+ rubocop_registry = double(:rubocop_registry)
+
+ allow(RuboCop::Cop::Registry).to receive(:global).and_return(rubocop_registry)
+
+ allow(rubocop_registry).to receive(:find_by_cop_name)
+ .with(String).and_return(nil)
+
+ cops.each do |cop_name, attributes|
+ allow(rubocop_registry).to receive(:find_by_cop_name)
+ .with(cop_name).and_return(fake_cop(**attributes))
+ end
+ end
+
+ def fake_cop(autocorrectable:)
+ double(:cop, support_autocorrect?: autocorrectable)
+ end
+end
+
+# rubocop:enable RSpec/VerifiedDoubles
diff --git a/spec/rubocop/todo_dir_spec.rb b/spec/rubocop/todo_dir_spec.rb
new file mode 100644
index 00000000000..ae59def885d
--- /dev/null
+++ b/spec/rubocop/todo_dir_spec.rb
@@ -0,0 +1,218 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'fileutils'
+require 'active_support/inflector/inflections'
+
+require_relative '../../rubocop/todo_dir'
+
+RSpec.describe RuboCop::TodoDir do
+ let(:todo_dir) { described_class.new(directory) }
+ let(:directory) { Dir.mktmpdir }
+ let(:cop_name) { 'RSpec/VariableInstance' }
+ let(:cop_name_underscore) { ActiveSupport::Inflector.underscore(cop_name) }
+ let(:yaml_path) { "#{File.join(directory, cop_name_underscore)}.yml" }
+
+ around do |example|
+ Dir.chdir(directory) do
+ example.run
+ end
+ end
+
+ after do
+ FileUtils.remove_entry(directory)
+ end
+
+ describe '#initialize' do
+ context 'when passing inflector' do
+ let(:fake_inflector) { double(:inflector) } # rubocop:disable RSpec/VerifiedDoubles
+ let(:todo_dir) { described_class.new(directory, inflector: fake_inflector) }
+
+ before do
+ allow(fake_inflector).to receive(:underscore)
+ .with(cop_name)
+ .and_return(cop_name_underscore)
+ end
+
+ it 'calls .underscore' do
+ todo_dir.write(cop_name, 'a')
+
+ expect(fake_inflector).to have_received(:underscore)
+ end
+ end
+ end
+
+ describe '#directory' do
+ subject { todo_dir.directory }
+
+ it { is_expected.to eq(directory) }
+ end
+
+ describe '#read' do
+ let(:content) { 'a' }
+
+ subject { todo_dir.read(cop_name) }
+
+ context 'when file exists' do
+ before do
+ todo_dir.write(cop_name, content)
+ end
+
+ it { is_expected.to eq(content) }
+ end
+
+ context 'when file is missing' do
+ it { is_expected.to be_nil }
+ end
+ end
+
+ describe '#write' do
+ let(:content) { 'a' }
+
+ subject { todo_dir.write(cop_name, content) }
+
+ it { is_expected.to eq(yaml_path) }
+
+ it 'writes content to YAML file' do
+ subject
+
+ expect(File.read(yaml_path)).to eq(content)
+ end
+ end
+
+ describe '#inspect' do
+ subject { todo_dir.inspect(cop_name) }
+
+ context 'with existing YAML file' do
+ before do
+ todo_dir.write(cop_name, 'a')
+ end
+
+ it { is_expected.to eq(true) }
+
+ it 'moves YAML file to .inspect' do
+ subject
+
+ expect(File).not_to exist(yaml_path)
+ expect(File).to exist("#{yaml_path}.inspect")
+ end
+ end
+
+ context 'with missing YAML file' do
+ it { is_expected.to eq(false) }
+ end
+ end
+
+ describe '#inspect_all' do
+ subject { todo_dir.inspect_all }
+
+ context 'with YAML files' do
+ before do
+ todo_dir.write(cop_name, 'a')
+ todo_dir.write('Other/Rule', 'a')
+ todo_dir.write('Very/Nested/Rule', 'a')
+ end
+
+ it { is_expected.to eq(3) }
+
+ it 'moves all YAML files to .inspect' do
+ subject
+
+ expect(Dir.glob('**/*.yml')).to be_empty
+ expect(Dir.glob('**/*.yml.inspect').size).to eq(3)
+ end
+ end
+
+ context 'with non-YAML files' do
+ before do
+ File.write('file', 'a')
+ File.write('file.txt', 'a')
+ File.write('file.yaml', 'a') # not .yml
+ end
+
+ it { is_expected.to eq(0) }
+
+ it 'does not move non-YAML files' do
+ subject
+
+ expect(Dir.glob('**/*'))
+ .to contain_exactly('file', 'file.txt', 'file.yaml')
+ end
+ end
+
+ context 'without files' do
+ it { is_expected.to eq(0) }
+ end
+ end
+
+ describe '#list_inspect' do
+ let(:content) { 'a' }
+
+ subject { todo_dir.list_inspect }
+
+ context 'when file exists and is being inspected' do
+ before do
+ todo_dir.write(cop_name, content)
+ todo_dir.inspect_all
+ end
+
+ it do
+ is_expected.to contain_exactly("#{yaml_path}.inspect")
+ end
+ end
+
+ context 'when file exists but not being inspected' do
+ before do
+ todo_dir.write(cop_name, content)
+ end
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'when file is missing' do
+ it { is_expected.to be_empty }
+ end
+ end
+
+ describe '#delete_inspected' do
+ subject { todo_dir.delete_inspected }
+
+ context 'with YAML files' do
+ before do
+ todo_dir.write(cop_name, 'a')
+ todo_dir.write('Other/Rule', 'a')
+ todo_dir.write('Very/Nested/Rule', 'a')
+ todo_dir.inspect_all
+ end
+
+ it { is_expected.to eq(3) }
+
+ it 'deletes all .inspected YAML files' do
+ subject
+
+ expect(Dir.glob('**/*.yml.inspect')).to be_empty
+ end
+ end
+
+ context 'with non-YAML files' do
+ before do
+ File.write('file.inspect', 'a')
+ File.write('file.txt.inspect', 'a')
+ File.write('file.yaml.inspect', 'a') # not .yml
+ end
+
+ it { is_expected.to eq(0) }
+
+ it 'does not delete non-YAML files' do
+ subject
+
+ expect(Dir.glob('**/*')).to contain_exactly(
+ 'file.inspect', 'file.txt.inspect', 'file.yaml.inspect')
+ end
+ end
+
+ context 'without files' do
+ it { is_expected.to eq(0) }
+ end
+ end
+end