parseChromeCoverage function

Future<Map<String, dynamic>> parseChromeCoverage(
  1. List<Map<String, dynamic>> preciseCoverage,
  2. Future<String?> sourceProvider(
    1. String scriptId
    ),
  3. Future<String?> sourceMapProvider(
    1. String scriptId
    ),
  4. Future<Uri?> sourceUriProvider(
    1. String sourceUrl,
    2. String scriptId
    ),
)

Returns a Dart based hit-map containing coverage report for the provided Chrome preciseCoverage.

sourceProvider returns the source content for the Chrome scriptId, or null if not available.

sourceMapProvider returns the associated source map content for the Chrome scriptId, or null if not available.

sourceUriProvider returns the uri for the provided sourceUrl and associated scriptId, or null if not available.

Chrome coverage information for which the corresponding source map or source content is null will be ignored.

Implementation

Future<Map<String, dynamic>> parseChromeCoverage(
  List<Map<String, dynamic>> preciseCoverage,
  Future<String?> Function(String scriptId) sourceProvider,
  Future<String?> Function(String scriptId) sourceMapProvider,
  Future<Uri?> Function(String sourceUrl, String scriptId) sourceUriProvider,
) async {
  final coverageReport = <Uri, Map<int, bool>>{};
  for (var entry in preciseCoverage) {
    final scriptId = entry['scriptId'] as String;

    final mapResponse = await sourceMapProvider(scriptId);
    if (mapResponse == null) continue;

    SingleMapping mapping;
    try {
      mapping = parse(mapResponse) as SingleMapping;
    } on FormatException {
      continue;
      // ignore: avoid_catching_errors
    } on ArgumentError {
      continue;
    }

    final compiledSource = await sourceProvider(scriptId);
    if (compiledSource == null) continue;

    final coverageInfo = _coverageInfoFor(entry);
    final offsetCoverage = _offsetCoverage(coverageInfo, compiledSource.length);
    final coveredPositions = _coveredPositions(compiledSource, offsetCoverage);

    for (var lineEntry in mapping.lines) {
      for (var columnEntry in lineEntry.entries) {
        final sourceUrlId = columnEntry.sourceUrlId;
        if (sourceUrlId == null) continue;
        final sourceUrl = mapping.urls[sourceUrlId];

        // Ignore coverage information for the SDK.
        if (sourceUrl.startsWith('org-dartlang-sdk:')) continue;

        final uri = await sourceUriProvider(sourceUrl, scriptId);
        if (uri == null) continue;
        final coverage = coverageReport.putIfAbsent(uri, () => <int, bool>{});

        final sourceLine = columnEntry.sourceLine!;
        final current = coverage[sourceLine + 1] ?? false;
        coverage[sourceLine + 1] = current ||
            coveredPositions.contains(
                _Position(lineEntry.line + 1, columnEntry.column + 1));
      }
    }
  }

  final coverageHitMaps = <Uri, HitMap>{};
  coverageReport.forEach((uri, coverage) {
    final hitMap = HitMap();
    for (var line in coverage.keys.toList()..sort()) {
      hitMap.lineHits[line] = coverage[line]! ? 1 : 0;
    }
    coverageHitMaps[uri] = hitMap;
  });

  final allCoverage = <Map<String, dynamic>>[];
  coverageHitMaps.forEach((uri, hitMap) {
    allCoverage.add(hitmapToJson(hitMap, uri));
  });
  return <String, dynamic>{'type': 'CodeCoverage', 'coverage': allCoverage};
}