Unverified Commit eea60f86 authored by Jesús S Guerrero's avatar Jesús S Guerrero Committed by GitHub

Dependency injection Attach command (#113227)

parent 9995e370
...@@ -154,7 +154,17 @@ List<FlutterCommand> generateCommands({ ...@@ -154,7 +154,17 @@ List<FlutterCommand> generateCommands({
], ],
), ),
AssembleCommand(verboseHelp: verboseHelp, buildSystem: globals.buildSystem), AssembleCommand(verboseHelp: verboseHelp, buildSystem: globals.buildSystem),
AttachCommand(verboseHelp: verboseHelp), AttachCommand(
verboseHelp: verboseHelp,
artifacts: globals.artifacts,
stdio: globals.stdio,
logger: globals.logger,
terminal: globals.terminal,
signals: globals.signals,
platform: globals.platform,
processInfo: globals.processInfo,
fileSystem: globals.fs,
),
BuildCommand(verboseHelp: verboseHelp), BuildCommand(verboseHelp: verboseHelp),
ChannelCommand(verboseHelp: verboseHelp), ChannelCommand(verboseHelp: verboseHelp),
CleanCommand(verbose: verbose), CleanCommand(verbose: verbose),
......
...@@ -12,6 +12,10 @@ import '../base/common.dart'; ...@@ -12,6 +12,10 @@ import '../base/common.dart';
import '../base/context.dart'; import '../base/context.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/io.dart'; import '../base/io.dart';
import '../base/logger.dart';
import '../base/platform.dart';
import '../base/signals.dart';
import '../base/terminal.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../commands/daemon.dart'; import '../commands/daemon.dart';
import '../compile.dart'; import '../compile.dart';
...@@ -19,7 +23,6 @@ import '../daemon.dart'; ...@@ -19,7 +23,6 @@ import '../daemon.dart';
import '../device.dart'; import '../device.dart';
import '../device_port_forwarder.dart'; import '../device_port_forwarder.dart';
import '../fuchsia/fuchsia_device.dart'; import '../fuchsia/fuchsia_device.dart';
import '../globals.dart' as globals;
import '../ios/devices.dart'; import '../ios/devices.dart';
import '../ios/simulators.dart'; import '../ios/simulators.dart';
import '../macos/macos_ipad_device.dart'; import '../macos/macos_ipad_device.dart';
...@@ -58,7 +61,26 @@ import '../vmservice.dart'; ...@@ -58,7 +61,26 @@ import '../vmservice.dart';
/// To attach to a flutter mod running on a fuchsia device, `--module` must /// To attach to a flutter mod running on a fuchsia device, `--module` must
/// also be provided. /// also be provided.
class AttachCommand extends FlutterCommand { class AttachCommand extends FlutterCommand {
AttachCommand({bool verboseHelp = false, this.hotRunnerFactory}) { AttachCommand({
bool verboseHelp = false,
HotRunnerFactory? hotRunnerFactory,
required Artifacts? artifacts,
required Stdio stdio,
required Logger logger,
required Terminal terminal,
required Signals signals,
required Platform platform,
required ProcessInfo processInfo,
required FileSystem fileSystem,
}): _artifacts = artifacts,
_hotRunnerFactory = hotRunnerFactory ?? HotRunnerFactory(),
_stdio = stdio,
_logger = logger,
_terminal = terminal,
_signals = signals,
_platform = platform,
_processInfo = processInfo,
_fileSystem = fileSystem {
addBuildModeFlags(verboseHelp: verboseHelp, defaultToRelease: false, excludeRelease: true); addBuildModeFlags(verboseHelp: verboseHelp, defaultToRelease: false, excludeRelease: true);
usesTargetOption(); usesTargetOption();
usesPortOptions(verboseHelp: verboseHelp); usesPortOptions(verboseHelp: verboseHelp);
...@@ -117,10 +139,17 @@ class AttachCommand extends FlutterCommand { ...@@ -117,10 +139,17 @@ class AttachCommand extends FlutterCommand {
addDdsOptions(verboseHelp: verboseHelp); addDdsOptions(verboseHelp: verboseHelp);
addDevToolsOptions(verboseHelp: verboseHelp); addDevToolsOptions(verboseHelp: verboseHelp);
usesDeviceTimeoutOption(); usesDeviceTimeoutOption();
hotRunnerFactory ??= HotRunnerFactory();
} }
HotRunnerFactory? hotRunnerFactory; final HotRunnerFactory _hotRunnerFactory;
final Artifacts? _artifacts;
final Stdio _stdio;
final Logger _logger;
final Terminal _terminal;
final Signals _signals;
final Platform _platform;
final ProcessInfo _processInfo;
final FileSystem _fileSystem;
@override @override
final String name = 'attach'; final String name = 'attach';
...@@ -221,7 +250,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. ...@@ -221,7 +250,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
throwToolExit('Did not find any valid target devices.'); throwToolExit('Did not find any valid target devices.');
} }
final Artifacts? overrideArtifacts = device.artifactOverrides ?? globals.artifacts; final Artifacts? overrideArtifacts = device.artifactOverrides ?? _artifacts;
await context.run<void>( await context.run<void>(
body: () => _attachToDevice(device), body: () => _attachToDevice(device),
overrides: <Type, Generator>{ overrides: <Type, Generator>{
...@@ -238,12 +267,12 @@ known, it can be explicitly provided to attach via the command-line, e.g. ...@@ -238,12 +267,12 @@ known, it can be explicitly provided to attach via the command-line, e.g.
final Daemon? daemon = boolArgDeprecated('machine') final Daemon? daemon = boolArgDeprecated('machine')
? Daemon( ? Daemon(
DaemonConnection( DaemonConnection(
daemonStreams: DaemonStreams.fromStdio(globals.stdio, logger: globals.logger), daemonStreams: DaemonStreams.fromStdio(_stdio, logger: _logger),
logger: globals.logger, logger: _logger,
), ),
notifyingLogger: (globals.logger is NotifyingLogger) notifyingLogger: (_logger is NotifyingLogger)
? globals.logger as NotifyingLogger ? _logger as NotifyingLogger
: NotifyingLogger(verbose: globals.logger.isVerbose, parent: globals.logger), : NotifyingLogger(verbose: _logger.isVerbose, parent: _logger),
logToStdout: true, logToStdout: true,
) )
: null; : null;
...@@ -296,9 +325,9 @@ known, it can be explicitly provided to attach via the command-line, e.g. ...@@ -296,9 +325,9 @@ known, it can be explicitly provided to attach via the command-line, e.g.
ipv6: ipv6!, ipv6: ipv6!,
devicePort: deviceVmservicePort, devicePort: deviceVmservicePort,
hostPort: hostVmservicePort, hostPort: hostVmservicePort,
logger: globals.logger, logger: _logger,
); );
globals.printStatus('Waiting for a connection from Flutter on ${device.name}...'); _logger.printStatus('Waiting for a connection from Flutter on ${device.name}...');
observatoryUri = observatoryDiscovery.uris; observatoryUri = observatoryDiscovery.uris;
// Determine ipv6 status from the scanned logs. // Determine ipv6 status from the scanned logs.
usesIpv6 = observatoryDiscovery.ipv6; usesIpv6 = observatoryDiscovery.ipv6;
...@@ -316,7 +345,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. ...@@ -316,7 +345,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
).asBroadcastStream(); ).asBroadcastStream();
} }
globals.terminal.usesTerminalUi = daemon == null; _terminal.usesTerminalUi = daemon == null;
try { try {
int? result; int? result;
...@@ -343,9 +372,9 @@ known, it can be explicitly provided to attach via the command-line, e.g. ...@@ -343,9 +372,9 @@ known, it can be explicitly provided to attach via the command-line, e.g.
device, device,
null, null,
true, true,
globals.fs.currentDirectory, _fileSystem.currentDirectory,
LaunchMode.attach, LaunchMode.attach,
globals.logger as AppRunLogger, _logger as AppRunLogger,
); );
} on Exception catch (error) { } on Exception catch (error) {
throwToolExit(error.toString()); throwToolExit(error.toString());
...@@ -366,10 +395,10 @@ known, it can be explicitly provided to attach via the command-line, e.g. ...@@ -366,10 +395,10 @@ known, it can be explicitly provided to attach via the command-line, e.g.
unawaited(onAppStart.future.whenComplete(() { unawaited(onAppStart.future.whenComplete(() {
terminalHandler = TerminalHandler( terminalHandler = TerminalHandler(
runner, runner,
logger: globals.logger, logger: _logger,
terminal: globals.terminal, terminal: _terminal,
signals: globals.signals, signals: _signals,
processInfo: globals.processInfo, processInfo: _processInfo,
reportReady: boolArgDeprecated('report-ready'), reportReady: boolArgDeprecated('report-ready'),
pidFile: stringArgDeprecated('pid-file'), pidFile: stringArgDeprecated('pid-file'),
) )
...@@ -389,7 +418,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. ...@@ -389,7 +418,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
if (runner.exited || !runner.isWaitingForObservatory) { if (runner.exited || !runner.isWaitingForObservatory) {
break; break;
} }
globals.printStatus('Waiting for a new connection from Flutter on ${device.name}...'); _logger.printStatus('Waiting for a new connection from Flutter on ${device.name}...');
} }
} on RPCError catch (err) { } on RPCError catch (err) {
if (err.code == RPCErrorCodes.kServiceDisappeared) { if (err.code == RPCErrorCodes.kServiceDisappeared) {
...@@ -422,7 +451,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. ...@@ -422,7 +451,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
targetModel: TargetModel(stringArgDeprecated('target-model')!), targetModel: TargetModel(stringArgDeprecated('target-model')!),
buildInfo: buildInfo, buildInfo: buildInfo,
userIdentifier: userIdentifier, userIdentifier: userIdentifier,
platform: globals.platform, platform: _platform,
); );
flutterDevice.observatoryUris = observatoryUris; flutterDevice.observatoryUris = observatoryUris;
final List<FlutterDevice> flutterDevices = <FlutterDevice>[flutterDevice]; final List<FlutterDevice> flutterDevices = <FlutterDevice>[flutterDevice];
...@@ -434,7 +463,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. ...@@ -434,7 +463,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
); );
return buildInfo.isDebug return buildInfo.isDebug
? hotRunnerFactory!.build( ? _hotRunnerFactory.build(
flutterDevices, flutterDevices,
target: targetFile, target: targetFile,
debuggingOptions: debuggingOptions, debuggingOptions: debuggingOptions,
......
...@@ -13,13 +13,14 @@ import 'package:flutter_tools/src/base/dds.dart'; ...@@ -13,13 +13,14 @@ import 'package:flutter_tools/src/base/dds.dart';
import 'package:flutter_tools/src/base/file_system.dart'; 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/base/signals.dart';
import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/attach.dart'; import 'package:flutter_tools/src/commands/attach.dart';
import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/device_port_forwarder.dart'; import 'package:flutter_tools/src/device_port_forwarder.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/ios/application_package.dart'; import 'package:flutter_tools/src/ios/application_package.dart';
import 'package:flutter_tools/src/ios/devices.dart'; import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/macos/macos_ipad_device.dart'; import 'package:flutter_tools/src/macos/macos_ipad_device.dart';
...@@ -38,6 +39,16 @@ import '../../src/context.dart'; ...@@ -38,6 +39,16 @@ import '../../src/context.dart';
import '../../src/fake_devices.dart'; import '../../src/fake_devices.dart';
import '../../src/test_flutter_command_runner.dart'; import '../../src/test_flutter_command_runner.dart';
class FakeStdio extends Fake implements Stdio {
@override
bool stdinHasTerminal = false;
}
class FakeProcessInfo extends Fake implements ProcessInfo {
@override
int maxRss = 0;
}
void main() { void main() {
tearDown(() { tearDown(() {
MacOSDesignedForIPadDevices.allowDiscovery = false; MacOSDesignedForIPadDevices.allowDiscovery = false;
...@@ -47,17 +58,25 @@ void main() { ...@@ -47,17 +58,25 @@ void main() {
late StreamLogger logger; late StreamLogger logger;
late FileSystem testFileSystem; late FileSystem testFileSystem;
late TestDeviceManager testDeviceManager; late TestDeviceManager testDeviceManager;
late Artifacts artifacts;
late Stdio stdio;
late Terminal terminal;
late Signals signals;
late Platform platform;
late ProcessInfo processInfo;
setUp(() { setUp(() {
Cache.disableLocking(); Cache.disableLocking();
logger = StreamLogger(); logger = StreamLogger();
testFileSystem = MemoryFileSystem( platform = FakePlatform();
style: globals.platform.isWindows testFileSystem = MemoryFileSystem.test();
? FileSystemStyle.windows
: FileSystemStyle.posix,
);
testFileSystem.directory('lib').createSync(); testFileSystem.directory('lib').createSync();
testFileSystem.file(testFileSystem.path.join('lib', 'main.dart')).createSync(); testFileSystem.file(testFileSystem.path.join('lib', 'main.dart')).createSync();
artifacts = Artifacts.test();
stdio = FakeStdio();
terminal = FakeTerminal();
signals = Signals.test();
processInfo = FakeProcessInfo();
testDeviceManager = TestDeviceManager(logger: BufferLogger.test()); testDeviceManager = TestDeviceManager(logger: BufferLogger.test());
}); });
...@@ -102,7 +121,16 @@ void main() { ...@@ -102,7 +121,16 @@ void main() {
completer.complete(); completer.complete();
} }
}); });
final Future<void> task = createTestCommandRunner(AttachCommand()).run(<String>['attach']); final Future<void> task = createTestCommandRunner(AttachCommand(
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
)).run(<String>['attach']);
await completer.future; await completer.future;
expect(portForwarder.devicePort, devicePort); expect(portForwarder.devicePort, devicePort);
...@@ -137,7 +165,16 @@ void main() { ...@@ -137,7 +165,16 @@ void main() {
completer.complete(); completer.complete();
} }
}); });
final Future<void> task = createTestCommandRunner(AttachCommand()).run(<String>['attach']); final Future<void> task = createTestCommandRunner(AttachCommand(
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
)).run(<String>['attach']);
await completer.future; await completer.future;
expect(portForwarder.devicePort, devicePort); expect(portForwarder.devicePort, devicePort);
...@@ -161,7 +198,16 @@ void main() { ...@@ -161,7 +198,16 @@ void main() {
return fakeLogReader; return fakeLogReader;
}; };
testDeviceManager.devices = <Device>[device]; testDeviceManager.devices = <Device>[device];
expect(() => createTestCommandRunner(AttachCommand()).run(<String>['attach']), throwsToolExit()); expect(() => createTestCommandRunner(AttachCommand(
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
)).run(<String>['attach']), throwsToolExit());
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => testFileSystem, FileSystem: () => testFileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
...@@ -197,6 +243,14 @@ void main() { ...@@ -197,6 +243,14 @@ void main() {
final AttachCommand command = AttachCommand( final AttachCommand command = AttachCommand(
hotRunnerFactory: hotRunnerFactory, hotRunnerFactory: hotRunnerFactory,
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
); );
await createTestCommandRunner(command).run(<String>[ await createTestCommandRunner(command).run(<String>[
'attach', 'attach',
...@@ -232,7 +286,16 @@ void main() { ...@@ -232,7 +286,16 @@ void main() {
testUsingContext('exits when ipv6 is specified and debug-port is not', () async { testUsingContext('exits when ipv6 is specified and debug-port is not', () async {
testDeviceManager.devices = <Device>[device]; testDeviceManager.devices = <Device>[device];
final AttachCommand command = AttachCommand(); final AttachCommand command = AttachCommand(
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
);
await expectLater( await expectLater(
createTestCommandRunner(command).run(<String>['attach', '--ipv6']), createTestCommandRunner(command).run(<String>['attach', '--ipv6']),
throwsToolExit( throwsToolExit(
...@@ -254,7 +317,16 @@ void main() { ...@@ -254,7 +317,16 @@ void main() {
}; };
testDeviceManager.devices = <Device>[device]; testDeviceManager.devices = <Device>[device];
final AttachCommand command = AttachCommand(); final AttachCommand command = AttachCommand(
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
);
await expectLater( await expectLater(
createTestCommandRunner(command).run(<String>['attach', '--observatory-port', '100']), createTestCommandRunner(command).run(<String>['attach', '--observatory-port', '100']),
throwsToolExit( throwsToolExit(
...@@ -294,7 +366,16 @@ void main() { ...@@ -294,7 +366,16 @@ void main() {
completer.complete(); completer.complete();
} }
}); });
final Future<void> task = createTestCommandRunner(AttachCommand()) final Future<void> task = createTestCommandRunner(AttachCommand(
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
))
.run(<String>['attach', '--debug-port', '$devicePort']); .run(<String>['attach', '--debug-port', '$devicePort']);
await completer.future; await completer.future;
expect(portForwarder.devicePort, devicePort); expect(portForwarder.devicePort, devicePort);
...@@ -320,7 +401,16 @@ void main() { ...@@ -320,7 +401,16 @@ void main() {
completer.complete(); completer.complete();
} }
}); });
final Future<void> task = createTestCommandRunner(AttachCommand()) final Future<void> task = createTestCommandRunner(AttachCommand(
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
))
.run(<String>['attach', '--debug-port', '$devicePort', '--ipv6']); .run(<String>['attach', '--debug-port', '$devicePort', '--ipv6']);
await completer.future; await completer.future;
...@@ -347,7 +437,16 @@ void main() { ...@@ -347,7 +437,16 @@ void main() {
completer.complete(); completer.complete();
} }
}); });
final Future<void> task = createTestCommandRunner(AttachCommand()).run( final Future<void> task = createTestCommandRunner(AttachCommand(
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
)).run(
<String>[ <String>[
'attach', 'attach',
'--debug-port', '--debug-port',
...@@ -383,7 +482,16 @@ void main() { ...@@ -383,7 +482,16 @@ void main() {
completer.complete(); completer.complete();
} }
}); });
final Future<void> task = createTestCommandRunner(AttachCommand()).run( final Future<void> task = createTestCommandRunner(AttachCommand(
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
)).run(
<String>[ <String>[
'attach', 'attach',
'--debug-port', '--debug-port',
...@@ -411,7 +519,16 @@ void main() { ...@@ -411,7 +519,16 @@ void main() {
}); });
testUsingContext('exits when no device connected', () async { testUsingContext('exits when no device connected', () async {
final AttachCommand command = AttachCommand(); final AttachCommand command = AttachCommand(
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
);
await expectLater( await expectLater(
createTestCommandRunner(command).run(<String>['attach']), createTestCommandRunner(command).run(<String>['attach']),
throwsToolExit(), throwsToolExit(),
...@@ -426,7 +543,16 @@ void main() { ...@@ -426,7 +543,16 @@ void main() {
testUsingContext('fails when targeted device is not Android with --device-user', () async { testUsingContext('fails when targeted device is not Android with --device-user', () async {
final FakeIOSDevice device = FakeIOSDevice(); final FakeIOSDevice device = FakeIOSDevice();
testDeviceManager.devices = <Device>[device]; testDeviceManager.devices = <Device>[device];
expect(createTestCommandRunner(AttachCommand()).run(<String>[ expect(createTestCommandRunner(AttachCommand(
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
)).run(<String>[
'attach', 'attach',
'--device-user', '--device-user',
'10', '10',
...@@ -438,7 +564,16 @@ void main() { ...@@ -438,7 +564,16 @@ void main() {
}); });
testUsingContext('exits when multiple devices connected', () async { testUsingContext('exits when multiple devices connected', () async {
final AttachCommand command = AttachCommand(); final AttachCommand command = AttachCommand(
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
);
testDeviceManager.devices = <Device>[ testDeviceManager.devices = <Device>[
FakeAndroidDevice(id: 'xx1'), FakeAndroidDevice(id: 'xx1'),
FakeAndroidDevice(id: 'yy2'), FakeAndroidDevice(id: 'yy2'),
...@@ -478,7 +613,17 @@ void main() { ...@@ -478,7 +613,17 @@ void main() {
testDeviceManager.devices = <Device>[device]; testDeviceManager.devices = <Device>[device];
testFileSystem.file('lib/main.dart').createSync(); testFileSystem.file('lib/main.dart').createSync();
final AttachCommand command = AttachCommand(hotRunnerFactory: hotRunnerFactory); final AttachCommand command = AttachCommand(
hotRunnerFactory: hotRunnerFactory,
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
);
await expectLater(createTestCommandRunner(command).run(<String>[ await expectLater(createTestCommandRunner(command).run(<String>[
'attach', 'attach',
]), throwsToolExit(message: 'Lost connection to device.')); ]), throwsToolExit(message: 'Lost connection to device.'));
...@@ -509,7 +654,17 @@ void main() { ...@@ -509,7 +654,17 @@ void main() {
testDeviceManager.devices = <Device>[device]; testDeviceManager.devices = <Device>[device];
testFileSystem.file('lib/main.dart').createSync(); testFileSystem.file('lib/main.dart').createSync();
final AttachCommand command = AttachCommand(hotRunnerFactory: hotRunnerFactory); final AttachCommand command = AttachCommand(
hotRunnerFactory: hotRunnerFactory,
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
);
await expectLater(createTestCommandRunner(command).run(<String>[ await expectLater(createTestCommandRunner(command).run(<String>[
'attach', 'attach',
]), throwsA(isA<vm_service.RPCError>())); ]), throwsA(isA<vm_service.RPCError>()));
...@@ -709,7 +864,7 @@ class StreamLogger extends Logger { ...@@ -709,7 +864,7 @@ class StreamLogger extends Logger {
bool get hasTerminal => false; bool get hasTerminal => false;
@override @override
void clear() => _log('[stdout] ${globals.terminal.clearScreen()}\n'); void clear() => _log('[stdout] ${terminal.clearScreen()}\n');
@override @override
Terminal get terminal => Terminal.test(); Terminal get terminal => Terminal.test();
...@@ -936,4 +1091,7 @@ class FakeTerminal extends Fake implements AnsiTerminal { ...@@ -936,4 +1091,7 @@ class FakeTerminal extends Fake implements AnsiTerminal {
@override @override
final bool stdinHasTerminal; final bool stdinHasTerminal;
@override
bool usesTerminalUi = false;
} }
...@@ -4,7 +4,16 @@ ...@@ -4,7 +4,16 @@
import 'package:args/args.dart'; import 'package:args/args.dart';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/signals.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/commands/attach.dart'; import 'package:flutter_tools/src/commands/attach.dart';
import 'package:flutter_tools/src/commands/build.dart'; import 'package:flutter_tools/src/commands/build.dart';
import 'package:flutter_tools/src/commands/build_aar.dart'; import 'package:flutter_tools/src/commands/build_aar.dart';
...@@ -16,17 +25,33 @@ import 'package:flutter_tools/src/commands/build_linux.dart'; ...@@ -16,17 +25,33 @@ import 'package:flutter_tools/src/commands/build_linux.dart';
import 'package:flutter_tools/src/commands/build_macos.dart'; import 'package:flutter_tools/src/commands/build_macos.dart';
import 'package:flutter_tools/src/commands/build_web.dart'; import 'package:flutter_tools/src/commands/build_web.dart';
import 'package:flutter_tools/src/commands/build_windows.dart'; import 'package:flutter_tools/src/commands/build_windows.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/runner/flutter_command.dart'; import 'package:flutter_tools/src/runner/flutter_command.dart';
import 'package:test/fake.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/context.dart';
import '../../src/fakes.dart';
class FakeTerminal extends Fake implements AnsiTerminal {
FakeTerminal({this.stdinHasTerminal = true});
@override
final bool stdinHasTerminal;
}
class FakeProcessInfo extends Fake implements ProcessInfo {
@override
int maxRss = 0;
}
void main() { void main() {
testUsingContext('All build commands support null safety options', () { testUsingContext('All build commands support null safety options', () {
final FileSystem fileSystem = MemoryFileSystem.test();
final Platform platform = FakePlatform();
final BufferLogger logger = BufferLogger.test();
final List<FlutterCommand> commands = <FlutterCommand>[ final List<FlutterCommand> commands = <FlutterCommand>[
BuildWindowsCommand(), BuildWindowsCommand(),
BuildLinuxCommand(operatingSystemUtils: globals.os), BuildLinuxCommand(operatingSystemUtils: FakeOperatingSystemUtils()),
BuildMacosCommand(verboseHelp: false), BuildMacosCommand(verboseHelp: false),
BuildWebCommand(verboseHelp: false), BuildWebCommand(verboseHelp: false),
BuildApkCommand(), BuildApkCommand(),
...@@ -36,9 +61,22 @@ void main() { ...@@ -36,9 +61,22 @@ void main() {
BuildAarCommand(verboseHelp: false), BuildAarCommand(verboseHelp: false),
BuildIOSFrameworkCommand( BuildIOSFrameworkCommand(
verboseHelp: false, verboseHelp: false,
buildSystem: globals.buildSystem, buildSystem: FlutterBuildSystem(
fileSystem: fileSystem,
platform: platform,
logger: logger,
),
),
AttachCommand(
artifacts: Artifacts.test(),
stdio: FakeStdio(),
logger: logger,
terminal: FakeTerminal(),
signals: Signals.test(),
platform: platform,
processInfo: FakeProcessInfo(),
fileSystem: MemoryFileSystem.test(),
), ),
AttachCommand(),
]; ];
for (final FlutterCommand command in commands) { for (final FlutterCommand command in commands) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment