blob: e41f5c148a5ae86892ca62dd278f422dc1f5d09b [file] [log] [blame]
// Copyright (c) 2015, 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:async';
import 'package:coverage/coverage.dart';
import 'package:coverage/src/util.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'test_util.dart';
final _isolateLibPath = p.join('test', 'test_files', 'test_app_isolate.dart');
final _sampleAppFileUri = p.toUri(p.absolute(testAppPath)).toString();
final _isolateLibFileUri = p.toUri(p.absolute(_isolateLibPath)).toString();
void main() {
test('collect_coverage_api', () async {
final coverage = coverageDataFromJson(await _collectCoverage());
expect(coverage, isNotEmpty);
final sources = coverage.sources();
for (var sampleCoverageData in sources[_sampleAppFileUri]!) {
expect(sampleCoverageData['hits'], isNotEmpty);
}
for (var sampleCoverageData in sources[_isolateLibFileUri]!) {
expect(sampleCoverageData['hits'], isNotEmpty);
}
});
test('collect_coverage_api with scoped output', () async {
final coverage = coverageDataFromJson(
await _collectCoverage(scopedOutput: <String>{}..add('coverage')),
);
expect(coverage, isNotEmpty);
final sources = coverage.sources();
for (var key in sources.keys) {
final uri = Uri.parse(key);
expect(uri.path.startsWith('coverage'), isTrue);
}
});
test('collect_coverage_api with isolateIds', () async {
final coverage =
coverageDataFromJson(await _collectCoverage(isolateIds: true));
expect(coverage, isEmpty);
});
test('collect_coverage_api with function coverage', () async {
final coverage =
coverageDataFromJson(await _collectCoverage(functionCoverage: true));
expect(coverage, isNotEmpty);
final sources = coverage.sources();
final functionInfo = functionInfoFromSources(sources);
expect(
functionInfo[_sampleAppFileUri]!,
{
'main': 1,
'usedMethod': 1,
'unusedMethod': 0,
},
);
expect(
functionInfo[_isolateLibFileUri]!,
{
'BarClass.BarClass': 1,
'fooAsync': 1,
'fooSync': 1,
'isolateTask': 1,
'BarClass.baz': 1
},
);
});
test('collect_coverage_api with branch coverage', () async {
final coverage =
coverageDataFromJson(await _collectCoverage(branchCoverage: true));
expect(coverage, isNotEmpty);
final sources = coverage.sources();
// Dart VM versions before 2.17 don't support branch coverage.
expect(sources[_sampleAppFileUri],
everyElement(containsPair('branchHits', isNotEmpty)));
expect(sources[_isolateLibFileUri],
everyElement(containsPair('branchHits', isNotEmpty)));
}, skip: !platformVersionCheck(2, 17));
test('collect_coverage_api with coverableLineCache', () async {
final coverableLineCache = <String, Set<int>>{};
final coverage =
await _collectCoverage(coverableLineCache: coverableLineCache);
final result = await HitMap.parseJson(
coverage['coverage'] as List<Map<String, dynamic>>);
expect(coverableLineCache, contains(_sampleAppFileUri));
expect(coverableLineCache, contains(_isolateLibFileUri));
// Expect that we have some missed lines.
expect(result[_sampleAppFileUri]!.lineHits.containsValue(0), isTrue);
expect(result[_isolateLibFileUri]!.lineHits.containsValue(0), isTrue);
// Clear _sampleAppFileUri's cache entry, then gather coverage again. We're
// doing this to verify that force compilation is disabled for these
// libraries. The result should be that _isolateLibFileUri should be the
// same, but _sampleAppFileUri should be missing all its missed lines.
coverableLineCache[_sampleAppFileUri] = {};
final coverage2 =
await _collectCoverage(coverableLineCache: coverableLineCache);
final result2 = await HitMap.parseJson(
coverage2['coverage'] as List<Map<String, dynamic>>);
// _isolateLibFileUri still has missed lines, but _sampleAppFileUri doesn't.
expect(result2[_sampleAppFileUri]!.lineHits.containsValue(0), isFalse);
expect(result2[_isolateLibFileUri]!.lineHits.containsValue(0), isTrue);
// _isolateLibFileUri is the same. _sampleAppFileUri is the same, but
// without all its missed lines.
expect(result2[_isolateLibFileUri]!.lineHits,
result[_isolateLibFileUri]!.lineHits);
result[_sampleAppFileUri]!.lineHits.removeWhere((line, hits) => hits == 0);
expect(result2[_sampleAppFileUri]!.lineHits,
result[_sampleAppFileUri]!.lineHits);
}, skip: !platformVersionCheck(3, 2));
}
Future<Map<String, dynamic>> _collectCoverage(
{Set<String> scopedOutput = const {},
bool isolateIds = false,
bool functionCoverage = false,
bool branchCoverage = false,
Map<String, Set<int>>? coverableLineCache}) async {
final openPort = await getOpenPort();
// run the sample app, with the right flags
final sampleProcess = await runTestApp(openPort);
final serviceUri = await serviceUriFromProcess(sampleProcess.stdoutStream());
final isolateIdSet = isolateIds ? <String>{} : null;
return collect(serviceUri, true, true, false, scopedOutput,
timeout: timeout,
isolateIds: isolateIdSet,
functionCoverage: functionCoverage,
branchCoverage: branchCoverage,
coverableLineCache: coverableLineCache);
}