mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
This reverts commit 388dcd2478
.
This commit is contained in:
parent
ffbbf93c6b
commit
912c3ab171
@ -156,6 +156,8 @@ Future<void> main(List<String> args) async {
|
|||||||
processManager: globals.processManager,
|
processManager: globals.processManager,
|
||||||
pubExecutable: globals.artifacts.getArtifactPath(Artifact.pubExecutable),
|
pubExecutable: globals.artifacts.getArtifactPath(Artifact.pubExecutable),
|
||||||
logger: globals.logger,
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
persistentToolState: globals.persistentToolState,
|
||||||
),
|
),
|
||||||
Logger: () {
|
Logger: () {
|
||||||
final LoggerFactory loggerFactory = LoggerFactory(
|
final LoggerFactory loggerFactory = LoggerFactory(
|
||||||
|
@ -101,6 +101,7 @@ class AttachCommand extends FlutterCommand {
|
|||||||
);
|
);
|
||||||
usesTrackWidgetCreation(verboseHelp: verboseHelp);
|
usesTrackWidgetCreation(verboseHelp: verboseHelp);
|
||||||
addDdsOptions(verboseHelp: verboseHelp);
|
addDdsOptions(verboseHelp: verboseHelp);
|
||||||
|
addDevToolsOptions();
|
||||||
usesDeviceTimeoutOption();
|
usesDeviceTimeoutOption();
|
||||||
hotRunnerFactory ??= HotRunnerFactory();
|
hotRunnerFactory ??= HotRunnerFactory();
|
||||||
}
|
}
|
||||||
@ -405,7 +406,11 @@ known, it can be explicitly provided to attach via the command-line, e.g.
|
|||||||
);
|
);
|
||||||
flutterDevice.observatoryUris = observatoryUris;
|
flutterDevice.observatoryUris = observatoryUris;
|
||||||
final List<FlutterDevice> flutterDevices = <FlutterDevice>[flutterDevice];
|
final List<FlutterDevice> flutterDevices = <FlutterDevice>[flutterDevice];
|
||||||
final DebuggingOptions debuggingOptions = DebuggingOptions.enabled(buildInfo, disableDds: boolArg('disable-dds'));
|
final DebuggingOptions debuggingOptions = DebuggingOptions.enabled(
|
||||||
|
buildInfo,
|
||||||
|
disableDds: boolArg('disable-dds'),
|
||||||
|
devToolsServerAddress: devToolsServerAddress,
|
||||||
|
);
|
||||||
|
|
||||||
return buildInfo.isDebug
|
return buildInfo.isDebug
|
||||||
? hotRunnerFactory.build(
|
? hotRunnerFactory.build(
|
||||||
|
@ -871,8 +871,7 @@ class DevToolsDomain extends Domain {
|
|||||||
|
|
||||||
Future<Map<String, dynamic>> serve([ Map<String, dynamic> args ]) async {
|
Future<Map<String, dynamic>> serve([ Map<String, dynamic> args ]) async {
|
||||||
_devtoolsLauncher ??= DevtoolsLauncher.instance;
|
_devtoolsLauncher ??= DevtoolsLauncher.instance;
|
||||||
final bool openInBrowser = args != null && (args['openInBrowser'] == 'true');
|
final DevToolsServerAddress server = await _devtoolsLauncher.serve();
|
||||||
final DevToolsServerAddress server = await _devtoolsLauncher.serve(openInBrowser: openInBrowser);
|
|
||||||
return<String, dynamic>{
|
return<String, dynamic>{
|
||||||
'host': server?.host,
|
'host': server?.host,
|
||||||
'port': server?.port,
|
'port': server?.port,
|
||||||
|
@ -134,6 +134,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
|
|||||||
usesDeviceUserOption();
|
usesDeviceUserOption();
|
||||||
usesDeviceTimeoutOption();
|
usesDeviceTimeoutOption();
|
||||||
addDdsOptions(verboseHelp: verboseHelp);
|
addDdsOptions(verboseHelp: verboseHelp);
|
||||||
|
addDevToolsOptions();
|
||||||
addAndroidSpecificBuildOptions(hide: !verboseHelp);
|
addAndroidSpecificBuildOptions(hide: !verboseHelp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +196,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
|
|||||||
hostVmServicePort: hostVmservicePort,
|
hostVmServicePort: hostVmservicePort,
|
||||||
disablePortPublication: disablePortPublication,
|
disablePortPublication: disablePortPublication,
|
||||||
ddsPort: ddsPort,
|
ddsPort: ddsPort,
|
||||||
|
devToolsServerAddress: devToolsServerAddress,
|
||||||
verboseSystemLogs: boolArg('verbose-system-logs'),
|
verboseSystemLogs: boolArg('verbose-system-logs'),
|
||||||
hostname: featureFlags.isWebEnabled ? stringArg('web-hostname') : '',
|
hostname: featureFlags.isWebEnabled ? stringArg('web-hostname') : '',
|
||||||
port: featureFlags.isWebEnabled ? stringArg('web-port') : '',
|
port: featureFlags.isWebEnabled ? stringArg('web-port') : '',
|
||||||
|
@ -184,6 +184,8 @@ Future<T> runInContext<T>(
|
|||||||
processManager: globals.processManager,
|
processManager: globals.processManager,
|
||||||
pubExecutable: globals.artifacts.getArtifactPath(Artifact.pubExecutable),
|
pubExecutable: globals.artifacts.getArtifactPath(Artifact.pubExecutable),
|
||||||
logger: globals.logger,
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
persistentToolState: globals.persistentToolState,
|
||||||
),
|
),
|
||||||
Doctor: () => Doctor(logger: globals.logger),
|
Doctor: () => Doctor(logger: globals.logger),
|
||||||
DoctorValidatorsProvider: () => DoctorValidatorsProvider.defaultInstance,
|
DoctorValidatorsProvider: () => DoctorValidatorsProvider.defaultInstance,
|
||||||
|
@ -852,6 +852,7 @@ class DebuggingOptions {
|
|||||||
this.disablePortPublication = false,
|
this.disablePortPublication = false,
|
||||||
this.deviceVmServicePort,
|
this.deviceVmServicePort,
|
||||||
this.ddsPort,
|
this.ddsPort,
|
||||||
|
this.devToolsServerAddress,
|
||||||
this.hostname,
|
this.hostname,
|
||||||
this.port,
|
this.port,
|
||||||
this.webEnableExposeUrl,
|
this.webEnableExposeUrl,
|
||||||
@ -895,6 +896,7 @@ class DebuggingOptions {
|
|||||||
disablePortPublication = false,
|
disablePortPublication = false,
|
||||||
deviceVmServicePort = null,
|
deviceVmServicePort = null,
|
||||||
ddsPort = null,
|
ddsPort = null,
|
||||||
|
devToolsServerAddress = null,
|
||||||
vmserviceOutFile = null,
|
vmserviceOutFile = null,
|
||||||
fastStart = false,
|
fastStart = false,
|
||||||
webEnableExpressionEvaluation = false,
|
webEnableExpressionEvaluation = false,
|
||||||
@ -924,6 +926,7 @@ class DebuggingOptions {
|
|||||||
final int deviceVmServicePort;
|
final int deviceVmServicePort;
|
||||||
final bool disablePortPublication;
|
final bool disablePortPublication;
|
||||||
final int ddsPort;
|
final int ddsPort;
|
||||||
|
final Uri devToolsServerAddress;
|
||||||
final String port;
|
final String port;
|
||||||
final String hostname;
|
final String hostname;
|
||||||
final bool webEnableExposeUrl;
|
final bool webEnableExposeUrl;
|
||||||
|
@ -4,13 +4,15 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:browser_launcher/browser_launcher.dart';
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:process/process.dart';
|
import 'package:process/process.dart';
|
||||||
|
|
||||||
import 'base/io.dart' as io;
|
import 'base/io.dart' as io;
|
||||||
import 'base/logger.dart';
|
import 'base/logger.dart';
|
||||||
|
import 'base/platform.dart';
|
||||||
import 'convert.dart';
|
import 'convert.dart';
|
||||||
|
import 'persistent_tool_state.dart';
|
||||||
import 'resident_runner.dart';
|
import 'resident_runner.dart';
|
||||||
|
|
||||||
/// An implementation of the devtools launcher that uses the server package.
|
/// An implementation of the devtools launcher that uses the server package.
|
||||||
@ -19,59 +21,68 @@ import 'resident_runner.dart';
|
|||||||
/// a devtools dep in google3.
|
/// a devtools dep in google3.
|
||||||
class DevtoolsServerLauncher extends DevtoolsLauncher {
|
class DevtoolsServerLauncher extends DevtoolsLauncher {
|
||||||
DevtoolsServerLauncher({
|
DevtoolsServerLauncher({
|
||||||
|
@required Platform platform,
|
||||||
@required ProcessManager processManager,
|
@required ProcessManager processManager,
|
||||||
@required String pubExecutable,
|
@required String pubExecutable,
|
||||||
@required Logger logger,
|
@required Logger logger,
|
||||||
|
@required PersistentToolState persistentToolState,
|
||||||
}) : _processManager = processManager,
|
}) : _processManager = processManager,
|
||||||
_pubExecutable = pubExecutable,
|
_pubExecutable = pubExecutable,
|
||||||
_logger = logger;
|
_logger = logger,
|
||||||
|
_platform = platform,
|
||||||
|
_persistentToolState = persistentToolState;
|
||||||
|
|
||||||
final ProcessManager _processManager;
|
final ProcessManager _processManager;
|
||||||
final String _pubExecutable;
|
final String _pubExecutable;
|
||||||
final Logger _logger;
|
final Logger _logger;
|
||||||
|
final Platform _platform;
|
||||||
|
final PersistentToolState _persistentToolState;
|
||||||
|
|
||||||
io.Process _devToolsProcess;
|
io.Process _devToolsProcess;
|
||||||
Uri _devToolsUri;
|
|
||||||
|
|
||||||
static final RegExp _serveDevToolsPattern =
|
static final RegExp _serveDevToolsPattern =
|
||||||
RegExp(r'Serving DevTools at ((http|//)[a-zA-Z0-9:/=_\-\.\[\]]+)');
|
RegExp(r'Serving DevTools at ((http|//)[a-zA-Z0-9:/=_\-\.\[\]]+)');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> launch(Uri vmServiceUri, {bool openInBrowser = false}) async {
|
Future<void> launch(Uri vmServiceUri) async {
|
||||||
if (_devToolsProcess != null && _devToolsUri != null) {
|
// Place this entire method in a try/catch that swallows exceptions because
|
||||||
// DevTools is already running.
|
// we do not want to block Flutter run/attach operations on a DevTools
|
||||||
if (openInBrowser) {
|
// failure.
|
||||||
await Chrome.start(<String>[_devToolsUri.toString()]);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Status status = _logger.startProgress(
|
|
||||||
'Activating Dart DevTools...',
|
|
||||||
);
|
|
||||||
try {
|
try {
|
||||||
// TODO(kenz): https://github.com/dart-lang/pub/issues/2791 - calling `pub
|
bool offline = false;
|
||||||
// global activate` adds ~ 4.5 seconds of latency.
|
try {
|
||||||
final io.ProcessResult _devToolsActivateProcess = await _processManager.run(<String>[
|
const String pubHostedUrlKey = 'PUB_HOSTED_URL';
|
||||||
_pubExecutable,
|
if (_platform.environment.containsKey(pubHostedUrlKey)) {
|
||||||
'global',
|
await http.head(_platform.environment[pubHostedUrlKey]);
|
||||||
'activate',
|
} else {
|
||||||
'devtools'
|
await http.head('https://pub.dev');
|
||||||
]);
|
}
|
||||||
if (_devToolsActivateProcess.exitCode != 0) {
|
} on Exception {
|
||||||
status.cancel();
|
offline = true;
|
||||||
_logger.printError('Error running `pub global activate '
|
}
|
||||||
'devtools`:\n${_devToolsActivateProcess.stderr}');
|
|
||||||
return;
|
if (offline) {
|
||||||
|
// TODO(kenz): we should launch an already activated version of DevTools
|
||||||
|
// here, if available, once DevTools has offline support. DevTools does
|
||||||
|
// not work without internet currently due to the failed request of a
|
||||||
|
// couple scripts. See https://github.com/flutter/devtools/issues/2420.
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
final bool didActivateDevTools = await _activateDevTools();
|
||||||
|
final bool devToolsActive = await _checkForActiveDevTools();
|
||||||
|
if (!didActivateDevTools && !devToolsActive) {
|
||||||
|
// At this point, we failed to activate the DevTools package and the
|
||||||
|
// package is not already active.
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
status.stop();
|
|
||||||
|
|
||||||
_devToolsProcess = await _processManager.start(<String>[
|
_devToolsProcess = await _processManager.start(<String>[
|
||||||
_pubExecutable,
|
_pubExecutable,
|
||||||
'global',
|
'global',
|
||||||
'run',
|
'run',
|
||||||
'devtools',
|
'devtools',
|
||||||
if (!openInBrowser) '--no-launch-browser',
|
'--no-launch-browser',
|
||||||
if (vmServiceUri != null) '--vm-uri=$vmServiceUri',
|
if (vmServiceUri != null) '--vm-uri=$vmServiceUri',
|
||||||
]);
|
]);
|
||||||
final Completer<Uri> completer = Completer<Uri>();
|
final Completer<Uri> completer = Completer<Uri>();
|
||||||
@ -91,30 +102,83 @@ class DevtoolsServerLauncher extends DevtoolsLauncher {
|
|||||||
}
|
}
|
||||||
completer.complete(Uri.parse(uri));
|
completer.complete(Uri.parse(uri));
|
||||||
}
|
}
|
||||||
_logger.printStatus(line);
|
|
||||||
});
|
});
|
||||||
_devToolsProcess.stderr
|
_devToolsProcess.stderr
|
||||||
.transform(utf8.decoder)
|
.transform(utf8.decoder)
|
||||||
.transform(const LineSplitter())
|
.transform(const LineSplitter())
|
||||||
.listen(_logger.printError);
|
.listen(_logger.printError);
|
||||||
_devToolsUri = await completer.future;
|
devToolsUri = await completer.future
|
||||||
|
.timeout(const Duration(seconds: 10));
|
||||||
} on Exception catch (e, st) {
|
} on Exception catch (e, st) {
|
||||||
status.cancel();
|
|
||||||
_logger.printError('Failed to launch DevTools: $e', stackTrace: st);
|
_logger.printError('Failed to launch DevTools: $e', stackTrace: st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
Future<bool> _checkForActiveDevTools() async {
|
||||||
Future<DevToolsServerAddress> serve({bool openInBrowser = false}) async {
|
// We are offline, and cannot activate DevTools, so check if the DevTools
|
||||||
await launch(null, openInBrowser: openInBrowser);
|
// package is already active.
|
||||||
if (_devToolsUri == null) {
|
final io.ProcessResult _pubGlobalListProcess = await _processManager.run(<String>[
|
||||||
return null;
|
_pubExecutable,
|
||||||
|
'global',
|
||||||
|
'list',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (_pubGlobalListProcess.stdout.toString().contains('devtools ')) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return DevToolsServerAddress(_devToolsUri.host, _devToolsUri.port);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper method to activate the DevTools pub package.
|
||||||
|
///
|
||||||
|
/// Returns a bool indicating whether or not the package was successfully
|
||||||
|
/// activated from pub.
|
||||||
|
Future<bool> _activateDevTools() async {
|
||||||
|
final DateTime now = DateTime.now();
|
||||||
|
// Only attempt to activate DevTools twice a day.
|
||||||
|
final bool shouldActivate =
|
||||||
|
_persistentToolState.lastDevToolsActivationTime == null ||
|
||||||
|
now.difference(_persistentToolState.lastDevToolsActivationTime).inHours >= 12;
|
||||||
|
if (!shouldActivate) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Status status = _logger.startProgress(
|
||||||
|
'Activating Dart DevTools...',
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
final io.ProcessResult _devToolsActivateProcess = await _processManager
|
||||||
|
.run(<String>[
|
||||||
|
_pubExecutable,
|
||||||
|
'global',
|
||||||
|
'activate',
|
||||||
|
'devtools'
|
||||||
|
]);
|
||||||
|
if (_devToolsActivateProcess.exitCode != 0) {
|
||||||
|
status.cancel();
|
||||||
|
_logger.printError('Error running `pub global activate '
|
||||||
|
'devtools`:\n${_devToolsActivateProcess.stderr}');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
status.stop();
|
||||||
|
_persistentToolState.lastDevToolsActivationTime = DateTime.now();
|
||||||
|
return true;
|
||||||
|
} on Exception catch (e, _) {
|
||||||
|
status.stop();
|
||||||
|
_logger.printError('Error running `pub global activate devtools`: $e');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<DevToolsServerAddress> serve() async {
|
||||||
|
await launch(null);
|
||||||
|
return activeDevToolsServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
|
devToolsUri = null;
|
||||||
if (_devToolsProcess != null) {
|
if (_devToolsProcess != null) {
|
||||||
_devToolsProcess.kill();
|
_devToolsProcess.kill();
|
||||||
await _devToolsProcess.exitCode;
|
await _devToolsProcess.exitCode;
|
||||||
|
@ -52,6 +52,9 @@ abstract class PersistentToolState {
|
|||||||
|
|
||||||
/// Whether this client was already determined to be or not be a bot.
|
/// Whether this client was already determined to be or not be a bot.
|
||||||
bool isRunningOnBot;
|
bool isRunningOnBot;
|
||||||
|
|
||||||
|
/// The last time the the DevTools package was activated from pub.
|
||||||
|
DateTime lastDevToolsActivationTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DefaultPersistentToolState implements PersistentToolState {
|
class _DefaultPersistentToolState implements PersistentToolState {
|
||||||
@ -85,6 +88,7 @@ class _DefaultPersistentToolState implements PersistentToolState {
|
|||||||
Channel.stable: 'last-active-stable-version'
|
Channel.stable: 'last-active-stable-version'
|
||||||
};
|
};
|
||||||
static const String _kBotKey = 'is-bot';
|
static const String _kBotKey = 'is-bot';
|
||||||
|
static const String _kLastDevToolsActivationTimeKey = 'last-devtools-activation-time';
|
||||||
static const String _kLicenseHash = 'license-hash';
|
static const String _kLicenseHash = 'license-hash';
|
||||||
|
|
||||||
final Config _config;
|
final Config _config;
|
||||||
@ -131,4 +135,14 @@ class _DefaultPersistentToolState implements PersistentToolState {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
set isRunningOnBot(bool value) => _config.setValue(_kBotKey, value);
|
set isRunningOnBot(bool value) => _config.setValue(_kBotKey, value);
|
||||||
|
|
||||||
|
@override
|
||||||
|
DateTime get lastDevToolsActivationTime {
|
||||||
|
final String value = _config.getValue(_kLastDevToolsActivationTimeKey) as String;
|
||||||
|
return value != null ? DateTime.parse(value) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
set lastDevToolsActivationTime(DateTime time) =>
|
||||||
|
_config.setValue(_kLastDevToolsActivationTimeKey, time.toString());
|
||||||
}
|
}
|
||||||
|
@ -774,7 +774,7 @@ abstract class ResidentRunner {
|
|||||||
final CommandHelp commandHelp;
|
final CommandHelp commandHelp;
|
||||||
final bool machine;
|
final bool machine;
|
||||||
|
|
||||||
DevtoolsLauncher _devtoolsLauncher;
|
DevtoolsLauncher _devToolsLauncher;
|
||||||
|
|
||||||
bool _exited = false;
|
bool _exited = false;
|
||||||
Completer<int> _finished = Completer<int>();
|
Completer<int> _finished = Completer<int>();
|
||||||
@ -926,7 +926,7 @@ abstract class ResidentRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void writeVmserviceFile() {
|
void writeVmServiceFile() {
|
||||||
if (debuggingOptions.vmserviceOutFile != null) {
|
if (debuggingOptions.vmserviceOutFile != null) {
|
||||||
try {
|
try {
|
||||||
final String address = flutterDevices.first.vmService.wsAddress.toString();
|
final String address = flutterDevices.first.vmService.wsAddress.toString();
|
||||||
@ -941,7 +941,7 @@ abstract class ResidentRunner {
|
|||||||
|
|
||||||
Future<void> exit() async {
|
Future<void> exit() async {
|
||||||
_exited = true;
|
_exited = true;
|
||||||
await shutdownDevtools();
|
await shutdownDevTools();
|
||||||
await stopEchoingDeviceLog();
|
await stopEchoingDeviceLog();
|
||||||
await preExit();
|
await preExit();
|
||||||
await exitApp();
|
await exitApp();
|
||||||
@ -949,7 +949,7 @@ abstract class ResidentRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> detach() async {
|
Future<void> detach() async {
|
||||||
await shutdownDevtools();
|
await shutdownDevTools();
|
||||||
await stopEchoingDeviceLog();
|
await stopEchoingDeviceLog();
|
||||||
await preExit();
|
await preExit();
|
||||||
await shutdownDartDevelopmentService();
|
await shutdownDartDevelopmentService();
|
||||||
@ -1250,22 +1250,29 @@ abstract class ResidentRunner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> launchDevTools({bool openInBrowser = false}) async {
|
DevToolsServerAddress activeDevToolsServer() {
|
||||||
if (!supportsServiceProtocol) {
|
_devToolsLauncher ??= DevtoolsLauncher.instance;
|
||||||
return false;
|
return _devToolsLauncher.activeDevToolsServer;
|
||||||
}
|
|
||||||
assert(supportsServiceProtocol);
|
|
||||||
_devtoolsLauncher ??= DevtoolsLauncher.instance;
|
|
||||||
unawaited(_devtoolsLauncher.launch(
|
|
||||||
flutterDevices.first.vmService.httpAddress,
|
|
||||||
openInBrowser: openInBrowser,
|
|
||||||
));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> shutdownDevtools() async {
|
Future<void> serveDevToolsGracefully({
|
||||||
await _devtoolsLauncher?.close();
|
Uri devToolsServerAddress
|
||||||
_devtoolsLauncher = null;
|
}) async {
|
||||||
|
if (!supportsServiceProtocol) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_devToolsLauncher ??= DevtoolsLauncher.instance;
|
||||||
|
if (devToolsServerAddress != null) {
|
||||||
|
_devToolsLauncher.devToolsUri = devToolsServerAddress;
|
||||||
|
} else {
|
||||||
|
await _devToolsLauncher.serve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> shutdownDevTools() async {
|
||||||
|
await _devToolsLauncher?.close();
|
||||||
|
_devToolsLauncher = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _serviceProtocolDone(dynamic object) async {
|
Future<void> _serviceProtocolDone(dynamic object) async {
|
||||||
@ -1551,8 +1558,6 @@ class TerminalHandler {
|
|||||||
return residentRunner.debugDumpRenderTree();
|
return residentRunner.debugDumpRenderTree();
|
||||||
case 'U':
|
case 'U':
|
||||||
return residentRunner.debugDumpSemanticsTreeInInverseHitTestOrder();
|
return residentRunner.debugDumpSemanticsTreeInInverseHitTestOrder();
|
||||||
case 'v':
|
|
||||||
return residentRunner.launchDevTools(openInBrowser: true);
|
|
||||||
case 'w':
|
case 'w':
|
||||||
case 'W':
|
case 'W':
|
||||||
return residentRunner.debugDumpApp();
|
return residentRunner.debugDumpApp();
|
||||||
@ -1645,16 +1650,25 @@ String nextPlatform(String currentPlatform, FeatureFlags featureFlags) {
|
|||||||
|
|
||||||
/// A launcher for the devtools debugger and analysis tool.
|
/// A launcher for the devtools debugger and analysis tool.
|
||||||
abstract class DevtoolsLauncher {
|
abstract class DevtoolsLauncher {
|
||||||
|
Uri devToolsUri;
|
||||||
|
|
||||||
/// Launch a Dart DevTools process, optionally targeting a specific VM Service
|
/// Launch a Dart DevTools process, optionally targeting a specific VM Service
|
||||||
/// URI if [vmServiceUri] is non-null.
|
/// URI if [vmServiceUri] is non-null.
|
||||||
Future<void> launch(Uri vmServiceUri, {bool openInBrowser = false});
|
Future<void> launch(Uri vmServiceUri);
|
||||||
|
|
||||||
/// Serve Dart DevTools and return the host and port they are available on.
|
/// Serve Dart DevTools and return the host and port they are available on.
|
||||||
Future<DevToolsServerAddress> serve({bool openInBrowser = false});
|
Future<DevToolsServerAddress> serve();
|
||||||
|
|
||||||
Future<void> close();
|
Future<void> close();
|
||||||
|
|
||||||
static DevtoolsLauncher get instance => context.get<DevtoolsLauncher>();
|
static DevtoolsLauncher get instance => context.get<DevtoolsLauncher>();
|
||||||
|
|
||||||
|
DevToolsServerAddress get activeDevToolsServer {
|
||||||
|
if (devToolsUri == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return DevToolsServerAddress(devToolsUri.host, devToolsUri.port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DevToolsServerAddress {
|
class DevToolsServerAddress {
|
||||||
@ -1662,4 +1676,11 @@ class DevToolsServerAddress {
|
|||||||
|
|
||||||
final String host;
|
final String host;
|
||||||
final int port;
|
final int port;
|
||||||
|
|
||||||
|
Uri get uri {
|
||||||
|
if (host == null || port == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Uri(scheme: 'http', host: host, port: port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,12 @@ class ColdRunner extends ResidentRunner {
|
|||||||
// Connect to observatory.
|
// Connect to observatory.
|
||||||
if (debuggingOptions.debuggingEnabled) {
|
if (debuggingOptions.debuggingEnabled) {
|
||||||
try {
|
try {
|
||||||
await connectToServiceProtocol();
|
await Future.wait(<Future<void>>[
|
||||||
|
connectToServiceProtocol(),
|
||||||
|
serveDevToolsGracefully(
|
||||||
|
devToolsServerAddress: debuggingOptions.devToolsServerAddress,
|
||||||
|
),
|
||||||
|
]);
|
||||||
} on String catch (message) {
|
} on String catch (message) {
|
||||||
globals.printError(message);
|
globals.printError(message);
|
||||||
appFailedToStart();
|
appFailedToStart();
|
||||||
@ -115,7 +120,7 @@ class ColdRunner extends ResidentRunner {
|
|||||||
|
|
||||||
appStartedCompleter?.complete();
|
appStartedCompleter?.complete();
|
||||||
|
|
||||||
writeVmserviceFile();
|
writeVmServiceFile();
|
||||||
|
|
||||||
if (stayResident && !traceStartup) {
|
if (stayResident && !traceStartup) {
|
||||||
return waitForAppToFinish();
|
return waitForAppToFinish();
|
||||||
@ -132,10 +137,15 @@ class ColdRunner extends ResidentRunner {
|
|||||||
}) async {
|
}) async {
|
||||||
_didAttach = true;
|
_didAttach = true;
|
||||||
try {
|
try {
|
||||||
await connectToServiceProtocol(
|
await Future.wait(<Future<void>>[
|
||||||
getSkSLMethod: writeSkSL,
|
connectToServiceProtocol(
|
||||||
allowExistingDdsInstance: allowExistingDdsInstance,
|
getSkSLMethod: writeSkSL,
|
||||||
);
|
allowExistingDdsInstance: allowExistingDdsInstance,
|
||||||
|
),
|
||||||
|
serveDevToolsGracefully(
|
||||||
|
devToolsServerAddress: debuggingOptions.devToolsServerAddress,
|
||||||
|
),
|
||||||
|
]);
|
||||||
} on Exception catch (error) {
|
} on Exception catch (error) {
|
||||||
globals.printError('Error connecting to the service protocol: $error');
|
globals.printError('Error connecting to the service protocol: $error');
|
||||||
return 2;
|
return 2;
|
||||||
@ -195,6 +205,19 @@ class ColdRunner extends ResidentRunner {
|
|||||||
'An Observatory debugger and profiler on $dname is available at: '
|
'An Observatory debugger and profiler on $dname is available at: '
|
||||||
'${device.vmService.httpAddress}',
|
'${device.vmService.httpAddress}',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final DevToolsServerAddress devToolsServerAddress = activeDevToolsServer();
|
||||||
|
if (devToolsServerAddress != null) {
|
||||||
|
final Uri uri = devToolsServerAddress.uri?.replace(
|
||||||
|
queryParameters: <String, dynamic>{'uri': '${device.vmService.httpAddress}'},
|
||||||
|
);
|
||||||
|
if (uri != null) {
|
||||||
|
globals.printStatus(
|
||||||
|
'\nFlutter DevTools, a Flutter debugger and profiler, on '
|
||||||
|
'${device.device.name} is available at: $uri',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,13 +174,18 @@ class HotRunner extends ResidentRunner {
|
|||||||
}) async {
|
}) async {
|
||||||
_didAttach = true;
|
_didAttach = true;
|
||||||
try {
|
try {
|
||||||
await connectToServiceProtocol(
|
await Future.wait(<Future<void>>[
|
||||||
reloadSources: _reloadSourcesService,
|
connectToServiceProtocol(
|
||||||
restart: _restartService,
|
reloadSources: _reloadSourcesService,
|
||||||
compileExpression: _compileExpressionService,
|
restart: _restartService,
|
||||||
getSkSLMethod: writeSkSL,
|
compileExpression: _compileExpressionService,
|
||||||
allowExistingDdsInstance: allowExistingDdsInstance,
|
getSkSLMethod: writeSkSL,
|
||||||
);
|
allowExistingDdsInstance: allowExistingDdsInstance,
|
||||||
|
),
|
||||||
|
serveDevToolsGracefully(
|
||||||
|
devToolsServerAddress: debuggingOptions.devToolsServerAddress,
|
||||||
|
),
|
||||||
|
]);
|
||||||
// Catches all exceptions, non-Exception objects are rethrown.
|
// Catches all exceptions, non-Exception objects are rethrown.
|
||||||
} catch (error) { // ignore: avoid_catches_without_on_clauses
|
} catch (error) { // ignore: avoid_catches_without_on_clauses
|
||||||
if (error is! Exception && error is! String) {
|
if (error is! Exception && error is! String) {
|
||||||
@ -280,7 +285,7 @@ class HotRunner extends ResidentRunner {
|
|||||||
benchmarkOutput.writeAsStringSync(toPrettyJson(benchmarkData));
|
benchmarkOutput.writeAsStringSync(toPrettyJson(benchmarkData));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
writeVmserviceFile();
|
writeVmServiceFile();
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
if (stayResident) {
|
if (stayResident) {
|
||||||
@ -1087,6 +1092,19 @@ class HotRunner extends ResidentRunner {
|
|||||||
'An Observatory debugger and profiler on ${device.device.name} is available at: '
|
'An Observatory debugger and profiler on ${device.device.name} is available at: '
|
||||||
'${device.vmService.httpAddress}',
|
'${device.vmService.httpAddress}',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final DevToolsServerAddress devToolsServerAddress = activeDevToolsServer();
|
||||||
|
if (devToolsServerAddress != null) {
|
||||||
|
final Uri uri = devToolsServerAddress.uri?.replace(
|
||||||
|
queryParameters: <String, dynamic>{'uri': '${device.vmService.httpAddress}'},
|
||||||
|
);
|
||||||
|
if (uri != null) {
|
||||||
|
globals.printStatus(
|
||||||
|
'\nFlutter DevTools, a Flutter debugger and profiler, on '
|
||||||
|
'${device.device.name} is available at: $uri',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
globals.printStatus('');
|
globals.printStatus('');
|
||||||
if (debuggingOptions.buildInfo.nullSafetyMode == NullSafetyMode.sound) {
|
if (debuggingOptions.buildInfo.nullSafetyMode == NullSafetyMode.sound) {
|
||||||
|
@ -128,6 +128,9 @@ abstract class FlutterCommand extends Command<void> {
|
|||||||
/// The option name for a custom observatory port.
|
/// The option name for a custom observatory port.
|
||||||
static const String observatoryPortOption = 'observatory-port';
|
static const String observatoryPortOption = 'observatory-port';
|
||||||
|
|
||||||
|
/// The option name for a custom DevTools server address.
|
||||||
|
static const String kDevToolsServerAddress = 'devtools-server-address';
|
||||||
|
|
||||||
/// The flag name for whether or not to use ipv6.
|
/// The flag name for whether or not to use ipv6.
|
||||||
static const String ipv6Flag = 'ipv6';
|
static const String ipv6Flag = 'ipv6';
|
||||||
|
|
||||||
@ -322,6 +325,13 @@ abstract class FlutterCommand extends Command<void> {
|
|||||||
_usesPortOption = true;
|
_usesPortOption = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addDevToolsOptions() {
|
||||||
|
argParser.addOption(kDevToolsServerAddress,
|
||||||
|
help: 'When this value is provided, the Flutter tool will not spin up a '
|
||||||
|
'new DevTools server instance, but instead will use the one provided '
|
||||||
|
'at this address.');
|
||||||
|
}
|
||||||
|
|
||||||
void addDdsOptions({@required bool verboseHelp}) {
|
void addDdsOptions({@required bool verboseHelp}) {
|
||||||
argParser.addOption('dds-port',
|
argParser.addOption('dds-port',
|
||||||
help: 'When this value is provided, the Dart Development Service (DDS) will be '
|
help: 'When this value is provided, the Dart Development Service (DDS) will be '
|
||||||
@ -365,6 +375,16 @@ abstract class FlutterCommand extends Command<void> {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Uri get devToolsServerAddress {
|
||||||
|
if (argResults.wasParsed(kDevToolsServerAddress)) {
|
||||||
|
final Uri uri = Uri.tryParse(stringArg(kDevToolsServerAddress));
|
||||||
|
if (uri != null && uri.host.isNotEmpty && uri.port != 0) {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the vmservice port provided to in the 'observatory-port' or
|
/// Gets the vmservice port provided to in the 'observatory-port' or
|
||||||
/// 'host-vmservice-port option.
|
/// 'host-vmservice-port option.
|
||||||
///
|
///
|
||||||
|
@ -4,20 +4,41 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter_tools/src/base/file_system.dart';
|
||||||
import 'package:flutter_tools/src/base/io.dart';
|
import 'package:flutter_tools/src/base/io.dart';
|
||||||
import 'package:flutter_tools/src/base/logger.dart';
|
import 'package:flutter_tools/src/base/logger.dart';
|
||||||
|
import 'package:flutter_tools/src/base/platform.dart';
|
||||||
import 'package:flutter_tools/src/devtools_launcher.dart';
|
import 'package:flutter_tools/src/devtools_launcher.dart';
|
||||||
|
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||||
|
import 'package:flutter_tools/src/persistent_tool_state.dart';
|
||||||
import 'package:flutter_tools/src/resident_runner.dart';
|
import 'package:flutter_tools/src/resident_runner.dart';
|
||||||
|
|
||||||
import '../src/common.dart';
|
import '../src/common.dart';
|
||||||
import '../src/context.dart';
|
import '../src/context.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
BufferLogger logger;
|
||||||
|
FakePlatform platform;
|
||||||
|
PersistentToolState persistentToolState;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
logger = BufferLogger.test();
|
||||||
|
platform = FakePlatform(environment: <String, String>{});
|
||||||
|
|
||||||
|
final Directory tempDir = globals.fs.systemTempDirectory.createTempSync('devtools_launcher_test');
|
||||||
|
persistentToolState = PersistentToolState.test(
|
||||||
|
directory: tempDir,
|
||||||
|
logger: logger,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
testWithoutContext('DevtoolsLauncher launches DevTools through pub and saves the URI', () async {
|
testWithoutContext('DevtoolsLauncher launches DevTools through pub and saves the URI', () async {
|
||||||
final Completer<void> completer = Completer<void>();
|
final Completer<void> completer = Completer<void>();
|
||||||
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
||||||
pubExecutable: 'pub',
|
pubExecutable: 'pub',
|
||||||
logger: BufferLogger.test(),
|
logger: logger,
|
||||||
|
platform: platform,
|
||||||
|
persistentToolState: persistentToolState,
|
||||||
processManager: FakeProcessManager.list(<FakeCommand>[
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
||||||
const FakeCommand(
|
const FakeCommand(
|
||||||
command: <String>[
|
command: <String>[
|
||||||
@ -28,6 +49,14 @@ void main() {
|
|||||||
],
|
],
|
||||||
stdout: 'Activated DevTools 0.9.5',
|
stdout: 'Activated DevTools 0.9.5',
|
||||||
),
|
),
|
||||||
|
const FakeCommand(
|
||||||
|
command: <String>[
|
||||||
|
'pub',
|
||||||
|
'global',
|
||||||
|
'list',
|
||||||
|
],
|
||||||
|
stdout: 'devtools 0.9.6',
|
||||||
|
),
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: const <String>[
|
command: const <String>[
|
||||||
'pub',
|
'pub',
|
||||||
@ -51,7 +80,9 @@ void main() {
|
|||||||
final Completer<void> completer = Completer<void>();
|
final Completer<void> completer = Completer<void>();
|
||||||
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
||||||
pubExecutable: 'pub',
|
pubExecutable: 'pub',
|
||||||
logger: BufferLogger.test(),
|
logger: logger,
|
||||||
|
platform: platform,
|
||||||
|
persistentToolState: persistentToolState,
|
||||||
processManager: FakeProcessManager.list(<FakeCommand>[
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
||||||
const FakeCommand(
|
const FakeCommand(
|
||||||
command: <String>[
|
command: <String>[
|
||||||
@ -62,12 +93,21 @@ void main() {
|
|||||||
],
|
],
|
||||||
stdout: 'Activated DevTools 0.9.5',
|
stdout: 'Activated DevTools 0.9.5',
|
||||||
),
|
),
|
||||||
|
const FakeCommand(
|
||||||
|
command: <String>[
|
||||||
|
'pub',
|
||||||
|
'global',
|
||||||
|
'list',
|
||||||
|
],
|
||||||
|
stdout: 'devtools 0.9.6',
|
||||||
|
),
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: const <String>[
|
command: const <String>[
|
||||||
'pub',
|
'pub',
|
||||||
'global',
|
'global',
|
||||||
'run',
|
'run',
|
||||||
'devtools',
|
'devtools',
|
||||||
|
'--no-launch-browser',
|
||||||
],
|
],
|
||||||
stdout: 'Serving DevTools at http://127.0.0.1:9100\n',
|
stdout: 'Serving DevTools at http://127.0.0.1:9100\n',
|
||||||
completer: completer,
|
completer: completer,
|
||||||
@ -75,16 +115,49 @@ void main() {
|
|||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
|
|
||||||
final DevToolsServerAddress address = await launcher.serve(openInBrowser: true);
|
final DevToolsServerAddress address = await launcher.serve();
|
||||||
expect(address.host, '127.0.0.1');
|
expect(address.host, '127.0.0.1');
|
||||||
expect(address.port, 9100);
|
expect(address.port, 9100);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('DevtoolsLauncher prints error if exception is thrown during activate', () async {
|
testWithoutContext('DevtoolsLauncher does not activate DevTools if it was recently activated', () async {
|
||||||
final BufferLogger logger = BufferLogger.test();
|
persistentToolState.lastDevToolsActivationTime = DateTime.now();
|
||||||
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
||||||
pubExecutable: 'pub',
|
pubExecutable: 'pub',
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
platform: platform,
|
||||||
|
persistentToolState: persistentToolState,
|
||||||
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
||||||
|
const FakeCommand(
|
||||||
|
command: <String>[
|
||||||
|
'pub',
|
||||||
|
'global',
|
||||||
|
'list',
|
||||||
|
],
|
||||||
|
stdout: 'devtools 0.9.6',
|
||||||
|
),
|
||||||
|
const FakeCommand(
|
||||||
|
command: <String>[
|
||||||
|
'pub',
|
||||||
|
'global',
|
||||||
|
'run',
|
||||||
|
'devtools',
|
||||||
|
'--no-launch-browser',
|
||||||
|
],
|
||||||
|
stdout: 'Serving DevTools at http://127.0.0.1:9100\n',
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
await launcher.serve();
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('DevtoolsLauncher prints error if exception is thrown during activate', () async {
|
||||||
|
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
||||||
|
pubExecutable: 'pub',
|
||||||
|
logger: logger,
|
||||||
|
platform: platform,
|
||||||
|
persistentToolState: persistentToolState,
|
||||||
processManager: FakeProcessManager.list(<FakeCommand>[
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
||||||
const FakeCommand(
|
const FakeCommand(
|
||||||
command: <String>[
|
command: <String>[
|
||||||
@ -96,6 +169,14 @@ void main() {
|
|||||||
stderr: 'Error - could not activate devtools',
|
stderr: 'Error - could not activate devtools',
|
||||||
exitCode: 1,
|
exitCode: 1,
|
||||||
),
|
),
|
||||||
|
const FakeCommand(
|
||||||
|
command: <String>[
|
||||||
|
'pub',
|
||||||
|
'global',
|
||||||
|
'list',
|
||||||
|
],
|
||||||
|
stdout: 'devtools 0.9.6',
|
||||||
|
),
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: const <String>[
|
command: const <String>[
|
||||||
'pub',
|
'pub',
|
||||||
@ -118,10 +199,11 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('DevtoolsLauncher prints error if exception is thrown during launch', () async {
|
testWithoutContext('DevtoolsLauncher prints error if exception is thrown during launch', () async {
|
||||||
final BufferLogger logger = BufferLogger.test();
|
|
||||||
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
||||||
pubExecutable: 'pub',
|
pubExecutable: 'pub',
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
platform: platform,
|
||||||
|
persistentToolState: persistentToolState,
|
||||||
processManager: FakeProcessManager.list(<FakeCommand>[
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
||||||
const FakeCommand(
|
const FakeCommand(
|
||||||
command: <String>[
|
command: <String>[
|
||||||
@ -132,6 +214,14 @@ void main() {
|
|||||||
],
|
],
|
||||||
stdout: 'Activated DevTools 0.9.5',
|
stdout: 'Activated DevTools 0.9.5',
|
||||||
),
|
),
|
||||||
|
const FakeCommand(
|
||||||
|
command: <String>[
|
||||||
|
'pub',
|
||||||
|
'global',
|
||||||
|
'list',
|
||||||
|
],
|
||||||
|
stdout: 'devtools 0.9.6',
|
||||||
|
),
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: const <String>[
|
command: const <String>[
|
||||||
'pub',
|
'pub',
|
||||||
|
@ -57,4 +57,23 @@ void main() {
|
|||||||
expect(state2.lastActiveVersion(Channel.beta), 'ghi');
|
expect(state2.lastActiveVersion(Channel.beta), 'ghi');
|
||||||
expect(state2.lastActiveVersion(Channel.stable), 'jkl');
|
expect(state2.lastActiveVersion(Channel.stable), 'jkl');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWithoutContext('lastDevToolsActivationTime can be cached and stored', () {
|
||||||
|
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
|
||||||
|
final Directory directory = fileSystem.directory('state_dir')..createSync();
|
||||||
|
final PersistentToolState state1 = PersistentToolState.test(
|
||||||
|
directory: directory,
|
||||||
|
logger: BufferLogger.test(),
|
||||||
|
);
|
||||||
|
|
||||||
|
final DateTime time = DateTime.now();
|
||||||
|
state1.lastDevToolsActivationTime = time;
|
||||||
|
|
||||||
|
final PersistentToolState state2 = PersistentToolState.test(
|
||||||
|
directory: directory,
|
||||||
|
logger: BufferLogger.test(),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(state2.lastDevToolsActivationTime, equals(time));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,9 @@ void main() {
|
|||||||
expect((await connectionInfo).baseUri, 'foo://bar');
|
expect((await connectionInfo).baseUri, 'foo://bar');
|
||||||
expect(onAppStart.isCompleted, true);
|
expect(onAppStart.isCompleted, true);
|
||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner suppresses errors for the initial compilation', () => testbed.run(() async {
|
testUsingContext('ResidentRunner suppresses errors for the initial compilation', () => testbed.run(() async {
|
||||||
globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
|
globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
|
||||||
@ -274,7 +276,9 @@ void main() {
|
|||||||
suppressErrors: true,
|
suppressErrors: true,
|
||||||
)).called(1);
|
)).called(1);
|
||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
// Regression test for https://github.com/flutter/flutter/issues/60613
|
// Regression test for https://github.com/flutter/flutter/issues/60613
|
||||||
testUsingContext('ResidentRunner calls appFailedToStart if initial compilation fails', () => testbed.run(() async {
|
testUsingContext('ResidentRunner calls appFailedToStart if initial compilation fails', () => testbed.run(() async {
|
||||||
@ -406,7 +410,9 @@ void main() {
|
|||||||
suppressErrors: false,
|
suppressErrors: false,
|
||||||
)).called(1);
|
)).called(1);
|
||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner can attach to device successfully with --fast-start', () => testbed.run(() async {
|
testUsingContext('ResidentRunner can attach to device successfully with --fast-start', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -486,7 +492,9 @@ void main() {
|
|||||||
expect((await connectionInfo).baseUri, 'foo://bar');
|
expect((await connectionInfo).baseUri, 'foo://bar');
|
||||||
expect(onAppStart.isCompleted, true);
|
expect(onAppStart.isCompleted, true);
|
||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner can handle an RPC exception from hot reload', () => testbed.run(() async {
|
testUsingContext('ResidentRunner can handle an RPC exception from hot reload', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -539,7 +547,9 @@ void main() {
|
|||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Usage: () => MockUsage(),
|
Usage: () => MockUsage(),
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner fails its operation if the device initialization is not complete', () => testbed.run(() async {
|
testUsingContext('ResidentRunner fails its operation if the device initialization is not complete', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -624,7 +634,9 @@ void main() {
|
|||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Usage: () => MockUsage(),
|
Usage: () => MockUsage(),
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner reports hot reload event with null safety analytics', () => testbed.run(() async {
|
testUsingContext('ResidentRunner reports hot reload event with null safety analytics', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -688,6 +700,7 @@ void main() {
|
|||||||
})).called(1);
|
})).called(1);
|
||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
Usage: () => MockUsage(),
|
Usage: () => MockUsage(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -756,7 +769,9 @@ void main() {
|
|||||||
|
|
||||||
expect(result.code, 0);
|
expect(result.code, 0);
|
||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner reports error with missing entrypoint file', () => testbed.run(() async {
|
testUsingContext('ResidentRunner reports error with missing entrypoint file', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -840,7 +855,9 @@ void main() {
|
|||||||
expect(testLogger.errorText, contains('The entrypoint file (i.e. the file with main())'));
|
expect(testLogger.errorText, contains('The entrypoint file (i.e. the file with main())'));
|
||||||
expect(result.fatal, false);
|
expect(result.fatal, false);
|
||||||
expect(result.code, 0);
|
expect(result.code, 0);
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner resets compilation time on reload reject', () => testbed.run(() async {
|
testUsingContext('ResidentRunner resets compilation time on reload reject', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -928,7 +945,9 @@ void main() {
|
|||||||
expect(result.message, contains('Reload rejected: Failed to hot reload')); // contains error message from reload report.
|
expect(result.message, contains('Reload rejected: Failed to hot reload')); // contains error message from reload report.
|
||||||
expect(result.code, 1);
|
expect(result.code, 1);
|
||||||
verify(mockDevFS.resetLastCompiled()).called(1); // compilation time is reset.
|
verify(mockDevFS.resetLastCompiled()).called(1); // compilation time is reset.
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner can send target platform to analytics from hot reload', () => testbed.run(() async {
|
testUsingContext('ResidentRunner can send target platform to analytics from hot reload', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -1000,7 +1019,9 @@ void main() {
|
|||||||
);
|
);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Usage: () => MockUsage(),
|
Usage: () => MockUsage(),
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner can perform fast reassemble', () => testbed.run(() async {
|
testUsingContext('ResidentRunner can perform fast reassemble', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -1114,7 +1135,9 @@ void main() {
|
|||||||
ProjectFileInvalidator: () => FakeProjectFileInvalidator(),
|
ProjectFileInvalidator: () => FakeProjectFileInvalidator(),
|
||||||
Usage: () => MockUsage(),
|
Usage: () => MockUsage(),
|
||||||
FeatureFlags: () => TestFeatureFlags(isSingleWidgetReloadEnabled: true),
|
FeatureFlags: () => TestFeatureFlags(isSingleWidgetReloadEnabled: true),
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner can send target platform to analytics from full restart', () => testbed.run(() async {
|
testUsingContext('ResidentRunner can send target platform to analytics from full restart', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -1184,7 +1207,9 @@ void main() {
|
|||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Usage: () => MockUsage(),
|
Usage: () => MockUsage(),
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner can remove breakpoints from paused isolate during hot restart', () => testbed.run(() async {
|
testUsingContext('ResidentRunner can remove breakpoints from paused isolate during hot restart', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -1260,7 +1285,9 @@ void main() {
|
|||||||
|
|
||||||
expect(result.isOk, true);
|
expect(result.isOk, true);
|
||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner will alternative the name of the dill file uploaded for a hot restart', () => testbed.run(() async {
|
testUsingContext('ResidentRunner will alternative the name of the dill file uploaded for a hot restart', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -1392,7 +1419,9 @@ void main() {
|
|||||||
await residentRunner.restart(fullRestart: true);
|
await residentRunner.restart(fullRestart: true);
|
||||||
|
|
||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner Can handle an RPC exception from hot restart', () => testbed.run(() async {
|
testUsingContext('ResidentRunner Can handle an RPC exception from hot restart', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -1445,7 +1474,9 @@ void main() {
|
|||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Usage: () => MockUsage(),
|
Usage: () => MockUsage(),
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('ResidentRunner uses temp directory when there is no output dill path', () => testbed.run(() {
|
testUsingContext('ResidentRunner uses temp directory when there is no output dill path', () => testbed.run(() {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
||||||
@ -1650,13 +1681,88 @@ void main() {
|
|||||||
)
|
)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
testUsingContext('ResidentRunner invokes DevtoolsLauncher when launching and shutting down Devtools', () => testbed.run(() async {
|
testUsingContext('ResidentRunner invokes DevToolsLauncher when attaching and shutting down DevTools', () => testbed.run(() async {
|
||||||
when(mockFlutterDevice.vmService).thenReturn(fakeVmServiceHost.vmService);
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
setHttpAddress(testUri, fakeVmServiceHost.vmService);
|
listViews,
|
||||||
await residentRunner.launchDevTools();
|
listViews,
|
||||||
verify(mockDevtoolsLauncher.launch(testUri)).called(1);
|
setAssetBundlePath,
|
||||||
|
]);
|
||||||
|
final Future<int> result = residentRunner.attach();
|
||||||
|
expect(await result, 0);
|
||||||
|
|
||||||
await residentRunner.shutdownDevtools();
|
// Verify DevTools was served.
|
||||||
|
verify(mockDevtoolsLauncher.serve()).called(1);
|
||||||
|
|
||||||
|
// Shutdown
|
||||||
|
await residentRunner.shutdownDevTools();
|
||||||
|
verify(mockDevtoolsLauncher.close()).called(1);
|
||||||
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
|
testUsingContext('ResidentRunner invokes DevtoolsLauncher when attaching and shutting down - cold mode', () => testbed.run(() async {
|
||||||
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
|
listViews,
|
||||||
|
listViews,
|
||||||
|
setAssetBundlePath,
|
||||||
|
]);
|
||||||
|
residentRunner = ColdRunner(
|
||||||
|
<FlutterDevice>[
|
||||||
|
mockFlutterDevice,
|
||||||
|
],
|
||||||
|
stayResident: false,
|
||||||
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'),
|
||||||
|
target: 'main.dart',
|
||||||
|
);
|
||||||
|
when(mockFlutterDevice.runCold(
|
||||||
|
coldRunner: anyNamed('coldRunner'),
|
||||||
|
route: anyNamed('route'),
|
||||||
|
)).thenAnswer((Invocation invocation) async {
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
final Future<int> result = residentRunner.attach();
|
||||||
|
expect(await result, 0);
|
||||||
|
|
||||||
|
// Verify DevTools was served.
|
||||||
|
verify(mockDevtoolsLauncher.serve()).called(1);
|
||||||
|
|
||||||
|
// Shutdown
|
||||||
|
await residentRunner.shutdownDevTools();
|
||||||
|
verify(mockDevtoolsLauncher.close()).called(1);
|
||||||
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
|
testUsingContext('ResidentRunner invokes DevtoolsLauncher when running and shutting down - cold mode', () => testbed.run(() async {
|
||||||
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
|
listViews,
|
||||||
|
listViews,
|
||||||
|
setAssetBundlePath,
|
||||||
|
]);
|
||||||
|
residentRunner = ColdRunner(
|
||||||
|
<FlutterDevice>[
|
||||||
|
mockFlutterDevice,
|
||||||
|
],
|
||||||
|
stayResident: false,
|
||||||
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'),
|
||||||
|
target: 'main.dart',
|
||||||
|
);
|
||||||
|
when(mockFlutterDevice.runCold(
|
||||||
|
coldRunner: anyNamed('coldRunner'),
|
||||||
|
route: anyNamed('route'),
|
||||||
|
)).thenAnswer((Invocation invocation) async {
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
final Future<int> result = residentRunner.run();
|
||||||
|
expect(await result, 0);
|
||||||
|
|
||||||
|
// Verify DevTools was served.
|
||||||
|
verify(mockDevtoolsLauncher.serve()).called(1);
|
||||||
|
|
||||||
|
// Shutdown
|
||||||
|
await residentRunner.shutdownDevTools();
|
||||||
verify(mockDevtoolsLauncher.close()).called(1);
|
verify(mockDevtoolsLauncher.close()).called(1);
|
||||||
}), overrides: <Type, Generator>{
|
}), overrides: <Type, Generator>{
|
||||||
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
@ -2299,7 +2405,9 @@ void main() {
|
|||||||
await residentRunner.run();
|
await residentRunner.run();
|
||||||
|
|
||||||
expect(await globals.fs.file('foo').readAsString(), testUri.toString());
|
expect(await globals.fs.file('foo').readAsString(), testUri.toString());
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('HotRunner copies compiled app.dill to cache during startup', () => testbed.run(() async {
|
testUsingContext('HotRunner copies compiled app.dill to cache during startup', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -2327,7 +2435,9 @@ void main() {
|
|||||||
await residentRunner.run();
|
await residentRunner.run();
|
||||||
|
|
||||||
expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill')).readAsString(), 'ABC');
|
expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill')).readAsString(), 'ABC');
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('HotRunner copies compiled app.dill to cache during startup with dart defines', () => testbed.run(() async {
|
testUsingContext('HotRunner copies compiled app.dill to cache during startup with dart defines', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -2363,7 +2473,9 @@ void main() {
|
|||||||
|
|
||||||
expect(await globals.fs.file(globals.fs.path.join(
|
expect(await globals.fs.file(globals.fs.path.join(
|
||||||
'build', '187ef4436122d1cc2f40dc2b92f0eba0.cache.dill')).readAsString(), 'ABC');
|
'build', '187ef4436122d1cc2f40dc2b92f0eba0.cache.dill')).readAsString(), 'ABC');
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('HotRunner copies compiled app.dill to cache during startup with null safety', () => testbed.run(() async {
|
testUsingContext('HotRunner copies compiled app.dill to cache during startup with null safety', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -2399,7 +2511,9 @@ void main() {
|
|||||||
|
|
||||||
expect(await globals.fs.file(globals.fs.path.join(
|
expect(await globals.fs.file(globals.fs.path.join(
|
||||||
'build', '3416d3007730479552122f01c01e326d.cache.dill')).readAsString(), 'ABC');
|
'build', '3416d3007730479552122f01c01e326d.cache.dill')).readAsString(), 'ABC');
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('HotRunner does not copy app.dill if a dillOutputPath is given', () => testbed.run(() async {
|
testUsingContext('HotRunner does not copy app.dill if a dillOutputPath is given', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -2428,7 +2542,9 @@ void main() {
|
|||||||
await residentRunner.run();
|
await residentRunner.run();
|
||||||
|
|
||||||
expect(globals.fs.file(globals.fs.path.join('build', 'cache.dill')), isNot(exists));
|
expect(globals.fs.file(globals.fs.path.join('build', 'cache.dill')), isNot(exists));
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('HotRunner copies compiled app.dill to cache during startup with --track-widget-creation', () => testbed.run(() async {
|
testUsingContext('HotRunner copies compiled app.dill to cache during startup with --track-widget-creation', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -2461,7 +2577,9 @@ void main() {
|
|||||||
await residentRunner.run();
|
await residentRunner.run();
|
||||||
|
|
||||||
expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill.track.dill')).readAsString(), 'ABC');
|
expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill.track.dill')).readAsString(), 'ABC');
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('HotRunner unforwards device ports', () => testbed.run(() async {
|
testUsingContext('HotRunner unforwards device ports', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -2494,7 +2612,9 @@ void main() {
|
|||||||
await residentRunner.run();
|
await residentRunner.run();
|
||||||
|
|
||||||
verify(mockPortForwarder.dispose()).called(1);
|
verify(mockPortForwarder.dispose()).called(1);
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('HotRunner handles failure to write vmservice file', () => testbed.run(() async {
|
testUsingContext('HotRunner handles failure to write vmservice file', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
||||||
@ -2523,7 +2643,9 @@ void main() {
|
|||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => ThrowingForwardingFileSystem(MemoryFileSystem.test()),
|
FileSystem: () => ThrowingForwardingFileSystem(MemoryFileSystem.test()),
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
testUsingContext('ColdRunner writes vm service file when providing debugging option', () => testbed.run(() async {
|
testUsingContext('ColdRunner writes vm service file when providing debugging option', () => testbed.run(() async {
|
||||||
@ -2550,7 +2672,9 @@ void main() {
|
|||||||
|
|
||||||
expect(await globals.fs.file('foo').readAsString(), testUri.toString());
|
expect(await globals.fs.file('foo').readAsString(), testUri.toString());
|
||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}));
|
}), overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => mockDevtoolsLauncher,
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('FlutterDevice uses dartdevc configuration when targeting web', () async {
|
testUsingContext('FlutterDevice uses dartdevc configuration when targeting web', () async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
||||||
|
@ -290,6 +290,48 @@ void main() {
|
|||||||
expect(FlutterCommandResult.warning().exitStatus, ExitStatus.warning);
|
expect(FlutterCommandResult.warning().exitStatus, ExitStatus.warning);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUsingContext('devToolsServerAddress returns parsed uri', () async {
|
||||||
|
final DummyFlutterCommand command = DummyFlutterCommand()..addDevToolsOptions();
|
||||||
|
await createTestCommandRunner(command).run(<String>[
|
||||||
|
'dummy',
|
||||||
|
'--${FlutterCommand.kDevToolsServerAddress}',
|
||||||
|
'http://127.0.0.1:9105',
|
||||||
|
]);
|
||||||
|
expect(command.devToolsServerAddress.toString(), equals('http://127.0.0.1:9105'));
|
||||||
|
});
|
||||||
|
|
||||||
|
testUsingContext('devToolsServerAddress returns null for bad input', () async {
|
||||||
|
final DummyFlutterCommand command = DummyFlutterCommand()..addDevToolsOptions();
|
||||||
|
final CommandRunner<void> runner = createTestCommandRunner(command);
|
||||||
|
await runner.run(<String>[
|
||||||
|
'dummy',
|
||||||
|
'--${FlutterCommand.kDevToolsServerAddress}',
|
||||||
|
'hello-world',
|
||||||
|
]);
|
||||||
|
expect(command.devToolsServerAddress, isNull);
|
||||||
|
|
||||||
|
await runner.run(<String>[
|
||||||
|
'dummy',
|
||||||
|
'--${FlutterCommand.kDevToolsServerAddress}',
|
||||||
|
'',
|
||||||
|
]);
|
||||||
|
expect(command.devToolsServerAddress, isNull);
|
||||||
|
|
||||||
|
await runner.run(<String>[
|
||||||
|
'dummy',
|
||||||
|
'--${FlutterCommand.kDevToolsServerAddress}',
|
||||||
|
'9101',
|
||||||
|
]);
|
||||||
|
expect(command.devToolsServerAddress, isNull);
|
||||||
|
|
||||||
|
await runner.run(<String>[
|
||||||
|
'dummy',
|
||||||
|
'--${FlutterCommand.kDevToolsServerAddress}',
|
||||||
|
'127.0.0.1:9101',
|
||||||
|
]);
|
||||||
|
expect(command.devToolsServerAddress, isNull);
|
||||||
|
});
|
||||||
|
|
||||||
group('signals tests', () {
|
group('signals tests', () {
|
||||||
MockIoProcessSignal mockSignal;
|
MockIoProcessSignal mockSignal;
|
||||||
ProcessSignal signalUnderTest;
|
ProcessSignal signalUnderTest;
|
||||||
|
@ -285,13 +285,6 @@ void main() {
|
|||||||
verify(mockResidentRunner.debugDumpSemanticsTreeInInverseHitTestOrder()).called(1);
|
verify(mockResidentRunner.debugDumpSemanticsTreeInInverseHitTestOrder()).called(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('v - launchDevTools', () async {
|
|
||||||
when(mockResidentRunner.supportsServiceProtocol).thenReturn(true);
|
|
||||||
await terminalHandler.processTerminalInput('v');
|
|
||||||
|
|
||||||
verify(mockResidentRunner.launchDevTools(openInBrowser: true)).called(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
testWithoutContext('w,W - debugDumpApp with service protocol', () async {
|
testWithoutContext('w,W - debugDumpApp with service protocol', () async {
|
||||||
await terminalHandler.processTerminalInput('w');
|
await terminalHandler.processTerminalInput('w');
|
||||||
await terminalHandler.processTerminalInput('W');
|
await terminalHandler.processTerminalInput('W');
|
||||||
|
Loading…
Reference in New Issue
Block a user