Skip to content

Commit

Permalink
Provide natural mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
unused committed Sep 22, 2024
1 parent 124e3e5 commit a4a238b
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 12 deletions.
6 changes: 6 additions & 0 deletions .test-map.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ lib/test_map/config.rb:
- lib/test_map/config.rb
- lib/test_map/file_recorder.rb
- lib/test_map/filter.rb
- lib/test_map/natural_mapping.rb
lib/test_map/errors.rb:
- lib/test_map/file_recorder.rb
lib/test_map/file_recorder.rb:
Expand All @@ -11,19 +12,24 @@ lib/test_map/file_recorder.rb:
- lib/test_map/file_recorder.rb
- lib/test_map/filter.rb
- lib/test_map/mapping.rb
- lib/test_map/natural_mapping.rb
- lib/test_map/plugins/minitest.rb
- lib/test_map/report.rb
lib/test_map/filter.rb:
- lib/test_map/file_recorder.rb
- lib/test_map/filter.rb
lib/test_map/mapping.rb:
- lib/test_map/mapping.rb
lib/test_map/natural_mapping.rb:
- lib/test_map/mapping.rb
- lib/test_map/natural_mapping.rb
lib/test_map/plugins/minitest.rb:
- lib/test_map/config.rb
- lib/test_map/errors.rb
- lib/test_map/file_recorder.rb
- lib/test_map/filter.rb
- lib/test_map/mapping.rb
- lib/test_map/natural_mapping.rb
- lib/test_map/report.rb
lib/test_map/report.rb:
- lib/test_map/report.rb
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ TestMap::Configure.configure do |config|
config.out_file = 'my-test-map.yml' # default is .test-map.yml
# defaults to [%r{^(vendor|test|spec)/}] }
config.exclude_patterns = [%r{^(libraries|testsuite)/}]
# register a custom rule to match new files; must implement `call(file)`;
# defaults to nil
config.natural_mapping = ->(file) { file.sub(%r{^library/}, 'test/') }
end
```

Expand Down
1 change: 1 addition & 0 deletions lib/test_map.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require_relative 'test_map/filter'
require_relative 'test_map/report'
require_relative 'test_map/file_recorder'
require_relative 'test_map/natural_mapping'
require_relative 'test_map/mapping'

# TestMap records associated files to test execution.
Expand Down
2 changes: 1 addition & 1 deletion lib/test_map/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def self.configure = yield(config)

def self.default_config
{ logger: Logger.new('/dev/null'), out_file: '.test-map.yml',
exclude_patterns: [%r{^(vendor|test|spec)/}] }
exclude_patterns: [%r{^(vendor|test|spec)/}], natural_mapping: nil }
end
end
end
13 changes: 2 additions & 11 deletions lib/test_map/mapping.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,11 @@ def map = YAML.safe_load_file(map_file)

def lookup(*changed_files)
new_files = apply_natural_mapping(changed_files - map.keys)
map.values_at(*changed_files).flatten.compact.uniq.concat(new_files)
map.values_at(*changed_files).concat(new_files).flatten.compact.uniq
end

def apply_natural_mapping(files)
pattern = if File.exist?("#{Dir.pwd}/test")
'test/%s_test.rb'
elsif File.exist?("#{Dir.pwd}/spec")
'spec/%s_spec.rb'
# elseif Handle files in packs
else
return [] # skip files
end

files.map { format(pattern, File.basename(_1, '.rb')) }
files.map { |file| NaturalMapping.new(file).test_files }
end
end
end
50 changes: 50 additions & 0 deletions lib/test_map/natural_mapping.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

require 'yaml'

module TestMap
# Natural mapping determines the test file for a given source file by
# applying common and configurable rules and transformation.
class NaturalMapping
CommonRule = Struct.new(:file) do
def self.call(file) = new(file).call

def call
if File.exist?('test')
transform('test')
elsif File.exist?('spec')
transform('spec')
end
end

def transform(type)
test_file = "#{File.basename(file, '.rb')}_#{type}.rb"
test_path = File.dirname(file).sub('app/', '')
test_path = nil if test_path == '.'
[type, test_path, test_file].compact.join('/')
end
end

attr_reader :file

def initialize(file) = @file = file
def test_files = Array(transform(file))

def transform(file)
self.class.registered_rules.each do |rule|
test_files = rule.call(file)

return test_files if test_files
end

nil
end

def self.registered_rules
@registered_rules ||= [
Config.config[:natural_mapping],
CommonRule
].compact
end
end
end
39 changes: 39 additions & 0 deletions test/test_map/natural_mapping_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

require 'test_helper'

# Tests for mapping.
class NaturalMappingTest < Minitest::Test
def test_mapping
mapping = subject.new('lib/animal.rb')

assert_equal ['test/lib/animal_test.rb'], mapping.test_files
end

def test_rails_mapping
mapping = subject.new('app/model/animal.rb')

assert_equal ['test/model/animal_test.rb'], mapping.test_files
end

def test_specs
File.stub(:exist?, ->(type) { type == 'spec' }) do
mapping = subject.new('app/model/animal.rb')

assert_equal ['spec/model/animal_spec.rb'], mapping.test_files
end
end

def test_no_known_test_lib
File.stub(:exist?, ->(_) { false }) do
mapping = subject.new('lib/animal.rb')
puts mapping.test_files

assert_empty mapping.test_files
end
end

private

def subject = TestMap::NaturalMapping
end

0 comments on commit a4a238b

Please sign in to comment.