Class: TTNT::TestToCodeMapping

Inherits:
Object
  • Object
show all
Defined in:
lib/ttnt/test_to_code_mapping.rb

Overview

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

Terminologies:

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

Constant Summary collapse

STORAGE_SECTION =
'mapping'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(repo, sha = nil) ⇒ TestToCodeMapping

Returns a new instance of TestToCodeMapping.

Parameters:

  • repo (Rugged::Reposiotry)

    repository to save test-to-code mapping

  • sha (String) (defaults to: nil)

    sha of commit from which mapping is read. nil means to read from current working tree. See Storage for more.



21
22
23
24
25
# 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

Instance Attribute Details

#mappingObject (readonly)

Returns the value of attribute mapping.



16
17
18
# File 'lib/ttnt/test_to_code_mapping.rb', line 16

def mapping
  @mapping
end

Instance Method Details

#append_from_coverage(test, coverage) ⇒ void

This method returns an undefined value.

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

Parameters:

  • test (String)

    test file for which the coverage data is produced

  • coverage (Hash)

    coverage data generated using ‘Coverage.start` and `Coverage.result`



32
33
34
35
# 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:) ⇒ Set

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

Parameters:

  • file (String)

    file name which might have effects on some tests

  • lineno (Integer)

    line number in the file which might have effects on some tests

Returns:

  • (Set)

    a set of test files which might be affected by the change in file at lineno



52
53
54
55
56
57
58
59
60
61
62
63
64
# 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

#normalize_paths(spectra) ⇒ Hash (private)

Normalize all file names in a spectra.

Parameters:

  • spectra (Hash)

    spectra data

Returns:

  • (Hash)

    spectra whose keys (file names) are normalized



91
92
93
94
95
# 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) ⇒ String (private)

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

Parameters:

  • file (String)

    file name (absolute path)

Returns:

  • (String)

    normalized file path



83
84
85
# File 'lib/ttnt/test_to_code_mapping.rb', line 83

def normalized_path(file)
  File.expand_path(file).sub("#{TTNT.root_dir}/", '')
end

#read!Object

Read test-to-code mapping from storage.



38
39
40
# File 'lib/ttnt/test_to_code_mapping.rb', line 38

def read!
  @mapping = @storage.read(STORAGE_SECTION)
end

#select_code_files!(code_files) ⇒ Object

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

Parameters:

  • code_files (#include?)

    code file names to filter



69
70
71
72
73
74
75
# 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

#select_project_files(spectra) ⇒ Hash (private)

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

Parameters:

  • spectra (Hash)

    spectra data

Returns:

  • (Hash)

    spectra with only files inside the target project



101
102
103
104
105
# 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) ⇒ Hash (private)

Generate spectra data from Ruby coverage library’s data

Parameters:

  • cov (Hash)

    coverage data generated using ‘Coverage.result`

Returns:

  • (Hash)

    spectra data



111
112
113
114
115
116
117
118
119
120
# 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

#write!Object

Write test-to-code mapping to storage.



43
44
45
# File 'lib/ttnt/test_to_code_mapping.rb', line 43

def write!
  @storage.write!(STORAGE_SECTION, @mapping)
end