2019-11-27 23:04:02 +00:00
|
|
|
// Copyright 2014 The Flutter Authors. All rights reserved.
|
2019-08-05 23:51:57 +00:00
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
import 'dart:async';
|
2019-09-26 21:23:19 +00:00
|
|
|
import 'dart:convert';
|
2019-08-05 23:51:57 +00:00
|
|
|
|
2019-10-24 16:06:45 +00:00
|
|
|
import 'package:build_daemon/client.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'package:dwds/dwds.dart';
|
|
|
|
import 'package:flutter_tools/src/base/common.dart';
|
2019-10-10 23:34:27 +00:00
|
|
|
import 'package:flutter_tools/src/base/io.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'package:flutter_tools/src/base/logger.dart';
|
2019-12-12 18:43:58 +00:00
|
|
|
import 'package:flutter_tools/src/base/net.dart';
|
2020-01-08 20:35:12 +00:00
|
|
|
import 'package:flutter_tools/src/base/terminal.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'package:flutter_tools/src/build_info.dart';
|
2019-11-24 05:54:43 +00:00
|
|
|
import 'package:flutter_tools/src/build_runner/resident_web_runner.dart';
|
|
|
|
import 'package:flutter_tools/src/build_runner/web_fs.dart';
|
2019-11-08 04:13:02 +00:00
|
|
|
import 'package:flutter_tools/src/compile.dart';
|
|
|
|
import 'package:flutter_tools/src/devfs.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'package:flutter_tools/src/device.dart';
|
2019-11-08 04:13:02 +00:00
|
|
|
import 'package:flutter_tools/src/features.dart';
|
2020-01-06 19:04:20 +00:00
|
|
|
import 'package:flutter_tools/src/globals.dart' as globals;
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'package:flutter_tools/src/project.dart';
|
2019-09-11 16:38:42 +00:00
|
|
|
import 'package:flutter_tools/src/reporting/reporting.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'package:flutter_tools/src/resident_runner.dart';
|
2019-11-08 04:13:02 +00:00
|
|
|
import 'package:flutter_tools/src/web/chrome.dart';
|
2019-09-11 02:29:31 +00:00
|
|
|
import 'package:flutter_tools/src/web/web_device.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'package:meta/meta.dart';
|
|
|
|
import 'package:mockito/mockito.dart';
|
2020-01-08 20:35:12 +00:00
|
|
|
import 'package:platform/platform.dart';
|
2019-08-09 16:58:49 +00:00
|
|
|
import 'package:vm_service/vm_service.dart';
|
2019-11-08 04:13:02 +00:00
|
|
|
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
|
|
|
|
import '../src/common.dart';
|
2019-11-24 05:54:43 +00:00
|
|
|
import '../src/context.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
import '../src/testbed.dart';
|
|
|
|
|
|
|
|
void main() {
|
|
|
|
Testbed testbed;
|
|
|
|
MockFlutterWebFs mockWebFs;
|
|
|
|
ResidentWebRunner residentWebRunner;
|
|
|
|
MockDebugConnection mockDebugConnection;
|
|
|
|
MockVmService mockVmService;
|
2019-11-08 04:13:02 +00:00
|
|
|
MockChromeDevice mockChromeDevice;
|
2019-09-26 21:23:19 +00:00
|
|
|
MockAppConnection mockAppConnection;
|
2019-11-08 04:13:02 +00:00
|
|
|
MockFlutterDevice mockFlutterDevice;
|
|
|
|
MockWebDevFS mockWebDevFS;
|
|
|
|
MockResidentCompiler mockResidentCompiler;
|
|
|
|
MockChrome mockChrome;
|
|
|
|
MockChromeConnection mockChromeConnection;
|
|
|
|
MockChromeTab mockChromeTab;
|
|
|
|
MockWipConnection mockWipConnection;
|
|
|
|
MockWipDebugger mockWipDebugger;
|
2019-11-27 21:32:45 +00:00
|
|
|
MockWebServerDevice mockWebServerDevice;
|
2019-11-12 23:24:45 +00:00
|
|
|
bool didSkipDwds;
|
2019-08-05 23:51:57 +00:00
|
|
|
|
|
|
|
setUp(() {
|
2019-11-08 04:13:02 +00:00
|
|
|
resetChromeForTesting();
|
2019-08-05 23:51:57 +00:00
|
|
|
mockWebFs = MockFlutterWebFs();
|
|
|
|
mockDebugConnection = MockDebugConnection();
|
|
|
|
mockVmService = MockVmService();
|
2019-11-08 04:13:02 +00:00
|
|
|
mockChromeDevice = MockChromeDevice();
|
2019-09-26 21:23:19 +00:00
|
|
|
mockAppConnection = MockAppConnection();
|
2019-11-08 04:13:02 +00:00
|
|
|
mockFlutterDevice = MockFlutterDevice();
|
|
|
|
mockWebDevFS = MockWebDevFS();
|
|
|
|
mockResidentCompiler = MockResidentCompiler();
|
|
|
|
mockChrome = MockChrome();
|
|
|
|
mockChromeConnection = MockChromeConnection();
|
|
|
|
mockChromeTab = MockChromeTab();
|
|
|
|
mockWipConnection = MockWipConnection();
|
|
|
|
mockWipDebugger = MockWipDebugger();
|
2019-11-27 21:32:45 +00:00
|
|
|
mockWebServerDevice = MockWebServerDevice();
|
2019-11-08 04:13:02 +00:00
|
|
|
when(mockFlutterDevice.device).thenReturn(mockChromeDevice);
|
2019-08-05 23:51:57 +00:00
|
|
|
testbed = Testbed(
|
|
|
|
setup: () {
|
2019-11-08 04:13:02 +00:00
|
|
|
residentWebRunner = DwdsWebRunnerFactory().createWebRunner(
|
|
|
|
mockFlutterDevice,
|
2019-08-05 23:51:57 +00:00
|
|
|
flutterProject: FlutterProject.current(),
|
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
|
|
|
ipv6: true,
|
2019-11-08 04:13:02 +00:00
|
|
|
stayResident: true,
|
2019-11-10 01:08:53 +00:00
|
|
|
dartDefines: const <String>[],
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2019-11-24 05:54:43 +00:00
|
|
|
) as ResidentWebRunner;
|
2020-01-16 21:32:49 +00:00
|
|
|
globals.fs.currentDirectory.childFile('.packages')
|
|
|
|
..writeAsStringSync('\n');
|
2019-08-05 23:51:57 +00:00
|
|
|
},
|
|
|
|
overrides: <Type, Generator>{
|
2019-09-27 08:46:45 +00:00
|
|
|
WebFsFactory: () => ({
|
|
|
|
@required String target,
|
|
|
|
@required FlutterProject flutterProject,
|
|
|
|
@required BuildInfo buildInfo,
|
|
|
|
@required bool skipDwds,
|
|
|
|
@required bool initializePlatform,
|
|
|
|
@required String hostname,
|
|
|
|
@required String port,
|
2019-11-10 01:08:53 +00:00
|
|
|
@required List<String> dartDefines,
|
2019-12-12 18:43:58 +00:00
|
|
|
@required UrlTunneller urlTunneller,
|
2019-09-27 08:46:45 +00:00
|
|
|
}) async {
|
2019-11-12 23:24:45 +00:00
|
|
|
didSkipDwds = skipDwds;
|
2019-09-27 08:46:45 +00:00
|
|
|
return mockWebFs;
|
|
|
|
},
|
2019-08-05 23:51:57 +00:00
|
|
|
},
|
2019-09-27 08:46:45 +00:00
|
|
|
);
|
2019-08-05 23:51:57 +00:00
|
|
|
});
|
|
|
|
|
2019-09-24 19:03:37 +00:00
|
|
|
void _setupMocks() {
|
2020-01-06 19:04:20 +00:00
|
|
|
globals.fs.file('pubspec.yaml').createSync();
|
|
|
|
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
|
|
|
|
globals.fs.file(globals.fs.path.join('web', 'index.html')).createSync(recursive: true);
|
2019-09-26 21:23:19 +00:00
|
|
|
when(mockWebFs.connect(any)).thenAnswer((Invocation _) async {
|
|
|
|
return ConnectionResult(mockAppConnection, mockDebugConnection);
|
2019-08-05 23:51:57 +00:00
|
|
|
});
|
2019-08-20 00:33:46 +00:00
|
|
|
when(mockWebFs.recompile()).thenAnswer((Invocation _) {
|
|
|
|
return Future<bool>.value(false);
|
|
|
|
});
|
2019-11-18 18:10:15 +00:00
|
|
|
when(mockWebFs.uri).thenReturn('http://localhost:8765/app/');
|
2019-08-05 23:51:57 +00:00
|
|
|
when(mockDebugConnection.vmService).thenReturn(mockVmService);
|
2019-08-26 22:06:36 +00:00
|
|
|
when(mockDebugConnection.onDone).thenAnswer((Invocation invocation) {
|
|
|
|
return Completer<void>().future;
|
|
|
|
});
|
2019-08-05 23:51:57 +00:00
|
|
|
when(mockVmService.onStdoutEvent).thenAnswer((Invocation _) {
|
|
|
|
return const Stream<Event>.empty();
|
|
|
|
});
|
2019-10-24 14:57:52 +00:00
|
|
|
when(mockVmService.onDebugEvent).thenAnswer((Invocation _) {
|
|
|
|
return const Stream<Event>.empty();
|
|
|
|
});
|
2019-08-09 16:58:49 +00:00
|
|
|
when(mockDebugConnection.uri).thenReturn('ws://127.0.0.1/abcd/');
|
2019-11-08 04:13:02 +00:00
|
|
|
when(mockFlutterDevice.devFS).thenReturn(mockWebDevFS);
|
|
|
|
when(mockWebDevFS.sources).thenReturn(<Uri>[]);
|
|
|
|
when(mockFlutterDevice.generator).thenReturn(mockResidentCompiler);
|
|
|
|
when(mockChrome.chromeConnection).thenReturn(mockChromeConnection);
|
|
|
|
when(mockChromeConnection.getTab(any)).thenAnswer((Invocation invocation) async {
|
|
|
|
return mockChromeTab;
|
|
|
|
});
|
|
|
|
when(mockChromeTab.connect()).thenAnswer((Invocation invocation) async {
|
|
|
|
return mockWipConnection;
|
|
|
|
});
|
|
|
|
when(mockWipConnection.debugger).thenReturn(mockWipDebugger);
|
2019-08-05 23:51:57 +00:00
|
|
|
}
|
|
|
|
|
2019-11-19 20:11:53 +00:00
|
|
|
test('runner with web server device does not support debugging without --start-paused', () => testbed.run(() {
|
2019-11-08 04:13:02 +00:00
|
|
|
when(mockFlutterDevice.device).thenReturn(WebServerDevice());
|
2019-11-12 23:24:45 +00:00
|
|
|
final ResidentRunner profileResidentWebRunner = DwdsWebRunnerFactory().createWebRunner(
|
2019-11-08 04:13:02 +00:00
|
|
|
mockFlutterDevice,
|
2019-09-11 02:29:31 +00:00
|
|
|
flutterProject: FlutterProject.current(),
|
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
|
|
|
ipv6: true,
|
2019-11-08 04:13:02 +00:00
|
|
|
stayResident: true,
|
2019-11-10 01:08:53 +00:00
|
|
|
dartDefines: const <String>[],
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2019-11-24 05:54:43 +00:00
|
|
|
) as ResidentWebRunner;
|
2019-09-11 02:29:31 +00:00
|
|
|
|
|
|
|
expect(profileResidentWebRunner.debuggingEnabled, false);
|
2019-11-08 04:13:02 +00:00
|
|
|
|
|
|
|
when(mockFlutterDevice.device).thenReturn(MockChromeDevice());
|
2019-09-11 02:29:31 +00:00
|
|
|
expect(residentWebRunner.debuggingEnabled, true);
|
|
|
|
}));
|
|
|
|
|
2019-11-12 23:24:45 +00:00
|
|
|
test('runner with web server device does not initialize dwds', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
when(mockFlutterDevice.device).thenReturn(WebServerDevice());
|
|
|
|
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
|
|
|
expect(didSkipDwds, true);
|
|
|
|
}));
|
|
|
|
|
2019-11-19 20:11:53 +00:00
|
|
|
test('runner with web server device supports debugging with --start-paused', () => testbed.run(() {
|
|
|
|
when(mockFlutterDevice.device).thenReturn(WebServerDevice());
|
|
|
|
final ResidentRunner profileResidentWebRunner = DwdsWebRunnerFactory().createWebRunner(
|
|
|
|
mockFlutterDevice,
|
|
|
|
flutterProject: FlutterProject.current(),
|
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, startPaused: true),
|
|
|
|
ipv6: true,
|
|
|
|
stayResident: true,
|
|
|
|
dartDefines: <String>[],
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2019-11-19 20:11:53 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
expect(profileResidentWebRunner.debuggingEnabled, true);
|
|
|
|
}));
|
|
|
|
|
|
|
|
test('runner with web server device uses debug extension with --start-paused', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
when(mockFlutterDevice.device).thenReturn(WebServerDevice());
|
|
|
|
final ResidentWebRunner runner = DwdsWebRunnerFactory().createWebRunner(
|
|
|
|
mockFlutterDevice,
|
|
|
|
flutterProject: FlutterProject.current(),
|
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, startPaused: true),
|
|
|
|
ipv6: true,
|
|
|
|
stayResident: true,
|
|
|
|
dartDefines: <String>[],
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2019-11-24 05:54:43 +00:00
|
|
|
) as ResidentWebRunner;
|
2019-11-19 20:11:53 +00:00
|
|
|
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(runner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
|
|
|
// Check connect() was told to use the debug extension.
|
|
|
|
verify(mockWebFs.connect(true)).called(1);
|
|
|
|
// And ensure the debug services was started.
|
2019-11-24 05:54:43 +00:00
|
|
|
expect(testLogger.statusText, contains('Debug service listening on'));
|
2019-11-19 20:11:53 +00:00
|
|
|
}));
|
2019-11-12 23:24:45 +00:00
|
|
|
|
2019-08-28 02:06:48 +00:00
|
|
|
test('profile does not supportsServiceProtocol', () => testbed.run(() {
|
2019-11-08 04:13:02 +00:00
|
|
|
when(mockFlutterDevice.device).thenReturn(mockChromeDevice);
|
|
|
|
final ResidentRunner profileResidentWebRunner = DwdsWebRunnerFactory().createWebRunner(
|
|
|
|
mockFlutterDevice,
|
2019-08-28 02:06:48 +00:00
|
|
|
flutterProject: FlutterProject.current(),
|
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile),
|
|
|
|
ipv6: true,
|
2019-11-08 04:13:02 +00:00
|
|
|
stayResident: true,
|
2019-11-10 01:08:53 +00:00
|
|
|
dartDefines: const <String>[],
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2019-08-28 02:06:48 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
expect(profileResidentWebRunner.supportsServiceProtocol, false);
|
|
|
|
expect(residentWebRunner.supportsServiceProtocol, true);
|
|
|
|
}));
|
|
|
|
|
2019-08-05 23:51:57 +00:00
|
|
|
test('Exits on run if application does not support the web', () => testbed.run(() async {
|
2020-01-06 19:04:20 +00:00
|
|
|
globals.fs.file('pubspec.yaml').createSync();
|
2019-08-05 23:51:57 +00:00
|
|
|
|
|
|
|
expect(await residentWebRunner.run(), 1);
|
2019-11-24 05:54:43 +00:00
|
|
|
expect(testLogger.errorText, contains('This application is not configured to build on the web'));
|
2019-08-05 23:51:57 +00:00
|
|
|
}));
|
|
|
|
|
|
|
|
test('Exits on run if target file does not exist', () => testbed.run(() async {
|
2020-01-06 19:04:20 +00:00
|
|
|
globals.fs.file('pubspec.yaml').createSync();
|
|
|
|
globals.fs.file(globals.fs.path.join('web', 'index.html')).createSync(recursive: true);
|
2019-08-05 23:51:57 +00:00
|
|
|
|
|
|
|
expect(await residentWebRunner.run(), 1);
|
2020-01-06 19:04:20 +00:00
|
|
|
final String absoluteMain = globals.fs.path.absolute(globals.fs.path.join('lib', 'main.dart'));
|
2019-11-24 05:54:43 +00:00
|
|
|
expect(testLogger.errorText, contains('Tried to run $absoluteMain, but that file does not exist.'));
|
2019-08-05 23:51:57 +00:00
|
|
|
}));
|
|
|
|
|
|
|
|
test('Can successfully run and connect to vmservice', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
2020-01-06 19:04:20 +00:00
|
|
|
final DelegateLogger delegateLogger = globals.logger as DelegateLogger;
|
2019-11-24 05:54:43 +00:00
|
|
|
final BufferLogger bufferLogger = delegateLogger.delegate as BufferLogger;
|
2019-10-15 04:36:31 +00:00
|
|
|
final MockStatus status = MockStatus();
|
|
|
|
delegateLogger.status = status;
|
2019-08-05 23:51:57 +00:00
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
final DebugConnectionInfo debugConnectionInfo = await connectionInfoCompleter.future;
|
|
|
|
|
2019-09-26 21:23:19 +00:00
|
|
|
verify(mockAppConnection.runMain()).called(1);
|
2019-09-06 17:41:15 +00:00
|
|
|
verify(mockVmService.registerService('reloadSources', 'FlutterTools')).called(1);
|
2019-10-15 04:36:31 +00:00
|
|
|
verify(status.stop()).called(2);
|
|
|
|
|
2019-08-20 00:32:43 +00:00
|
|
|
expect(bufferLogger.statusText, contains('Debug service listening on ws://127.0.0.1/abcd/'));
|
2019-08-05 23:51:57 +00:00
|
|
|
expect(debugConnectionInfo.wsUri.toString(), 'ws://127.0.0.1/abcd/');
|
2019-10-15 04:36:31 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
2020-01-08 20:35:12 +00:00
|
|
|
Logger: () => DelegateLogger(BufferLogger(
|
|
|
|
terminal: AnsiTerminal(
|
|
|
|
stdio: null,
|
|
|
|
platform: const LocalPlatform(),
|
|
|
|
),
|
|
|
|
outputPreferences: OutputPreferences.test(),
|
|
|
|
)),
|
2019-08-05 23:51:57 +00:00
|
|
|
}));
|
|
|
|
|
2019-11-04 17:08:40 +00:00
|
|
|
test('Can successfully run and disconnect with --no-resident', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
2019-11-08 04:13:02 +00:00
|
|
|
residentWebRunner = DwdsWebRunnerFactory().createWebRunner(
|
|
|
|
mockFlutterDevice,
|
2019-11-04 17:08:40 +00:00
|
|
|
flutterProject: FlutterProject.current(),
|
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
|
|
|
ipv6: true,
|
|
|
|
stayResident: false,
|
2019-11-10 01:08:53 +00:00
|
|
|
dartDefines: const <String>[],
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2019-11-24 05:54:43 +00:00
|
|
|
) as ResidentWebRunner;
|
2019-11-04 17:08:40 +00:00
|
|
|
|
|
|
|
expect(await residentWebRunner.run(), 0);
|
|
|
|
}));
|
|
|
|
|
2019-09-26 21:23:19 +00:00
|
|
|
test('Listens to stdout streams before running main', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
final StreamController<Event> controller = StreamController<Event>.broadcast();
|
|
|
|
when(mockVmService.onStdoutEvent).thenAnswer((Invocation _) {
|
|
|
|
return controller.stream;
|
|
|
|
});
|
|
|
|
when(mockAppConnection.runMain()).thenAnswer((Invocation invocation) {
|
|
|
|
controller.add(Event.parse(<String, Object>{
|
|
|
|
'type': 'Event',
|
|
|
|
'kind': 'WriteEvent',
|
|
|
|
'timestamp': 1569473488296,
|
2019-09-30 16:48:23 +00:00
|
|
|
'bytes': base64.encode('THIS MESSAGE IS IMPORTANT'.codeUnits),
|
2019-09-26 21:23:19 +00:00
|
|
|
}));
|
|
|
|
});
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
2019-11-24 05:54:43 +00:00
|
|
|
expect(testLogger.statusText, contains('THIS MESSAGE IS IMPORTANT'));
|
2019-09-26 21:23:19 +00:00
|
|
|
}));
|
|
|
|
|
2019-10-24 14:57:52 +00:00
|
|
|
test('Does not run main with --start-paused', () => testbed.run(() async {
|
2019-11-08 04:13:02 +00:00
|
|
|
residentWebRunner = DwdsWebRunnerFactory().createWebRunner(
|
|
|
|
mockFlutterDevice,
|
2019-10-24 14:57:52 +00:00
|
|
|
flutterProject: FlutterProject.current(),
|
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, startPaused: true),
|
|
|
|
ipv6: true,
|
2019-11-08 04:13:02 +00:00
|
|
|
stayResident: true,
|
2019-11-10 01:08:53 +00:00
|
|
|
dartDefines: const <String>[],
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2019-11-24 05:54:43 +00:00
|
|
|
) as ResidentWebRunner;
|
2019-10-24 14:57:52 +00:00
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
final StreamController<Event> controller = StreamController<Event>.broadcast();
|
|
|
|
when(mockVmService.onStdoutEvent).thenAnswer((Invocation _) {
|
|
|
|
return controller.stream;
|
|
|
|
});
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
|
|
|
verifyNever(mockAppConnection.runMain());
|
|
|
|
}));
|
|
|
|
|
2019-09-06 17:41:15 +00:00
|
|
|
test('Can hot reload after attaching', () => testbed.run(() async {
|
2019-09-24 19:03:37 +00:00
|
|
|
_setupMocks();
|
2019-08-05 23:51:57 +00:00
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
2019-09-30 19:45:03 +00:00
|
|
|
when(mockWebFs.recompile()).thenAnswer((Invocation invocation) async {
|
2019-09-06 17:41:15 +00:00
|
|
|
return true;
|
|
|
|
});
|
|
|
|
when(mockVmService.callServiceExtension('hotRestart')).thenAnswer((Invocation _) async {
|
|
|
|
return Response.parse(<String, Object>{'type': 'Success'});
|
|
|
|
});
|
2019-08-05 23:51:57 +00:00
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: false);
|
|
|
|
|
2019-11-24 05:54:43 +00:00
|
|
|
expect(testLogger.statusText, contains('Reloaded application in'));
|
2019-09-06 17:41:15 +00:00
|
|
|
expect(result.code, 0);
|
2019-09-11 16:38:42 +00:00
|
|
|
// ensure that analytics are sent.
|
|
|
|
verify(Usage.instance.sendEvent('hot', 'restart', parameters: <String, String>{
|
2019-09-24 06:06:09 +00:00
|
|
|
'cd27': 'web-javascript',
|
|
|
|
'cd28': null,
|
|
|
|
'cd29': 'false',
|
|
|
|
'cd30': 'true',
|
2019-09-11 16:38:42 +00:00
|
|
|
})).called(1);
|
2019-09-30 19:45:03 +00:00
|
|
|
verify(Usage.instance.sendTiming('hot', 'web-restart', any)).called(1);
|
|
|
|
verify(Usage.instance.sendTiming('hot', 'web-refresh', any)).called(1);
|
|
|
|
verify(Usage.instance.sendTiming('hot', 'web-recompile', any)).called(1);
|
2019-09-11 16:38:42 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
Usage: () => MockFlutterUsage(),
|
2019-08-05 23:51:57 +00:00
|
|
|
}));
|
|
|
|
|
2019-11-08 04:13:02 +00:00
|
|
|
test('Can hot reload after attaching - experimental', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
launchChromeInstance(mockChrome);
|
|
|
|
when(mockWebDevFS.update(
|
|
|
|
mainPath: anyNamed('mainPath'),
|
|
|
|
target: anyNamed('target'),
|
|
|
|
bundle: anyNamed('bundle'),
|
|
|
|
firstBuildTime: anyNamed('firstBuildTime'),
|
|
|
|
bundleFirstUpload: anyNamed('bundleFirstUpload'),
|
|
|
|
generator: anyNamed('generator'),
|
|
|
|
fullRestart: anyNamed('fullRestart'),
|
|
|
|
dillOutputPath: anyNamed('dillOutputPath'),
|
|
|
|
trackWidgetCreation: anyNamed('trackWidgetCreation'),
|
|
|
|
projectRootPath: anyNamed('projectRootPath'),
|
|
|
|
pathToReload: anyNamed('pathToReload'),
|
|
|
|
invalidatedFiles: anyNamed('invalidatedFiles'),
|
|
|
|
)).thenAnswer((Invocation invocation) async {
|
2020-01-16 21:32:49 +00:00
|
|
|
// Generated entrypoint file in temp dir.
|
|
|
|
expect(invocation.namedArguments[#mainPath], contains('entrypoint.dart'));
|
2019-11-08 04:13:02 +00:00
|
|
|
return UpdateFSReport(success: true)
|
|
|
|
..invalidatedModules = <String>['example'];
|
|
|
|
});
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
2019-12-12 21:55:09 +00:00
|
|
|
final DebugConnectionInfo debugConnectionInfo = await connectionInfoCompleter.future;
|
|
|
|
|
|
|
|
expect(debugConnectionInfo, isNotNull);
|
|
|
|
|
2019-11-08 04:13:02 +00:00
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: false);
|
|
|
|
|
2019-11-24 05:54:43 +00:00
|
|
|
expect(testLogger.statusText, contains('Reloaded application in'));
|
2019-11-08 04:13:02 +00:00
|
|
|
expect(result.code, 0);
|
|
|
|
verify(mockResidentCompiler.accept()).called(2);
|
|
|
|
// ensure that analytics are sent.
|
|
|
|
verify(Usage.instance.sendEvent('hot', 'restart', parameters: <String, String>{
|
|
|
|
'cd27': 'web-javascript',
|
|
|
|
'cd28': null,
|
|
|
|
'cd29': 'false',
|
|
|
|
'cd30': 'true',
|
|
|
|
})).called(1);
|
|
|
|
verify(Usage.instance.sendTiming('hot', 'web-incremental-restart', any)).called(1);
|
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
Usage: () => MockFlutterUsage(),
|
|
|
|
FeatureFlags: () => TestFeatureFlags(isWebIncrementalCompilerEnabled: true),
|
|
|
|
}));
|
|
|
|
|
|
|
|
test('Can hot restart after attaching - experimental', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
launchChromeInstance(mockChrome);
|
|
|
|
when(mockWebDevFS.update(
|
|
|
|
mainPath: anyNamed('mainPath'),
|
|
|
|
target: anyNamed('target'),
|
|
|
|
bundle: anyNamed('bundle'),
|
|
|
|
firstBuildTime: anyNamed('firstBuildTime'),
|
|
|
|
bundleFirstUpload: anyNamed('bundleFirstUpload'),
|
|
|
|
generator: anyNamed('generator'),
|
|
|
|
fullRestart: anyNamed('fullRestart'),
|
|
|
|
dillOutputPath: anyNamed('dillOutputPath'),
|
|
|
|
trackWidgetCreation: anyNamed('trackWidgetCreation'),
|
|
|
|
projectRootPath: anyNamed('projectRootPath'),
|
|
|
|
pathToReload: anyNamed('pathToReload'),
|
|
|
|
invalidatedFiles: anyNamed('invalidatedFiles'),
|
|
|
|
)).thenAnswer((Invocation invocation) async {
|
|
|
|
return UpdateFSReport(success: true)
|
|
|
|
..invalidatedModules = <String>['example'];
|
|
|
|
});
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: true);
|
|
|
|
|
2019-11-24 05:54:43 +00:00
|
|
|
expect(testLogger.statusText, contains('Restarted application in'));
|
2019-11-08 04:13:02 +00:00
|
|
|
expect(result.code, 0);
|
|
|
|
verify(mockResidentCompiler.accept()).called(2);
|
|
|
|
// ensure that analytics are sent.
|
|
|
|
verify(Usage.instance.sendEvent('hot', 'restart', parameters: <String, String>{
|
|
|
|
'cd27': 'web-javascript',
|
|
|
|
'cd28': null,
|
|
|
|
'cd29': 'false',
|
|
|
|
'cd30': 'true',
|
|
|
|
})).called(1);
|
|
|
|
verifyNever(Usage.instance.sendTiming('hot', 'web-incremental-restart', any));
|
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
Usage: () => MockFlutterUsage(),
|
|
|
|
FeatureFlags: () => TestFeatureFlags(isWebIncrementalCompilerEnabled: true),
|
|
|
|
}));
|
|
|
|
|
2019-11-27 21:32:45 +00:00
|
|
|
test('Can hot restart after attaching - experimental with web-server device', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
when(mockFlutterDevice.device).thenReturn(mockWebServerDevice);
|
|
|
|
when(mockWebDevFS.update(
|
|
|
|
mainPath: anyNamed('mainPath'),
|
|
|
|
target: anyNamed('target'),
|
|
|
|
bundle: anyNamed('bundle'),
|
|
|
|
firstBuildTime: anyNamed('firstBuildTime'),
|
|
|
|
bundleFirstUpload: anyNamed('bundleFirstUpload'),
|
|
|
|
generator: anyNamed('generator'),
|
|
|
|
fullRestart: anyNamed('fullRestart'),
|
|
|
|
dillOutputPath: anyNamed('dillOutputPath'),
|
|
|
|
trackWidgetCreation: anyNamed('trackWidgetCreation'),
|
|
|
|
projectRootPath: anyNamed('projectRootPath'),
|
|
|
|
pathToReload: anyNamed('pathToReload'),
|
|
|
|
invalidatedFiles: anyNamed('invalidatedFiles'),
|
|
|
|
)).thenAnswer((Invocation invocation) async {
|
|
|
|
return UpdateFSReport(success: true)
|
|
|
|
..invalidatedModules = <String>['example'];
|
|
|
|
});
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: true);
|
|
|
|
|
|
|
|
expect(testLogger.statusText, contains('Restarted application in'));
|
|
|
|
expect(result.code, 0);
|
|
|
|
verify(mockResidentCompiler.accept()).called(2);
|
|
|
|
// ensure that analytics are sent.
|
|
|
|
verify(Usage.instance.sendEvent('hot', 'restart', parameters: <String, String>{
|
|
|
|
'cd27': 'web-javascript',
|
|
|
|
'cd28': null,
|
|
|
|
'cd29': 'false',
|
|
|
|
'cd30': 'true',
|
|
|
|
})).called(1);
|
|
|
|
verifyNever(Usage.instance.sendTiming('hot', 'web-incremental-restart', any));
|
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
Usage: () => MockFlutterUsage(),
|
|
|
|
FeatureFlags: () => TestFeatureFlags(isWebIncrementalCompilerEnabled: true),
|
2019-12-13 03:05:48 +00:00
|
|
|
}));
|
|
|
|
|
|
|
|
test('experimental resident runner is not debuggable', () => testbed.run(() {
|
|
|
|
expect(residentWebRunner.debuggingEnabled, false);
|
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FeatureFlags: () => TestFeatureFlags(isWebIncrementalCompilerEnabled: true),
|
2019-11-27 21:32:45 +00:00
|
|
|
}));
|
|
|
|
|
2019-08-05 23:51:57 +00:00
|
|
|
test('Can hot restart after attaching', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
2019-09-30 19:45:03 +00:00
|
|
|
when(mockWebFs.recompile()).thenAnswer((Invocation invocation) async {
|
2019-08-05 23:51:57 +00:00
|
|
|
return true;
|
|
|
|
});
|
2019-10-22 19:36:56 +00:00
|
|
|
when(mockVmService.callServiceExtension('fullReload')).thenAnswer((Invocation _) async {
|
2019-08-05 23:51:57 +00:00
|
|
|
return Response.parse(<String, Object>{'type': 'Success'});
|
|
|
|
});
|
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: true);
|
|
|
|
|
2019-11-24 05:54:43 +00:00
|
|
|
expect(testLogger.statusText, contains('Restarted application in'));
|
2019-08-05 23:51:57 +00:00
|
|
|
expect(result.code, 0);
|
2019-09-11 16:38:42 +00:00
|
|
|
// ensure that analytics are sent.
|
|
|
|
verify(Usage.instance.sendEvent('hot', 'restart', parameters: <String, String>{
|
2019-09-24 06:06:09 +00:00
|
|
|
'cd27': 'web-javascript',
|
|
|
|
'cd28': null,
|
|
|
|
'cd29': 'false',
|
|
|
|
'cd30': 'true',
|
2019-09-11 16:38:42 +00:00
|
|
|
})).called(1);
|
2019-10-22 19:36:56 +00:00
|
|
|
verifyNever(Usage.instance.sendTiming('hot', 'web-restart', any));
|
|
|
|
verifyNever(Usage.instance.sendTiming('hot', 'web-refresh', any));
|
2019-09-30 19:45:03 +00:00
|
|
|
verify(Usage.instance.sendTiming('hot', 'web-recompile', any)).called(1);
|
2019-09-11 16:38:42 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
Usage: () => MockFlutterUsage(),
|
2019-08-05 23:51:57 +00:00
|
|
|
}));
|
|
|
|
|
2019-11-27 21:32:45 +00:00
|
|
|
test('Selects Dwds runner in profile mode with incremental compiler enabled', () => testbed.run(() async {
|
|
|
|
final ResidentWebRunner residentWebRunner = DwdsWebRunnerFactory().createWebRunner(
|
|
|
|
mockFlutterDevice,
|
|
|
|
flutterProject: FlutterProject.current(),
|
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile),
|
|
|
|
ipv6: true,
|
|
|
|
stayResident: true,
|
|
|
|
dartDefines: const <String>[],
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2019-11-27 21:32:45 +00:00
|
|
|
) as ResidentWebRunner;
|
|
|
|
|
|
|
|
expect(residentWebRunner.runtimeType.toString(), '_DwdsResidentWebRunner');
|
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FeatureFlags: () => TestFeatureFlags(isWebIncrementalCompilerEnabled: true),
|
|
|
|
}));
|
|
|
|
|
2019-08-05 23:51:57 +00:00
|
|
|
test('Fails on compilation errors in hot restart', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
when(mockWebFs.recompile()).thenAnswer((Invocation _) async {
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: true);
|
|
|
|
|
|
|
|
expect(result.code, 1);
|
|
|
|
expect(result.message, contains('Failed to recompile application.'));
|
2019-10-09 03:06:13 +00:00
|
|
|
verifyNever(Usage.instance.sendTiming('hot', 'web-restart', any));
|
|
|
|
verifyNever(Usage.instance.sendTiming('hot', 'web-refresh', any));
|
|
|
|
verifyNever(Usage.instance.sendTiming('hot', 'web-recompile', any));
|
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
Usage: () => MockFlutterUsage(),
|
2019-08-05 23:51:57 +00:00
|
|
|
}));
|
|
|
|
|
2019-10-22 19:36:56 +00:00
|
|
|
test('Fails on vmservice response error for hot restart', () => testbed.run(() async {
|
2019-08-05 23:51:57 +00:00
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
when(mockWebFs.recompile()).thenAnswer((Invocation _) async {
|
|
|
|
return true;
|
|
|
|
});
|
2019-10-22 19:36:56 +00:00
|
|
|
when(mockVmService.callServiceExtension('fullReload')).thenAnswer((Invocation _) async {
|
2019-08-05 23:51:57 +00:00
|
|
|
return Response.parse(<String, Object>{'type': 'Failed'});
|
|
|
|
});
|
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: true);
|
|
|
|
|
|
|
|
expect(result.code, 1);
|
|
|
|
expect(result.message, contains('Failed'));
|
2019-10-09 03:06:13 +00:00
|
|
|
verifyNever(Usage.instance.sendTiming('hot', 'web-restart', any));
|
|
|
|
verifyNever(Usage.instance.sendTiming('hot', 'web-refresh', any));
|
|
|
|
verify(Usage.instance.sendTiming('hot', 'web-recompile', any)).called(1);
|
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
Usage: () => MockFlutterUsage(),
|
2019-08-05 23:51:57 +00:00
|
|
|
}));
|
|
|
|
|
2019-10-22 19:36:56 +00:00
|
|
|
test('Fails on vmservice response error for hot reload', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
when(mockWebFs.recompile()).thenAnswer((Invocation _) async {
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
when(mockVmService.callServiceExtension('hotRestart')).thenAnswer((Invocation _) async {
|
|
|
|
return Response.parse(<String, Object>{'type': 'Failed'});
|
|
|
|
});
|
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: false);
|
|
|
|
|
|
|
|
expect(result.code, 1);
|
|
|
|
expect(result.message, contains('Failed'));
|
|
|
|
verifyNever(Usage.instance.sendTiming('hot', 'web-restart', any));
|
|
|
|
verifyNever(Usage.instance.sendTiming('hot', 'web-refresh', any));
|
|
|
|
verify(Usage.instance.sendTiming('hot', 'web-recompile', any)).called(1);
|
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
Usage: () => MockFlutterUsage(),
|
|
|
|
}));
|
|
|
|
|
2019-08-20 00:33:46 +00:00
|
|
|
test('Fails on vmservice RpcError', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
when(mockWebFs.recompile()).thenAnswer((Invocation _) async {
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
when(mockVmService.callServiceExtension('hotRestart')).thenThrow(RPCError('', 2, '123'));
|
2019-10-22 19:36:56 +00:00
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: false);
|
2019-08-20 00:33:46 +00:00
|
|
|
|
|
|
|
expect(result.code, 1);
|
2019-09-11 02:29:31 +00:00
|
|
|
expect(result.message, contains('Page requires refresh'));
|
2019-08-20 00:33:46 +00:00
|
|
|
}));
|
|
|
|
|
2019-10-17 22:08:15 +00:00
|
|
|
test('printHelp without details has web warning', () => testbed.run(() async {
|
2019-08-05 23:51:57 +00:00
|
|
|
residentWebRunner.printHelp(details: false);
|
|
|
|
|
2019-11-24 05:54:43 +00:00
|
|
|
expect(testLogger.statusText, contains('Warning'));
|
|
|
|
expect(testLogger.statusText, contains('https://flutter.dev/web'));
|
|
|
|
expect(testLogger.statusText, isNot(contains('https://flutter.dev/web.')));
|
2019-08-05 23:51:57 +00:00
|
|
|
}));
|
|
|
|
|
|
|
|
test('debugDumpApp', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
await residentWebRunner.debugDumpApp();
|
|
|
|
|
|
|
|
verify(mockVmService.callServiceExtension('ext.flutter.debugDumpApp')).called(1);
|
|
|
|
}));
|
|
|
|
|
|
|
|
test('debugDumpLayerTree', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
await residentWebRunner.debugDumpLayerTree();
|
|
|
|
|
|
|
|
verify(mockVmService.callServiceExtension('ext.flutter.debugDumpLayerTree')).called(1);
|
|
|
|
}));
|
|
|
|
|
|
|
|
test('debugDumpRenderTree', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
await residentWebRunner.debugDumpRenderTree();
|
|
|
|
|
|
|
|
verify(mockVmService.callServiceExtension('ext.flutter.debugDumpRenderTree')).called(1);
|
|
|
|
}));
|
|
|
|
|
|
|
|
test('debugDumpSemanticsTreeInTraversalOrder', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
await residentWebRunner.debugDumpSemanticsTreeInTraversalOrder();
|
|
|
|
|
|
|
|
verify(mockVmService.callServiceExtension('ext.flutter.debugDumpSemanticsTreeInTraversalOrder')).called(1);
|
|
|
|
}));
|
|
|
|
|
|
|
|
test('debugDumpSemanticsTreeInInverseHitTestOrder', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
await residentWebRunner.debugDumpSemanticsTreeInInverseHitTestOrder();
|
|
|
|
|
|
|
|
verify(mockVmService.callServiceExtension('ext.flutter.debugDumpSemanticsTreeInInverseHitTestOrder')).called(1);
|
|
|
|
}));
|
|
|
|
|
|
|
|
test('debugToggleDebugPaintSizeEnabled', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
when(mockVmService.callServiceExtension('ext.flutter.debugPaint'))
|
|
|
|
.thenAnswer((Invocation _) async {
|
|
|
|
return Response.parse(<String, Object>{'enabled': false});
|
|
|
|
});
|
|
|
|
await residentWebRunner.debugToggleDebugPaintSizeEnabled();
|
|
|
|
|
|
|
|
verify(mockVmService.callServiceExtension('ext.flutter.debugPaint',
|
|
|
|
args: <String, Object>{'enabled': true})).called(1);
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
test('debugTogglePerformanceOverlayOverride', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
when(mockVmService.callServiceExtension('ext.flutter.showPerformanceOverlay'))
|
|
|
|
.thenAnswer((Invocation _) async {
|
|
|
|
return Response.parse(<String, Object>{'enabled': false});
|
|
|
|
});
|
|
|
|
|
|
|
|
await residentWebRunner.debugTogglePerformanceOverlayOverride();
|
|
|
|
|
|
|
|
verify(mockVmService.callServiceExtension('ext.flutter.showPerformanceOverlay',
|
|
|
|
args: <String, Object>{'enabled': true})).called(1);
|
|
|
|
}));
|
|
|
|
|
|
|
|
test('debugToggleWidgetInspector', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
when(mockVmService.callServiceExtension('ext.flutter.debugToggleWidgetInspector'))
|
|
|
|
.thenAnswer((Invocation _) async {
|
|
|
|
return Response.parse(<String, Object>{'enabled': false});
|
|
|
|
});
|
|
|
|
|
|
|
|
await residentWebRunner.debugToggleWidgetInspector();
|
|
|
|
|
|
|
|
verify(mockVmService.callServiceExtension('ext.flutter.debugToggleWidgetInspector',
|
|
|
|
args: <String, Object>{'enabled': true})).called(1);
|
|
|
|
}));
|
|
|
|
|
|
|
|
test('debugToggleProfileWidgetBuilds', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
when(mockVmService.callServiceExtension('ext.flutter.profileWidgetBuilds'))
|
|
|
|
.thenAnswer((Invocation _) async {
|
|
|
|
return Response.parse(<String, Object>{'enabled': false});
|
|
|
|
});
|
|
|
|
|
|
|
|
await residentWebRunner.debugToggleProfileWidgetBuilds();
|
|
|
|
|
|
|
|
verify(mockVmService.callServiceExtension('ext.flutter.profileWidgetBuilds',
|
|
|
|
args: <String, Object>{'enabled': true})).called(1);
|
|
|
|
}));
|
2019-09-03 18:00:39 +00:00
|
|
|
|
2019-10-18 19:41:15 +00:00
|
|
|
test('debugTogglePlatform', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
when(mockVmService.callServiceExtension('ext.flutter.platformOverride'))
|
|
|
|
.thenAnswer((Invocation _) async {
|
|
|
|
return Response.parse(<String, Object>{'value': 'iOS'});
|
|
|
|
});
|
|
|
|
|
|
|
|
await residentWebRunner.debugTogglePlatform();
|
|
|
|
|
2019-12-12 23:20:52 +00:00
|
|
|
expect(testLogger.statusText, contains('Switched operating system to fuchsia'));
|
2019-10-18 19:41:15 +00:00
|
|
|
verify(mockVmService.callServiceExtension('ext.flutter.platformOverride',
|
2019-12-12 23:20:52 +00:00
|
|
|
args: <String, Object>{'value': 'fuchsia'})).called(1);
|
2019-10-18 19:41:15 +00:00
|
|
|
}));
|
|
|
|
|
2019-09-03 18:00:39 +00:00
|
|
|
test('cleanup of resources is safe to call multiple times', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
bool debugClosed = false;
|
2019-11-08 04:13:02 +00:00
|
|
|
when(mockChromeDevice.stopApp(any)).thenAnswer((Invocation invocation) async {
|
2019-09-03 18:00:39 +00:00
|
|
|
if (debugClosed) {
|
|
|
|
throw StateError('debug connection closed twice');
|
|
|
|
}
|
|
|
|
debugClosed = true;
|
2019-10-15 00:29:04 +00:00
|
|
|
return true;
|
2019-09-03 18:00:39 +00:00
|
|
|
});
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-09-03 18:00:39 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
|
|
|
await residentWebRunner.exit();
|
|
|
|
await residentWebRunner.exit();
|
2019-10-15 00:29:04 +00:00
|
|
|
|
|
|
|
verifyNever(mockDebugConnection.close());
|
2019-09-03 18:00:39 +00:00
|
|
|
}));
|
2019-09-03 19:55:06 +00:00
|
|
|
|
2019-10-28 17:26:18 +00:00
|
|
|
test('cleans up Chrome if tab is closed', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<void> onDone = Completer<void>();
|
|
|
|
when(mockDebugConnection.onDone).thenAnswer((Invocation invocation) {
|
|
|
|
return onDone.future;
|
|
|
|
});
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
final Future<int> result = residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
);
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
onDone.complete();
|
|
|
|
|
|
|
|
await result;
|
|
|
|
verify(mockWebFs.stop()).called(1);
|
|
|
|
}));
|
|
|
|
|
2019-09-03 19:55:06 +00:00
|
|
|
test('Prints target and device name on run', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
2019-11-08 04:13:02 +00:00
|
|
|
when(mockChromeDevice.name).thenReturn('Chromez');
|
2019-09-03 19:55:06 +00:00
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-09-03 19:55:06 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
2020-01-06 19:04:20 +00:00
|
|
|
expect(testLogger.statusText, contains('Launching ${globals.fs.path.join('lib', 'main.dart')} on Chromez in debug mode'));
|
2019-09-03 19:55:06 +00:00
|
|
|
}));
|
2019-10-10 23:34:27 +00:00
|
|
|
|
2019-11-18 18:10:15 +00:00
|
|
|
test('Sends launched app.webLaunchUrl event for Chrome device', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
when(mockFlutterDevice.device).thenReturn(ChromeDevice());
|
|
|
|
|
2020-01-06 19:04:20 +00:00
|
|
|
final DelegateLogger delegateLogger = globals.logger as DelegateLogger;
|
2019-11-18 18:10:15 +00:00
|
|
|
final MockStatus mockStatus = MockStatus();
|
|
|
|
delegateLogger.status = mockStatus;
|
|
|
|
final ResidentWebRunner runner = DwdsWebRunnerFactory().createWebRunner(
|
|
|
|
mockFlutterDevice,
|
|
|
|
flutterProject: FlutterProject.current(),
|
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
|
|
|
ipv6: true,
|
|
|
|
stayResident: true,
|
|
|
|
dartDefines: const <String>[],
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2019-11-24 05:54:43 +00:00
|
|
|
) as ResidentWebRunner;
|
2019-11-18 18:10:15 +00:00
|
|
|
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(runner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
|
|
|
// Ensure we got the URL and that it was already launched.
|
2020-01-06 19:04:20 +00:00
|
|
|
verify(globals.logger.sendEvent(
|
2019-11-18 18:10:15 +00:00
|
|
|
'app.webLaunchUrl',
|
|
|
|
argThat(allOf(
|
|
|
|
containsPair('url', 'http://localhost:8765/app/'),
|
|
|
|
containsPair('launched', true),
|
|
|
|
))
|
|
|
|
));
|
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
Logger: () => DelegateLogger(MockLogger()),
|
|
|
|
ChromeLauncher: () => MockChromeLauncher(),
|
|
|
|
}));
|
|
|
|
|
|
|
|
test('Sends unlaunched app.webLaunchUrl event for Web Server device', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
when(mockFlutterDevice.device).thenReturn(WebServerDevice());
|
|
|
|
|
2020-01-06 19:04:20 +00:00
|
|
|
final DelegateLogger delegateLogger = globals.logger as DelegateLogger;
|
2019-11-18 18:10:15 +00:00
|
|
|
final MockStatus mockStatus = MockStatus();
|
|
|
|
delegateLogger.status = mockStatus;
|
|
|
|
final ResidentWebRunner runner = DwdsWebRunnerFactory().createWebRunner(
|
|
|
|
mockFlutterDevice,
|
|
|
|
flutterProject: FlutterProject.current(),
|
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
|
|
|
ipv6: true,
|
|
|
|
stayResident: true,
|
|
|
|
dartDefines: const <String>[],
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2019-11-24 05:54:43 +00:00
|
|
|
) as ResidentWebRunner;
|
2019-11-18 18:10:15 +00:00
|
|
|
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(runner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
|
|
|
// Ensure we got the URL and that it was not already launched.
|
2020-01-06 19:04:20 +00:00
|
|
|
verify(globals.logger.sendEvent(
|
2019-11-18 18:10:15 +00:00
|
|
|
'app.webLaunchUrl',
|
|
|
|
argThat(allOf(
|
|
|
|
containsPair('url', 'http://localhost:8765/app/'),
|
|
|
|
containsPair('launched', false),
|
|
|
|
))
|
|
|
|
));
|
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
Logger: () => DelegateLogger(MockLogger())
|
|
|
|
}));
|
|
|
|
|
2019-10-10 23:34:27 +00:00
|
|
|
test('Successfully turns WebSocketException into ToolExit', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
final Completer<void> unhandledErrorCompleter = Completer<void>();
|
|
|
|
when(mockWebFs.connect(any)).thenAnswer((Invocation _) async {
|
|
|
|
unawaited(unhandledErrorCompleter.future.then((void value) {
|
|
|
|
throw const WebSocketException();
|
|
|
|
}));
|
|
|
|
return ConnectionResult(mockAppConnection, mockDebugConnection);
|
|
|
|
});
|
|
|
|
|
|
|
|
final Future<void> expectation = expectLater(() => residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
2020-01-16 20:43:03 +00:00
|
|
|
), throwsToolExit());
|
2019-10-10 23:34:27 +00:00
|
|
|
|
2019-10-15 00:28:28 +00:00
|
|
|
unhandledErrorCompleter.complete();
|
|
|
|
await expectation;
|
|
|
|
}));
|
|
|
|
|
2019-10-26 03:35:19 +00:00
|
|
|
test('Successfully turns AppConnectionException into ToolExit', () => testbed.run(() async {
|
2019-10-15 00:28:28 +00:00
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
final Completer<void> unhandledErrorCompleter = Completer<void>();
|
|
|
|
when(mockWebFs.connect(any)).thenAnswer((Invocation _) async {
|
|
|
|
unawaited(unhandledErrorCompleter.future.then((void value) {
|
2019-10-26 03:35:19 +00:00
|
|
|
throw AppConnectionException('Could not connect to application with appInstanceId: c0ae0750-ee91-11e9-cea6-35d95a968356');
|
2019-10-15 00:28:28 +00:00
|
|
|
}));
|
|
|
|
return ConnectionResult(mockAppConnection, mockDebugConnection);
|
|
|
|
});
|
|
|
|
|
|
|
|
final Future<void> expectation = expectLater(() => residentWebRunner.run(
|
2019-10-24 17:55:42 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
2020-01-16 20:43:03 +00:00
|
|
|
), throwsToolExit());
|
2019-10-24 17:55:42 +00:00
|
|
|
|
|
|
|
unhandledErrorCompleter.complete();
|
|
|
|
await expectation;
|
|
|
|
}));
|
|
|
|
|
|
|
|
test('Successfully turns ChromeDebugError into ToolExit', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
final Completer<void> unhandledErrorCompleter = Completer<void>();
|
|
|
|
when(mockWebFs.connect(any)).thenAnswer((Invocation _) async {
|
|
|
|
unawaited(unhandledErrorCompleter.future.then((void value) {
|
|
|
|
throw ChromeDebugException(<String, dynamic>{});
|
|
|
|
}));
|
|
|
|
return ConnectionResult(mockAppConnection, mockDebugConnection);
|
|
|
|
});
|
|
|
|
|
|
|
|
final Future<void> expectation = expectLater(() => residentWebRunner.run(
|
2019-10-15 00:28:28 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
2020-01-16 20:43:03 +00:00
|
|
|
), throwsToolExit());
|
2019-10-15 00:28:28 +00:00
|
|
|
|
2019-10-10 23:34:27 +00:00
|
|
|
unhandledErrorCompleter.complete();
|
|
|
|
await expectation;
|
|
|
|
}));
|
|
|
|
|
2019-10-24 16:06:45 +00:00
|
|
|
test('Successfully turns OptionsSkew error into ToolExit', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
final Completer<void> unhandledErrorCompleter = Completer<void>();
|
|
|
|
when(mockWebFs.connect(any)).thenAnswer((Invocation _) async {
|
|
|
|
unawaited(unhandledErrorCompleter.future.then((void value) {
|
|
|
|
throw OptionsSkew();
|
|
|
|
}));
|
|
|
|
return ConnectionResult(mockAppConnection, mockDebugConnection);
|
|
|
|
});
|
|
|
|
|
|
|
|
final Future<void> expectation = expectLater(() => residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
2020-01-16 20:43:03 +00:00
|
|
|
), throwsToolExit());
|
2019-10-24 16:06:45 +00:00
|
|
|
|
|
|
|
unhandledErrorCompleter.complete();
|
|
|
|
await expectation;
|
|
|
|
}));
|
|
|
|
|
|
|
|
test('Successfully turns VersionSkew error into ToolExit', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
final Completer<void> unhandledErrorCompleter = Completer<void>();
|
|
|
|
when(mockWebFs.connect(any)).thenAnswer((Invocation _) async {
|
|
|
|
unawaited(unhandledErrorCompleter.future.then((void value) {
|
|
|
|
throw VersionSkew();
|
|
|
|
}));
|
|
|
|
return ConnectionResult(mockAppConnection, mockDebugConnection);
|
|
|
|
});
|
|
|
|
|
|
|
|
final Future<void> expectation = expectLater(() => residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
2020-01-16 20:43:03 +00:00
|
|
|
), throwsToolExit());
|
2019-10-24 16:06:45 +00:00
|
|
|
|
|
|
|
unhandledErrorCompleter.complete();
|
|
|
|
await expectation;
|
|
|
|
}));
|
|
|
|
|
2019-10-28 22:58:14 +00:00
|
|
|
test('Successfully turns failed startup StateError error into ToolExit', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
final Completer<void> unhandledErrorCompleter = Completer<void>();
|
|
|
|
when(mockWebFs.connect(any)).thenAnswer((Invocation _) async {
|
|
|
|
unawaited(unhandledErrorCompleter.future.then((void value) {
|
|
|
|
throw StateError('Unable to start build daemon');
|
|
|
|
}));
|
|
|
|
return ConnectionResult(mockAppConnection, mockDebugConnection);
|
|
|
|
});
|
|
|
|
|
|
|
|
final Future<void> expectation = expectLater(() => residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
2020-01-16 20:43:03 +00:00
|
|
|
), throwsToolExit());
|
2019-10-28 22:58:14 +00:00
|
|
|
|
|
|
|
unhandledErrorCompleter.complete();
|
|
|
|
await expectation;
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
2019-10-10 23:34:27 +00:00
|
|
|
test('Rethrows Exception type', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
final Completer<void> unhandledErrorCompleter = Completer<void>();
|
|
|
|
when(mockWebFs.connect(any)).thenAnswer((Invocation _) async {
|
|
|
|
unawaited(unhandledErrorCompleter.future.then((void value) {
|
|
|
|
throw Exception('Something went wrong');
|
|
|
|
}));
|
|
|
|
return ConnectionResult(mockAppConnection, mockDebugConnection);
|
|
|
|
});
|
|
|
|
|
|
|
|
final Future<void> expectation = expectLater(() => residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
2020-01-16 20:43:03 +00:00
|
|
|
), throwsException);
|
2019-10-10 23:34:27 +00:00
|
|
|
|
|
|
|
unhandledErrorCompleter.complete();
|
|
|
|
await expectation;
|
|
|
|
}));
|
|
|
|
|
2019-10-28 17:26:43 +00:00
|
|
|
test('Successfully turns MissingPortFile error into ToolExit', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
final Completer<void> unhandledErrorCompleter = Completer<void>();
|
|
|
|
when(mockWebFs.connect(any)).thenAnswer((Invocation _) async {
|
|
|
|
unawaited(unhandledErrorCompleter.future.then((void value) {
|
|
|
|
throw MissingPortFile();
|
|
|
|
}));
|
|
|
|
return ConnectionResult(mockAppConnection, mockDebugConnection);
|
|
|
|
});
|
|
|
|
|
|
|
|
final Future<void> expectation = expectLater(() => residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
2020-01-16 20:43:03 +00:00
|
|
|
), throwsToolExit());
|
2019-10-28 17:26:43 +00:00
|
|
|
|
|
|
|
unhandledErrorCompleter.complete();
|
|
|
|
await expectation;
|
|
|
|
}));
|
|
|
|
|
2019-10-10 23:34:27 +00:00
|
|
|
test('Rethrows unknown exception type from web tooling', () => testbed.run(() async {
|
|
|
|
_setupMocks();
|
2020-01-06 19:04:20 +00:00
|
|
|
final DelegateLogger delegateLogger = globals.logger as DelegateLogger;
|
2019-10-15 04:36:31 +00:00
|
|
|
final MockStatus mockStatus = MockStatus();
|
|
|
|
delegateLogger.status = mockStatus;
|
2019-10-10 23:34:27 +00:00
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
final Completer<void> unhandledErrorCompleter = Completer<void>();
|
|
|
|
when(mockWebFs.connect(any)).thenAnswer((Invocation _) async {
|
|
|
|
unawaited(unhandledErrorCompleter.future.then((void value) {
|
|
|
|
throw StateError('Something went wrong');
|
|
|
|
}));
|
|
|
|
return ConnectionResult(mockAppConnection, mockDebugConnection);
|
|
|
|
});
|
|
|
|
|
|
|
|
final Future<void> expectation = expectLater(() => residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
2020-01-16 20:43:03 +00:00
|
|
|
), throwsStateError);
|
2019-10-10 23:34:27 +00:00
|
|
|
|
|
|
|
unhandledErrorCompleter.complete();
|
|
|
|
await expectation;
|
2019-10-15 04:36:31 +00:00
|
|
|
verify(mockStatus.stop()).called(2);
|
|
|
|
}, overrides: <Type, Generator>{
|
2020-01-08 20:35:12 +00:00
|
|
|
Logger: () => DelegateLogger(BufferLogger(
|
|
|
|
terminal: AnsiTerminal(
|
|
|
|
stdio: null,
|
|
|
|
platform: const LocalPlatform(),
|
|
|
|
),
|
|
|
|
outputPreferences: OutputPreferences.test(),
|
|
|
|
))
|
2019-10-10 23:34:27 +00:00
|
|
|
}));
|
2019-08-05 23:51:57 +00:00
|
|
|
}
|
|
|
|
|
2019-11-18 18:10:15 +00:00
|
|
|
class MockChromeLauncher extends Mock implements ChromeLauncher {}
|
2019-09-11 16:38:42 +00:00
|
|
|
class MockFlutterUsage extends Mock implements Usage {}
|
2019-11-08 04:13:02 +00:00
|
|
|
class MockChromeDevice extends Mock implements ChromeDevice {}
|
2019-08-05 23:51:57 +00:00
|
|
|
class MockBuildDaemonCreator extends Mock implements BuildDaemonCreator {}
|
|
|
|
class MockFlutterWebFs extends Mock implements WebFs {}
|
|
|
|
class MockDebugConnection extends Mock implements DebugConnection {}
|
2019-09-26 21:23:19 +00:00
|
|
|
class MockAppConnection extends Mock implements AppConnection {}
|
2019-08-05 23:51:57 +00:00
|
|
|
class MockVmService extends Mock implements VmService {}
|
2019-10-15 04:36:31 +00:00
|
|
|
class MockStatus extends Mock implements Status {}
|
2019-11-08 04:13:02 +00:00
|
|
|
class MockFlutterDevice extends Mock implements FlutterDevice {}
|
|
|
|
class MockWebDevFS extends Mock implements DevFS {}
|
|
|
|
class MockResidentCompiler extends Mock implements ResidentCompiler {}
|
|
|
|
class MockChrome extends Mock implements Chrome {}
|
|
|
|
class MockChromeConnection extends Mock implements ChromeConnection {}
|
|
|
|
class MockChromeTab extends Mock implements ChromeTab {}
|
|
|
|
class MockWipConnection extends Mock implements WipConnection {}
|
|
|
|
class MockWipDebugger extends Mock implements WipDebugger {}
|
2019-11-18 18:10:15 +00:00
|
|
|
class MockLogger extends Mock implements Logger {}
|
2019-11-27 21:32:45 +00:00
|
|
|
class MockWebServerDevice extends Mock implements WebServerDevice {}
|