class TTNT::TestToCodeMapping

Mapping from test file to executed code (i.e. coverage without execution count).

Terminologies:

spectra: { filename => [line, numbers, executed], ... }
mapping: { test_file => spectra }

Constants

STORAGE_SECTION

Attributes

mapping[R]

Public Class Methods

new(repo, sha = nil) click to toggle source

@param repo [Rugged::Reposiotry] repository to save test-to-code mapping @param sha [String] sha of commit from which mapping is read.

nil means to read from current working tree. See {Storage} for more.
# File lib/ttnt/test_to_code_mapping.rb, line 21
def initialize(repo, sha = nil)
  @repo    = repo || raise('Not in a git repository')
  @storage = Storage.new(repo, sha)
  read!
end

Public Instance Methods

append_from_coverage(test, coverage) click to toggle source

Append the new mapping to test-to-code mapping file.

@param test [String] test file for which the coverage data is produced @param coverage [Hash] coverage data generated using `Coverage.start` and `Coverage.result` @return [void]

# File lib/ttnt/test_to_code_mapping.rb, line 32
def append_from_coverage(test, coverage)
  spectra = normalize_paths(select_project_files(spectra_from_coverage(coverage)))
  @mapping[test] = spectra
end
get_tests(file:, lineno:) click to toggle source

Get tests affected from change of file `file` at line number `lineno`

@param file [String] file name which might have effects on some tests @param lineno [Integer] line number in the file which might have effects on some tests @return [Set] a set of test files which might be affected by the change in file at lineno

# File lib/ttnt/test_to_code_mapping.rb, line 52
def get_tests(file:, lineno:)
  tests = Set.new
  @mapping.each do |test, spectra|
    lines = spectra[file]
    next unless lines
    topmost = lines.first
    downmost = lines.last
    if topmost <= lineno && lineno <= downmost
      tests << test
    end
  end
  tests
end
read!() click to toggle source

Read test-to-code mapping from storage.

# File lib/ttnt/test_to_code_mapping.rb, line 38
def read!
  @mapping = @storage.read(STORAGE_SECTION)
end
select_code_files!(code_files) click to toggle source

Select (filter) code files from mapping by given file names.

@param code_files [#include?] code file names to filter

# File lib/ttnt/test_to_code_mapping.rb, line 69
def select_code_files!(code_files)
  @mapping.map do |test, spectra|
    spectra.select! do |code, lines|
      code_files.include?(code)
    end
  end
end
write!() click to toggle source

Write test-to-code mapping to storage.

# File lib/ttnt/test_to_code_mapping.rb, line 43
def write!
  @storage.write!(STORAGE_SECTION, @mapping)
end

Private Instance Methods

normalize_paths(spectra) click to toggle source

Normalize all file names in a spectra.

@param spectra [Hash] spectra data @return [Hash] spectra whose keys (file names) are normalized

# File lib/ttnt/test_to_code_mapping.rb, line 91
def normalize_paths(spectra)
  spectra.map do |filename, lines|
    [normalized_path(filename), lines]
  end.to_h
end
normalized_path(file) click to toggle source

Convert absolute path to relative path from the project (Git repository) root.

@param file [String] file name (absolute path) @return [String] normalized file path

# File lib/ttnt/test_to_code_mapping.rb, line 83
def normalized_path(file)
  File.expand_path(file).sub("#{TTNT.root_dir}/", '')
end
select_project_files(spectra) click to toggle source

Filter out the files outside of the target project using file path.

@param spectra [Hash] spectra data @return [Hash] spectra with only files inside the target project

# File lib/ttnt/test_to_code_mapping.rb, line 101
def select_project_files(spectra)
  spectra.select do |filename, lines|
    filename.start_with?(TTNT.root_dir)
  end
end
spectra_from_coverage(cov) click to toggle source

Generate spectra data from Ruby coverage library's data

@param cov [Hash] coverage data generated using `Coverage.result` @return [Hash] spectra data

# File lib/ttnt/test_to_code_mapping.rb, line 111
def spectra_from_coverage(cov)
  spectra = Hash.new { |h, k| h[k] = [] }
  cov.each do |filename, executions|
    executions.each_with_index do |execution, i|
      next if execution.nil? || execution == 0
      spectra[filename] << i + 1
    end
  end
  spectra
end