Module: SimpleCov::Combine::BranchesCombiner

Defined in:
lib/simplecov/combine/branches_combiner.rb

Overview

Combine different branch coverage results on single file.

Should be called through ‘SimpleCov.combine`.

Class Method Summary collapse

Class Method Details

.combine(coverage_a, coverage_b) ⇒ Hash

Return merged branches or the existed branch if other is missing.

Branches inside files are always same if they exist, the difference only in coverage count. Branch coverage report for any conditional case is built from hash, it’s key is a condition and it’s body is a hash << keys from condition and value is coverage rate >>. ex: branches => { [:if, 3, 8, 6, 8, 36] =>

{[:then, 4, 8, 6, 8, 12] => 1, [:else, 5, 8, 6, 8, 36] => 2}, ... }

We create copy of result and update it values depending on the combined branches coverage values.

Returns:

  • (Hash)


26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/simplecov/combine/branches_combiner.rb', line 26

def combine(coverage_a, coverage_b)
  combined = [coverage_a, coverage_b].each_with_object({}) do |coverage, memo|
    coverage.each do |condition, branches_inside|
      condition_key = tuple_identity(condition)
      condition_tuple, merged_branches = memo[condition_key] ||= [condition, {}]
      merge_branches(merged_branches, branches_inside)
      memo[condition_key] = [condition_tuple, merged_branches]
    end
  end

  combined.values.to_h { |condition, branches| [condition, branches.values.to_h] }
end

.merge_branches(target, source) ⇒ Object



39
40
41
42
43
44
45
# File 'lib/simplecov/combine/branches_combiner.rb', line 39

def merge_branches(target, source)
  source.each do |branch, count|
    branch_key = tuple_identity(branch)
    branch_tuple, existing_count = target[branch_key]
    target[branch_key] = [branch_tuple || branch, existing_count ? existing_count + count : count]
  end
end

.tuple_identity(tuple) ⇒ Object



47
48
49
50
51
# File 'lib/simplecov/combine/branches_combiner.rb', line 47

def tuple_identity(tuple)
  tuple = SourceFile::RubyDataParser.call(tuple)
  type, _id, start_line, start_column, end_line, end_column = tuple
  [type, start_line, start_column, end_line, end_column]
end