Module: SimpleCov::CLI::Tests::Redundancy

Extended by:
Redundancy
Included in:
Redundancy
Defined in:
lib/simplecov/cli/tests/redundancy.rb

Overview

The --redundant sweep: the contexts whose covered lines other contexts also cover, the tests contributing no coverage of their own. A context is non-redundant exactly when some line is covered by it alone, so per file two bitmaps (lines seen once, lines seen more than once) find the uniquely covered lines and a second pass credits each to its owner.

Instance Method Summary collapse

Instance Method Details

#complaint(path, entry) ⇒ Object



66
67
68
69
70
# File 'lib/simplecov/cli/tests/redundancy.rb', line 66

def complaint(path, entry)
  return "entry for #{path} must be an object" unless entry.is_a?(Hash)

  "entry for #{path} carries a malformed \"contexts\" table"
end

#invalid(opts, stderr, reason) ⇒ Object



72
73
74
# File 'lib/simplecov/cli/tests/redundancy.rb', line 72

def invalid(opts, stderr, reason)
  CoverageFile.report_invalid(stderr, "tests", opts.fetch(:input), reason)
end

#lone_bits(table) ⇒ Object

A bit enters once when brand new and leaves for good when any later bitmap carries it again. The two halves of the update are provably disjoint, so they are summed: for disjoint bits that builds the number OR would, and it leaves no spelling of the combination without a witness.



35
36
37
38
39
40
41
42
43
# File 'lib/simplecov/cli/tests/redundancy.rb', line 35

def lone_bits(table)
  once = 0
  ever = 0
  table.each_value do |bitmap|
    once = (once & ~bitmap) + (bitmap & ~ever)
    ever |= bitmap
  end
  once
end

#redundant_ids(document, contexts, opts, stderr) ⇒ Object



14
15
16
17
18
19
20
# File 'lib/simplecov/cli/tests/redundancy.rb', line 14

def redundant_ids(document, contexts, opts, stderr)
  tables = sweep_tables(document, contexts, opts, stderr)
  return unless tables

  unique = unique_owners(tables, contexts.size)
  contexts.each_index.reject { |index| unique.fetch(index) }.map { |index| contexts.fetch(index) }.sort
end

#sweep_tables(document, contexts, opts, stderr) ⇒ Object

The sweep reads tables no query named, so a malformed one anywhere poisons the whole answer, matching the targeted queries' all-or-nothing tolerance.



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/simplecov/cli/tests/redundancy.rb', line 47

def sweep_tables(document, contexts, opts, stderr)
  coverage = document["coverage"]
  return invalid(opts, stderr, '"coverage" must be an object') unless coverage.is_a?(Hash)

  tables = [] #: Array[Hash[Integer, Integer]]
  coverage.each do |path, entry|
    table = entry.is_a?(Hash) && swept_table(entry, contexts)
    return invalid(opts, stderr, complaint(path, entry)) unless table

    tables << table
  end
  tables
end

#swept_table(entry, contexts) ⇒ Object



61
62
63
64
# File 'lib/simplecov/cli/tests/redundancy.rb', line 61

def swept_table(entry, contexts)
  raw = entry["contexts"] || {}
  Tests.decode_table(raw, contexts.size) if raw.is_a?(Hash)
end

#unique_owners(tables, context_count) ⇒ Object



22
23
24
25
26
27
28
29
# File 'lib/simplecov/cli/tests/redundancy.rb', line 22

def unique_owners(tables, context_count)
  unique = Array.new(context_count, false)
  tables.each do |table|
    lone = lone_bits(table)
    table.each { |index, bitmap| unique[index] = true if bitmap.anybits?(lone) }
  end
  unique
end