mirror of
https://github.com/flutter/flutter
synced 2024-08-24 18:36:03 +00:00
Add a --print-dtd
flag to print the DTD address served by DevTools server (#144272)
This commit is contained in:
parent
dbdcead932
commit
31f4f2b6c0
|
@ -3,7 +3,6 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'runner.dart' as runner;
|
import 'runner.dart' as runner;
|
||||||
import 'src/artifacts.dart';
|
|
||||||
import 'src/base/context.dart';
|
import 'src/base/context.dart';
|
||||||
import 'src/base/io.dart';
|
import 'src/base/io.dart';
|
||||||
import 'src/base/logger.dart';
|
import 'src/base/logger.dart';
|
||||||
|
@ -110,7 +109,7 @@ Future<void> main(List<String> args) async {
|
||||||
// devtools source code.
|
// devtools source code.
|
||||||
DevtoolsLauncher: () => DevtoolsServerLauncher(
|
DevtoolsLauncher: () => DevtoolsServerLauncher(
|
||||||
processManager: globals.processManager,
|
processManager: globals.processManager,
|
||||||
dartExecutable: globals.artifacts!.getArtifactPath(Artifact.engineDartBinary),
|
artifacts: globals.artifacts!,
|
||||||
logger: globals.logger,
|
logger: globals.logger,
|
||||||
botDetector: globals.botDetector,
|
botDetector: globals.botDetector,
|
||||||
),
|
),
|
||||||
|
|
|
@ -218,7 +218,7 @@ Future<T> runInContext<T>(
|
||||||
),
|
),
|
||||||
DevtoolsLauncher: () => DevtoolsServerLauncher(
|
DevtoolsLauncher: () => DevtoolsServerLauncher(
|
||||||
processManager: globals.processManager,
|
processManager: globals.processManager,
|
||||||
dartExecutable: globals.artifacts!.getArtifactPath(Artifact.engineDartBinary),
|
artifacts: globals.artifacts!,
|
||||||
logger: globals.logger,
|
logger: globals.logger,
|
||||||
botDetector: globals.botDetector,
|
botDetector: globals.botDetector,
|
||||||
),
|
),
|
||||||
|
|
|
@ -2,13 +2,12 @@
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:process/process.dart';
|
import 'package:process/process.dart';
|
||||||
|
|
||||||
|
import 'artifacts.dart';
|
||||||
import 'base/bot_detector.dart';
|
import 'base/bot_detector.dart';
|
||||||
import 'base/common.dart';
|
import 'base/common.dart';
|
||||||
import 'base/io.dart' as io;
|
import 'base/io.dart' as io;
|
||||||
|
@ -16,21 +15,22 @@ import 'base/logger.dart';
|
||||||
import 'convert.dart';
|
import 'convert.dart';
|
||||||
import 'resident_runner.dart';
|
import 'resident_runner.dart';
|
||||||
|
|
||||||
/// An implementation of the devtools launcher that uses `pub global activate` to
|
/// An implementation of the devtools launcher that uses `dart devtools` to
|
||||||
/// start a server instance.
|
/// start a DevTools server instance.
|
||||||
class DevtoolsServerLauncher extends DevtoolsLauncher {
|
class DevtoolsServerLauncher extends DevtoolsLauncher {
|
||||||
DevtoolsServerLauncher({
|
DevtoolsServerLauncher({
|
||||||
required ProcessManager processManager,
|
required ProcessManager processManager,
|
||||||
required String dartExecutable,
|
|
||||||
required Logger logger,
|
required Logger logger,
|
||||||
required BotDetector botDetector,
|
required BotDetector botDetector,
|
||||||
|
required Artifacts artifacts,
|
||||||
}) : _processManager = processManager,
|
}) : _processManager = processManager,
|
||||||
_dartExecutable = dartExecutable,
|
|
||||||
_logger = logger,
|
_logger = logger,
|
||||||
_botDetector = botDetector;
|
_botDetector = botDetector,
|
||||||
|
_artifacts = artifacts;
|
||||||
|
|
||||||
final ProcessManager _processManager;
|
final ProcessManager _processManager;
|
||||||
final String _dartExecutable;
|
final Artifacts _artifacts;
|
||||||
|
late final String _dartExecutable = _artifacts.getArtifactPath(Artifact.engineDartBinary);
|
||||||
final Logger _logger;
|
final Logger _logger;
|
||||||
final BotDetector _botDetector;
|
final BotDetector _botDetector;
|
||||||
final Completer<void> _processStartCompleter = Completer<void>();
|
final Completer<void> _processStartCompleter = Completer<void>();
|
||||||
|
@ -42,6 +42,8 @@ class DevtoolsServerLauncher extends DevtoolsLauncher {
|
||||||
|
|
||||||
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:/=_\-\.\[\]]+?)\.?$');
|
||||||
|
static final RegExp _serveDtdPattern =
|
||||||
|
RegExp(r'Serving the Dart Tooling Daemon at (ws:\/\/[a-zA-Z0-9:/=_\-\.\[\]]+?)\.?$');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> get processStart => _processStartCompleter.future;
|
Future<void> get processStart => _processStartCompleter.future;
|
||||||
|
@ -55,21 +57,28 @@ class DevtoolsServerLauncher extends DevtoolsLauncher {
|
||||||
_dartExecutable,
|
_dartExecutable,
|
||||||
'devtools',
|
'devtools',
|
||||||
'--no-launch-browser',
|
'--no-launch-browser',
|
||||||
|
if (printDtdUri) '--print-dtd',
|
||||||
if (vmServiceUri != null) '--vm-uri=$vmServiceUri',
|
if (vmServiceUri != null) '--vm-uri=$vmServiceUri',
|
||||||
...?additionalArguments,
|
...?additionalArguments,
|
||||||
]);
|
]);
|
||||||
_processStartCompleter.complete();
|
_processStartCompleter.complete();
|
||||||
final Completer<Uri> completer = Completer<Uri>();
|
|
||||||
|
final Completer<Uri> devToolsCompleter = Completer<Uri>();
|
||||||
_devToolsProcess!.stdout
|
_devToolsProcess!.stdout
|
||||||
.transform(utf8.decoder)
|
.transform(utf8.decoder)
|
||||||
.transform(const LineSplitter())
|
.transform(const LineSplitter())
|
||||||
.listen((String line) {
|
.listen((String line) {
|
||||||
final Match? match = _serveDevToolsPattern.firstMatch(line);
|
final Match? dtdMatch = _serveDtdPattern.firstMatch(line);
|
||||||
if (match != null) {
|
if (dtdMatch != null) {
|
||||||
final String url = match[1]!;
|
final String uri = dtdMatch[1]!;
|
||||||
completer.complete(Uri.parse(url));
|
dtdUri = Uri.parse(uri);
|
||||||
}
|
}
|
||||||
});
|
final Match? devToolsMatch = _serveDevToolsPattern.firstMatch(line);
|
||||||
|
if (devToolsMatch != null) {
|
||||||
|
final String url = devToolsMatch[1]!;
|
||||||
|
devToolsCompleter.complete(Uri.parse(url));
|
||||||
|
}
|
||||||
|
});
|
||||||
_devToolsProcess!.stderr
|
_devToolsProcess!.stderr
|
||||||
.transform(utf8.decoder)
|
.transform(utf8.decoder)
|
||||||
.transform(const LineSplitter())
|
.transform(const LineSplitter())
|
||||||
|
@ -84,7 +93,11 @@ class DevtoolsServerLauncher extends DevtoolsLauncher {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
devToolsUrl = await completer.future;
|
// We do not need to wait for a [Completer] holding the DTD URI because
|
||||||
|
// the DTD URI will be output to stdout before the DevTools URI. Awaiting
|
||||||
|
// a [Completer] for the DevTools URI ensures both values will be
|
||||||
|
// populated before returning.
|
||||||
|
devToolsUrl = await devToolsCompleter.future;
|
||||||
} on Exception catch (e, st) {
|
} on Exception catch (e, st) {
|
||||||
_logger.printError('Failed to launch DevTools: $e', stackTrace: st);
|
_logger.printError('Failed to launch DevTools: $e', stackTrace: st);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,19 @@ abstract class ResidentDevtoolsHandler {
|
||||||
/// The current devtools server, or null if one is not running.
|
/// The current devtools server, or null if one is not running.
|
||||||
DevToolsServerAddress? get activeDevToolsServer;
|
DevToolsServerAddress? get activeDevToolsServer;
|
||||||
|
|
||||||
|
/// The Dart Tooling Daemon (DTD) URI for the DTD instance being hosted by
|
||||||
|
/// DevTools server.
|
||||||
|
///
|
||||||
|
/// This will be null if the DevTools server is not served through Flutter
|
||||||
|
/// tools (e.g. if it is served from an IDE).
|
||||||
|
Uri? get dtdUri;
|
||||||
|
|
||||||
|
/// Whether to print the Dart Tooling Daemon URI.
|
||||||
|
///
|
||||||
|
/// This will always return false when there is not a DTD instance being
|
||||||
|
/// served from the DevTools server.
|
||||||
|
bool get printDtdUri;
|
||||||
|
|
||||||
/// Whether it's ok to announce the [activeDevToolsServer].
|
/// Whether it's ok to announce the [activeDevToolsServer].
|
||||||
///
|
///
|
||||||
/// This should only return true once all the devices have been notified
|
/// This should only return true once all the devices have been notified
|
||||||
|
@ -63,6 +76,12 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler {
|
||||||
return _devToolsLauncher?.activeDevToolsServer;
|
return _devToolsLauncher?.activeDevToolsServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Uri? get dtdUri => _devToolsLauncher?.dtdUri;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get printDtdUri => _devToolsLauncher?.printDtdUri ?? false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get readyToAnnounce => _readyToAnnounce;
|
bool get readyToAnnounce => _readyToAnnounce;
|
||||||
bool _readyToAnnounce = false;
|
bool _readyToAnnounce = false;
|
||||||
|
@ -337,6 +356,12 @@ class NoOpDevtoolsHandler implements ResidentDevtoolsHandler {
|
||||||
wasShutdown = true;
|
wasShutdown = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Uri? get dtdUri => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get printDtdUri => false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a [URI] with query parameters into a display format instead
|
/// Convert a [URI] with query parameters into a display format instead
|
||||||
|
|
|
@ -1526,6 +1526,12 @@ abstract class ResidentRunner extends ResidentHandlers {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (includeDevtools) {
|
if (includeDevtools) {
|
||||||
|
if (_residentDevtoolsHandler!.printDtdUri) {
|
||||||
|
final Uri? dtdUri = residentDevtoolsHandler!.dtdUri;
|
||||||
|
if (dtdUri != null) {
|
||||||
|
globals.printStatus('The Dart Tooling Daemon is available at: $dtdUri\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
final Uri? uri = devToolsServerAddress!.uri?.replace(
|
final Uri? uri = devToolsServerAddress!.uri?.replace(
|
||||||
queryParameters: <String, dynamic>{'uri': '${device.vmService!.httpAddress}'},
|
queryParameters: <String, dynamic>{'uri': '${device.vmService!.httpAddress}'},
|
||||||
);
|
);
|
||||||
|
@ -1945,6 +1951,26 @@ abstract class DevtoolsLauncher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The Dart Tooling Daemon (DTD) URI for the DTD instance being hosted by
|
||||||
|
/// DevTools server.
|
||||||
|
///
|
||||||
|
/// This will be null if the DevTools server is not served through Flutter
|
||||||
|
/// tools (e.g. if it is served from an IDE).
|
||||||
|
Uri? get dtdUri => _dtdUri;
|
||||||
|
Uri? _dtdUri;
|
||||||
|
@protected
|
||||||
|
set dtdUri(Uri? value) => _dtdUri = value;
|
||||||
|
|
||||||
|
/// Whether to print the Dart Tooling Daemon URI.
|
||||||
|
///
|
||||||
|
/// This will always return false when there is not a DTD instance being
|
||||||
|
/// served from the DevTools server.
|
||||||
|
bool get printDtdUri => _printDtdUri ?? false;
|
||||||
|
bool? _printDtdUri;
|
||||||
|
set printDtdUri(bool value) {
|
||||||
|
_printDtdUri = value;
|
||||||
|
}
|
||||||
|
|
||||||
/// The URL of the current DevTools server.
|
/// The URL of the current DevTools server.
|
||||||
///
|
///
|
||||||
/// Returns null if [ready] is not complete.
|
/// Returns null if [ready] is not complete.
|
||||||
|
|
|
@ -17,6 +17,7 @@ import '../base/utils.dart';
|
||||||
import '../cache.dart';
|
import '../cache.dart';
|
||||||
import '../convert.dart';
|
import '../convert.dart';
|
||||||
import '../globals.dart' as globals;
|
import '../globals.dart' as globals;
|
||||||
|
import '../resident_runner.dart';
|
||||||
import '../tester/flutter_tester.dart';
|
import '../tester/flutter_tester.dart';
|
||||||
import '../version.dart';
|
import '../version.dart';
|
||||||
import '../web/web_device.dart';
|
import '../web/web_device.dart';
|
||||||
|
@ -35,6 +36,7 @@ abstract final class FlutterGlobalOptions {
|
||||||
static const String kMachineFlag = 'machine';
|
static const String kMachineFlag = 'machine';
|
||||||
static const String kPackagesOption = 'packages';
|
static const String kPackagesOption = 'packages';
|
||||||
static const String kPrefixedErrorsFlag = 'prefixed-errors';
|
static const String kPrefixedErrorsFlag = 'prefixed-errors';
|
||||||
|
static const String kPrintDtd = 'print-dtd';
|
||||||
static const String kQuietFlag = 'quiet';
|
static const String kQuietFlag = 'quiet';
|
||||||
static const String kShowTestDeviceFlag = 'show-test-device';
|
static const String kShowTestDeviceFlag = 'show-test-device';
|
||||||
static const String kShowWebServerDeviceFlag = 'show-web-server-device';
|
static const String kShowWebServerDeviceFlag = 'show-web-server-device';
|
||||||
|
@ -116,6 +118,12 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||||
argParser.addOption(FlutterGlobalOptions.kPackagesOption,
|
argParser.addOption(FlutterGlobalOptions.kPackagesOption,
|
||||||
hide: !verboseHelp,
|
hide: !verboseHelp,
|
||||||
help: 'Path to your "package_config.json" file.');
|
help: 'Path to your "package_config.json" file.');
|
||||||
|
argParser.addFlag(
|
||||||
|
FlutterGlobalOptions.kPrintDtd,
|
||||||
|
negatable: false,
|
||||||
|
help: 'Print the address of the Dart Tooling Daemon, if one is hosted by the Flutter CLI.',
|
||||||
|
hide: !verboseHelp,
|
||||||
|
);
|
||||||
if (verboseHelp) {
|
if (verboseHelp) {
|
||||||
argParser.addSeparator('Local build selection options (not normally required):');
|
argParser.addSeparator('Local build selection options (not normally required):');
|
||||||
}
|
}
|
||||||
|
@ -357,6 +365,10 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||||
if (machineFlag && topLevelResults.command?.name != 'analyze') {
|
if (machineFlag && topLevelResults.command?.name != 'analyze') {
|
||||||
throwToolExit('The "--machine" flag is only valid with the "--version" flag or the "analyze --suggestions" command.', exitCode: 2);
|
throwToolExit('The "--machine" flag is only valid with the "--version" flag or the "analyze --suggestions" command.', exitCode: 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final bool shouldPrintDtdUri = topLevelResults[FlutterGlobalOptions.kPrintDtd] as bool? ?? false;
|
||||||
|
DevtoolsLauncher.instance!.printDtdUri = shouldPrintDtdUri;
|
||||||
|
|
||||||
await super.runCommand(topLevelResults);
|
await super.runCommand(topLevelResults);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -824,7 +824,7 @@ void main() {
|
||||||
expect(result['host'], '127.0.0.1');
|
expect(result['host'], '127.0.0.1');
|
||||||
expect(result['port'], 1234);
|
expect(result['port'], 1234);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
DevtoolsLauncher: () => FakeDevtoolsLauncher(DevToolsServerAddress('127.0.0.1', 1234)),
|
DevtoolsLauncher: () => FakeDevtoolsLauncher(serverAddress: DevToolsServerAddress('127.0.0.1', 1234)),
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('devtools.serve command should return null fields if null returned', () async {
|
testUsingContext('devtools.serve command should return null fields if null returned', () async {
|
||||||
|
@ -840,7 +840,7 @@ void main() {
|
||||||
expect(result['host'], null);
|
expect(result['host'], null);
|
||||||
expect(result['port'], null);
|
expect(result['port'], null);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
DevtoolsLauncher: () => FakeDevtoolsLauncher(null),
|
DevtoolsLauncher: () => FakeDevtoolsLauncher(),
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('proxy.connect tries to connect to an ipv4 address and proxies the connection correctly', () async {
|
testUsingContext('proxy.connect tries to connect to an ipv4 address and proxies the connection correctly', () async {
|
||||||
|
@ -1286,18 +1286,6 @@ class FakeDeviceLogReader implements DeviceLogReader {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeDevtoolsLauncher extends Fake implements DevtoolsLauncher {
|
|
||||||
FakeDevtoolsLauncher(this._serverAddress);
|
|
||||||
|
|
||||||
final DevToolsServerAddress? _serverAddress;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<DevToolsServerAddress?> serve() async => _serverAddress;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FakeApplicationPackageFactory implements ApplicationPackageFactory {
|
class FakeApplicationPackageFactory implements ApplicationPackageFactory {
|
||||||
TargetPlatform? platformRequested;
|
TargetPlatform? platformRequested;
|
||||||
File? applicationBinaryRequested;
|
File? applicationBinaryRequested;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter_tools/src/artifacts.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/cache.dart';
|
import 'package:flutter_tools/src/cache.dart';
|
||||||
|
@ -15,52 +16,87 @@ import '../src/fake_process_manager.dart';
|
||||||
import '../src/fakes.dart';
|
import '../src/fakes.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
late BufferLogger logger;
|
|
||||||
|
|
||||||
Cache.flutterRoot = '';
|
Cache.flutterRoot = '';
|
||||||
|
|
||||||
setUp(() {
|
(BufferLogger, Artifacts) getTestState() => (BufferLogger.test(), Artifacts.test());
|
||||||
logger = BufferLogger.test();
|
|
||||||
});
|
|
||||||
|
|
||||||
testWithoutContext('DevtoolsLauncher launches DevTools from the SDK and saves the URI', () async {
|
testWithoutContext('DevtoolsLauncher launches DevTools from the SDK and saves the URI', () async {
|
||||||
|
final (BufferLogger logger, Artifacts artifacts) = getTestState();
|
||||||
final Completer<void> completer = Completer<void>();
|
final Completer<void> completer = Completer<void>();
|
||||||
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
||||||
dartExecutable: 'dart',
|
artifacts: artifacts,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
botDetector: const FakeBotDetector(false),
|
botDetector: const FakeBotDetector(false),
|
||||||
processManager: FakeProcessManager.list(<FakeCommand>[
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: const <String>[
|
command: const <String>[
|
||||||
'dart',
|
'Artifact.engineDartBinary',
|
||||||
'devtools',
|
'devtools',
|
||||||
'--no-launch-browser',
|
'--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,
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
expect(launcher.dtdUri, isNull);
|
||||||
|
expect(launcher.printDtdUri, false);
|
||||||
final DevToolsServerAddress? address = await launcher.serve();
|
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);
|
||||||
|
expect(launcher.dtdUri, isNull);
|
||||||
|
expect(launcher.printDtdUri, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('DevtoolsLauncher does not launch a new DevTools instance if one is already active', () async {
|
testWithoutContext('DevtoolsLauncher saves the Dart Tooling Daemon uri', () async {
|
||||||
|
final (BufferLogger logger, Artifacts artifacts) = getTestState();
|
||||||
final Completer<void> completer = Completer<void>();
|
final Completer<void> completer = Completer<void>();
|
||||||
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
||||||
dartExecutable: 'dart',
|
artifacts: artifacts,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
botDetector: const FakeBotDetector(false),
|
botDetector: const FakeBotDetector(false),
|
||||||
processManager: FakeProcessManager.list(<FakeCommand>[
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: const <String>[
|
command: const <String>[
|
||||||
'dart',
|
'Artifact.engineDartBinary',
|
||||||
|
'devtools',
|
||||||
|
'--no-launch-browser',
|
||||||
|
'--print-dtd',
|
||||||
|
],
|
||||||
|
stdout: '''
|
||||||
|
Serving the Dart Tooling Daemon at ws://127.0.0.1:53449/
|
||||||
|
Serving DevTools at http://127.0.0.1:9100.
|
||||||
|
''',
|
||||||
|
completer: completer,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
)..printDtdUri = true;
|
||||||
|
|
||||||
|
expect(launcher.dtdUri, isNull);
|
||||||
|
expect(launcher.printDtdUri, true);
|
||||||
|
final DevToolsServerAddress? address = await launcher.serve();
|
||||||
|
expect(address?.host, '127.0.0.1');
|
||||||
|
expect(address?.port, 9100);
|
||||||
|
expect(launcher.dtdUri?.toString(), 'ws://127.0.0.1:53449/');
|
||||||
|
expect(launcher.printDtdUri, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('DevtoolsLauncher does not launch a new DevTools instance if one is already active', () async {
|
||||||
|
final (BufferLogger logger, Artifacts artifacts) = getTestState();
|
||||||
|
final Completer<void> completer = Completer<void>();
|
||||||
|
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
||||||
|
artifacts: artifacts,
|
||||||
|
logger: logger,
|
||||||
|
botDetector: const FakeBotDetector(false),
|
||||||
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
||||||
|
FakeCommand(
|
||||||
|
command: const <String>[
|
||||||
|
'Artifact.engineDartBinary',
|
||||||
'devtools',
|
'devtools',
|
||||||
'--no-launch-browser',
|
'--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,
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
|
@ -70,27 +106,28 @@ void main() {
|
||||||
expect(address?.host, '127.0.0.1');
|
expect(address?.host, '127.0.0.1');
|
||||||
expect(address?.port, 9100);
|
expect(address?.port, 9100);
|
||||||
|
|
||||||
// Call `serve` again and verify that the already running server is returned.
|
// Call `serve` again and verify that the already-running server is returned.
|
||||||
address = await launcher.serve();
|
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 can launch devtools with a memory profile', () async {
|
testWithoutContext('DevtoolsLauncher can launch devtools with a memory profile', () async {
|
||||||
|
final (BufferLogger logger, Artifacts artifacts) = getTestState();
|
||||||
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
||||||
const FakeCommand(
|
const FakeCommand(
|
||||||
command: <String>[
|
command: <String>[
|
||||||
'dart',
|
'Artifact.engineDartBinary',
|
||||||
'devtools',
|
'devtools',
|
||||||
'--no-launch-browser',
|
'--no-launch-browser',
|
||||||
'--vm-uri=localhost:8181/abcdefg',
|
'--vm-uri=localhost:8181/abcdefg',
|
||||||
'--profile-memory=foo',
|
'--profile-memory=foo',
|
||||||
],
|
],
|
||||||
stdout: 'Serving DevTools at http://127.0.0.1:9100\n',
|
stdout: 'Serving DevTools at http://127.0.0.1:9100.\n',
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
||||||
dartExecutable: 'dart',
|
artifacts: artifacts,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
botDetector: const FakeBotDetector(false),
|
botDetector: const FakeBotDetector(false),
|
||||||
processManager: processManager,
|
processManager: processManager,
|
||||||
|
@ -103,14 +140,15 @@ 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, Artifacts artifacts) = getTestState();
|
||||||
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
final DevtoolsLauncher launcher = DevtoolsServerLauncher(
|
||||||
dartExecutable: 'dart',
|
artifacts: artifacts,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
botDetector: const FakeBotDetector(false),
|
botDetector: const FakeBotDetector(false),
|
||||||
processManager: FakeProcessManager.list(<FakeCommand>[
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
||||||
const FakeCommand(
|
const FakeCommand(
|
||||||
command: <String>[
|
command: <String>[
|
||||||
'dart',
|
'Artifact.engineDartBinary',
|
||||||
'devtools',
|
'devtools',
|
||||||
'--no-launch-browser',
|
'--no-launch-browser',
|
||||||
'--vm-uri=http://127.0.0.1:1234/abcdefg',
|
'--vm-uri=http://127.0.0.1:1234/abcdefg',
|
||||||
|
@ -126,19 +164,20 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('DevtoolsLauncher handles failure of DevTools process on a bot', () async {
|
testWithoutContext('DevtoolsLauncher handles failure of DevTools process on a bot', () async {
|
||||||
|
final (BufferLogger logger, Artifacts artifacts) = getTestState();
|
||||||
final Completer<void> completer = Completer<void>();
|
final Completer<void> completer = Completer<void>();
|
||||||
final DevtoolsServerLauncher launcher = DevtoolsServerLauncher(
|
final DevtoolsServerLauncher launcher = DevtoolsServerLauncher(
|
||||||
dartExecutable: 'dart',
|
artifacts: artifacts,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
botDetector: const FakeBotDetector(true),
|
botDetector: const FakeBotDetector(true),
|
||||||
processManager: FakeProcessManager.list(<FakeCommand>[
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: const <String>[
|
command: const <String>[
|
||||||
'dart',
|
'Artifact.engineDartBinary',
|
||||||
'devtools',
|
'devtools',
|
||||||
'--no-launch-browser',
|
'--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,
|
||||||
exitCode: 255,
|
exitCode: 255,
|
||||||
),
|
),
|
||||||
|
|
|
@ -28,7 +28,6 @@ import '../../src/context.dart';
|
||||||
import '../../src/fake_vm_services.dart';
|
import '../../src/fake_vm_services.dart';
|
||||||
import '../../src/fakes.dart';
|
import '../../src/fakes.dart';
|
||||||
|
|
||||||
|
|
||||||
final vm_service.Isolate fakeUnpausedIsolate = vm_service.Isolate(
|
final vm_service.Isolate fakeUnpausedIsolate = vm_service.Isolate(
|
||||||
id: '1',
|
id: '1',
|
||||||
pauseEvent: vm_service.Event(
|
pauseEvent: vm_service.Event(
|
||||||
|
@ -565,22 +564,3 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService
|
||||||
disposed = true;
|
disposed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeDevtoolsLauncher extends Fake implements DevtoolsLauncher {
|
|
||||||
bool closed = false;
|
|
||||||
final Completer<void> _processStarted = Completer<void>();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> launch(Uri vmServiceUri, {List<String>? additionalArguments}) {
|
|
||||||
_processStarted.complete();
|
|
||||||
return Completer<void>().future;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> get processStart => _processStarted.future;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
closed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter_tools/src/artifacts.dart';
|
||||||
import 'package:flutter_tools/src/base/dds.dart';
|
import 'package:flutter_tools/src/base/dds.dart';
|
||||||
import 'package:flutter_tools/src/base/logger.dart';
|
import 'package:flutter_tools/src/base/logger.dart';
|
||||||
import 'package:flutter_tools/src/build_info.dart';
|
import 'package:flutter_tools/src/build_info.dart';
|
||||||
|
@ -61,6 +62,8 @@ final FakeVmServiceRequest listViews = FakeVmServiceRequest(
|
||||||
void main() {
|
void main() {
|
||||||
Cache.flutterRoot = '';
|
Cache.flutterRoot = '';
|
||||||
|
|
||||||
|
(BufferLogger, Artifacts) getTestState() => (BufferLogger.test(), Artifacts.test());
|
||||||
|
|
||||||
testWithoutContext('Does not serve devtools if launcher is null', () async {
|
testWithoutContext('Does not serve devtools if launcher is null', () async {
|
||||||
final ResidentDevtoolsHandler handler = FlutterResidentDevtoolsHandler(
|
final ResidentDevtoolsHandler handler = FlutterResidentDevtoolsHandler(
|
||||||
null,
|
null,
|
||||||
|
@ -86,10 +89,11 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('Can use devtools with existing devtools URI', () async {
|
testWithoutContext('Can use devtools with existing devtools URI', () async {
|
||||||
|
final (BufferLogger logger, Artifacts artifacts) = getTestState();
|
||||||
final DevtoolsServerLauncher launcher = DevtoolsServerLauncher(
|
final DevtoolsServerLauncher launcher = DevtoolsServerLauncher(
|
||||||
processManager: FakeProcessManager.empty(),
|
processManager: FakeProcessManager.empty(),
|
||||||
dartExecutable: 'dart',
|
artifacts: artifacts,
|
||||||
logger: BufferLogger.test(),
|
logger: logger,
|
||||||
botDetector: const FakeBotDetector(false),
|
botDetector: const FakeBotDetector(false),
|
||||||
);
|
);
|
||||||
final ResidentDevtoolsHandler handler = FlutterResidentDevtoolsHandler(
|
final ResidentDevtoolsHandler handler = FlutterResidentDevtoolsHandler(
|
||||||
|
@ -429,22 +433,6 @@ void main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeDevtoolsLauncher extends Fake implements DevtoolsLauncher {
|
|
||||||
@override
|
|
||||||
DevToolsServerAddress? activeDevToolsServer;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Uri? devToolsUrl;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<DevToolsServerAddress?> serve() async => null;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> get ready => readyCompleter.future;
|
|
||||||
|
|
||||||
Completer<void> readyCompleter = Completer<void>()..complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
class FakeResidentRunner extends Fake implements ResidentRunner {
|
class FakeResidentRunner extends Fake implements ResidentRunner {
|
||||||
@override
|
@override
|
||||||
bool supportsServiceProtocol = true;
|
bool supportsServiceProtocol = true;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import 'package:flutter_tools/src/base/terminal.dart';
|
||||||
import 'package:flutter_tools/src/cache.dart';
|
import 'package:flutter_tools/src/cache.dart';
|
||||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||||
|
import 'package:flutter_tools/src/resident_runner.dart';
|
||||||
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
||||||
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
|
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
|
||||||
import 'package:flutter_tools/src/version.dart';
|
import 'package:flutter_tools/src/version.dart';
|
||||||
|
@ -175,116 +176,134 @@ void main() {
|
||||||
Analytics: () => fakeAnalytics,
|
Analytics: () => fakeAnalytics,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext("Doesn't crash on invalid .packages file", () async {
|
group('${FlutterGlobalOptions.kPrintDtd} flag', () {
|
||||||
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
testUsingContext('sets DevtoolsLauncher.printDtdUri to false when not present', () async {
|
||||||
fileSystem.file('pubspec.yaml').createSync();
|
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
||||||
fileSystem.file('.packages')
|
await runner.run(<String>[]);
|
||||||
..createSync()
|
expect(DevtoolsLauncher.instance!.printDtdUri, false);
|
||||||
..writeAsStringSync('Not a valid package');
|
}, overrides: <Type, Generator>{
|
||||||
|
DevtoolsLauncher: () => FakeDevtoolsLauncher()..dtdUri = Uri(),
|
||||||
|
});
|
||||||
|
|
||||||
await runner.run(<String>['dummy']);
|
testUsingContext('sets DevtoolsLauncher.printDtdUri to true when present', () async {
|
||||||
|
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
||||||
}, overrides: <Type, Generator>{
|
await runner.run(<String>['--${FlutterGlobalOptions.kPrintDtd}']);
|
||||||
FileSystem: () => fileSystem,
|
expect(DevtoolsLauncher.instance!.printDtdUri, true);
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
}, overrides: <Type, Generator>{
|
||||||
Platform: () => platform,
|
DevtoolsLauncher: () => FakeDevtoolsLauncher()..dtdUri = Uri(),
|
||||||
OutputPreferences: () => OutputPreferences.test(),
|
});
|
||||||
});
|
|
||||||
|
|
||||||
group('getRepoPackages', () {
|
|
||||||
late String? oldFlutterRoot;
|
|
||||||
|
|
||||||
setUp(() {
|
|
||||||
oldFlutterRoot = Cache.flutterRoot;
|
|
||||||
Cache.flutterRoot = _kFlutterRoot;
|
|
||||||
fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'examples'))
|
|
||||||
.createSync(recursive: true);
|
|
||||||
fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'packages'))
|
|
||||||
.createSync(recursive: true);
|
|
||||||
fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools', 'aatool'))
|
|
||||||
.createSync(recursive: true);
|
|
||||||
|
|
||||||
fileSystem.file(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools', 'pubspec.yaml'))
|
|
||||||
.createSync();
|
|
||||||
fileSystem.file(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools', 'aatool', 'pubspec.yaml'))
|
|
||||||
.createSync();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
testUsingContext("Doesn't crash on invalid .packages file", () async {
|
||||||
Cache.flutterRoot = oldFlutterRoot;
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('', () {
|
|
||||||
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
||||||
final List<String> packagePaths = runner.getRepoPackages()
|
fileSystem.file('pubspec.yaml').createSync();
|
||||||
.map((Directory d) => d.path).toList();
|
fileSystem.file('.packages')
|
||||||
expect(packagePaths, <String>[
|
..createSync()
|
||||||
fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools', 'aatool')).path,
|
..writeAsStringSync('Not a valid package');
|
||||||
fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools')).path,
|
|
||||||
]);
|
await runner.run(<String>['dummy']);
|
||||||
|
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
Platform: () => platform,
|
Platform: () => platform,
|
||||||
FlutterVersion: () => FakeFlutterVersion(),
|
|
||||||
OutputPreferences: () => OutputPreferences.test(),
|
OutputPreferences: () => OutputPreferences.test(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group('getRepoPackages', () {
|
||||||
|
late String? oldFlutterRoot;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
oldFlutterRoot = Cache.flutterRoot;
|
||||||
|
Cache.flutterRoot = _kFlutterRoot;
|
||||||
|
fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'examples'))
|
||||||
|
.createSync(recursive: true);
|
||||||
|
fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'packages'))
|
||||||
|
.createSync(recursive: true);
|
||||||
|
fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools', 'aatool'))
|
||||||
|
.createSync(recursive: true);
|
||||||
|
|
||||||
|
fileSystem.file(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools', 'pubspec.yaml'))
|
||||||
|
.createSync();
|
||||||
|
fileSystem.file(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools', 'aatool', 'pubspec.yaml'))
|
||||||
|
.createSync();
|
||||||
|
});
|
||||||
|
|
||||||
|
tearDown(() {
|
||||||
|
Cache.flutterRoot = oldFlutterRoot;
|
||||||
|
});
|
||||||
|
|
||||||
|
testUsingContext('', () {
|
||||||
|
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
||||||
|
final List<String> packagePaths = runner.getRepoPackages()
|
||||||
|
.map((Directory d) => d.path).toList();
|
||||||
|
expect(packagePaths, <String>[
|
||||||
|
fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools', 'aatool')).path,
|
||||||
|
fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools')).path,
|
||||||
|
]);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fileSystem,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
Platform: () => platform,
|
||||||
|
FlutterVersion: () => FakeFlutterVersion(),
|
||||||
|
OutputPreferences: () => OutputPreferences.test(),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('wrapping', () {
|
||||||
|
testUsingContext('checks that output wrapping is turned on when writing to a terminal', () async {
|
||||||
|
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
||||||
|
final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
|
||||||
|
runner.addCommand(fakeCommand);
|
||||||
|
await runner.run(<String>['fake']);
|
||||||
|
expect(fakeCommand.preferences.wrapText, isTrue);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fileSystem,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
Stdio: () => FakeStdio(hasFakeTerminal: true),
|
||||||
|
OutputPreferences: () => OutputPreferences.test(),
|
||||||
|
}, initializeFlutterRoot: false);
|
||||||
|
|
||||||
|
testUsingContext('checks that output wrapping is turned off when not writing to a terminal', () async {
|
||||||
|
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
||||||
|
final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
|
||||||
|
runner.addCommand(fakeCommand);
|
||||||
|
await runner.run(<String>['fake']);
|
||||||
|
expect(fakeCommand.preferences.wrapText, isFalse);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fileSystem,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
Stdio: () => FakeStdio(hasFakeTerminal: false),
|
||||||
|
OutputPreferences: () => OutputPreferences.test(),
|
||||||
|
}, initializeFlutterRoot: false);
|
||||||
|
|
||||||
|
testUsingContext('checks that output wrapping is turned off when set on the command line and writing to a terminal', () async {
|
||||||
|
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
||||||
|
final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
|
||||||
|
runner.addCommand(fakeCommand);
|
||||||
|
await runner.run(<String>['--no-wrap', 'fake']);
|
||||||
|
expect(fakeCommand.preferences.wrapText, isFalse);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fileSystem,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
Stdio: () => FakeStdio(hasFakeTerminal: true),
|
||||||
|
OutputPreferences: () => OutputPreferences.test(),
|
||||||
|
}, initializeFlutterRoot: false);
|
||||||
|
|
||||||
|
testUsingContext('checks that output wrapping is turned on when set on the command line, but not writing to a terminal', () async {
|
||||||
|
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
||||||
|
final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
|
||||||
|
runner.addCommand(fakeCommand);
|
||||||
|
await runner.run(<String>['--wrap', 'fake']);
|
||||||
|
expect(fakeCommand.preferences.wrapText, isTrue);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fileSystem,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
Stdio: () => FakeStdio(hasFakeTerminal: false),
|
||||||
|
OutputPreferences: () => OutputPreferences.test(),
|
||||||
|
}, initializeFlutterRoot: false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('wrapping', () {
|
|
||||||
testUsingContext('checks that output wrapping is turned on when writing to a terminal', () async {
|
|
||||||
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
|
||||||
final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
|
|
||||||
runner.addCommand(fakeCommand);
|
|
||||||
await runner.run(<String>['fake']);
|
|
||||||
expect(fakeCommand.preferences.wrapText, isTrue);
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
FileSystem: () => fileSystem,
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
Stdio: () => FakeStdio(hasFakeTerminal: true),
|
|
||||||
OutputPreferences: () => OutputPreferences.test(),
|
|
||||||
}, initializeFlutterRoot: false);
|
|
||||||
|
|
||||||
testUsingContext('checks that output wrapping is turned off when not writing to a terminal', () async {
|
|
||||||
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
|
||||||
final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
|
|
||||||
runner.addCommand(fakeCommand);
|
|
||||||
await runner.run(<String>['fake']);
|
|
||||||
expect(fakeCommand.preferences.wrapText, isFalse);
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
FileSystem: () => fileSystem,
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
Stdio: () => FakeStdio(hasFakeTerminal: false),
|
|
||||||
OutputPreferences: () => OutputPreferences.test(),
|
|
||||||
}, initializeFlutterRoot: false);
|
|
||||||
|
|
||||||
testUsingContext('checks that output wrapping is turned off when set on the command line and writing to a terminal', () async {
|
|
||||||
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
|
||||||
final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
|
|
||||||
runner.addCommand(fakeCommand);
|
|
||||||
await runner.run(<String>['--no-wrap', 'fake']);
|
|
||||||
expect(fakeCommand.preferences.wrapText, isFalse);
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
FileSystem: () => fileSystem,
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
Stdio: () => FakeStdio(hasFakeTerminal: true),
|
|
||||||
OutputPreferences: () => OutputPreferences.test(),
|
|
||||||
}, initializeFlutterRoot: false);
|
|
||||||
|
|
||||||
testUsingContext('checks that output wrapping is turned on when set on the command line, but not writing to a terminal', () async {
|
|
||||||
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
|
|
||||||
final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
|
|
||||||
runner.addCommand(fakeCommand);
|
|
||||||
await runner.run(<String>['--wrap', 'fake']);
|
|
||||||
expect(fakeCommand.preferences.wrapText, isTrue);
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
FileSystem: () => fileSystem,
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
Stdio: () => FakeStdio(hasFakeTerminal: false),
|
|
||||||
OutputPreferences: () => OutputPreferences.test(),
|
|
||||||
}, initializeFlutterRoot: false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import 'package:flutter_tools/src/convert.dart';
|
||||||
import 'package:flutter_tools/src/features.dart';
|
import 'package:flutter_tools/src/features.dart';
|
||||||
import 'package:flutter_tools/src/ios/plist_parser.dart';
|
import 'package:flutter_tools/src/ios/plist_parser.dart';
|
||||||
import 'package:flutter_tools/src/project.dart';
|
import 'package:flutter_tools/src/project.dart';
|
||||||
|
import 'package:flutter_tools/src/resident_runner.dart';
|
||||||
import 'package:flutter_tools/src/version.dart';
|
import 'package:flutter_tools/src/version.dart';
|
||||||
import 'package:test/fake.dart';
|
import 'package:test/fake.dart';
|
||||||
|
|
||||||
|
@ -686,3 +687,48 @@ class FakeJava extends Fake implements Java {
|
||||||
return _canRun;
|
return _canRun;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FakeDevtoolsLauncher extends Fake implements DevtoolsLauncher {
|
||||||
|
FakeDevtoolsLauncher({DevToolsServerAddress? serverAddress})
|
||||||
|
: _serverAddress = serverAddress;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> get processStart => _processStarted.future;
|
||||||
|
|
||||||
|
final Completer<void> _processStarted = Completer<void>();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> get ready => readyCompleter.future;
|
||||||
|
|
||||||
|
Completer<void> readyCompleter = Completer<void>()..complete();
|
||||||
|
|
||||||
|
@override
|
||||||
|
DevToolsServerAddress? activeDevToolsServer;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Uri? devToolsUrl;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Uri? dtdUri;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool printDtdUri = false;
|
||||||
|
|
||||||
|
final DevToolsServerAddress? _serverAddress;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<DevToolsServerAddress?> serve() async => _serverAddress;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> launch(Uri vmServiceUri, {List<String>? additionalArguments}) {
|
||||||
|
_processStarted.complete();
|
||||||
|
return Completer<void>().future;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool closed = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
closed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue