Unverified Commit 9f040865 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] macOS cleanups, attach to log reader in release mode (#61913)

parent 93ca301a
...@@ -142,6 +142,10 @@ Future<T> runInContext<T>( ...@@ -142,6 +142,10 @@ Future<T> runInContext<T>(
config: globals.config, config: globals.config,
fuchsiaWorkflow: fuchsiaWorkflow, fuchsiaWorkflow: fuchsiaWorkflow,
xcDevice: globals.xcdevice, xcDevice: globals.xcdevice,
macOSWorkflow: MacOSWorkflow(
platform: globals.platform,
featureFlags: featureFlags,
),
), ),
Doctor: () => Doctor(logger: globals.logger), Doctor: () => Doctor(logger: globals.logger),
DoctorValidatorsProvider: () => DoctorValidatorsProvider.defaultInstance, DoctorValidatorsProvider: () => DoctorValidatorsProvider.defaultInstance,
...@@ -193,7 +197,10 @@ Future<T> runInContext<T>( ...@@ -193,7 +197,10 @@ Future<T> runInContext<T>(
outputPreferences: globals.outputPreferences, outputPreferences: globals.outputPreferences,
timeoutConfiguration: timeoutConfiguration, timeoutConfiguration: timeoutConfiguration,
), ),
MacOSWorkflow: () => const MacOSWorkflow(), MacOSWorkflow: () => MacOSWorkflow(
featureFlags: featureFlags,
platform: globals.platform,
),
MDnsObservatoryDiscovery: () => MDnsObservatoryDiscovery(), MDnsObservatoryDiscovery: () => MDnsObservatoryDiscovery(),
OperatingSystemUtils: () => OperatingSystemUtils( OperatingSystemUtils: () => OperatingSystemUtils(
fileSystem: globals.fs, fileSystem: globals.fs,
......
...@@ -5,10 +5,12 @@ ...@@ -5,10 +5,12 @@
import 'dart:async'; import 'dart:async';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:process/process.dart';
import 'application_package.dart'; import 'application_package.dart';
import 'base/common.dart'; import 'base/common.dart';
import 'base/io.dart'; import 'base/io.dart';
import 'base/logger.dart';
import 'build_info.dart'; import 'build_info.dart';
import 'convert.dart'; import 'convert.dart';
import 'device.dart'; import 'device.dart';
...@@ -18,15 +20,23 @@ import 'protocol_discovery.dart'; ...@@ -18,15 +20,23 @@ import 'protocol_discovery.dart';
/// A partial implementation of Device for desktop-class devices to inherit /// A partial implementation of Device for desktop-class devices to inherit
/// from, containing implementations that are common to all desktop devices. /// from, containing implementations that are common to all desktop devices.
abstract class DesktopDevice extends Device { abstract class DesktopDevice extends Device {
DesktopDevice(String identifier, {@required PlatformType platformType, @required bool ephemeral}) : super( DesktopDevice(String identifier, {
identifier, @required PlatformType platformType,
category: Category.desktop, @required bool ephemeral,
platformType: platformType, Logger logger,
ephemeral: ephemeral, ProcessManager processManager,
); }) : _logger = logger ?? globals.logger, // TODO(jonahwilliams): remove after updating google3
_processManager = processManager ?? globals.processManager,
super(
identifier,
category: Category.desktop,
platformType: platformType,
ephemeral: ephemeral,
);
final Logger _logger;
final ProcessManager _processManager;
final Set<Process> _runningProcesses = <Process>{}; final Set<Process> _runningProcesses = <Process>{};
final DesktopLogReader _deviceLogReader = DesktopLogReader(); final DesktopLogReader _deviceLogReader = DesktopLogReader();
// Since the host and target devices are the same, no work needs to be done // Since the host and target devices are the same, no work needs to be done
...@@ -108,20 +118,20 @@ abstract class DesktopDevice extends Device { ...@@ -108,20 +118,20 @@ abstract class DesktopDevice extends Device {
final BuildMode buildMode = debuggingOptions?.buildInfo?.mode; final BuildMode buildMode = debuggingOptions?.buildInfo?.mode;
final String executable = executablePathForDevice(package, buildMode); final String executable = executablePathForDevice(package, buildMode);
if (executable == null) { if (executable == null) {
globals.printError('Unable to find executable to run'); _logger.printError('Unable to find executable to run');
return LaunchResult.failed(); return LaunchResult.failed();
} }
final Process process = await globals.processManager.start(<String>[ final Process process = await _processManager.start(<String>[
executable, executable,
]); ]);
_runningProcesses.add(process); _runningProcesses.add(process);
unawaited(process.exitCode.then((_) => _runningProcesses.remove(process))); unawaited(process.exitCode.then((_) => _runningProcesses.remove(process)));
_deviceLogReader.initializeProcess(process);
if (debuggingOptions?.buildInfo?.isRelease == true) { if (debuggingOptions?.buildInfo?.isRelease == true) {
return LaunchResult.succeeded(); return LaunchResult.succeeded();
} }
_deviceLogReader.initializeProcess(process);
final ProtocolDiscovery observatoryDiscovery = ProtocolDiscovery.observatory(_deviceLogReader, final ProtocolDiscovery observatoryDiscovery = ProtocolDiscovery.observatory(_deviceLogReader,
devicePort: debuggingOptions?.deviceVmServicePort, devicePort: debuggingOptions?.deviceVmServicePort,
hostPort: debuggingOptions?.hostVmServicePort, hostPort: debuggingOptions?.hostVmServicePort,
...@@ -133,12 +143,12 @@ abstract class DesktopDevice extends Device { ...@@ -133,12 +143,12 @@ abstract class DesktopDevice extends Device {
onAttached(package, buildMode, process); onAttached(package, buildMode, process);
return LaunchResult.succeeded(observatoryUri: observatoryUri); return LaunchResult.succeeded(observatoryUri: observatoryUri);
} }
globals.printError( _logger.printError(
'Error waiting for a debug connection: ' 'Error waiting for a debug connection: '
'The log reader stopped unexpectedly.', 'The log reader stopped unexpectedly.',
); );
} on Exception catch (error) { } on Exception catch (error) {
globals.printError('Error waiting for a debug connection: $error'); _logger.printError('Error waiting for a debug connection: $error');
} finally { } finally {
await observatoryDiscovery.cancel(); await observatoryDiscovery.cancel();
} }
...@@ -186,9 +196,7 @@ class DesktopLogReader extends DeviceLogReader { ...@@ -186,9 +196,7 @@ class DesktopLogReader extends DeviceLogReader {
void initializeProcess(Process process) { void initializeProcess(Process process) {
process.stdout.listen(_inputController.add); process.stdout.listen(_inputController.add);
process.stderr.listen(_inputController.add); process.stderr.listen(_inputController.add);
process.exitCode.then((int result) { process.exitCode.whenComplete(_inputController.close);
_inputController.close();
});
} }
@override @override
......
...@@ -33,6 +33,7 @@ import 'ios/ios_workflow.dart'; ...@@ -33,6 +33,7 @@ import 'ios/ios_workflow.dart';
import 'ios/simulators.dart'; import 'ios/simulators.dart';
import 'linux/linux_device.dart'; import 'linux/linux_device.dart';
import 'macos/macos_device.dart'; import 'macos/macos_device.dart';
import 'macos/macos_workflow.dart';
import 'macos/xcode.dart'; import 'macos/xcode.dart';
import 'project.dart'; import 'project.dart';
import 'tester/flutter_tester.dart'; import 'tester/flutter_tester.dart';
...@@ -292,6 +293,7 @@ class FlutterDeviceManager extends DeviceManager { ...@@ -292,6 +293,7 @@ class FlutterDeviceManager extends DeviceManager {
@required FlutterVersion flutterVersion, @required FlutterVersion flutterVersion,
@required Config config, @required Config config,
@required Artifacts artifacts, @required Artifacts artifacts,
@required MacOSWorkflow macOSWorkflow,
}) : deviceDiscoverers = <DeviceDiscovery>[ }) : deviceDiscoverers = <DeviceDiscovery>[
AndroidDevices( AndroidDevices(
logger: logger, logger: logger,
...@@ -322,10 +324,17 @@ class FlutterDeviceManager extends DeviceManager { ...@@ -322,10 +324,17 @@ class FlutterDeviceManager extends DeviceManager {
logger: logger, logger: logger,
artifacts: artifacts, artifacts: artifacts,
), ),
MacOSDevices(), MacOSDevices(
processManager: processManager,
macOSWorkflow: macOSWorkflow,
logger: logger,
platform: platform,
),
LinuxDevices( LinuxDevices(
platform: platform, platform: platform,
featureFlags: featureFlags, featureFlags: featureFlags,
processManager: processManager,
logger: logger,
), ),
WindowsDevices(), WindowsDevices(),
WebDevices( WebDevices(
......
...@@ -65,6 +65,11 @@ class _DefaultDoctorValidatorsProvider implements DoctorValidatorsProvider { ...@@ -65,6 +65,11 @@ class _DefaultDoctorValidatorsProvider implements DoctorValidatorsProvider {
featureFlags: featureFlags, featureFlags: featureFlags,
); );
final MacOSWorkflow macOSWorkflow = MacOSWorkflow(
platform: globals.platform,
featureFlags: featureFlags,
);
@override @override
List<DoctorValidator> get validators { List<DoctorValidator> get validators {
if (_validators != null) { if (_validators != null) {
......
...@@ -3,12 +3,15 @@ ...@@ -3,12 +3,15 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:process/process.dart';
import '../base/logger.dart';
import '../base/platform.dart'; import '../base/platform.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../desktop_device.dart'; import '../desktop_device.dart';
import '../device.dart'; import '../device.dart';
import '../features.dart'; import '../features.dart';
import '../globals.dart' as globals;
import '../project.dart'; import '../project.dart';
import 'application_package.dart'; import 'application_package.dart';
import 'build_linux.dart'; import 'build_linux.dart';
...@@ -16,10 +19,15 @@ import 'linux_workflow.dart'; ...@@ -16,10 +19,15 @@ import 'linux_workflow.dart';
/// A device that represents a desktop Linux target. /// A device that represents a desktop Linux target.
class LinuxDevice extends DesktopDevice { class LinuxDevice extends DesktopDevice {
LinuxDevice() : super( LinuxDevice({
@required ProcessManager processManager,
@required Logger logger,
}) : super(
'linux', 'linux',
platformType: PlatformType.linux, platformType: PlatformType.linux,
ephemeral: false, ephemeral: false,
logger: logger,
processManager: processManager,
); );
@override @override
...@@ -59,15 +67,21 @@ class LinuxDevices extends PollingDeviceDiscovery { ...@@ -59,15 +67,21 @@ class LinuxDevices extends PollingDeviceDiscovery {
LinuxDevices({ LinuxDevices({
@required Platform platform, @required Platform platform,
@required FeatureFlags featureFlags, @required FeatureFlags featureFlags,
}) : _platform = platform, ProcessManager processManager,
Logger logger,
}) : _platform = platform ?? globals.platform, // TODO(jonahwilliams): remove after google3 roll
_linuxWorkflow = LinuxWorkflow( _linuxWorkflow = LinuxWorkflow(
platform: platform, platform: platform,
featureFlags: featureFlags, featureFlags: featureFlags,
), ),
_logger = logger,
_processManager = processManager ?? globals.processManager,
super('linux devices'); super('linux devices');
final Platform _platform; final Platform _platform;
final LinuxWorkflow _linuxWorkflow; final LinuxWorkflow _linuxWorkflow;
final ProcessManager _processManager;
final Logger _logger;
@override @override
bool get supportsPlatform => _platform.isLinux; bool get supportsPlatform => _platform.isLinux;
...@@ -81,7 +95,10 @@ class LinuxDevices extends PollingDeviceDiscovery { ...@@ -81,7 +95,10 @@ class LinuxDevices extends PollingDeviceDiscovery {
return const <Device>[]; return const <Device>[];
} }
return <Device>[ return <Device>[
LinuxDevice(), LinuxDevice(
logger: _logger,
processManager: _processManager,
),
]; ];
} }
......
...@@ -2,11 +2,15 @@ ...@@ -2,11 +2,15 @@
// 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 'package:meta/meta.dart';
import 'package:process/process.dart';
import '../base/io.dart'; import '../base/io.dart';
import '../base/logger.dart';
import '../base/platform.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../desktop_device.dart'; import '../desktop_device.dart';
import '../device.dart'; import '../device.dart';
import '../globals.dart' as globals;
import '../macos/application_package.dart'; import '../macos/application_package.dart';
import '../project.dart'; import '../project.dart';
import 'build_macos.dart'; import 'build_macos.dart';
...@@ -14,11 +18,21 @@ import 'macos_workflow.dart'; ...@@ -14,11 +18,21 @@ import 'macos_workflow.dart';
/// A device that represents a desktop MacOS target. /// A device that represents a desktop MacOS target.
class MacOSDevice extends DesktopDevice { class MacOSDevice extends DesktopDevice {
MacOSDevice() : super( MacOSDevice({
'macos', @required ProcessManager processManager,
platformType: PlatformType.macos, @required Logger logger,
ephemeral: false, }) : _processManager = processManager,
); _logger = logger,
super(
'macos',
platformType: PlatformType.macos,
ephemeral: false,
processManager: processManager,
logger: logger,
);
final ProcessManager _processManager;
final Logger _logger;
@override @override
bool isSupported() => true; bool isSupported() => true;
...@@ -44,7 +58,7 @@ class MacOSDevice extends DesktopDevice { ...@@ -44,7 +58,7 @@ class MacOSDevice extends DesktopDevice {
flutterProject: FlutterProject.current(), flutterProject: FlutterProject.current(),
buildInfo: buildInfo, buildInfo: buildInfo,
targetOverride: mainPath, targetOverride: mainPath,
verboseLogging: globals.logger.isVerbose, verboseLogging: _logger.isVerbose,
); );
} }
...@@ -59,7 +73,7 @@ class MacOSDevice extends DesktopDevice { ...@@ -59,7 +73,7 @@ class MacOSDevice extends DesktopDevice {
// than post-attach, since this won't run for release builds, but there's // than post-attach, since this won't run for release builds, but there's
// no general-purpose way of knowing when a process is far enoug along in // no general-purpose way of knowing when a process is far enoug along in
// the launch process for 'open' to foreground it. // the launch process for 'open' to foreground it.
globals.processManager.run(<String>[ _processManager.run(<String>[
'open', package.applicationBundle(buildMode), 'open', package.applicationBundle(buildMode),
]).then((ProcessResult result) { ]).then((ProcessResult result) {
if (result.exitCode != 0) { if (result.exitCode != 0) {
...@@ -70,13 +84,27 @@ class MacOSDevice extends DesktopDevice { ...@@ -70,13 +84,27 @@ class MacOSDevice extends DesktopDevice {
} }
class MacOSDevices extends PollingDeviceDiscovery { class MacOSDevices extends PollingDeviceDiscovery {
MacOSDevices() : super('macOS devices'); MacOSDevices({
@required Platform platform,
@required MacOSWorkflow macOSWorkflow,
@required ProcessManager processManager,
@required Logger logger,
}) : _logger = logger,
_platform = platform,
_macOSWorkflow = macOSWorkflow,
_processManager = processManager,
super('macOS devices');
final MacOSWorkflow _macOSWorkflow;
final Platform _platform;
final ProcessManager _processManager;
final Logger _logger;
@override @override
bool get supportsPlatform => globals.platform.isMacOS; bool get supportsPlatform => _platform.isMacOS;
@override @override
bool get canListAnything => macOSWorkflow.canListDevices; bool get canListAnything => _macOSWorkflow.canListDevices;
@override @override
Future<List<Device>> pollingGetDevices({ Duration timeout }) async { Future<List<Device>> pollingGetDevices({ Duration timeout }) async {
...@@ -84,7 +112,7 @@ class MacOSDevices extends PollingDeviceDiscovery { ...@@ -84,7 +112,7 @@ class MacOSDevices extends PollingDeviceDiscovery {
return const <Device>[]; return const <Device>[];
} }
return <Device>[ return <Device>[
MacOSDevice(), MacOSDevice(processManager: _processManager, logger: _logger),
]; ];
} }
......
...@@ -2,29 +2,35 @@ ...@@ -2,29 +2,35 @@
// 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 '../base/context.dart'; import 'package:meta/meta.dart';
import '../base/platform.dart';
import '../doctor.dart'; import '../doctor.dart';
import '../features.dart'; import '../features.dart';
import '../globals.dart' as globals;
/// The [MacOSWorkflow] instance.
MacOSWorkflow get macOSWorkflow => context.get<MacOSWorkflow>();
/// The macOS-specific implementation of a [Workflow]. /// The macOS-specific implementation of a [Workflow].
/// ///
/// This workflow requires the flutter-desktop-embedding as a sibling /// This workflow requires the flutter-desktop-embedding as a sibling
/// repository to the flutter repo. /// repository to the flutter repo.
class MacOSWorkflow implements Workflow { class MacOSWorkflow implements Workflow {
const MacOSWorkflow(); const MacOSWorkflow({
@required Platform platform,
@required FeatureFlags featureFlags,
}) : _platform = platform,
_featureFlags = featureFlags;
final Platform _platform;
final FeatureFlags _featureFlags;
@override @override
bool get appliesToHostPlatform => globals.platform.isMacOS && featureFlags.isMacOSEnabled; bool get appliesToHostPlatform => _platform.isMacOS && _featureFlags.isMacOSEnabled;
@override @override
bool get canLaunchDevices => globals.platform.isMacOS && featureFlags.isMacOSEnabled; bool get canLaunchDevices => _platform.isMacOS && _featureFlags.isMacOSEnabled;
@override @override
bool get canListDevices => globals.platform.isMacOS && featureFlags.isMacOSEnabled; bool get canListDevices => _platform.isMacOS && _featureFlags.isMacOSEnabled;
@override @override
bool get canListEmulators => false; bool get canListEmulators => false;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:file/memory.dart'; import 'package:file/memory.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/logger.dart';
import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/device.dart';
...@@ -17,15 +18,21 @@ import '../../src/common.dart'; ...@@ -17,15 +18,21 @@ import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/context.dart';
import '../../src/testbed.dart'; import '../../src/testbed.dart';
void main() { final FakePlatform linux = FakePlatform(
final LinuxDevice device = LinuxDevice(); operatingSystem: 'linux',
final MockPlatform notLinux = MockPlatform(); );
when(notLinux.isLinux).thenReturn(false); final FakePlatform windows = FakePlatform(
operatingSystem: 'windows',
);
final MockPlatform mockLinuxPlatform = MockPlatform(); void main() {
when(mockLinuxPlatform.isLinux).thenReturn(true);
testWithoutContext('LinuxDevice defaults', () async { testWithoutContext('LinuxDevice defaults', () async {
final LinuxDevice device = LinuxDevice(
processManager: FakeProcessManager.any(),
logger: BufferLogger.test(),
);
final PrebuiltLinuxApp linuxApp = PrebuiltLinuxApp(executable: 'foo'); final PrebuiltLinuxApp linuxApp = PrebuiltLinuxApp(executable: 'foo');
expect(await device.targetPlatform, TargetPlatform.linux_x64); expect(await device.targetPlatform, TargetPlatform.linux_x64);
expect(device.name, 'Linux'); expect(device.name, 'Linux');
...@@ -44,30 +51,38 @@ void main() { ...@@ -44,30 +51,38 @@ void main() {
testWithoutContext('LinuxDevice: no devices listed if platform unsupported', () async { testWithoutContext('LinuxDevice: no devices listed if platform unsupported', () async {
expect(await LinuxDevices( expect(await LinuxDevices(
platform: notLinux, platform: windows,
featureFlags: TestFeatureFlags(isLinuxEnabled: true), featureFlags: TestFeatureFlags(isLinuxEnabled: true),
logger: BufferLogger.test(),
processManager: FakeProcessManager.any(),
).devices, <Device>[]); ).devices, <Device>[]);
}); });
testWithoutContext('LinuxDevice: no devices listed if Linux feature flag disabled', () async { testWithoutContext('LinuxDevice: no devices listed if Linux feature flag disabled', () async {
expect(await LinuxDevices( expect(await LinuxDevices(
platform: mockLinuxPlatform, platform: linux,
featureFlags: TestFeatureFlags(isLinuxEnabled: false), featureFlags: TestFeatureFlags(isLinuxEnabled: false),
logger: BufferLogger.test(),
processManager: FakeProcessManager.any(),
).devices, <Device>[]); ).devices, <Device>[]);
}); });
testWithoutContext('LinuxDevice: devices', () async { testWithoutContext('LinuxDevice: devices', () async {
expect(await LinuxDevices( expect(await LinuxDevices(
platform: mockLinuxPlatform, platform: linux,
featureFlags: TestFeatureFlags(isLinuxEnabled: true), featureFlags: TestFeatureFlags(isLinuxEnabled: true),
logger: BufferLogger.test(),
processManager: FakeProcessManager.any(),
).devices, hasLength(1)); ).devices, hasLength(1));
}); });
testWithoutContext('LinuxDevice: discoverDevices', () async { testWithoutContext('LinuxDevice: discoverDevices', () async {
// Timeout ignored. // Timeout ignored.
final List<Device> devices = await LinuxDevices( final List<Device> devices = await LinuxDevices(
platform: mockLinuxPlatform, platform: linux,
featureFlags: TestFeatureFlags(isLinuxEnabled: true), featureFlags: TestFeatureFlags(isLinuxEnabled: true),
logger: BufferLogger.test(),
processManager: FakeProcessManager.any(),
).discoverDevices(timeout: const Duration(seconds: 10)); ).discoverDevices(timeout: const Duration(seconds: 10));
expect(devices, hasLength(1)); expect(devices, hasLength(1));
}); });
...@@ -78,7 +93,10 @@ void main() { ...@@ -78,7 +93,10 @@ void main() {
globals.fs.directory('linux').createSync(); globals.fs.directory('linux').createSync();
final FlutterProject flutterProject = FlutterProject.current(); final FlutterProject flutterProject = FlutterProject.current();
expect(LinuxDevice().isSupportedForProject(flutterProject), true); expect(LinuxDevice(
logger: BufferLogger.test(),
processManager: FakeProcessManager.any(),
).isSupportedForProject(flutterProject), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem(), FileSystem: () => MemoryFileSystem(),
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
...@@ -89,7 +107,10 @@ void main() { ...@@ -89,7 +107,10 @@ void main() {
globals.fs.file('.packages').createSync(); globals.fs.file('.packages').createSync();
final FlutterProject flutterProject = FlutterProject.current(); final FlutterProject flutterProject = FlutterProject.current();
expect(LinuxDevice().isSupportedForProject(flutterProject), false); expect(LinuxDevice(
logger: BufferLogger.test(),
processManager: FakeProcessManager.any(),
).isSupportedForProject(flutterProject), false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem(), FileSystem: () => MemoryFileSystem(),
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
...@@ -97,6 +118,10 @@ void main() { ...@@ -97,6 +118,10 @@ void main() {
testUsingContext('LinuxDevice.executablePathForDevice uses the correct package executable', () async { testUsingContext('LinuxDevice.executablePathForDevice uses the correct package executable', () async {
final MockLinuxApp mockApp = MockLinuxApp(); final MockLinuxApp mockApp = MockLinuxApp();
final LinuxDevice device = LinuxDevice(
logger: BufferLogger.test(),
processManager: FakeProcessManager.any(),
);
const String debugPath = 'debug/executable'; const String debugPath = 'debug/executable';
const String profilePath = 'profile/executable'; const String profilePath = 'profile/executable';
const String releasePath = 'release/executable'; const String releasePath = 'release/executable';
...@@ -104,15 +129,13 @@ void main() { ...@@ -104,15 +129,13 @@ void main() {
when(mockApp.executable(BuildMode.profile)).thenReturn(profilePath); when(mockApp.executable(BuildMode.profile)).thenReturn(profilePath);
when(mockApp.executable(BuildMode.release)).thenReturn(releasePath); when(mockApp.executable(BuildMode.release)).thenReturn(releasePath);
expect(LinuxDevice().executablePathForDevice(mockApp, BuildMode.debug), debugPath); expect(device.executablePathForDevice(mockApp, BuildMode.debug), debugPath);
expect(LinuxDevice().executablePathForDevice(mockApp, BuildMode.profile), profilePath); expect(device.executablePathForDevice(mockApp, BuildMode.profile), profilePath);
expect(LinuxDevice().executablePathForDevice(mockApp, BuildMode.release), releasePath); expect(device.executablePathForDevice(mockApp, BuildMode.release), releasePath);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem(), FileSystem: () => MemoryFileSystem(),
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
}); });
} }
class MockPlatform extends Mock implements Platform {}
class MockLinuxApp extends Mock implements LinuxApp {} class MockLinuxApp extends Mock implements LinuxApp {}
...@@ -3,60 +3,53 @@ ...@@ -3,60 +3,53 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/macos/macos_workflow.dart'; import 'package:flutter_tools/src/macos/macos_workflow.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/testbed.dart'; import '../../src/testbed.dart';
final FakePlatform macOS = FakePlatform(
operatingSystem: 'macos',
);
final FakePlatform linux = FakePlatform(
operatingSystem: 'linux',
);
void main() { void main() {
MockPlatform mac; testWithoutContext('Applies to macOS platform', () {
MockPlatform notMac; final MacOSWorkflow macOSWorkflow = MacOSWorkflow(
Testbed testbed; platform: macOS,
featureFlags: TestFeatureFlags(isMacOSEnabled: true),
setUp(() { );
mac = MockPlatform();
notMac = MockPlatform();
when(mac.isMacOS).thenReturn(true);
when(notMac.isMacOS).thenReturn(false);
testbed = Testbed(overrides: <Type, Generator>{
Platform: () => mac,
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
});
});
test('Applies to macOS platform', () => testbed.run(() {
expect(macOSWorkflow.appliesToHostPlatform, true); expect(macOSWorkflow.appliesToHostPlatform, true);
expect(macOSWorkflow.canListDevices, true); expect(macOSWorkflow.canListDevices, true);
expect(macOSWorkflow.canLaunchDevices, true); expect(macOSWorkflow.canLaunchDevices, true);
expect(macOSWorkflow.canListEmulators, false); expect(macOSWorkflow.canListEmulators, false);
})); });
testWithoutContext('Does not apply to non-macOS platform', () {
final MacOSWorkflow macOSWorkflow = MacOSWorkflow(
platform: linux,
featureFlags: TestFeatureFlags(isMacOSEnabled: true),
);
test('Does not apply to non-macOS platform', () => testbed.run(() {
expect(macOSWorkflow.appliesToHostPlatform, false); expect(macOSWorkflow.appliesToHostPlatform, false);
expect(macOSWorkflow.canListDevices, false); expect(macOSWorkflow.canListDevices, false);
expect(macOSWorkflow.canLaunchDevices, false); expect(macOSWorkflow.canLaunchDevices, false);
expect(macOSWorkflow.canListEmulators, false); expect(macOSWorkflow.canListEmulators, false);
}, overrides: <Type, Generator>{ });
Platform: () => notMac,
})); testWithoutContext('Does not apply when feature is disabled', () {
final MacOSWorkflow macOSWorkflow = MacOSWorkflow(
platform: macOS,
featureFlags: TestFeatureFlags(isMacOSEnabled: false),
);
test('Does not apply when feature is disabled', () => testbed.run(() {
expect(macOSWorkflow.appliesToHostPlatform, false); expect(macOSWorkflow.appliesToHostPlatform, false);
expect(macOSWorkflow.canListDevices, false); expect(macOSWorkflow.canListDevices, false);
expect(macOSWorkflow.canLaunchDevices, false); expect(macOSWorkflow.canLaunchDevices, false);
expect(macOSWorkflow.canListEmulators, false); expect(macOSWorkflow.canListEmulators, false);
}, overrides: <Type, Generator>{ });
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: false),
}));
}
class MockPlatform extends Mock implements Platform {
@override
Map<String, String> environment = <String, String>{};
} }
class MockProcessManager extends Mock implements ProcessManager {}
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