class TTNT::TestSelector

Select tests using Git information and {TestToCodeMapping}.

Attributes

tests[R]

Public Class Methods

new(repo, target_sha, test_files) click to toggle source

@param repo [Rugged::Reposiotry] repository of the project @param target_sha [String] sha of the target object

(nil means to target current working tree)

@param test_files [#include?] candidate test files

# File lib/ttnt/test_selector.rb, line 16
def initialize(repo, target_sha, test_files)
  @repo = repo
  storage_src_sha = target_sha ? target_sha : @repo.head.target_id
  @metadata = MetaData.new(repo, storage_src_sha)
  @target_obj = @repo.lookup(target_sha) if target_sha

  # Base should be the commit `ttnt:anchor` has run on.
  # NOT the one test-to-code mapping was commited to.
  @base_obj = find_anchored_commit

  @test_files = test_files
end

Public Instance Methods

select_tests!() click to toggle source

Select tests using differences in anchored commit and target commit (or current working tree) and {TestToCodeMapping}.

@return [Set] a set of tests that might be affected by changes in base_sha…target_sha

# File lib/ttnt/test_selector.rb, line 33
def select_tests!
  # select all tests if anchored commit does not exist
  return Set.new(@test_files) unless @base_obj

  @tests ||= Set.new

  opts = {
    include_untracked: true,
    recurse_untracked_dirs: true
  }
  diff = defined?(@target_obj) ? @base_obj.diff(@target_obj, opts) : @base_obj.diff_workdir(opts)

  diff.each_patch do |patch|
    file = patch.delta.old_file[:path]
    if test_file?(file)
      @tests << file
    else
      select_tests_from_patch(patch)
    end
  end
  @tests.delete(nil)
end

Private Instance Methods

find_anchored_commit() click to toggle source

Find the commit `ttnt:anchor` has been run on.

# File lib/ttnt/test_selector.rb, line 97
def find_anchored_commit
  if @metadata['anchored_commit']
    @repo.lookup(@metadata['anchored_commit'])
  else
    nil
  end
end
mapping() click to toggle source
# File lib/ttnt/test_selector.rb, line 58
def mapping
  @mapping ||= begin
    sha = defined?(@target_obj) ? @target_obj.oid : @repo.head.target_id
    TTNT::TestToCodeMapping.new(@repo, sha)
  end
end
select_tests_from_patch(patch) click to toggle source

Select tests which are affected by the change of given patch.

@param patch [Rugged::Patch] @return [Set] set of selected tests

# File lib/ttnt/test_selector.rb, line 69
def select_tests_from_patch(patch)
  target_lines = Set.new
  file = patch.delta.old_file[:path]
  prev_line = nil

  patch.each_hunk do |hunk|
    hunk.each_line do |line|
      case line.line_origin
      when :addition
        if prev_line && !prev_line.addition?
          target_lines << prev_line.old_lineno
        elsif prev_line.nil?
          target_lines << hunk.old_start
        end
      when :deletion
        target_lines << line.old_lineno
      end

      prev_line = line
    end
  end

  target_lines.each do |line|
    @tests += mapping.get_tests(file: file, lineno: line)
  end
end
test_file?(filename) click to toggle source

Check if the given file is a test file.

@param filename [String]

# File lib/ttnt/test_selector.rb, line 108
def test_file?(filename)
  @test_files.include?(filename)
end