Module: SimpleCov::ResultMerger::UnloadedFiles
- Extended by:
- UnloadedFiles
- Included in:
- UnloadedFiles
- Defined in:
- lib/simplecov/result_merger/unloaded_files.rb
Overview
The merge step's half of unloaded-file handling: the policy of when to
inject and which criteria simulated files carry. The mechanism, expanding
globs and simulating each file, is SimpleCov::UnloadedFileInjector.
Injection moved here from the individual processes because only the union of what they all loaded says what was really never loaded. Doing it per process meant N workers simulated the same file up to N times and the merge threw all but one away (#1250).
Instance Method Summary collapse
-
#carries?(coverage, criterion) ⇒ Boolean
A simulated file should have the same shape as the files it is being merged alongside, so the criteria come from the merged data rather than from this process's configuration, which is not necessarily what any contributing process measured under:
simplecov mergenever ranSimpleCov.startat all. -
#carry_tracked(entry, existing, incoming) ⇒ Object
Concurrent workers sharing a command name may have been told to track different sets, so keep both rather than letting the later write win.
-
#collector(into) ⇒ Object
A collector for the merge to hand
merge_valid_results, gathering the tracked paths of every resultset that survives the merge timeout. -
#inject(coverage, tracked_files) ⇒ Object
Simulates each tracked file the merged coverage doesn't already carry.
-
#never_executed(coverage) ⇒ Object
Which files no contributing process ever loaded.
- #tracked_in(resultset) ⇒ Object
Instance Method Details
#carries?(coverage, criterion) ⇒ Boolean
A simulated file should have the same shape as the files it is being
merged alongside, so the criteria come from the merged data rather than
from this process's configuration, which is not necessarily what any
contributing process measured under: simplecov merge never ran
SimpleCov.start at all. Giving injected files fewer tables than their
neighbours is what inflates the percentage #1059 fixed.
Falls back to the configuration when there is nothing to be consistent with, which is a merge of resultsets that carried no files.
59 60 61 62 63 |
# File 'lib/simplecov/result_merger/unloaded_files.rb', line 59 def carries?(coverage, criterion) return SimpleCov.public_send(CRITERION_PREDICATES.fetch(criterion)) if coverage.empty? coverage.any? { |_filename, file_coverage| file_coverage[criterion] } end |
#carry_tracked(entry, existing, incoming) ⇒ Object
Concurrent workers sharing a command name may have been told to track different sets, so keep both rather than letting the later write win.
32 33 34 35 |
# File 'lib/simplecov/result_merger/unloaded_files.rb', line 32 def carry_tracked(entry, existing, incoming) tracked = Array(existing["tracked_files"]) | Array(incoming["tracked_files"]) tracked.empty? ? entry : entry.merge("tracked_files" => tracked) end |
#collector(into) ⇒ Object
A collector for the merge to hand merge_valid_results, gathering the
tracked paths of every resultset that survives the merge timeout.
Absent from resultsets written before this was recorded, in which case
those processes injected their own unloaded files already.
20 21 22 |
# File 'lib/simplecov/result_merger/unloaded_files.rb', line 20 def collector(into) ->(surviving) { into.merge(tracked_in(surviving)) } end |
#inject(coverage, tracked_files) ⇒ Object
Simulates each tracked file the merged coverage doesn't already carry.
The paths come from the resultsets rather than this process's own
configuration, which a standalone collate would not have. Idempotent,
so resultsets that already carry their unloaded files pass through
untouched.
42 43 44 45 46 47 48 |
# File 'lib/simplecov/result_merger/unloaded_files.rb', line 42 def inject(coverage, tracked_files) SimpleCov.inject_unloaded_files( coverage, tracked_files.to_a, synthesize: carries?(coverage, "branches") || carries?(coverage, "methods"), lines: carries?(coverage, "lines") ) end |
#never_executed(coverage) ⇒ Object
Which files no contributing process ever loaded. Injection reports the ones it added, but a file can also arrive already simulated from a resultset this merge didn't inject into, so the merged line counts are still consulted.
A file is judged only when it has a relevant line. A branch-only or
method-only run reports no line data at all for the files it loaded,
and a loaded file with no executable lines reports every line as nil.
Either would otherwise read as "never executed" and mark a genuinely
loaded file not loaded, turning its branch and method coverage into
#902's 0%.
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/simplecov/result_merger/unloaded_files.rb', line 83 def never_executed(coverage) coverage.each_with_object(Set.new) do |(filename, file_coverage), set| counts = Array(file_coverage["lines"]) #: Array[Integer?] # A line count is an Integer or nil, and every Integer is truthy, so a # truthy element is exactly a relevant line. next unless counts.any? set << filename unless Combine::CoverageAccumulator.executed?(counts) end end |
#tracked_in(resultset) ⇒ Object
24 25 26 27 28 |
# File 'lib/simplecov/result_merger/unloaded_files.rb', line 24 def tracked_in(resultset) resultset.each_with_object(Set.new) do |(_command_name, data), set| set.merge(Array(data["tracked_files"])) end end |