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/tooling')
-rw-r--r--spec/tooling/danger/specs_spec.rb33
-rw-r--r--spec/tooling/danger/user_types_spec.rb56
-rw-r--r--spec/tooling/lib/tooling/view_to_js_mappings_spec.rb356
-rw-r--r--spec/tooling/quality/test_level_spec.rb36
4 files changed, 389 insertions, 92 deletions
diff --git a/spec/tooling/danger/specs_spec.rb b/spec/tooling/danger/specs_spec.rb
index dcc1f592062..422923827a8 100644
--- a/spec/tooling/danger/specs_spec.rb
+++ b/spec/tooling/danger/specs_spec.rb
@@ -245,15 +245,16 @@ RSpec.describe Tooling::Danger::Specs, feature_category: :tooling do
" let_it_be(:user) { create(:user) }",
" end",
" describe 'GET \"time_summary\"' do",
- " end"
- ]
- end
-
- let(:matching_lines) do
- [
- "+ RSpec.describe Projects::Analytics::CycleAnalytics::SummaryController, feature_category: :planning_analytics do",
- "+RSpec.describe Projects::Analytics::CycleAnalytics::SummaryController do",
- "+ RSpec.describe Projects::Analytics::CycleAnalytics::SummaryController do"
+ " end",
+ " \n",
+ "RSpec.describe Projects :aggregate_failures,",
+ " feature_category: planning_analytics do",
+ " \n",
+ "RSpec.describe Epics :aggregate_failures,",
+ " ee: true do",
+ "\n",
+ "RSpec.describe Issues :aggregate_failures,",
+ " feature_category: :team_planning do"
]
end
@@ -264,14 +265,24 @@ RSpec.describe Tooling::Danger::Specs, feature_category: :tooling do
"+ let_it_be(:user) { create(:user) }",
"- end",
"+ describe 'GET \"time_summary\"' do",
- "+ RSpec.describe Projects::Analytics::CycleAnalytics::SummaryController do"
+ "+ RSpec.describe Projects::Analytics::CycleAnalytics::SummaryController do",
+ "+RSpec.describe Projects :aggregate_failures,",
+ "+ feature_category: planning_analytics do",
+ "+RSpec.describe Epics :aggregate_failures,",
+ "+ ee: true do",
+ "+RSpec.describe Issues :aggregate_failures,"
]
end
+ before do
+ allow(specs.helper).to receive(:changed_lines).with(filename).and_return(changed_lines)
+ end
+
it 'adds suggestions at the correct lines', :aggregate_failures do
[
{ suggested_line: "RSpec.describe Projects::Analytics::CycleAnalytics::SummaryController do", number: 5 },
- { suggested_line: " RSpec.describe Projects::Analytics::CycleAnalytics::SummaryController do", number: 10 }
+ { suggested_line: " RSpec.describe Projects::Analytics::CycleAnalytics::SummaryController do", number: 10 },
+ { suggested_line: "RSpec.describe Epics :aggregate_failures,", number: 19 }
].each do |test_case|
comment = format(template, suggested_line: test_case[:suggested_line])
diff --git a/spec/tooling/danger/user_types_spec.rb b/spec/tooling/danger/user_types_spec.rb
deleted file mode 100644
index 53556601212..00000000000
--- a/spec/tooling/danger/user_types_spec.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# frozen_string_literal: true
-
-require 'gitlab-dangerfiles'
-require 'gitlab/dangerfiles/spec_helper'
-require_relative '../../../tooling/danger/user_types'
-
-RSpec.describe Tooling::Danger::UserTypes, feature_category: :subscription_cost_management do
- include_context 'with dangerfile'
-
- let(:fake_danger) { DangerSpecHelper.fake_danger.include(described_class) }
- let(:user_types) { fake_danger.new(helper: fake_helper) }
-
- describe 'changed files' do
- subject(:bot_user_types_change_warning) { user_types.bot_user_types_change_warning }
-
- before do
- allow(fake_helper).to receive(:modified_files).and_return(modified_files)
- allow(fake_helper).to receive(:changed_lines).and_return(changed_lines)
- end
-
- context 'when has_user_type.rb file is not impacted' do
- let(:modified_files) { ['app/models/concerns/importable.rb'] }
- let(:changed_lines) { ['+ANY_CHANGES'] }
-
- it "doesn't add any warnings" do
- expect(user_types).not_to receive(:warn)
-
- bot_user_types_change_warning
- end
- end
-
- context 'when the has_user_type.rb file is impacted' do
- let(:modified_files) { ['app/models/concerns/has_user_type.rb'] }
-
- context 'with BOT_USER_TYPES changes' do
- let(:changed_lines) { ['+BOT_USER_TYPES'] }
-
- it 'adds warning' do
- expect(user_types).to receive(:warn).with(described_class::BOT_USER_TYPES_CHANGED_WARNING)
-
- bot_user_types_change_warning
- end
- end
-
- context 'without BOT_USER_TYPES changes' do
- let(:changed_lines) { ['+OTHER_CHANGES'] }
-
- it "doesn't add any warnings" do
- expect(user_types).not_to receive(:warn)
-
- bot_user_types_change_warning
- end
- end
- end
- end
-end
diff --git a/spec/tooling/lib/tooling/view_to_js_mappings_spec.rb b/spec/tooling/lib/tooling/view_to_js_mappings_spec.rb
new file mode 100644
index 00000000000..b09df2a9200
--- /dev/null
+++ b/spec/tooling/lib/tooling/view_to_js_mappings_spec.rb
@@ -0,0 +1,356 @@
+# frozen_string_literal: true
+
+require 'tempfile'
+require_relative '../../../../tooling/lib/tooling/view_to_js_mappings'
+
+RSpec.describe Tooling::ViewToJsMappings, feature_category: :tooling do
+ # We set temporary folders, and those readers give access to those folder paths
+ attr_accessor :view_base_folder, :js_base_folder
+
+ around do |example|
+ Dir.mktmpdir do |tmp_js_base_folder|
+ Dir.mktmpdir do |tmp_views_base_folder|
+ self.js_base_folder = tmp_js_base_folder
+ self.view_base_folder = tmp_views_base_folder
+
+ example.run
+ end
+ end
+ end
+
+ describe '#execute' do
+ let(:instance) do
+ described_class.new(
+ view_base_folder: view_base_folder,
+ js_base_folder: js_base_folder
+ )
+ end
+
+ let(:changed_files) { %W[#{view_base_folder}/index.html] }
+
+ subject { instance.execute(changed_files) }
+
+ context 'when no view files have been changed' do
+ before do
+ allow(instance).to receive(:view_files).and_return([])
+ end
+
+ it 'returns nothing' do
+ expect(subject).to match_array([])
+ end
+ end
+
+ context 'when some view files have been changed' do
+ before do
+ File.write("#{view_base_folder}/index.html", index_html_content)
+ end
+
+ context 'when they do not contain the HTML attribute value we search for' do
+ let(:index_html_content) do
+ <<~FILE
+ Beginning of file
+ End of file
+ FILE
+ end
+
+ it 'returns nothing' do
+ expect(subject).to match_array([])
+ end
+ end
+
+ context 'when they contain the HTML attribute value we search for' do
+ let(:index_html_content) do
+ <<~FILE
+ Beginning of file
+
+ <a id="js-some-id">A link</a>
+
+ End of file
+ FILE
+ end
+
+ context 'when no matching JS files are found' do
+ it 'returns nothing' do
+ expect(subject).to match_array([])
+ end
+ end
+
+ context 'when some matching JS files are found' do
+ let(:index_js_content) do
+ <<~FILE
+ Beginning of file
+
+ const isMainAwardsBlock = votesBlock.closest('#js-some-id.some_class').length;
+
+ End of file
+ FILE
+ end
+
+ before do
+ File.write("#{js_base_folder}/index.js", index_js_content)
+ end
+
+ it 'returns the matching JS files' do
+ expect(subject).to match_array(["#{js_base_folder}/index.js"])
+ end
+ end
+ end
+ end
+
+ context 'when rails partials are included in the file' do
+ before do
+ File.write("#{view_base_folder}/index.html", index_html_content)
+ File.write("#{view_base_folder}/_my-partial.html.haml", partial_file_content)
+ File.write("#{js_base_folder}/index.js", index_js_content)
+ end
+
+ let(:index_html_content) do
+ <<~FILE
+ Beginning of file
+
+ = render 'my-partial'
+
+ End of file
+ FILE
+ end
+
+ let(:partial_file_content) do
+ <<~FILE
+ Beginning of file
+
+ <a class="js-some-class">A link with class</a>
+
+ End of file
+ FILE
+ end
+
+ let(:index_js_content) do
+ <<~FILE
+ Beginning of file
+
+ const isMainAwardsBlock = votesBlock.closest('.js-some-class').length;
+
+ End of file
+ FILE
+ end
+
+ it 'scans those partials for the HTML attribute value' do
+ expect(subject).to match_array(["#{js_base_folder}/index.js"])
+ end
+ end
+ end
+
+ describe '#view_files' do
+ subject { described_class.new(view_base_folder: view_base_folder).view_files(changed_files) }
+
+ before do
+ File.write("#{js_base_folder}/index.js", "index.js")
+ File.write("#{view_base_folder}/index.html", "index.html")
+ end
+
+ context 'when no files were changed' do
+ let(:changed_files) { [] }
+
+ it 'returns an empty array' do
+ expect(subject).to match_array([])
+ end
+ end
+
+ context 'when no view files were changed' do
+ let(:changed_files) { ["#{js_base_folder}/index.js"] }
+
+ it 'returns an empty array' do
+ expect(subject).to match_array([])
+ end
+ end
+
+ context 'when view files were changed' do
+ let(:changed_files) { ["#{js_base_folder}/index.js", "#{view_base_folder}/index.html"] }
+
+ it 'returns the path to the view files' do
+ expect(subject).to match_array(["#{view_base_folder}/index.html"])
+ end
+ end
+
+ context 'when view files are deleted' do
+ let(:changed_files) { ["#{js_base_folder}/index.js", "#{view_base_folder}/deleted.html"] }
+
+ it 'returns an empty array' do
+ expect(subject).to match_array([])
+ end
+ end
+ end
+
+ describe '#folders_for_available_editions' do
+ let(:base_folder_path) { 'app/views' }
+
+ subject { described_class.new.folders_for_available_editions(base_folder_path) }
+
+ context 'when FOSS' do
+ before do
+ allow(GitlabEdition).to receive(:ee?).and_return(false)
+ allow(GitlabEdition).to receive(:jh?).and_return(false)
+ end
+
+ it 'returns the correct paths' do
+ expect(subject).to match_array([base_folder_path])
+ end
+ end
+
+ context 'when EE' do
+ before do
+ allow(GitlabEdition).to receive(:ee?).and_return(true)
+ allow(GitlabEdition).to receive(:jh?).and_return(false)
+ end
+
+ it 'returns the correct paths' do
+ expect(subject).to eq([base_folder_path, "ee/#{base_folder_path}"])
+ end
+ end
+
+ context 'when JiHu' do
+ before do
+ allow(GitlabEdition).to receive(:ee?).and_return(true)
+ allow(GitlabEdition).to receive(:jh?).and_return(true)
+ end
+
+ it 'returns the correct paths' do
+ expect(subject).to eq([base_folder_path, "ee/#{base_folder_path}", "jh/#{base_folder_path}"])
+ end
+ end
+ end
+
+ describe '#find_partials' do
+ subject { described_class.new(view_base_folder: view_base_folder).find_partials(file_path) }
+
+ let(:file_path) { "#{view_base_folder}/my_html_file.html" }
+
+ before do
+ File.write(file_path, file_content)
+ end
+
+ context 'when the file includes a partial' do
+ context 'when the partial is in the same folder as the view file' do
+ before do
+ File.write("#{view_base_folder}/_my-partial.html.haml", 'Hello from partial')
+ end
+
+ let(:file_content) do
+ <<~FILE
+ Beginning of file
+
+ = render "my-partial"
+
+ End of file
+ FILE
+ end
+
+ it "returns the partial file path" do
+ expect(subject).to match_array(["#{view_base_folder}/_my-partial.html.haml"])
+ end
+ end
+
+ context 'when the partial is in a subfolder' do
+ before do
+ FileUtils.mkdir_p("#{view_base_folder}/subfolder")
+
+ (1..12).each do |i|
+ FileUtils.touch "#{view_base_folder}/subfolder/_my-partial#{i}.html.haml"
+ end
+ end
+
+ let(:file_content) do
+ <<~FILE
+ Beginning of file
+
+ = render("subfolder/my-partial1")
+ = render "subfolder/my-partial2"
+ = render(partial: "subfolder/my-partial3")
+ = render partial: "subfolder/my-partial4"
+ = render(partial:"subfolder/my-partial5", path: 'else')
+ = render partial:"subfolder/my-partial6"
+ = render_if_exist("subfolder/my-partial7", path: 'else')
+ = render_if_exist "subfolder/my-partial8"
+ = render_if_exist(partial: "subfolder/my-partial9", path: 'else')
+ = render_if_exist partial: "subfolder/my-partial10"
+ = render_if_exist(partial:"subfolder/my-partial11", path: 'else')
+ = render_if_exist partial:"subfolder/my-partial12"
+
+ End of file
+ FILE
+ end
+
+ it "returns the partials file path" do
+ expect(subject).to match_array([
+ "#{view_base_folder}/subfolder/_my-partial1.html.haml",
+ "#{view_base_folder}/subfolder/_my-partial2.html.haml",
+ "#{view_base_folder}/subfolder/_my-partial3.html.haml",
+ "#{view_base_folder}/subfolder/_my-partial4.html.haml",
+ "#{view_base_folder}/subfolder/_my-partial5.html.haml",
+ "#{view_base_folder}/subfolder/_my-partial6.html.haml",
+ "#{view_base_folder}/subfolder/_my-partial7.html.haml",
+ "#{view_base_folder}/subfolder/_my-partial8.html.haml",
+ "#{view_base_folder}/subfolder/_my-partial9.html.haml",
+ "#{view_base_folder}/subfolder/_my-partial10.html.haml",
+ "#{view_base_folder}/subfolder/_my-partial11.html.haml",
+ "#{view_base_folder}/subfolder/_my-partial12.html.haml"
+ ])
+ end
+ end
+
+ context 'when the file does not include a partial' do
+ let(:file_content) do
+ <<~FILE
+ Beginning of file
+ End of file
+ FILE
+ end
+
+ it 'returns an empty array' do
+ expect(subject).to match_array([])
+ end
+ end
+ end
+ end
+
+ describe '#find_pattern_in_file' do
+ let(:subject) { described_class.new.find_pattern_in_file(file.path, /pattern/) }
+ let(:file) { Tempfile.new('find_pattern_in_file') }
+
+ before do
+ file.write(file_content)
+ file.close
+ end
+
+ context 'when the file contains the pattern' do
+ let(:file_content) do
+ <<~FILE
+ Beginning of file
+
+ pattern
+ pattern
+ pattern
+
+ End of file
+ FILE
+ end
+
+ it 'returns the pattern once' do
+ expect(subject).to match_array(%w[pattern])
+ end
+ end
+
+ context 'when the file does not contain the pattern' do
+ let(:file_content) do
+ <<~FILE
+ Beginning of file
+ End of file
+ FILE
+ end
+
+ it 'returns an empty array' do
+ expect(subject).to match_array([])
+ end
+ end
+ end
+end
diff --git a/spec/tooling/quality/test_level_spec.rb b/spec/tooling/quality/test_level_spec.rb
index 3f46b3e79f4..aac7d19c079 100644
--- a/spec/tooling/quality/test_level_spec.rb
+++ b/spec/tooling/quality/test_level_spec.rb
@@ -4,9 +4,9 @@ require 'fast_spec_helper'
require_relative '../../../tooling/quality/test_level'
-RSpec.describe Quality::TestLevel do
+RSpec.describe Quality::TestLevel, feature_category: :tooling do
describe 'TEST_LEVEL_FOLDERS constant' do
- it 'all directories it refers to exists', :aggregate_failures do
+ it 'ensures all directories it refers to exists', :aggregate_failures do
ee_only_directories = %w[
lib/ee/gitlab/background_migration
elastic
@@ -53,7 +53,7 @@ RSpec.describe Quality::TestLevel do
context 'when level is migration' do
it 'returns a pattern' do
expect(subject.pattern(:migration))
- .to eq("spec/{migrations,lib/gitlab/background_migration,lib/ee/gitlab/background_migration}{,/**/}*_spec.rb")
+ .to eq("spec/{migrations}{,/**/}*_spec.rb")
end
end
@@ -128,7 +128,7 @@ RSpec.describe Quality::TestLevel do
context 'when level is migration' do
it 'returns a regexp' do
expect(subject.regexp(:migration))
- .to eq(%r{spec/(migrations|lib/gitlab/background_migration|lib/ee/gitlab/background_migration)/})
+ .to eq(%r{spec/(migrations)/})
end
end
@@ -196,7 +196,7 @@ RSpec.describe Quality::TestLevel do
end
it 'returns the correct level for a background migration test' do
- expect(subject.level_for('spec/lib/gitlab/background_migration/archive_legacy_traces_spec.rb')).to eq(:migration)
+ expect(subject.level_for('spec/lib/gitlab/background_migration/archive_legacy_traces_spec.rb')).to eq(:background_migration)
end
it 'returns the correct level for an EE file without passing a prefix' do
@@ -208,7 +208,7 @@ RSpec.describe Quality::TestLevel do
end
it 'returns the correct level for a EE-namespaced background migration test' do
- expect(described_class.new('ee/').level_for('ee/spec/lib/ee/gitlab/background_migration/prune_orphaned_geo_events_spec.rb')).to eq(:migration)
+ expect(described_class.new('ee/').level_for('ee/spec/lib/ee/gitlab/background_migration/prune_orphaned_geo_events_spec.rb')).to eq(:background_migration)
end
it 'returns the correct level for an integration test' do
@@ -228,27 +228,13 @@ RSpec.describe Quality::TestLevel do
.to raise_error(described_class::UnknownTestLevelError,
%r{Test level for spec/unknown/foo_spec.rb couldn't be set. Please rename the file properly or change the test level detection regexes in .+/tooling/quality/test_level.rb.})
end
- end
- describe '#background_migration?' do
- it 'returns false for a unit test' do
- expect(subject.background_migration?('spec/models/abuse_report_spec.rb')).to be(false)
- end
+ it 'ensures all spec/ folders are covered by a test level' do
+ Dir['{,ee/}spec/**/*/'].each do |path|
+ next if path =~ %r{\A(ee/)?spec/(benchmarks|docs_screenshots|fixtures|frontend_integration|support)/}
- it 'returns true for a migration test' do
- expect(subject.background_migration?('spec/migrations/add_default_and_free_plans_spec.rb')).to be(false)
- end
-
- it 'returns true for a background migration test' do
- expect(subject.background_migration?('spec/lib/gitlab/background_migration/archive_legacy_traces_spec.rb')).to be(true)
- end
-
- it 'returns true for a geo migration test' do
- expect(described_class.new('ee/').background_migration?('ee/spec/migrations/geo/migrate_ci_job_artifacts_to_separate_registry_spec.rb')).to be(false)
- end
-
- it 'returns true for a EE-namespaced background migration test' do
- expect(described_class.new('ee/').background_migration?('ee/spec/lib/ee/gitlab/background_migration/prune_orphaned_geo_events_spec.rb')).to be(true)
+ expect { subject.level_for(path) }.not_to raise_error
+ end
end
end
end