Commit 28005627 authored by Lin Jen-Shin's avatar Lin Jen-Shin

Merge branch...

Merge branch '220005-follow-up-from-run-foss-impact-tests-for-modified-files-in-as-if-foss-mode' into 'master'

Improve `TestFileFinder`

Closes #220748 and #220005

See merge request gitlab-org/gitlab!34047
parents d6628cd7 4340f937
...@@ -31,10 +31,10 @@ RSpec.describe Tooling::TestFileFinder do ...@@ -31,10 +31,10 @@ RSpec.describe Tooling::TestFileFinder do
end end
context 'when given a file in tooling/' do context 'when given a file in tooling/' do
let(:file) { 'tooling/lib/quality/test_file_finder.rb' } let(:file) { 'tooling/lib/tooling/test_file_finder.rb' }
it 'returns the matching tooling test' do it 'returns the matching tooling test' do
expect(subject.test_files).to contain_exactly('spec/tooling/lib/quality/test_file_finder_spec.rb') expect(subject.test_files).to contain_exactly('spec/tooling/lib/tooling/test_file_finder_spec.rb')
end end
end end
...@@ -54,11 +54,11 @@ RSpec.describe Tooling::TestFileFinder do ...@@ -54,11 +54,11 @@ RSpec.describe Tooling::TestFileFinder do
end end
end end
context 'when given a module file in ee/' do context 'when given an ee extension module file' do
let(:file) { 'ee/app/models/ee/user.rb' } let(:file) { 'ee/app/models/ee/user.rb' }
it 'returns the matching ee/ module test file and the ee/ model test file' do it 'returns the matching ee/ class test file, ee extension module test file and the foss class test file' do
test_files = ['ee/spec/models/ee/user_spec.rb', 'spec/app/models/user_spec.rb'] test_files = ['ee/spec/models/user_spec.rb', 'ee/spec/models/ee/user_spec.rb', 'spec/app/models/user_spec.rb']
expect(subject.test_files).to contain_exactly(*test_files) expect(subject.test_files).to contain_exactly(*test_files)
end end
end end
......
# frozen_string_literal: true # frozen_string_literal: true
require 'ostruct'
require 'set' require 'set'
module Tooling module Tooling
class TestFileFinder class TestFileFinder
RUBY_EXTENSION = '.rb'
EE_PREFIX = 'ee/' EE_PREFIX = 'ee/'
def initialize(file, foss_test_only: false) def initialize(file, foss_test_only: false)
@file = file @file = file
@foss_test_only = foss_test_only @foss_test_only = foss_test_only
@result = Set.new
end end
def test_files def test_files
contexts = [ee_context, foss_context] impacted_tests = ee_impact | non_ee_impact
contexts.flat_map do |context| impacted_tests.impact(@file)
match_test_files_for(context)
end
result.to_a
end end
private private
attr_reader :file, :foss_test_only, :result attr_reader :file, :foss_test_only, :result
def ee_context class ImpactedTestFile
OpenStruct.new.tap do |ee| attr_reader :pattern_matchers
ee.app = %r{^#{EE_PREFIX}app/(.+)\.rb$} unless foss_test_only
ee.lib = %r{^#{EE_PREFIX}lib/(.+)\.rb$} unless foss_test_only
ee.spec = %r{^#{EE_PREFIX}spec/(.+)_spec.rb$} unless foss_test_only
ee.spec_dir = "#{EE_PREFIX}spec" unless foss_test_only
ee.ee_modules = %r{^#{EE_PREFIX}(?!spec)(.*\/)ee/(.+)\.rb$}
ee.ee_module_spec = %r{^#{EE_PREFIX}spec/(.*\/)ee/(.+)\.rb$}
ee.foss_spec_dir = 'spec'
end
end
def foss_context def initialize
OpenStruct.new.tap do |foss| @pattern_matchers = {}
foss.app = %r{^app/(.+)\.rb$}
foss.lib = %r{^lib/(.+)\.rb$}
foss.tooling = %r{^(tooling/lib/.+)\.rb$}
foss.spec = %r{^spec/(.+)_spec.rb$}
foss.spec_dir = 'spec'
end
end
def match_test_files_for(context) yield self if block_given?
if (match = context.app&.match(file))
result << "#{context.spec_dir}/#{match[1]}_spec.rb"
end end
if (match = context.lib&.match(file)) def associate(pattern, &block)
result << "#{context.spec_dir}/lib/#{match[1]}_spec.rb" @pattern_matchers[pattern] = block
end end
if (match = context.tooling&.match(file)) def impact(file)
result << "#{context.spec_dir}/#{match[1]}_spec.rb" @pattern_matchers.each_with_object(Set.new) do |(pattern, block), result|
if (match = pattern.match(file))
result << block.call(match)
end
end.to_a
end end
if context.spec&.match(file) def |(other)
result << file self.class.new do |combined_matcher|
self.pattern_matchers.each do |pattern, block|
combined_matcher.associate(pattern, &block)
end
other.pattern_matchers.each do |pattern, block|
combined_matcher.associate(pattern, &block)
end
end
end end
end
if (match = context.ee_modules&.match(file)) def ee_impact
result << "#{context.foss_spec_dir}/#{match[1]}#{match[2]}_spec.rb" ImpactedTestFile.new do |impact|
unless foss_test_only
impact.associate(%r{^#{EE_PREFIX}app/(.+)\.rb$}) { |match| "#{EE_PREFIX}spec/#{match[1]}_spec.rb" }
impact.associate(%r{^#{EE_PREFIX}app/(.*/)ee/(.+)\.rb$}) { |match| "#{EE_PREFIX}spec/#{match[1]}#{match[2]}_spec.rb" }
impact.associate(%r{^#{EE_PREFIX}lib/(.+)\.rb$}) { |match| "#{EE_PREFIX}spec/lib/#{match[1]}_spec.rb" }
impact.associate(%r{^#{EE_PREFIX}spec/(.+)_spec.rb$}) { |match| match[0] }
end
impact.associate(%r{^#{EE_PREFIX}(?!spec)(.*/)ee/(.+)\.rb$}) { |match| "spec/#{match[1]}#{match[2]}_spec.rb" }
impact.associate(%r{^#{EE_PREFIX}spec/(.*/)ee/(.+)\.rb$}) { |match| "spec/#{match[1]}#{match[2]}.rb" }
end end
end
if (match = context.ee_module_spec&.match(file)) def non_ee_impact
result << "#{context.foss_spec_dir}/#{match[1]}#{match[2]}.rb" ImpactedTestFile.new do |impact|
impact.associate(%r{^app/(.+)\.rb$}) { |match| "spec/#{match[1]}_spec.rb" }
impact.associate(%r{^(tooling/)?lib/(.+)\.rb$}) { |match| "spec/#{match[1]}lib/#{match[2]}_spec.rb" }
impact.associate(%r{^spec/(.+)_spec.rb$}) { |match| match[0] }
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment