1"""Combine integration test target code coverage reports."""
2from __future__ import (absolute_import, division, print_function)
3__metaclass__ = type
4
5from .... import types as t
6
7from . import (
8    CoverageAnalyzeTargetsConfig,
9    get_target_index,
10    make_report,
11    read_report,
12    write_report,
13)
14
15if t.TYPE_CHECKING:
16    from . import (
17        Arcs,
18        IndexedPoints,
19        Lines,
20        TargetIndexes,
21    )
22
23
24class CoverageAnalyzeTargetsCombineConfig(CoverageAnalyzeTargetsConfig):
25    """Configuration for the `coverage analyze targets combine` command."""
26    def __init__(self, args):  # type: (t.Any) -> None
27        super(CoverageAnalyzeTargetsCombineConfig, self).__init__(args)
28
29        self.input_files = args.input_file  # type: t.List[str]
30        self.output_file = args.output_file  # type: str
31
32
33def command_coverage_analyze_targets_combine(args):  # type: (CoverageAnalyzeTargetsCombineConfig) -> None
34    """Combine integration test target code coverage reports."""
35    combined_target_indexes = {}  # type: TargetIndexes
36    combined_path_arcs = {}  # type: Arcs
37    combined_path_lines = {}  # type: Lines
38
39    for report_path in args.input_files:
40        covered_targets, covered_path_arcs, covered_path_lines = read_report(report_path)
41
42        merge_indexes(covered_path_arcs, covered_targets, combined_path_arcs, combined_target_indexes)
43        merge_indexes(covered_path_lines, covered_targets, combined_path_lines, combined_target_indexes)
44
45    report = make_report(combined_target_indexes, combined_path_arcs, combined_path_lines)
46
47    write_report(args, report, args.output_file)
48
49
50def merge_indexes(
51        source_data,  # type: IndexedPoints
52        source_index,  # type: t.List[str]
53        combined_data,  # type: IndexedPoints
54        combined_index,  # type: TargetIndexes
55):  # type: (...) -> None
56    """Merge indexes from the source into the combined data set (arcs or lines)."""
57    for covered_path, covered_points in source_data.items():
58        combined_points = combined_data.setdefault(covered_path, {})
59
60        for covered_point, covered_target_indexes in covered_points.items():
61            combined_point = combined_points.setdefault(covered_point, set())
62
63            for covered_target_index in covered_target_indexes:
64                combined_point.add(get_target_index(source_index[covered_target_index], combined_index))
65