| // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'dart:convert'; |
| import 'dart:io'; |
| |
| import 'package:coverage/coverage.dart'; |
| import 'package:path/path.dart' as p; |
| |
| import '../util/package_config.dart'; |
| import 'live_suite_controller.dart'; |
| |
| /// Collects coverage and outputs to the [coveragePath] path. |
| Future<Coverage> writeCoverage( |
| String? coveragePath, |
| LiveSuiteController controller, |
| ) async { |
| final suite = controller.liveSuite.suite; |
| final coverage = await controller.liveSuite.suite.gatherCoverage(); |
| if (coveragePath != null) { |
| final outfile = File( |
| p.join( |
| coveragePath, |
| '${suite.path}.${suite.platform.runtime.name.toLowerCase()}.json', |
| ), |
| )..createSync(recursive: true); |
| final out = outfile.openWrite(); |
| out.write(json.encode(coverage)); |
| await out.flush(); |
| await out.close(); |
| } |
| return switch (coverage['coverage']) { |
| // Matching on `List<dynamic>` the runtime type of `List` in JSON is |
| // never `Map<String, dynamic>`. The `cast` below ensures the runtime type |
| // is correct for `HitMap.parseJson`. |
| List<dynamic> hitMapJson => HitMap.parseJson( |
| hitMapJson.cast<Map<String, dynamic>>(), |
| ), |
| null => const {}, |
| _ => throw StateError('Invalid coverage data'), |
| }; |
| } |
| |
| Future<void> writeCoverageLcov( |
| String coverageLcov, |
| Coverage allCoverageData, |
| ) async { |
| final resolver = await Resolver.create( |
| packagePath: (await currentPackage).root.toFilePath(), |
| ); |
| final filteredCoverageData = allCoverageData.filterIgnored( |
| ignoredLinesInFilesCache: {}, |
| resolver: resolver, |
| ); |
| final lcovData = filteredCoverageData.formatLcov(resolver); |
| final outfile = File(coverageLcov)..createSync(recursive: true); |
| final out = outfile.openWrite(); |
| out.write(lcovData); |
| await out.flush(); |
| await out.close(); |
| } |
| |
| typedef Coverage = Map<String, HitMap>; |
| |
| extension Merge on Coverage { |
| void merge(Coverage other) => FileHitMaps(this).merge(other); |
| } |