Skip to content
代码片段 群组 项目
提交 f05cbbf6 编辑于 作者: David Dieulivol's avatar David Dieulivol 提交者: Rémy Coutable
浏览文件

Resolve "test-selection gap: run system specs when some views changed"

上级 3769eb0c
No related branches found
No related tags found
无相关合并请求
......@@ -124,6 +124,7 @@ detect-tests:
tooling/bin/find_tests ${RSPEC_VIEWS_INCLUDING_PARTIALS_PATH} ${RSPEC_MATCHING_TESTS_PATH};
tooling/bin/js_to_system_specs_mappings ${RSPEC_CHANGED_FILES_PATH} ${RSPEC_MATCHING_TESTS_PATH};
tooling/bin/graphql_base_type_mappings ${RSPEC_CHANGED_FILES_PATH} ${RSPEC_MATCHING_TESTS_PATH};
tooling/bin/view_to_system_specs_mappings ${RSPEC_CHANGED_FILES_PATH} ${RSPEC_MATCHING_TESTS_PATH};
tooling/bin/find_changes ${RSPEC_CHANGED_FILES_PATH} ${RSPEC_MATCHING_TESTS_PATH} ${FRONTEND_FIXTURES_MAPPING_PATH};
filter_rspec_matched_foss_tests ${RSPEC_MATCHING_TESTS_PATH} ${RSPEC_MATCHING_TESTS_FOSS_PATH};
filter_rspec_matched_ee_tests ${RSPEC_MATCHING_TESTS_PATH} ${RSPEC_MATCHING_TESTS_EE_PATH};
......
# frozen_string_literal: true
require 'tempfile'
require 'fileutils'
require_relative '../../../../../tooling/lib/tooling/mappings/view_to_system_specs_mappings'
RSpec.describe Tooling::Mappings::ViewToSystemSpecsMappings, feature_category: :tooling do
attr_accessor :view_base_folder, :changes_file, :output_file
let(:instance) { described_class.new(changes_file, output_file, view_base_folder: view_base_folder) }
let(:changes_file_content) { "changed_file1 changed_file2" }
let(:output_file_initial_content) { "previously_added_spec.rb" }
around do |example|
self.changes_file = Tempfile.new('changes')
self.output_file = Tempfile.new('output_file')
# See https://ruby-doc.org/stdlib-1.9.3/libdoc/tempfile/rdoc/
# Tempfile.html#class-Tempfile-label-Explicit+close
begin
Dir.mktmpdir do |tmp_views_base_folder|
self.view_base_folder = tmp_views_base_folder
example.run
end
ensure
changes_file.close
output_file.close
changes_file.unlink
output_file.unlink
end
end
before do
FileUtils.mkdir_p("#{view_base_folder}/app/views/dashboard")
# We write into the temp files initially, to check how the code modified those files
File.write(changes_file, changes_file_content)
File.write(output_file, output_file_initial_content)
end
shared_examples 'writes nothing to the output file' do
it 'writes nothing to the output file' do
expect { subject }.not_to change { File.read(changes_file) }
end
end
describe '#execute' do
subject { instance.execute }
let(:changed_files) { ["#{view_base_folder}/app/views/dashboard/my_view.html.haml"] }
let(:changes_file_content) { changed_files.join(" ") }
before do
# We create all of the changed_files, so that they are part of the filtered files
changed_files.each { |changed_file| FileUtils.touch(changed_file) }
end
context 'when the changed files are not view files' do
let(:changed_files) { ["#{view_base_folder}/app/views/dashboard/my_helper.rb"] }
it_behaves_like 'writes nothing to the output file'
end
context 'when the changed files are view files' do
let(:changed_files) { ["#{view_base_folder}/app/views/dashboard/my_view.html.haml"] }
context 'when the view files do not exist on disk' do
before do
allow(File).to receive(:exist?).with(changed_files.first).and_return(false)
end
it_behaves_like 'writes nothing to the output file'
end
context 'when the view files exist on disk' do
context 'when no feature match the view' do
# Nothing in this context, because the spec corresponding to `changed_files` doesn't exist
it_behaves_like 'writes nothing to the output file'
end
context 'when there is a feature spec that exactly matches the view' do
let(:expected_feature_spec) { "#{view_base_folder}/spec/features/dashboard/my_view_spec.rb" }
before do
allow(File).to receive(:exist?).and_call_original
allow(File).to receive(:exist?).with(expected_feature_spec).and_return(true)
end
it 'writes that feature spec to the output file' do
expect { subject }.to change { File.read(output_file) }
.from(output_file_initial_content)
.to("#{output_file_initial_content} #{expected_feature_spec}")
end
end
context 'when there is a feature spec that matches the parent folder of the view' do
let(:expected_feature_specs) do
[
"#{view_base_folder}/spec/features/dashboard/another_feature_spec.rb",
"#{view_base_folder}/spec/features/dashboard/other_feature_spec.rb"
]
end
before do
FileUtils.mkdir_p("#{view_base_folder}/spec/features/dashboard")
expected_feature_specs.each do |expected_feature_spec|
FileUtils.touch(expected_feature_spec)
end
end
it 'writes all of the feature specs for the parent folder to the output file' do
expect { subject }.to change { File.read(output_file) }
.from(output_file_initial_content)
.to("#{output_file_initial_content} #{expected_feature_specs.join(' ')}")
end
end
end
end
end
end
#!/usr/bin/env ruby
# frozen_string_literal: true
require_relative '../lib/tooling/mappings/view_to_system_specs_mappings'
changes_file = ARGV.shift
output_file = ARGV.shift
Tooling::Mappings::ViewToSystemSpecsMappings.new(changes_file, output_file).execute
# frozen_string_literal: true
require_relative 'base'
require_relative '../../../../lib/gitlab_edition'
# Returns system specs files that are related to the Rails views files that were changed in the MR.
module Tooling
module Mappings
class ViewToSystemSpecsMappings < Base
def initialize(changes_file, output_file, view_base_folder: 'app/views')
@output_file = output_file
@changed_files = read_array_from_file(changes_file)
@view_base_folders = folders_for_available_editions(view_base_folder)
end
def execute
found_system_specs = []
filter_files.each do |modified_view_file|
system_specs_exact_match = find_system_specs_exact_match(modified_view_file)
if system_specs_exact_match
found_system_specs << system_specs_exact_match
next
else
system_specs_parent_folder_match = find_system_specs_parent_folder_match(modified_view_file)
found_system_specs += system_specs_parent_folder_match unless system_specs_parent_folder_match.empty?
end
end
write_array_to_file(output_file, found_system_specs.compact.uniq.sort)
end
private
attr_reader :changed_files, :output_file, :view_base_folders
# Keep the views files that are in the @view_base_folders folder
def filter_files
@_filter_files ||= changed_files.select do |filename|
filename.start_with?(*view_base_folders) &&
File.basename(filename).end_with?('.html.haml') &&
File.exist?(filename)
end
end
def find_system_specs_exact_match(view_file)
potential_spec_file = to_feature_spec_folder(view_file).sub('.html.haml', '_spec.rb')
potential_spec_file if File.exist?(potential_spec_file)
end
def find_system_specs_parent_folder_match(view_file)
parent_system_specs_folder = File.dirname(to_feature_spec_folder(view_file))
Dir["#{parent_system_specs_folder}/**/*_spec.rb"]
end
# e.g. go from app/views/groups/merge_requests.html.haml to spec/features/groups/merge_requests.html.haml
def to_feature_spec_folder(view_file)
view_file.sub(%r{(ee/|jh/)?app/views}, '\1spec/features')
end
end
end
end
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册