Class: TTNT::TestSelector

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

Overview

Select tests using Git information and TestToCodeMapping.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(repo, target_sha, test_files) ⇒ TestSelector

Returns a new instance of TestSelector.

Parameters:

  • repo (Rugged::Reposiotry)

    repository of the project

  • target_sha (String)

    sha of the target object (nil means to target current working tree)

  • test_files (#include?)

    candidate test files



16
17
18
19
20
21
22
23
24
25
26
27
# 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
   = .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

Instance Attribute Details

#testsObject (readonly)

Returns the value of attribute tests.



10
11
12
# File 'lib/ttnt/test_selector.rb', line 10

def tests
  @tests
end

Instance Method Details

#find_anchored_commitObject (private)

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



97
98
99
100
101
102
103
# File 'lib/ttnt/test_selector.rb', line 97

def find_anchored_commit
  if ['anchored_commit']
    @repo.lookup(['anchored_commit'])
  else
    nil
  end
end

#mappingObject (private)



58
59
60
61
62
63
# 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!Set

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

Returns:

  • (Set)

    a set of tests that might be affected by changes in base_sha…target_sha



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 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

#select_tests_from_patch(patch) ⇒ Set (private)

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

Parameters:

  • patch (Rugged::Patch)

Returns:

  • (Set)

    set of selected tests



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# 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) ⇒ Boolean (private)

Check if the given file is a test file.

Parameters:

  • filename (String)

Returns:

  • (Boolean)


108
109
110
# File 'lib/ttnt/test_selector.rb', line 108

def test_file?(filename)
  @test_files.include?(filename)
end