Relands #136851, which was rolled back in #137121 package:coverage has been rolled, so the breakages should be fixed. Also, in this reland I've changed the `coverableLineCache` parameter to be optional, which is safer.
This commit is contained in:
parent
f05bb9a182
commit
e12d1a798c
@ -37,6 +37,7 @@ class CoverageCollector extends TestWatcher {
|
|||||||
|
|
||||||
final coverage.Resolver? resolver;
|
final coverage.Resolver? resolver;
|
||||||
final Map<String, List<List<int>>?> _ignoredLinesInFilesCache = <String, List<List<int>>?>{};
|
final Map<String, List<List<int>>?> _ignoredLinesInFilesCache = <String, List<List<int>>?>{};
|
||||||
|
final Map<String, Set<int>> _coverableLineCache = <String, Set<int>>{};
|
||||||
|
|
||||||
final TestTimeRecorder? testTimeRecorder;
|
final TestTimeRecorder? testTimeRecorder;
|
||||||
|
|
||||||
@ -103,7 +104,11 @@ class CoverageCollector extends TestWatcher {
|
|||||||
Future<void> collectCoverageIsolate(Uri vmServiceUri) async {
|
Future<void> collectCoverageIsolate(Uri vmServiceUri) async {
|
||||||
_logMessage('collecting coverage data from $vmServiceUri...');
|
_logMessage('collecting coverage data from $vmServiceUri...');
|
||||||
final Map<String, dynamic> data = await collect(
|
final Map<String, dynamic> data = await collect(
|
||||||
vmServiceUri, libraryNames, branchCoverage: branchCoverage);
|
vmServiceUri,
|
||||||
|
libraryNames,
|
||||||
|
branchCoverage: branchCoverage,
|
||||||
|
coverableLineCache: _coverableLineCache,
|
||||||
|
);
|
||||||
|
|
||||||
_logMessage('($vmServiceUri): collected coverage data; merging...');
|
_logMessage('($vmServiceUri): collected coverage data; merging...');
|
||||||
_addHitmap(await coverage.HitMap.parseJson(
|
_addHitmap(await coverage.HitMap.parseJson(
|
||||||
@ -145,9 +150,12 @@ class CoverageCollector extends TestWatcher {
|
|||||||
.then((Uri? vmServiceUri) {
|
.then((Uri? vmServiceUri) {
|
||||||
_logMessage('collecting coverage data from $testDevice at $vmServiceUri...');
|
_logMessage('collecting coverage data from $testDevice at $vmServiceUri...');
|
||||||
return collect(
|
return collect(
|
||||||
vmServiceUri!, libraryNames, serviceOverride: serviceOverride,
|
vmServiceUri!,
|
||||||
branchCoverage: branchCoverage)
|
libraryNames,
|
||||||
.then<void>((Map<String, dynamic> result) {
|
serviceOverride: serviceOverride,
|
||||||
|
branchCoverage: branchCoverage,
|
||||||
|
coverableLineCache: _coverableLineCache,
|
||||||
|
).then<void>((Map<String, dynamic> result) {
|
||||||
_logMessage('Collected coverage data.');
|
_logMessage('Collected coverage data.');
|
||||||
data = result;
|
data = result;
|
||||||
});
|
});
|
||||||
@ -267,9 +275,12 @@ Future<Map<String, dynamic>> collect(Uri serviceUri, Set<String>? libraryNames,
|
|||||||
@visibleForTesting bool forceSequential = false,
|
@visibleForTesting bool forceSequential = false,
|
||||||
@visibleForTesting FlutterVmService? serviceOverride,
|
@visibleForTesting FlutterVmService? serviceOverride,
|
||||||
bool branchCoverage = false,
|
bool branchCoverage = false,
|
||||||
|
Map<String, Set<int>>? coverableLineCache,
|
||||||
}) {
|
}) {
|
||||||
return coverage.collect(
|
return coverage.collect(
|
||||||
serviceUri, false, false, false, libraryNames,
|
serviceUri, false, false, false, libraryNames,
|
||||||
serviceOverrideForTesting: serviceOverride?.service,
|
serviceOverrideForTesting: serviceOverride?.service,
|
||||||
branchCoverage: branchCoverage);
|
branchCoverage: branchCoverage,
|
||||||
|
coverableLineCache: coverableLineCache,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ void main() {
|
|||||||
Uri(),
|
Uri(),
|
||||||
<String>{'foo'},
|
<String>{'foo'},
|
||||||
serviceOverride: fakeVmServiceHost.vmService,
|
serviceOverride: fakeVmServiceHost.vmService,
|
||||||
|
coverableLineCache: <String, Set<int>>{},
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result, <String, Object>{'type': 'CodeCoverage', 'coverage': <Object>[]});
|
expect(result, <String, Object>{'type': 'CodeCoverage', 'coverage': <Object>[]});
|
||||||
@ -123,6 +124,7 @@ void main() {
|
|||||||
Uri(),
|
Uri(),
|
||||||
<String>{'foo'},
|
<String>{'foo'},
|
||||||
serviceOverride: fakeVmServiceHost.vmService,
|
serviceOverride: fakeVmServiceHost.vmService,
|
||||||
|
coverableLineCache: <String, Set<int>>{},
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result, <String, Object>{
|
expect(result, <String, Object>{
|
||||||
@ -151,6 +153,7 @@ void main() {
|
|||||||
Uri(),
|
Uri(),
|
||||||
null,
|
null,
|
||||||
serviceOverride: fakeVmServiceHost.vmService,
|
serviceOverride: fakeVmServiceHost.vmService,
|
||||||
|
coverableLineCache: <String, Set<int>>{},
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result, <String, Object>{
|
expect(result, <String, Object>{
|
||||||
@ -237,6 +240,7 @@ void main() {
|
|||||||
Uri(),
|
Uri(),
|
||||||
<String>{'foo'},
|
<String>{'foo'},
|
||||||
serviceOverride: fakeVmServiceHost.vmService,
|
serviceOverride: fakeVmServiceHost.vmService,
|
||||||
|
coverableLineCache: <String, Set<int>>{},
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result, <String, Object>{
|
expect(result, <String, Object>{
|
||||||
@ -311,6 +315,7 @@ void main() {
|
|||||||
Uri(),
|
Uri(),
|
||||||
null,
|
null,
|
||||||
serviceOverride: fakeVmServiceHost.vmService,
|
serviceOverride: fakeVmServiceHost.vmService,
|
||||||
|
coverableLineCache: <String, Set<int>>{},
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result, <String, Object>{
|
expect(result, <String, Object>{
|
||||||
@ -401,6 +406,7 @@ void main() {
|
|||||||
<String>{'foo'},
|
<String>{'foo'},
|
||||||
serviceOverride: fakeVmServiceHost.vmService,
|
serviceOverride: fakeVmServiceHost.vmService,
|
||||||
branchCoverage: true,
|
branchCoverage: true,
|
||||||
|
coverableLineCache: <String, Set<int>>{},
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result, <String, Object>{
|
expect(result, <String, Object>{
|
||||||
@ -601,6 +607,179 @@ void main() {
|
|||||||
tempDir?.deleteSync(recursive: true);
|
tempDir?.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWithoutContext('Coverage collector fills coverableLineCache', () async {
|
||||||
|
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
|
||||||
|
requests: <VmServiceExpectation>[
|
||||||
|
FakeVmServiceRequest(
|
||||||
|
method: 'getVM',
|
||||||
|
jsonResponse: (VM.parse(<String, Object>{})!
|
||||||
|
..isolates = <IsolateRef>[
|
||||||
|
IsolateRef.parse(<String, Object>{
|
||||||
|
'id': '1',
|
||||||
|
})!,
|
||||||
|
]
|
||||||
|
).toJson(),
|
||||||
|
),
|
||||||
|
FakeVmServiceRequest(
|
||||||
|
method: 'getVersion',
|
||||||
|
jsonResponse: Version(major: 4, minor: 13).toJson(),
|
||||||
|
),
|
||||||
|
FakeVmServiceRequest(
|
||||||
|
method: 'getSourceReport',
|
||||||
|
args: <String, Object>{
|
||||||
|
'isolateId': '1',
|
||||||
|
'reports': <Object>['Coverage'],
|
||||||
|
'forceCompile': true,
|
||||||
|
'reportLines': true,
|
||||||
|
'libraryFilters': <String>['package:foo/'],
|
||||||
|
'librariesAlreadyCompiled': <String>[],
|
||||||
|
},
|
||||||
|
jsonResponse: SourceReport(
|
||||||
|
ranges: <SourceReportRange>[
|
||||||
|
SourceReportRange(
|
||||||
|
scriptIndex: 0,
|
||||||
|
startPos: 0,
|
||||||
|
endPos: 0,
|
||||||
|
compiled: true,
|
||||||
|
coverage: SourceReportCoverage(
|
||||||
|
hits: <int>[1, 3],
|
||||||
|
misses: <int>[2],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
scripts: <ScriptRef>[
|
||||||
|
ScriptRef(
|
||||||
|
uri: 'package:foo/foo.dart',
|
||||||
|
id: '1',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).toJson(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
final Map<String, Set<int>> coverableLineCache = <String, Set<int>>{};
|
||||||
|
final Map<String, Object?> result = await collect(
|
||||||
|
Uri(),
|
||||||
|
<String>{'foo'},
|
||||||
|
serviceOverride: fakeVmServiceHost.vmService,
|
||||||
|
coverableLineCache: coverableLineCache,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result, <String, Object>{
|
||||||
|
'type': 'CodeCoverage',
|
||||||
|
'coverage': <Object>[
|
||||||
|
<String, Object>{
|
||||||
|
'source': 'package:foo/foo.dart',
|
||||||
|
'script': <String, Object>{
|
||||||
|
'type': '@Script',
|
||||||
|
'fixedId': true,
|
||||||
|
'id': 'libraries/1/scripts/package%3Afoo%2Ffoo.dart',
|
||||||
|
'uri': 'package:foo/foo.dart',
|
||||||
|
'_kind': 'library',
|
||||||
|
},
|
||||||
|
'hits': <Object>[1, 1, 3, 1, 2, 0],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// coverableLineCache should contain every line mentioned in the report.
|
||||||
|
expect(coverableLineCache, <String, Set<int>>{
|
||||||
|
'package:foo/foo.dart': <int>{1, 2, 3},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('Coverage collector avoids recompiling libraries in coverableLineCache', () async {
|
||||||
|
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
|
||||||
|
requests: <VmServiceExpectation>[
|
||||||
|
FakeVmServiceRequest(
|
||||||
|
method: 'getVM',
|
||||||
|
jsonResponse: (VM.parse(<String, Object>{})!
|
||||||
|
..isolates = <IsolateRef>[
|
||||||
|
IsolateRef.parse(<String, Object>{
|
||||||
|
'id': '1',
|
||||||
|
})!,
|
||||||
|
]
|
||||||
|
).toJson(),
|
||||||
|
),
|
||||||
|
FakeVmServiceRequest(
|
||||||
|
method: 'getVersion',
|
||||||
|
jsonResponse: Version(major: 4, minor: 13).toJson(),
|
||||||
|
),
|
||||||
|
|
||||||
|
// This collection sets librariesAlreadyCompiled. The response doesn't
|
||||||
|
// include any misses.
|
||||||
|
FakeVmServiceRequest(
|
||||||
|
method: 'getSourceReport',
|
||||||
|
args: <String, Object>{
|
||||||
|
'isolateId': '1',
|
||||||
|
'reports': <Object>['Coverage'],
|
||||||
|
'forceCompile': true,
|
||||||
|
'reportLines': true,
|
||||||
|
'libraryFilters': <String>['package:foo/'],
|
||||||
|
'librariesAlreadyCompiled': <String>['package:foo/foo.dart'],
|
||||||
|
},
|
||||||
|
jsonResponse: SourceReport(
|
||||||
|
ranges: <SourceReportRange>[
|
||||||
|
SourceReportRange(
|
||||||
|
scriptIndex: 0,
|
||||||
|
startPos: 0,
|
||||||
|
endPos: 0,
|
||||||
|
compiled: true,
|
||||||
|
coverage: SourceReportCoverage(
|
||||||
|
hits: <int>[1, 3],
|
||||||
|
misses: <int>[],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
scripts: <ScriptRef>[
|
||||||
|
ScriptRef(
|
||||||
|
uri: 'package:foo/foo.dart',
|
||||||
|
id: '1',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).toJson(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
final Map<String, Set<int>> coverableLineCache = <String, Set<int>>{
|
||||||
|
'package:foo/foo.dart': <int>{1, 2, 3},
|
||||||
|
};
|
||||||
|
final Map<String, Object?> result2 = await collect(
|
||||||
|
Uri(),
|
||||||
|
<String>{'foo'},
|
||||||
|
serviceOverride: fakeVmServiceHost.vmService,
|
||||||
|
coverableLineCache: coverableLineCache,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Expect that line 2 is marked as missed, even though it wasn't mentioned
|
||||||
|
// in the getSourceReport response.
|
||||||
|
expect(result2, <String, Object>{
|
||||||
|
'type': 'CodeCoverage',
|
||||||
|
'coverage': <Object>[
|
||||||
|
<String, Object>{
|
||||||
|
'source': 'package:foo/foo.dart',
|
||||||
|
'script': <String, Object>{
|
||||||
|
'type': '@Script',
|
||||||
|
'fixedId': true,
|
||||||
|
'id': 'libraries/1/scripts/package%3Afoo%2Ffoo.dart',
|
||||||
|
'uri': 'package:foo/foo.dart',
|
||||||
|
'_kind': 'library',
|
||||||
|
},
|
||||||
|
'hits': <Object>[1, 1, 2, 0, 3, 1],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
expect(coverableLineCache, <String, Set<int>>{
|
||||||
|
'package:foo/foo.dart': <int>{1, 2, 3},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
File writeFooBarPackagesJson(Directory tempDir) {
|
File writeFooBarPackagesJson(Directory tempDir) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user