| // Copyright 2018 The Flutter 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:fuchsia_remote_debug_protocol/src/dart/dart_vm.dart'; |
| import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc; |
| import 'package:mockito/mockito.dart'; |
| import 'package:test/test.dart'; |
| |
| void main() { |
| group('DartVm.connect', () { |
| tearDown(() { |
| restoreVmServiceConnectionFunction(); |
| }); |
| |
| test('null connector', () async { |
| Future<json_rpc.Peer> mockServiceFunction(Uri uri) { |
| return new Future<json_rpc.Peer>(() => null); |
| } |
| |
| fuchsiaVmServiceConnectionFunction = mockServiceFunction; |
| expect(await DartVm.connect(Uri.parse('http://this.whatever/ws')), |
| equals(null)); |
| }); |
| |
| test('disconnect closes peer', () async { |
| final MockPeer peer = new MockPeer(); |
| Future<json_rpc.Peer> mockServiceFunction(Uri uri) { |
| return new Future<json_rpc.Peer>(() => peer); |
| } |
| |
| fuchsiaVmServiceConnectionFunction = mockServiceFunction; |
| final DartVm vm = |
| await DartVm.connect(Uri.parse('http://this.whatever/ws')); |
| expect(vm, isNot(null)); |
| await vm.stop(); |
| verify(peer.close()); |
| }); |
| }); |
| |
| group('DartVm.getAllFlutterViews', () { |
| MockPeer mockPeer; |
| |
| setUp(() { |
| mockPeer = new MockPeer(); |
| }); |
| |
| tearDown(() { |
| restoreVmServiceConnectionFunction(); |
| }); |
| |
| test('basic flutter view parsing', () async { |
| final Map<String, dynamic> flutterViewCannedResponses = <String, dynamic>{ |
| 'views': <Map<String, dynamic>>[ |
| <String, dynamic>{ |
| 'type': 'FlutterView', |
| 'id': 'flutterView0', |
| }, |
| <String, dynamic>{ |
| 'type': 'FlutterView', |
| 'id': 'flutterView1', |
| 'isolate': <String, dynamic>{ |
| 'type': '@Isolate', |
| 'fixedId': 'true', |
| 'id': 'isolates/1', |
| 'name': 'file://flutterBinary1', |
| 'number': '1', |
| }, |
| }, |
| <String, dynamic>{ |
| 'type': 'FlutterView', |
| 'id': 'flutterView2', |
| 'isolate': <String, dynamic>{ |
| 'type': '@Isolate', |
| 'fixedId': 'true', |
| 'id': 'isolates/2', |
| 'name': 'file://flutterBinary2', |
| 'number': '2', |
| }, |
| }, |
| ], |
| }; |
| |
| Future<json_rpc.Peer> mockVmConnectionFunction(Uri uri) { |
| when(mockPeer.sendRequest( |
| typed<String>(any), typed<Map<String, dynamic>>(any))) |
| .thenAnswer((_) => new Future<Map<String, dynamic>>( |
| () => flutterViewCannedResponses)); |
| return new Future<json_rpc.Peer>(() => mockPeer); |
| } |
| |
| fuchsiaVmServiceConnectionFunction = mockVmConnectionFunction; |
| final DartVm vm = |
| await DartVm.connect(Uri.parse('http://whatever.com/ws')); |
| expect(vm, isNot(null)); |
| final List<FlutterView> views = await vm.getAllFlutterViews(); |
| expect(views.length, 3); |
| // Check ID's as they cannot be null. |
| expect(views[0].id, 'flutterView0'); |
| expect(views[1].id, 'flutterView1'); |
| expect(views[2].id, 'flutterView2'); |
| |
| // Verify names. |
| expect(views[0].name, equals(null)); |
| expect(views[1].name, 'file://flutterBinary1'); |
| expect(views[2].name, 'file://flutterBinary2'); |
| }); |
| |
| test('invalid flutter view missing ID', () async { |
| final Map<String, dynamic> flutterViewCannedResponseMissingId = |
| <String, dynamic>{ |
| 'views': <Map<String, dynamic>>[ |
| // Valid flutter view. |
| <String, dynamic>{ |
| 'type': 'FlutterView', |
| 'id': 'flutterView1', |
| 'isolate': <String, dynamic>{ |
| 'type': '@Isolate', |
| 'name': 'IsolateThing', |
| 'fixedId': 'true', |
| 'id': 'isolates/1', |
| 'number': '1', |
| }, |
| }, |
| |
| // Missing ID. |
| <String, dynamic>{ |
| 'type': 'FlutterView', |
| }, |
| ] |
| }; |
| |
| Future<json_rpc.Peer> mockVmConnectionFunction(Uri uri) { |
| when(mockPeer.sendRequest( |
| typed<String>(any), typed<Map<String, dynamic>>(any))) |
| .thenAnswer((_) => new Future<Map<String, dynamic>>( |
| () => flutterViewCannedResponseMissingId)); |
| return new Future<json_rpc.Peer>(() => mockPeer); |
| } |
| |
| fuchsiaVmServiceConnectionFunction = mockVmConnectionFunction; |
| final DartVm vm = |
| await DartVm.connect(Uri.parse('http://whatever.com/ws')); |
| expect(vm, isNot(null)); |
| Future<Null> failingFunction() async { |
| await vm.getAllFlutterViews(); |
| } |
| |
| // Both views should be invalid as they were missing required fields. |
| expect(failingFunction, throwsA(const isInstanceOf<RpcFormatError>())); |
| }); |
| |
| test('invalid flutter view missing ID', () async { |
| final Map<String, dynamic> flutterViewCannedResponseMissingIsolateName = |
| <String, dynamic>{ |
| 'views': <Map<String, dynamic>>[ |
| // Missing isolate name. |
| <String, dynamic>{ |
| 'type': 'FlutterView', |
| 'id': 'flutterView1', |
| 'isolate': <String, dynamic>{ |
| 'type': '@Isolate', |
| 'fixedId': 'true', |
| 'id': 'isolates/1', |
| 'number': '1', |
| }, |
| }, |
| ], |
| }; |
| |
| Future<json_rpc.Peer> mockVmConnectionFunction(Uri uri) { |
| when(mockPeer.sendRequest( |
| typed<String>(any), typed<Map<String, dynamic>>(any))) |
| .thenAnswer((_) => new Future<Map<String, dynamic>>( |
| () => flutterViewCannedResponseMissingIsolateName)); |
| return new Future<json_rpc.Peer>(() => mockPeer); |
| } |
| |
| fuchsiaVmServiceConnectionFunction = mockVmConnectionFunction; |
| final DartVm vm = |
| await DartVm.connect(Uri.parse('http://whatever.com/ws')); |
| expect(vm, isNot(null)); |
| Future<Null> failingFunction() async { |
| await vm.getAllFlutterViews(); |
| } |
| |
| // Both views should be invalid as they were missing required fields. |
| expect(failingFunction, throwsA(const isInstanceOf<RpcFormatError>())); |
| }); |
| }); |
| |
| group('DartVm.invokeRpc', () { |
| MockPeer mockPeer; |
| |
| setUp(() { |
| mockPeer = new MockPeer(); |
| }); |
| |
| tearDown(() { |
| restoreVmServiceConnectionFunction(); |
| }); |
| |
| test('verify timeout fires', () async { |
| const Duration timeoutTime = const Duration(milliseconds: 100); |
| Future<json_rpc.Peer> mockVmConnectionFunction(Uri uri) { |
| // Return a command that will never complete. |
| when(mockPeer.sendRequest( |
| typed<String>(any), typed<Map<String, dynamic>>(any))) |
| .thenAnswer((_) => new Completer<Map<String, dynamic>>().future); |
| return new Future<json_rpc.Peer>(() => mockPeer); |
| } |
| |
| fuchsiaVmServiceConnectionFunction = mockVmConnectionFunction; |
| final DartVm vm = |
| await DartVm.connect(Uri.parse('http://whatever.com/ws')); |
| expect(vm, isNot(null)); |
| Future<Null> failingFunction() async { |
| await vm.invokeRpc('somesillyfunction', timeout: timeoutTime); |
| } |
| |
| expect(failingFunction, throwsA(const isInstanceOf<TimeoutException>())); |
| }); |
| }); |
| } |
| |
| class MockPeer extends Mock implements json_rpc.Peer {} |