lib/simplecov/combine/lines_combiner.rb
# frozen_string_literal: true module SimpleCov module Combine # # Combine two different lines coverage results on same file # # Should be called through `SimpleCov.combine`. module LinesCombiner module_function # Build a fresh array sized to the longer input. The previous # implementation mutated whichever input was longer in place, # which could surprise callers holding a reference to that array # (e.g. the parsed `coverage` key of a resultset hash being # passed into a second merge). def combine(coverage_a, coverage_b) size = [coverage_a.size, coverage_b.size].max Array.new(size) { |i| merge_line_coverage(coverage_a[i], coverage_b[i]) } end # Two runs of the same source file should agree on which lines # are coverage-relevant (`nil` for comments / whitespace, `0`+ # for executable). When they don't, treat "relevant on either # side" as relevant rather than masking a real `0` as `nil`, # which would silently drop an uncovered line from the # denominator and inflate the percentage. # # Logic: # # => nil + nil = nil # => nil + int = int (preserves a relevant-but-uncovered 0) # => int + int = int (sum) # # @param [Integer || nil] first_val # @param [Integer || nil] second_val # @return [Integer || nil] def merge_line_coverage(first_val, second_val) return nil if first_val.nil? && second_val.nil? first_val.to_i + second_val.to_i end end end end