123456789_123456789_123456789_123456789_123456789_

Module: SimpleCov::Combine::FilesCombiner

Relationships & Source Files
Defined in: lib/simplecov/combine/files_combiner.rb

Overview

Handle combining two coverage results for same file

Should be called through SimpleCov.combine.

Constant Summary

Class Method Summary

Class Method Details

.combine(coverage_a, coverage_b) ⇒ Hash (mod_func)

Combines the results for 2 coverages of a file.

[ GitHub ]

  
# File 'lib/simplecov/combine/files_combiner.rb', line 21

def combine(coverage_a, coverage_b)
  source_a, source_b = reconcile_synthesized(coverage_a, coverage_b)

  combination = {"lines" => Combine.combine(LinesCombiner, coverage_a["lines"], coverage_b["lines"])}
  if SimpleCov.branch_coverage?
    combined_branches = Combine.combine(BranchesCombiner, source_a["branches"], source_b["branches"])
    combination["branches"] = combined_branches || {}
  end
  if SimpleCov.method_coverage?
    combination["methods"] = Combine.combine(MethodsCombiner, source_a["methods"], source_b["methods"])
  end
  combination
end

.executed?(coverage) ⇒ Boolean (mod_func)

A file some process actually loaded has at least one executed line; a simulated (never-loaded) file's lines are all nil or 0.

[ GitHub ]

  
# File 'lib/simplecov/combine/files_combiner.rb', line 60

def executed?(coverage)
  Array(coverage["lines"]).any? { |count| count&.positive? }
end

.reconcile_synthesized(coverage_a, coverage_b) (mod_func)

When exactly one side of the merge was actually executed, its branch and method tuples are authoritative and the other side's are dropped. A simulated entry (SimulateCoverage backfills tracked-but-unloaded files) synthesizes those tuples statically, so a location that drifts from what Coverage emits would otherwise be unioned in by position and survive as a phantom, permanently-missed branch (see #1233). This contains any such drift to denominator inflation for files no process loaded, rather than a false miss on a covered file. Lines are never dropped: a simulated file's line shape is correct and carries the unloaded-file denominator (#1059).

Returns the two coverages to draw branch/method tuples from, blanking the non-executed side only when the other side was executed. When both sides were executed (two real runs) or neither was (all simulated), both are returned unchanged and combine normally.

[ GitHub ]

  
# File 'lib/simplecov/combine/files_combiner.rb', line 50

def reconcile_synthesized(coverage_a, coverage_b)
  executed_a = executed?(coverage_a)
  executed_b = executed?(coverage_b)
  return [coverage_a, coverage_b] if executed_a == executed_b

  executed_a ? [coverage_a, NO_SYNTHESIZED] : [NO_SYNTHESIZED, coverage_b]
end