Unverified Commit 278ac627 authored by Liam Appelbe's avatar Liam Appelbe Committed by GitHub

Migrate flutter_tools to use package:coverage (#111681)

parent 2bf83dd8
...@@ -2,11 +2,8 @@ ...@@ -2,11 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:coverage/coverage.dart' as coverage; import 'package:coverage/coverage.dart' as coverage;
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:vm_service/vm_service.dart' as vm_service;
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/io.dart'; import '../base/io.dart';
...@@ -99,13 +96,11 @@ class CoverageCollector extends TestWatcher { ...@@ -99,13 +96,11 @@ class CoverageCollector extends TestWatcher {
/// ///
/// The returned [Future] completes when the coverage is collected. /// The returned [Future] completes when the coverage is collected.
Future<void> collectCoverageIsolate(Uri observatoryUri) async { Future<void> collectCoverageIsolate(Uri observatoryUri) async {
assert(observatoryUri != null);
_logMessage('collecting coverage data from $observatoryUri...'); _logMessage('collecting coverage data from $observatoryUri...');
final Map<String, dynamic> data = await collect(observatoryUri, libraryNames); final Map<String, dynamic> data = await collect(observatoryUri, libraryNames);
if (data == null) { if (data == null) {
throw Exception('Failed to collect coverage.'); throw Exception('Failed to collect coverage.');
} }
assert(data != null);
_logMessage('($observatoryUri): collected coverage data; merging...'); _logMessage('($observatoryUri): collected coverage data; merging...');
_addHitmap(await coverage.HitMap.parseJson( _addHitmap(await coverage.HitMap.parseJson(
...@@ -122,12 +117,12 @@ class CoverageCollector extends TestWatcher { ...@@ -122,12 +117,12 @@ class CoverageCollector extends TestWatcher {
/// has been run to completion so that all coverage data has been recorded. /// has been run to completion so that all coverage data has been recorded.
/// ///
/// The returned [Future] completes when the coverage is collected. /// The returned [Future] completes when the coverage is collected.
Future<void> collectCoverage(TestDevice testDevice, {@visibleForTesting Future<FlutterVmService> Function(Uri?)? connector}) async { Future<void> collectCoverage(TestDevice testDevice, {
assert(testDevice != null); @visibleForTesting FlutterVmService? serviceOverride,
}) async {
final Stopwatch? totalTestTimeRecorderStopwatch = testTimeRecorder?.start(TestTimePhases.CoverageTotal); final Stopwatch? totalTestTimeRecorderStopwatch = testTimeRecorder?.start(TestTimePhases.CoverageTotal);
Map<String, dynamic>? data; late Map<String, dynamic> data;
final Stopwatch? collectTestTimeRecorderStopwatch = testTimeRecorder?.start(TestTimePhases.CoverageCollect); final Stopwatch? collectTestTimeRecorderStopwatch = testTimeRecorder?.start(TestTimePhases.CoverageCollect);
...@@ -141,7 +136,7 @@ class CoverageCollector extends TestWatcher { ...@@ -141,7 +136,7 @@ class CoverageCollector extends TestWatcher {
final Future<void> collectionComplete = testDevice.observatoryUri final Future<void> collectionComplete = testDevice.observatoryUri
.then((Uri? observatoryUri) { .then((Uri? observatoryUri) {
_logMessage('collecting coverage data from $testDevice at $observatoryUri...'); _logMessage('collecting coverage data from $testDevice at $observatoryUri...');
return collect(observatoryUri, libraryNames, connector: connector ?? _defaultConnect) return collect(observatoryUri!, libraryNames, serviceOverride: serviceOverride)
.then<void>((Map<String, dynamic> result) { .then<void>((Map<String, dynamic> result) {
if (result == null) { if (result == null) {
throw Exception('Failed to collect coverage.'); throw Exception('Failed to collect coverage.');
...@@ -152,13 +147,14 @@ class CoverageCollector extends TestWatcher { ...@@ -152,13 +147,14 @@ class CoverageCollector extends TestWatcher {
}); });
await Future.any<void>(<Future<void>>[ processComplete, collectionComplete ]); await Future.any<void>(<Future<void>>[ processComplete, collectionComplete ]);
assert(data != null);
testTimeRecorder?.stop(TestTimePhases.CoverageCollect, collectTestTimeRecorderStopwatch!); testTimeRecorder?.stop(TestTimePhases.CoverageCollect, collectTestTimeRecorderStopwatch!);
_logMessage('Merging coverage data...'); _logMessage('Merging coverage data...');
final Stopwatch? parseTestTimeRecorderStopwatch = testTimeRecorder?.start(TestTimePhases.CoverageParseJson); final Stopwatch? parseTestTimeRecorderStopwatch = testTimeRecorder?.start(TestTimePhases.CoverageParseJson);
final Map<String, coverage.HitMap> hitmap = coverage.HitMap.parseJsonSync(
data!['coverage'] as List<Map<String, dynamic>>, final Map<String, coverage.HitMap> hitmap = coverage.HitMap.parseJsonSync(
data['coverage'] as List<Map<String, dynamic>>,
checkIgnoredLines: true, checkIgnoredLines: true,
resolver: resolver ?? await CoverageCollector.getResolver(packageDirectory), resolver: resolver ?? await CoverageCollector.getResolver(packageDirectory),
ignoredLinesInFilesCache: _ignoredLinesInFilesCache); ignoredLinesInFilesCache: _ignoredLinesInFilesCache);
...@@ -253,158 +249,11 @@ class CoverageCollector extends TestWatcher { ...@@ -253,158 +249,11 @@ class CoverageCollector extends TestWatcher {
Future<void> handleTestTimedOut(TestDevice testDevice) async { } Future<void> handleTestTimedOut(TestDevice testDevice) async { }
} }
Future<FlutterVmService> _defaultConnect(Uri? serviceUri) { Future<Map<String, dynamic>> collect(Uri serviceUri, Set<String>? libraryNames, {
return connectToVmService(
serviceUri!, compression: CompressionOptions.compressionOff, logger: globals.logger,);
}
Future<Map<String, dynamic>> collect(Uri? serviceUri, Set<String>? libraryNames, {
bool waitPaused = false, bool waitPaused = false,
String? debugName, String? debugName,
Future<FlutterVmService> Function(Uri?) connector = _defaultConnect,
@visibleForTesting bool forceSequential = false, @visibleForTesting bool forceSequential = false,
}) async { @visibleForTesting FlutterVmService? serviceOverride,
final FlutterVmService vmService = await connector(serviceUri); }) {
final Map<String, dynamic> result = await _getAllCoverage(vmService.service, libraryNames, forceSequential); return coverage.collect(serviceUri, false, false, false, libraryNames, serviceOverrideForTesting: serviceOverride?.service);
await vmService.dispose();
return result;
}
Future<Map<String, dynamic>> _getAllCoverage(
vm_service.VmService service,
Set<String>? libraryNames,
bool forceSequential,
) async {
final vm_service.Version version = await service.getVersion();
final bool libraryFilters = (version.major == 3 && version.minor! >= 57) || version.major! > 3;
final vm_service.VM vm = await service.getVM();
final List<Map<String, dynamic>> coverage = <Map<String, dynamic>>[];
bool libraryPredicate(String? libraryName) {
if (libraryNames == null) {
return true;
}
final Uri uri = Uri.parse(libraryName!);
if (uri.scheme != 'package') {
return false;
}
final String scope = uri.path.split('/').first;
return libraryNames.contains(scope);
}
for (final vm_service.IsolateRef isolateRef in vm.isolates!) {
if (isolateRef.isSystemIsolate!) {
continue;
}
if (libraryFilters) {
final vm_service.SourceReport sourceReport = await service.getSourceReport(
isolateRef.id!,
<String>['Coverage'],
forceCompile: true,
reportLines: true,
libraryFilters: libraryNames == null ? null : List<String>.from(
libraryNames.map((String name) => 'package:$name/')),
);
_buildCoverageMap(
<String, vm_service.Script>{},
<vm_service.SourceReport>[sourceReport],
coverage,
);
} else {
vm_service.ScriptList scriptList;
try {
scriptList = await service.getScripts(isolateRef.id!);
} on vm_service.SentinelException {
continue;
}
final List<Future<void>> futures = <Future<void>>[];
final Map<String, vm_service.Script> scripts = <String, vm_service.Script>{};
final List<vm_service.SourceReport> sourceReports = <vm_service.SourceReport>[];
// For each ScriptRef loaded into the VM, load the corresponding Script
// and SourceReport object.
for (final vm_service.ScriptRef script in scriptList.scripts!) {
final String? libraryUri = script.uri;
if (!libraryPredicate(libraryUri)) {
continue;
}
final String? scriptId = script.id;
final Future<void> getSourceReport = service.getSourceReport(
isolateRef.id!,
<String>['Coverage'],
scriptId: scriptId,
forceCompile: true,
reportLines: true,
)
.then((vm_service.SourceReport report) {
sourceReports.add(report);
});
if (forceSequential) {
await null;
}
futures.add(getSourceReport);
}
await Future.wait(futures);
_buildCoverageMap(scripts, sourceReports, coverage);
}
}
return <String, dynamic>{'type': 'CodeCoverage', 'coverage': coverage};
}
// Build a hitmap of Uri -> Line -> Hit Count for each script object.
void _buildCoverageMap(
Map<String, vm_service.Script> scripts,
List<vm_service.SourceReport> sourceReports,
List<Map<String, dynamic>> coverage,
) {
final Map<String?, Map<int, int>> hitMaps = <String?, Map<int, int>>{};
for (final vm_service.SourceReport sourceReport in sourceReports) {
for (final vm_service.SourceReportRange range in sourceReport.ranges!) {
final vm_service.SourceReportCoverage? coverage = range.coverage;
// Coverage reports may sometimes be null for a Script.
if (coverage == null) {
continue;
}
final vm_service.ScriptRef scriptRef = sourceReport.scripts![range.scriptIndex!];
final String? uri = scriptRef.uri;
hitMaps[uri] ??= <int, int>{};
final Map<int, int>? hitMap = hitMaps[uri];
final List<int>? hits = coverage.hits;
final List<int>? misses = coverage.misses;
if (hits != null) {
for (final int line in hits) {
final int current = hitMap![line] ?? 0;
hitMap[line] = current + 1;
}
}
if (misses != null) {
for (final int line in misses) {
hitMap![line] ??= 0;
}
}
}
}
hitMaps.forEach((String? uri, Map<int, int> hitMap) {
coverage.add(_toScriptCoverageJson(uri!, hitMap));
});
}
// Returns a JSON hit map backward-compatible with pre-1.16.0 SDKs.
Map<String, dynamic> _toScriptCoverageJson(String scriptUri, Map<int, int> hitMap) {
final Map<String, dynamic> json = <String, dynamic>{};
final List<int> hits = <int>[];
hitMap.forEach((int line, int hitCount) {
hits.add(line);
hits.add(hitCount);
});
json['source'] = scriptUri;
json['script'] = <String, dynamic>{
'type': '@Script',
'fixedId': true,
'id': 'libraries/1/scripts/${Uri.encodeComponent(scriptUri)}',
'uri': scriptUri,
'_kind': 'library',
};
json['hits'] = hits;
return json;
} }
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
@Timeout.factor(10)
import 'dart:convert' show jsonEncode; import 'dart:convert' show jsonEncode;
import 'dart:io' show Directory, File; import 'dart:io' show Directory, File;
...@@ -20,10 +22,6 @@ void main() { ...@@ -20,10 +22,6 @@ void main() {
testWithoutContext('Coverage collector Can handle coverage SentinelException', () async { testWithoutContext('Coverage collector Can handle coverage SentinelException', () async {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost( final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[ requests: <VmServiceExpectation>[
FakeVmServiceRequest(
method: 'getVersion',
jsonResponse: Version(major: 3, minor: 51).toJson(),
),
FakeVmServiceRequest( FakeVmServiceRequest(
method: 'getVM', method: 'getVM',
jsonResponse: (VM.parse(<String, Object>{})! jsonResponse: (VM.parse(<String, Object>{})!
...@@ -34,6 +32,10 @@ void main() { ...@@ -34,6 +32,10 @@ void main() {
] ]
).toJson(), ).toJson(),
), ),
FakeVmServiceRequest(
method: 'getVersion',
jsonResponse: Version(major: 3, minor: 51).toJson(),
),
const FakeVmServiceRequest( const FakeVmServiceRequest(
method: 'getScripts', method: 'getScripts',
args: <String, Object>{ args: <String, Object>{
...@@ -47,11 +49,9 @@ void main() { ...@@ -47,11 +49,9 @@ void main() {
); );
final Map<String, Object?> result = await collect( final Map<String, Object?> result = await collect(
null, Uri(),
<String>{'foo'}, <String>{'foo'},
connector: (Uri? uri) async { serviceOverride: fakeVmServiceHost.vmService,
return fakeVmServiceHost.vmService;
},
); );
expect(result, <String, Object>{'type': 'CodeCoverage', 'coverage': <Object>[]}); expect(result, <String, Object>{'type': 'CodeCoverage', 'coverage': <Object>[]});
...@@ -61,10 +61,6 @@ void main() { ...@@ -61,10 +61,6 @@ void main() {
testWithoutContext('Coverage collector processes coverage and script data', () async { testWithoutContext('Coverage collector processes coverage and script data', () async {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost( final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[ requests: <VmServiceExpectation>[
FakeVmServiceRequest(
method: 'getVersion',
jsonResponse: Version(major: 3, minor: 51).toJson(),
),
FakeVmServiceRequest( FakeVmServiceRequest(
method: 'getVM', method: 'getVM',
jsonResponse: (VM.parse(<String, Object>{})! jsonResponse: (VM.parse(<String, Object>{})!
...@@ -75,6 +71,10 @@ void main() { ...@@ -75,6 +71,10 @@ void main() {
] ]
).toJson(), ).toJson(),
), ),
FakeVmServiceRequest(
method: 'getVersion',
jsonResponse: Version(major: 3, minor: 51).toJson(),
),
FakeVmServiceRequest( FakeVmServiceRequest(
method: 'getScripts', method: 'getScripts',
args: <String, Object>{ args: <String, Object>{
...@@ -119,11 +119,9 @@ void main() { ...@@ -119,11 +119,9 @@ void main() {
); );
final Map<String, Object?> result = await collect( final Map<String, Object?> result = await collect(
null, Uri(),
<String>{'foo'}, <String>{'foo'},
connector: (Uri? uri) async { serviceOverride: fakeVmServiceHost.vmService,
return fakeVmServiceHost.vmService;
},
); );
expect(result, <String, Object>{ expect(result, <String, Object>{
...@@ -149,11 +147,9 @@ void main() { ...@@ -149,11 +147,9 @@ void main() {
final FakeVmServiceHost fakeVmServiceHost = createFakeVmServiceHostWithFooAndBar(); final FakeVmServiceHost fakeVmServiceHost = createFakeVmServiceHostWithFooAndBar();
final Map<String, Object?> result = await collect( final Map<String, Object?> result = await collect(
Uri(),
null, null,
null, serviceOverride: fakeVmServiceHost.vmService,
connector: (Uri? uri) async {
return fakeVmServiceHost.vmService;
},
); );
expect(result, <String, Object>{ expect(result, <String, Object>{
...@@ -189,10 +185,6 @@ void main() { ...@@ -189,10 +185,6 @@ void main() {
testWithoutContext('Coverage collector with libraryFilters', () async { testWithoutContext('Coverage collector with libraryFilters', () async {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost( final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[ requests: <VmServiceExpectation>[
FakeVmServiceRequest(
method: 'getVersion',
jsonResponse: Version(major: 3, minor: 57).toJson(),
),
FakeVmServiceRequest( FakeVmServiceRequest(
method: 'getVM', method: 'getVM',
jsonResponse: (VM.parse(<String, Object>{})! jsonResponse: (VM.parse(<String, Object>{})!
...@@ -203,6 +195,10 @@ void main() { ...@@ -203,6 +195,10 @@ void main() {
] ]
).toJson(), ).toJson(),
), ),
FakeVmServiceRequest(
method: 'getVersion',
jsonResponse: Version(major: 3, minor: 57).toJson(),
),
FakeVmServiceRequest( FakeVmServiceRequest(
method: 'getSourceReport', method: 'getSourceReport',
args: <String, Object>{ args: <String, Object>{
...@@ -237,11 +233,9 @@ void main() { ...@@ -237,11 +233,9 @@ void main() {
); );
final Map<String, Object?> result = await collect( final Map<String, Object?> result = await collect(
null, Uri(),
<String>{'foo'}, <String>{'foo'},
connector: (Uri? uri) async { serviceOverride: fakeVmServiceHost.vmService,
return fakeVmServiceHost.vmService;
},
); );
expect(result, <String, Object>{ expect(result, <String, Object>{
...@@ -266,10 +260,6 @@ void main() { ...@@ -266,10 +260,6 @@ void main() {
testWithoutContext('Coverage collector with libraryFilters and null libraryNames', () async { testWithoutContext('Coverage collector with libraryFilters and null libraryNames', () async {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost( final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[ requests: <VmServiceExpectation>[
FakeVmServiceRequest(
method: 'getVersion',
jsonResponse: Version(major: 3, minor: 57).toJson(),
),
FakeVmServiceRequest( FakeVmServiceRequest(
method: 'getVM', method: 'getVM',
jsonResponse: (VM.parse(<String, Object>{})! jsonResponse: (VM.parse(<String, Object>{})!
...@@ -280,6 +270,10 @@ void main() { ...@@ -280,6 +270,10 @@ void main() {
] ]
).toJson(), ).toJson(),
), ),
FakeVmServiceRequest(
method: 'getVersion',
jsonResponse: Version(major: 3, minor: 57).toJson(),
),
FakeVmServiceRequest( FakeVmServiceRequest(
method: 'getSourceReport', method: 'getSourceReport',
args: <String, Object>{ args: <String, Object>{
...@@ -313,11 +307,9 @@ void main() { ...@@ -313,11 +307,9 @@ void main() {
); );
final Map<String, Object?> result = await collect( final Map<String, Object?> result = await collect(
Uri(),
null, null,
null, serviceOverride: fakeVmServiceHost.vmService,
connector: (Uri? uri) async {
return fakeVmServiceHost.vmService;
},
); );
expect(result, <String, Object>{ expect(result, <String, Object>{
...@@ -356,9 +348,10 @@ void main() { ...@@ -356,9 +348,10 @@ void main() {
packagesPath: packagesPath, packagesPath: packagesPath,
resolver: await CoverageCollector.getResolver(packagesPath) resolver: await CoverageCollector.getResolver(packagesPath)
); );
await collector.collectCoverage(TestTestDevice(), connector: (Uri? uri) async { await collector.collectCoverage(
return createFakeVmServiceHostWithFooAndBar().vmService; TestTestDevice(),
}); serviceOverride: createFakeVmServiceHostWithFooAndBar(libraryFilters: <String>['package:foo/', 'package:bar/']).vmService,
);
Future<void> getHitMapAndVerify() async { Future<void> getHitMapAndVerify() async {
final Map<String, HitMap> gottenHitmap = <String, HitMap>{}; final Map<String, HitMap> gottenHitmap = <String, HitMap>{};
...@@ -389,9 +382,10 @@ void main() { ...@@ -389,9 +382,10 @@ void main() {
// Collecting again gets us the same data even though the foo file has been deleted. // Collecting again gets us the same data even though the foo file has been deleted.
// This means that the fact that line 2 was ignored has been cached. // This means that the fact that line 2 was ignored has been cached.
fooFile.deleteSync(); fooFile.deleteSync();
await collector.collectCoverage(TestTestDevice(), connector: (Uri? uri) async { await collector.collectCoverage(
return createFakeVmServiceHostWithFooAndBar().vmService; TestTestDevice(),
}); serviceOverride: createFakeVmServiceHostWithFooAndBar(libraryFilters: <String>['package:foo/', 'package:bar/']).vmService,
);
await getHitMapAndVerify(); await getHitMapAndVerify();
} finally { } finally {
tempDir?.deleteSync(recursive: true); tempDir?.deleteSync(recursive: true);
...@@ -418,9 +412,10 @@ void main() { ...@@ -418,9 +412,10 @@ void main() {
resolver: await CoverageCollector.getResolver(packagesPath), resolver: await CoverageCollector.getResolver(packagesPath),
testTimeRecorder: testTimeRecorder testTimeRecorder: testTimeRecorder
); );
await collector.collectCoverage(TestTestDevice(), connector: (Uri? uri) async { await collector.collectCoverage(
return createFakeVmServiceHostWithFooAndBar().vmService; TestTestDevice(),
}); serviceOverride: createFakeVmServiceHostWithFooAndBar(libraryFilters: <String>['package:foo/', 'package:bar/']).vmService,
);
// Expect one message for each phase. // Expect one message for each phase.
final List<String> logPhaseMessages = testTimeRecorder.getPrintAsListForTesting().where((String m) => m.startsWith('Runtime for phase ')).toList(); final List<String> logPhaseMessages = testTimeRecorder.getPrintAsListForTesting().where((String m) => m.startsWith('Runtime for phase ')).toList();
...@@ -454,13 +449,11 @@ File writeFooBarPackagesJson(Directory tempDir) { ...@@ -454,13 +449,11 @@ File writeFooBarPackagesJson(Directory tempDir) {
return file; return file;
} }
FakeVmServiceHost createFakeVmServiceHostWithFooAndBar() { FakeVmServiceHost createFakeVmServiceHostWithFooAndBar({
List<String>? libraryFilters,
}) {
return FakeVmServiceHost( return FakeVmServiceHost(
requests: <VmServiceExpectation>[ requests: <VmServiceExpectation>[
FakeVmServiceRequest(
method: 'getVersion',
jsonResponse: Version(major: 3, minor: 51).toJson(),
),
FakeVmServiceRequest( FakeVmServiceRequest(
method: 'getVM', method: 'getVM',
jsonResponse: (VM.parse(<String, Object>{})! jsonResponse: (VM.parse(<String, Object>{})!
...@@ -472,23 +465,17 @@ FakeVmServiceHost createFakeVmServiceHostWithFooAndBar() { ...@@ -472,23 +465,17 @@ FakeVmServiceHost createFakeVmServiceHostWithFooAndBar() {
).toJson(), ).toJson(),
), ),
FakeVmServiceRequest( FakeVmServiceRequest(
method: 'getScripts', method: 'getVersion',
args: <String, Object>{ jsonResponse: Version(major: 3, minor: 61).toJson(),
'isolateId': '1',
},
jsonResponse: ScriptList(scripts: <ScriptRef>[
ScriptRef(uri: 'package:foo/foo.dart', id: '1'),
ScriptRef(uri: 'package:bar/bar.dart', id: '2'),
]).toJson(),
), ),
FakeVmServiceRequest( FakeVmServiceRequest(
method: 'getSourceReport', method: 'getSourceReport',
args: <String, Object>{ args: <String, Object>{
'isolateId': '1', 'isolateId': '1',
'reports': <Object>['Coverage'], 'reports': <Object>['Coverage'],
'scriptId': '1',
'forceCompile': true, 'forceCompile': true,
'reportLines': true, 'reportLines': true,
if (libraryFilters != null) 'libraryFilters': libraryFilters,
}, },
jsonResponse: SourceReport( jsonResponse: SourceReport(
ranges: <SourceReportRange>[ ranges: <SourceReportRange>[
...@@ -502,28 +489,8 @@ FakeVmServiceHost createFakeVmServiceHostWithFooAndBar() { ...@@ -502,28 +489,8 @@ FakeVmServiceHost createFakeVmServiceHostWithFooAndBar() {
misses: <int>[2], misses: <int>[2],
), ),
), ),
],
scripts: <ScriptRef>[
ScriptRef(
uri: 'package:foo/foo.dart',
id: '1',
),
],
).toJson(),
),
FakeVmServiceRequest(
method: 'getSourceReport',
args: <String, Object>{
'isolateId': '1',
'reports': <Object>['Coverage'],
'scriptId': '2',
'forceCompile': true,
'reportLines': true,
},
jsonResponse: SourceReport(
ranges: <SourceReportRange>[
SourceReportRange( SourceReportRange(
scriptIndex: 0, scriptIndex: 1,
startPos: 0, startPos: 0,
endPos: 0, endPos: 0,
compiled: true, compiled: true,
...@@ -534,6 +501,10 @@ FakeVmServiceHost createFakeVmServiceHostWithFooAndBar() { ...@@ -534,6 +501,10 @@ FakeVmServiceHost createFakeVmServiceHostWithFooAndBar() {
), ),
], ],
scripts: <ScriptRef>[ scripts: <ScriptRef>[
ScriptRef(
uri: 'package:foo/foo.dart',
id: '1',
),
ScriptRef( ScriptRef(
uri: 'package:bar/bar.dart', uri: 'package:bar/bar.dart',
id: '2', id: '2',
...@@ -553,7 +524,7 @@ class TestTestDevice extends TestDevice { ...@@ -553,7 +524,7 @@ class TestTestDevice extends TestDevice {
Future<void> kill() => Future<void>.value(); Future<void> kill() => Future<void>.value();
@override @override
Future<Uri?> get observatoryUri => Future<Uri?>.value(); Future<Uri?> get observatoryUri => Future<Uri?>.value(Uri());
@override @override
Future<StreamChannel<String>> start(String entrypointPath) { Future<StreamChannel<String>> start(String entrypointPath) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment