diff --git a/CHANGELOG.md b/CHANGELOG.md index 405431d..089f551 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.9.1-wip + +- Remove outdated VM service version checks. + ## 1.9.0 - Require Dart ^3.4 diff --git a/lib/src/collect.dart b/lib/src/collect.dart index 646a7e1..fa298b5 100644 --- a/lib/src/collect.dart +++ b/lib/src/collect.dart @@ -109,12 +109,6 @@ Future> collect(Uri serviceUri, bool resume, } } -bool _versionCheck(Version version, int minMajor, int minMinor) { - final major = version.major ?? 0; - final minor = version.minor ?? 0; - return major > minMajor || (major == minMajor && minor >= minMinor); -} - Future> _getAllCoverage( VmService service, bool includeDart, @@ -126,111 +120,51 @@ Future> _getAllCoverage( scopedOutput ??= {}; final vm = await service.getVM(); final allCoverage = >[]; - final version = await service.getVersion(); - final reportLines = _versionCheck(version, 3, 51); - final branchCoverageSupported = _versionCheck(version, 3, 56); - final libraryFilters = _versionCheck(version, 3, 57); - final fastIsoGroups = _versionCheck(version, 3, 61); - final lineCacheSupported = _versionCheck(version, 4, 13); - - if (branchCoverage && !branchCoverageSupported) { - branchCoverage = false; - stderr.writeln('Branch coverage was requested, but is not supported' - ' by the VM version. Try updating to a newer version of Dart'); - } final sourceReportKinds = [ SourceReportKind.kCoverage, if (branchCoverage) SourceReportKind.kBranchCoverage, ]; - final librariesAlreadyCompiled = - lineCacheSupported ? coverableLineCache?.keys.toList() : null; + final librariesAlreadyCompiled = coverableLineCache?.keys.toList(); // Program counters are shared between isolates in the same group. So we need // to make sure we're only gathering coverage data for one isolate in each // group, otherwise we'll double count the hits. - final isolateOwnerGroup = {}; final coveredIsolateGroups = {}; - if (!fastIsoGroups) { - for (var isolateGroupRef in vm.isolateGroups!) { - final isolateGroup = await service.getIsolateGroup(isolateGroupRef.id!); - for (var isolateRef in isolateGroup.isolates!) { - isolateOwnerGroup[isolateRef.id!] = isolateGroupRef.id!; - } - } - } for (var isolateRef in vm.isolates!) { if (isolateIds != null && !isolateIds.contains(isolateRef.id)) continue; - final isolateGroupId = fastIsoGroups - ? isolateRef.isolateGroupId - : isolateOwnerGroup[isolateRef.id]; + final isolateGroupId = isolateRef.isolateGroupId; if (isolateGroupId != null) { if (coveredIsolateGroups.contains(isolateGroupId)) continue; coveredIsolateGroups.add(isolateGroupId); } - if (scopedOutput.isNotEmpty && !libraryFilters) { - late final ScriptList scripts; - try { - scripts = await service.getScripts(isolateRef.id!); - } on SentinelException { - continue; - } - for (final script in scripts.scripts!) { - // Skip scripts which should not be included in the report. - if (!scopedOutput.includesScript(script.uri)) continue; - late final SourceReport scriptReport; - try { - scriptReport = await service.getSourceReport( - isolateRef.id!, - sourceReportKinds, - forceCompile: true, - scriptId: script.id, - reportLines: reportLines ? true : null, - librariesAlreadyCompiled: librariesAlreadyCompiled, - ); - } on SentinelException { - continue; - } - final coverage = await _processSourceReport( - service, - isolateRef, - scriptReport, - includeDart, - functionCoverage, - reportLines, - coverableLineCache, - scopedOutput); - allCoverage.addAll(coverage); - } - } else { - late final SourceReport isolateReport; - try { - isolateReport = await service.getSourceReport( - isolateRef.id!, - sourceReportKinds, - forceCompile: true, - reportLines: reportLines ? true : null, - libraryFilters: scopedOutput.isNotEmpty && libraryFilters - ? List.from(scopedOutput.map((filter) => 'package:$filter/')) - : null, - librariesAlreadyCompiled: librariesAlreadyCompiled, - ); - } on SentinelException { - continue; - } - final coverage = await _processSourceReport( - service, - isolateRef, - isolateReport, - includeDart, - functionCoverage, - reportLines, - coverableLineCache, - scopedOutput); - allCoverage.addAll(coverage); + + late final SourceReport isolateReport; + try { + isolateReport = await service.getSourceReport( + isolateRef.id!, + sourceReportKinds, + forceCompile: true, + reportLines: true, + libraryFilters: scopedOutput.isNotEmpty + ? List.from(scopedOutput.map((filter) => 'package:$filter/')) + : null, + librariesAlreadyCompiled: librariesAlreadyCompiled, + ); + } on SentinelException { + continue; } + final coverage = await _processSourceReport( + service, + isolateRef, + isolateReport, + includeDart, + functionCoverage, + coverableLineCache, + scopedOutput); + allCoverage.addAll(coverage); } return {'type': 'CodeCoverage', 'coverage': allCoverage}; } @@ -310,13 +244,12 @@ Future>> _processSourceReport( SourceReport report, bool includeDart, bool functionCoverage, - bool reportLines, Map>? coverableLineCache, Set scopedOutput) async { final hitMaps = {}; final scripts = {}; final libraries = {}; - final needScripts = functionCoverage || !reportLines; + final needScripts = functionCoverage; Future getScript(ScriptRef? scriptRef) async { if (scriptRef == null) { @@ -425,15 +358,7 @@ Future>> _processSourceReport( void forEachLine(List? tokenPositions, void Function(int line) body) { if (tokenPositions == null) return; - for (final pos in tokenPositions) { - final line = reportLines ? pos : _getLineFromTokenPos(script!, pos); - if (line == null) { - if (_debugTokenPositions) { - stderr.write( - 'tokenPos $pos has no line mapping for script $scriptUri'); - } - continue; - } + for (final line in tokenPositions) { body(line); } } diff --git a/pubspec.yaml b/pubspec.yaml index f3686fe..7251b74 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: coverage -version: 1.9.0 +version: 1.9.1-wip description: Coverage data manipulation and formatting repository: https://github.com/dart-lang/coverage diff --git a/test/collect_coverage_mock_test.dart b/test/collect_coverage_mock_test.dart index a919d9f..2c173d5 100644 --- a/test/collect_coverage_mock_test.dart +++ b/test/collect_coverage_mock_test.dart @@ -14,9 +14,6 @@ import 'collect_coverage_mock_test.mocks.dart'; SourceReportRange _range(int scriptIndex, SourceReportCoverage coverage) => SourceReportRange(scriptIndex: scriptIndex, coverage: coverage); -Script _script(List> tokenPosTable) => - Script(id: 'script', tokenPosTable: tokenPosTable); - IsolateRef _isoRef(String id, String isoGroupId) => IsolateRef(id: id, isolateGroupId: isoGroupId); @@ -63,59 +60,7 @@ MockVmService _mockService( void main() { group('Mock VM Service', () { test('Collect coverage', () async { - final service = _mockService(3, 0); - when(service.getSourceReport('isolate', ['Coverage'], forceCompile: true)) - .thenAnswer((_) async => SourceReport( - ranges: [ - _range( - 0, - SourceReportCoverage( - hits: [15], - misses: [32], - ), - ), - _range( - 1, - SourceReportCoverage( - hits: [75], - misses: [34], - ), - ), - ], - scripts: [ - ScriptRef( - uri: 'package:foo/foo.dart', - id: 'foo', - ), - ScriptRef( - uri: 'package:bar/bar.dart', - id: 'bar', - ), - ], - )); - when(service.getObject('isolate', 'foo')) - .thenAnswer((_) async => _script([ - [12, 15, 7], - [47, 32, 19], - ])); - when(service.getObject('isolate', 'bar')) - .thenAnswer((_) async => _script([ - [52, 34, 10], - [95, 75, 3], - ])); - - final jsonResult = await collect(Uri(), false, false, false, null, - serviceOverrideForTesting: service); - final result = await HitMap.parseJson( - jsonResult['coverage'] as List>); - - expect(result.length, 2); - expect(result['package:foo/foo.dart']?.lineHits, {12: 1, 47: 0}); - expect(result['package:bar/bar.dart']?.lineHits, {95: 1, 52: 0}); - }); - - test('Collect coverage, report lines', () async { - final service = _mockService(3, 51); + final service = _mockService(4, 13); when(service.getSourceReport( 'isolate', ['Coverage'], @@ -160,59 +105,8 @@ void main() { expect(result['package:bar/bar.dart']?.lineHits, {95: 1, 52: 0}); }); - test('Collect coverage, scoped output, no library filters', () async { - final service = _mockService(3, 0); - when(service.getScripts('isolate')).thenAnswer((_) async => ScriptList( - scripts: [ - ScriptRef( - uri: 'package:foo/foo.dart', - id: 'foo', - ), - ScriptRef( - uri: 'package:bar/bar.dart', - id: 'bar', - ), - ], - )); - when(service.getSourceReport( - 'isolate', - ['Coverage'], - scriptId: 'foo', - forceCompile: true, - )).thenAnswer((_) async => SourceReport( - ranges: [ - _range( - 0, - SourceReportCoverage( - hits: [15], - misses: [32], - ), - ), - ], - scripts: [ - ScriptRef( - uri: 'package:foo/foo.dart', - id: 'foo', - ), - ], - )); - when(service.getObject('isolate', 'foo')) - .thenAnswer((_) async => _script([ - [12, 15, 7], - [47, 32, 19], - ])); - - final jsonResult = await collect(Uri(), false, false, false, {'foo'}, - serviceOverrideForTesting: service); - final result = await HitMap.parseJson( - jsonResult['coverage'] as List>); - - expect(result.length, 1); - expect(result['package:foo/foo.dart']?.lineHits, {12: 1, 47: 0}); - }); - - test('Collect coverage, scoped output, library filters', () async { - final service = _mockService(3, 57); + test('Collect coverage, scoped output', () async { + final service = _mockService(4, 13); when(service.getSourceReport( 'isolate', ['Coverage'], @@ -246,84 +140,8 @@ void main() { expect(result['package:foo/foo.dart']?.lineHits, {12: 1, 47: 0}); }); - test('Collect coverage, old isolate group deduping', () async { - final service = _mockService(3, 60, isolateGroups: { - 'isolateGroupA': ['isolate1', 'isolate2'], - 'isolateGroupB': ['isolate3'], - }); - when(service.getSourceReport( - 'isolate1', - ['Coverage'], - forceCompile: true, - reportLines: true, - )).thenAnswer((_) async => SourceReport( - ranges: [ - _range( - 0, - SourceReportCoverage( - hits: [12], - misses: [47], - ), - ), - _range( - 1, - SourceReportCoverage( - hits: [95], - misses: [52], - ), - ), - ], - scripts: [ - ScriptRef( - uri: 'package:foo/foo.dart', - id: 'foo', - ), - ScriptRef( - uri: 'package:bar/bar.dart', - id: 'bar', - ), - ], - )); - when(service.getSourceReport( - 'isolate3', - ['Coverage'], - forceCompile: true, - reportLines: true, - )).thenAnswer((_) async => SourceReport( - ranges: [ - _range( - 0, - SourceReportCoverage( - hits: [34], - misses: [61], - ), - ), - ], - scripts: [ - ScriptRef( - uri: 'package:baz/baz.dart', - id: 'baz', - ), - ], - )); - - final jsonResult = await collect(Uri(), false, false, false, null, - serviceOverrideForTesting: service); - final result = await HitMap.parseJson( - jsonResult['coverage'] as List>); - - expect(result.length, 3); - expect(result['package:foo/foo.dart']?.lineHits, {12: 1, 47: 0}); - expect(result['package:bar/bar.dart']?.lineHits, {95: 1, 52: 0}); - expect(result['package:baz/baz.dart']?.lineHits, {34: 1, 61: 0}); - verifyNever(service.getSourceReport('isolate2', ['Coverage'], - forceCompile: true, reportLines: true)); - verify(service.getIsolateGroup('isolateGroupA')); - verify(service.getIsolateGroup('isolateGroupB')); - }); - test('Collect coverage, fast isolate group deduping', () async { - final service = _mockService(3, 61, isolateGroups: { + final service = _mockService(4, 13, isolateGroups: { 'isolateGroupA': ['isolate1', 'isolate2'], 'isolateGroupB': ['isolate3'], }); @@ -399,82 +217,15 @@ void main() { }); test( - 'Collect coverage, scoped output, no library filters, ' - 'handles SentinelException from getScripts', () async { - final service = _mockService(3, 0); - when(service.getScripts('isolate')).thenThrow(FakeSentinelException()); - - final jsonResult = await collect( - Uri(), false, false, false, {'foo', 'bar'}, - serviceOverrideForTesting: service); - final result = await HitMap.parseJson( - jsonResult['coverage'] as List>); - - expect(result.length, 0); - }); - - test( - 'Collect coverage, scoped output, no library filters, ' + 'Collect coverage, no scoped output, ' 'handles SentinelException from getSourceReport', () async { - final service = _mockService(3, 51); - when(service.getScripts('isolate')).thenAnswer((_) async => ScriptList( - scripts: [ - ScriptRef( - uri: 'package:foo/foo.dart', - id: 'foo', - ), - ScriptRef( - uri: 'package:bar/bar.dart', - id: 'bar', - ), - ], - )); + final service = _mockService(4, 13); when(service.getSourceReport( 'isolate', ['Coverage'], - scriptId: 'foo', forceCompile: true, reportLines: true, )).thenThrow(FakeSentinelException()); - when(service.getSourceReport( - 'isolate', - ['Coverage'], - scriptId: 'bar', - forceCompile: true, - reportLines: true, - )).thenAnswer((_) async => SourceReport( - ranges: [ - _range( - 0, - SourceReportCoverage( - hits: [95], - misses: [52], - ), - ), - ], - scripts: [ - ScriptRef( - uri: 'package:bar/bar.dart', - id: 'bar', - ), - ], - )); - - final jsonResult = await collect( - Uri(), false, false, false, {'foo', 'bar'}, - serviceOverrideForTesting: service); - final result = await HitMap.parseJson( - jsonResult['coverage'] as List>); - expect(result.length, 1); - expect(result['package:bar/bar.dart']?.lineHits, {95: 1, 52: 0}); - }); - - test( - 'Collect coverage, no scoped output, ' - 'handles SentinelException from getSourceReport', () async { - final service = _mockService(3, 0); - when(service.getSourceReport('isolate', ['Coverage'], forceCompile: true)) - .thenThrow(FakeSentinelException()); final jsonResult = await collect(Uri(), false, false, false, null, serviceOverrideForTesting: service); @@ -484,56 +235,6 @@ void main() { expect(result.length, 0); }); - test('Collect coverage, coverableLineCache, old vm service', () async { - // Expect that getSourceReport's librariesAlreadyCompiled param is not set - // when coverableLineCache is non-null but the service version is too old. - final service = _mockService(4, 12); - when(service.getSourceReport( - 'isolate', - ['Coverage'], - forceCompile: true, - reportLines: true, - )).thenAnswer((_) async => SourceReport( - ranges: [ - _range( - 0, - SourceReportCoverage( - hits: [12], - misses: [47], - ), - ), - _range( - 1, - SourceReportCoverage( - hits: [95], - misses: [52], - ), - ), - ], - scripts: [ - ScriptRef( - uri: 'package:foo/foo.dart', - id: 'foo', - ), - ScriptRef( - uri: 'package:bar/bar.dart', - id: 'bar', - ), - ], - )); - - final coverableLineCache = >{}; - final jsonResult = await collect(Uri(), false, false, false, null, - coverableLineCache: coverableLineCache, - serviceOverrideForTesting: service); - final result = await HitMap.parseJson( - jsonResult['coverage'] as List>); - - expect(result.length, 2); - expect(result['package:foo/foo.dart']?.lineHits, {12: 1, 47: 0}); - expect(result['package:bar/bar.dart']?.lineHits, {95: 1, 52: 0}); - }); - test('Collect coverage, coverableLineCache', () async { // Expect that on the first getSourceReport call, librariesAlreadyCompiled // is empty. @@ -664,10 +365,10 @@ void main() { }); test( - 'Collect coverage, scoped output, library filters, ' + 'Collect coverage, scoped output, ' 'handles SourceReports that contain unfiltered ranges', () async { // Regression test for https://github.com/dart-lang/coverage/issues/495 - final service = _mockService(3, 57); + final service = _mockService(4, 13); when(service.getSourceReport( 'isolate', ['Coverage'],