// Copyright 2019 The Chromium Authors. 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:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/test/coverage_collector.dart'; import 'package:flutter_tools/src/vmservice.dart'; import 'package:mockito/mockito.dart'; import '../src/common.dart'; void main() { MockVMService mockVMService; setUp(() { mockVMService = MockVMService(); }); test('Coverage collector Can handle coverage sentinenl data', () async { when(mockVMService.vm.isolates.first.invokeRpcRaw('getScripts', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return {'type': 'Sentinel', 'kind': 'Collected', 'valueAsString': ''}; }); final Map result = await collect(null, (String predicate) => true, connector: (Uri uri) async { return mockVMService; }); expect(result, {'type': 'CodeCoverage', 'coverage': []}); }); test('Coverage collector can handle null scripts value', () async { when(mockVMService.vm.isolates.first.invokeRpcRaw('getScripts', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': >[ {'uri': 'some_uri', 'id': 'some_id'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getSourceReport', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'ranges': >[{}] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getObject', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return {}; }); final Map result = await collect(null, (String predicate) => true, connector: (Uri uri) async { return mockVMService; }); expect(result, {'type': 'CodeCoverage', 'coverage': []}); }); test('Coverage collector can handle null ranges value', () async { when(mockVMService.vm.isolates.first.invokeRpcRaw('getScripts', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': >[ {'uri': 'some_uri', 'id': 'some_id'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getSourceReport', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return {'scripts': {}}; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getObject', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return {}; }); final Map result = await collect(null, (String predicate) => true, connector: (Uri uri) async { return mockVMService; }); expect(result, {'type': 'CodeCoverage', 'coverage': []}); }); test('Coverage collector can handle null scriptIndex values', () async { when(mockVMService.vm.isolates.first.invokeRpcRaw('getScripts', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': >[ {'uri': 'some_uri', 'id': 'some_id'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getSourceReport', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': {'uri': 'some_uri', 'id': 'some_id'}, 'ranges': >[ {'coverage': {}} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getObject', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return {}; }); final Map result = await collect(null, (String predicate) => true, connector: (Uri uri) async { return mockVMService; }); expect(result, {'type': 'CodeCoverage', 'coverage': []}); }); test('Coverage collector can handle null scriptRef values', () async { when(mockVMService.vm.isolates.first.invokeRpcRaw('getScripts', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': >[ {'uri': 'some_uri', 'id': 'some_id'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getSourceReport', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': {'uri': 'some_uri', 'id': 'some_id'}, 'ranges': >[ {'coverage': {}, 'scriptIndex': 'some_value'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getObject', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return {}; }); final Map result = await collect(null, (String predicate) => true, connector: (Uri uri) async { return mockVMService; }); expect(result, {'type': 'CodeCoverage', 'coverage': []}); }); test('Coverage collector can handle null scriptRef uri values', () async { when(mockVMService.vm.isolates.first.invokeRpcRaw('getScripts', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': >[ {'uri': 'some_uri', 'id': 'some_id'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getSourceReport', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': {'uri': 'some_uri', 'id': 'some_id', 'index_0': {}}, 'ranges': >[ {'coverage': {}, 'scriptIndex': 'index_0'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getObject', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return {}; }); final Map result = await collect(null, (String predicate) => true, connector: (Uri uri) async { return mockVMService; }); expect(result, {'type': 'CodeCoverage', 'coverage': []}); }); test('Coverage collector can handle null scriptRef id values', () async { when(mockVMService.vm.isolates.first.invokeRpcRaw('getScripts', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': >[ {'uri': 'some_uri', 'id': 'some_id'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getSourceReport', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': { 'uri': 'some_uri', 'id': 'some_id', 'index_0': {'uri': 'some_uri'} }, 'ranges': >[ {'coverage': {}, 'scriptIndex': 'index_0'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getObject', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return {}; }); final Map result = await collect(null, (String predicate) => true, connector: (Uri uri) async { return mockVMService; }); expect(result, {'type': 'CodeCoverage', 'coverage': []}); }); test('Coverage collector can handle null scriptById values', () async { when(mockVMService.vm.isolates.first.invokeRpcRaw('getScripts', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': >[ {'uri': 'some_uri', 'id': 'some_id'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getSourceReport', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': { 'uri': 'some_uri', 'id': 'some_id', 'index_0': {'uri': 'some_uri', 'id': '01'}, }, 'ranges': >[ {'coverage': {}, 'scriptIndex': 'index_0'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getObject', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return {}; }); final Map result = await collect(null, (String predicate) => true, connector: (Uri uri) async { return mockVMService; }); expect(result, {'type': 'CodeCoverage', 'coverage': []}); }); test('Coverage collector can handle null tokenPosTable values', () async { when(mockVMService.vm.isolates.first.invokeRpcRaw('getScripts', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': >[ {'uri': 'some_uri', 'id': 'some_id'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getSourceReport', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': { 'uri': 'some_uri', 'id': 'some_id', 'index_0': {'uri': 'some_uri', 'id': '01'}, '01': {}, }, 'ranges': >[ {'coverage': {}, 'scriptIndex': 'index_0'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getObject', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return {}; }); final Map result = await collect(null, (String predicate) => true, connector: (Uri uri) async { return mockVMService; }); expect(result, { 'type': 'CodeCoverage', 'coverage': >[ { 'source': 'some_uri', 'script': { 'type': '@Script', 'fixedId': true, 'id': 'libraries/1/scripts/some_uri', 'uri': 'some_uri', '_kind': 'library' }, 'hits': >[] } ] }); }); test('Coverage collector can handle null hits values', () async { when(mockVMService.vm.isolates.first.invokeRpcRaw('getScripts', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': >[ {'uri': 'some_uri', 'id': 'some_id'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getSourceReport', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': { 'uri': 'some_uri', 'id': 'some_id', 'index_0': {'uri': 'some_uri', 'id': '01'}, '01': {'tokenPosTable': []}, }, 'ranges': >[ {'coverage': {}, 'scriptIndex': 'index_0'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getObject', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return {}; }); final Map result = await collect(null, (String predicate) => true, connector: (Uri uri) async { return mockVMService; }); expect(result, { 'type': 'CodeCoverage', 'coverage': >[ { 'source': 'some_uri', 'script': { 'type': '@Script', 'fixedId': true, 'id': 'libraries/1/scripts/some_uri', 'uri': 'some_uri', '_kind': 'library' }, 'hits': >[] } ] }); }); test('Coverage collector can handle null misses values', () async { when(mockVMService.vm.isolates.first.invokeRpcRaw('getScripts', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': >[ {'uri': 'some_uri', 'id': 'some_id'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getSourceReport', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': { 'uri': 'some_uri', 'id': 'some_id', 'index_0': {'uri': 'some_uri', 'id': '01'}, '01': {'tokenPosTable': []}, }, 'ranges': >[ { 'coverage': {'hits': []}, 'scriptIndex': 'index_0' } ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getObject', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return {}; }); final Map result = await collect(null, (String predicate) => true, connector: (Uri uri) async { return mockVMService; }); expect(result, { 'type': 'CodeCoverage', 'coverage': >[ { 'source': 'some_uri', 'script': { 'type': '@Script', 'fixedId': true, 'id': 'libraries/1/scripts/some_uri', 'uri': 'some_uri', '_kind': 'library' }, 'hits': >[] } ] }); }); test('Coverage collector should process hits and misses', () async { when(mockVMService.vm.isolates.first.invokeRpcRaw('getScripts', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': >[ {'uri': 'some_uri', 'id': 'some_id'} ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getSourceReport', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return { 'scripts': { 'uri': 'some_uri', 'id': 'some_id', 'index_0': {'uri': 'some_uri', 'id': '01'}, '01': { 'tokenPosTable': [ [1, 100, 5, 101, 8], [2, 102, 7], ] }, }, 'ranges': >[ { 'coverage': { 'hits': [100, 101], 'misses': [102], }, 'scriptIndex': 'index_0' } ] }; }); when(mockVMService.vm.isolates.first.invokeRpcRaw('getObject', params: anyNamed('params'))) .thenAnswer((Invocation invocation) async { return {}; }); final Map result = await collect(null, (String predicate) => true, connector: (Uri uri) async { return mockVMService; }); expect(result, { 'type': 'CodeCoverage', 'coverage': >[ { 'source': 'some_uri', 'script': { 'type': '@Script', 'fixedId': true, 'id': 'libraries/1/scripts/some_uri', 'uri': 'some_uri', '_kind': 'library' }, 'hits': [1, 2, 2, 0] } ] }); }); } class MockVMService extends Mock implements VMService { @override final MockVM vm = MockVM(); } class MockVM extends Mock implements VM { @override final List isolates = [MockIsolate()]; } class MockIsolate extends Mock implements Isolate {} class MockProcess extends Mock implements Process { final Completer completer = Completer(); @override Future get exitCode => completer.future; }