Module: SimpleCov::Combine::MethodsCombiner

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

Overview

Combine different method coverage results on a single file.

Should be called through CoverageAccumulator.

Class Method Summary collapse

Class Method Details

.absorb(target, coverage) ⇒ Hash?

Folds coverage into target, an interned table keyed by method source identity. See BranchesCombiner.absorb for why a fold keeps its accumulator interned.

A nil target stays nil until some resultset actually carries methods, so a merge can tell "no method data anywhere" apart from "method data that covers nothing".

Returns:

  • (Hash, nil)

    target, created on the first coverage seen



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

def absorb(target, coverage)
  return target unless coverage

  target ||= {} #: Hash[untyped, [untyped, Integer]]
  InternedCounts.absorb_counts(target, coverage, identities)
end

.combine(coverage_a, coverage_b) ⇒ Hash

Return merged methods or the existing methods if other is missing.

Method coverage maps [class, name, start_line, start_col, end_line, end_col] keys to hit counts. Keys are matched on their SOURCE identity — the location, ignoring the class and name elements — because Ruby records one entry per defined method: the same define_method block defined onto different classes, or under different names, in different processes arrives with different receivers or names for the same source method, and matching on the full key would keep both, letting a never-called copy's 0 shadow a covered method after merge (issue #1234). Combining sums the hit counts for matching methods and preserves methods that only appear in one result.

Returns:

  • (Hash)


33
34
35
36
# File 'lib/simplecov/combine/methods_combiner.rb', line 33

def combine(coverage_a, coverage_b)
  merged = absorb({}, coverage_a) #: Hash[untyped, [untyped, Integer]]
  materialize(absorb(merged, coverage_b))
end

.identitiesObject

Bounded by the project's method count, like RubyDataParser's parse cache.



64
65
66
# File 'lib/simplecov/combine/methods_combiner.rb', line 64

def identities
  @identities ||= IdentityInterner.build { |key| source_identity(key) }
end

.materialize(target) ⇒ Hash

Turns an interned table back into the tuple-keyed hash the rest of SimpleCov reads. Done once, at the end of a fold.

Returns:

  • (Hash)


58
59
60
# File 'lib/simplecov/combine/methods_combiner.rb', line 58

def materialize(target)
  target.values.to_h
end

.source_identity(key) ⇒ Object



68
69
70
71
# File 'lib/simplecov/combine/methods_combiner.rb', line 68

def source_identity(key)
  _class_name, _method_name, *location = SourceFile::RubyDataParser.call(key)
  location.freeze
end