Module: RailVerdict::Coverage::ChangedLineEvaluator

Defined in:
lib/rail_verdict/coverage/changed_line_evaluator.rb

Class Method Summary collapse

Class Method Details

.evaluate(coverage_document:, line_set:) ⇒ Object

Raises:

  • (ArgumentError)


8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/rail_verdict/coverage/changed_line_evaluator.rb', line 8

def evaluate(coverage_document:, line_set:)
  raise ArgumentError, "coverage_document must be a Hash" unless coverage_document.is_a?(Hash)
  raise ArgumentError, "line_set must be a Hash" unless line_set.is_a?(Hash)

  files = coverage_document["files"]
  raise ArgumentError, "coverage document has no files array" unless files.is_a?(Array)

  coverage_map = {}
  files.each do |file|
    filename = file["filename"]
    coverage = file.dig("coverage", "lines")
    next unless filename.is_a?(String) && coverage.is_a?(Array)

    coverage_map[filename] = coverage
  end

  executable = 0
  covered = 0
  missing = []

  line_set.each do |path, lines|
    raise ArgumentError, "line_set path must be a string" unless path.is_a?(String)
    raise ArgumentError, "line_set lines must be an array" unless lines.is_a?(Array)

    coverage = coverage_map[path]
    lines.each do |line_number|
      raise ArgumentError, "line number must be an integer >= 1" unless line_number.is_a?(Integer) && line_number >= 1

      if coverage.nil? || line_number > coverage.length
        executable += 1
        missing << [path, line_number]
        next
      end

      hit = coverage[line_number - 1]
      if hit.nil?
        next
      end

      executable += 1
      if hit.to_i > 0
        covered += 1
      else
        missing << [path, line_number]
      end
    end
  end

  missing = missing.sort

  percent = executable == 0 ? 100.0 : ((covered.to_f / executable) * 100).round(2)

  {
    "covered_lines" => covered,
    "executable_lines" => executable,
    "missing_lines" => missing,
    "percent" => percent,
    "paths" => line_set.keys.sort
  }.freeze
end