Unverified Commit 3a694a6d authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

desktop workflow, devices, and test (#26511)

parent fda193aa
......@@ -33,9 +33,12 @@ import 'ios/ios_workflow.dart';
import 'ios/mac.dart';
import 'ios/simulators.dart';
import 'ios/xcodeproj.dart';
import 'linux/linux_workflow.dart';
import 'macos/macos_workflow.dart';
import 'run_hot.dart';
import 'usage.dart';
import 'version.dart';
import 'windows/windows_workflow.dart';
Future<T> runInContext<T>(
FutureOr<T> runner(), {
......@@ -75,7 +78,9 @@ Future<T> runInContext<T>(
IOSWorkflow: () => const IOSWorkflow(),
IOSValidator: () => const IOSValidator(),
KernelCompiler: () => const KernelCompiler(),
LinuxWorkflow: () => const LinuxWorkflow(),
Logger: () => platform.isWindows ? WindowsStdoutLogger() : StdoutLogger(),
MacOSWorkflow: () => const MacOSWorkflow(),
OperatingSystemUtils: () => OperatingSystemUtils(),
PlistBuddy: () => const PlistBuddy(),
SimControl: () => SimControl(),
......@@ -83,6 +88,7 @@ Future<T> runInContext<T>(
Stdio: () => const Stdio(),
Usage: () => Usage(),
UserMessages: () => UserMessages(),
WindowsWorkflow: () => const WindowsWorkflow(),
Xcode: () => Xcode(),
XcodeProjectInterpreter: () => XcodeProjectInterpreter(),
},
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'base/file_system.dart';
import 'base/platform.dart';
import 'cache.dart';
// Only launch or display desktop embedding devices if there is a sibling
// FDE repository or a `FLUTTER_DESKTOP_EMBEDDING` environment variable which
// contains a FDE repo.
bool get hasFlutterDesktopRepository {
if (_hasFlutterDesktopRepository == null) {
final String desktopLocation = platform.environment['FLUTTER_DESKTOP_EMBEDDING'];
if (desktopLocation != null && desktopLocation.isNotEmpty) {
_hasFlutterDesktopRepository = fs.directory(desktopLocation)
.existsSync();
} else {
final Directory parent = fs.directory(Cache.flutterRoot).parent;
_hasFlutterDesktopRepository = parent
.childDirectory('flutter-desktop-embedding')
.existsSync();
}
}
return _hasFlutterDesktopRepository;
}
bool _hasFlutterDesktopRepository;
......@@ -16,7 +16,10 @@ import 'fuchsia/fuchsia_device.dart';
import 'globals.dart';
import 'ios/devices.dart';
import 'ios/simulators.dart';
import 'linux/linux_device.dart';
import 'macos/macos_device.dart';
import 'tester/flutter_tester.dart';
import 'windows/windows_device.dart';
DeviceManager get deviceManager => context[DeviceManager];
......@@ -31,6 +34,9 @@ class DeviceManager {
_deviceDiscoverers.add(IOSSimulators());
_deviceDiscoverers.add(FuchsiaDevices());
_deviceDiscoverers.add(FlutterTesterDevices());
_deviceDiscoverers.add(MacOSDevices());
_deviceDiscoverers.add(LinuxDevices());
_deviceDiscoverers.add(WindowsDevices());
}
final List<DeviceDiscovery> _deviceDiscoverers = <DeviceDiscovery>[];
......@@ -441,3 +447,31 @@ class DiscoveredApp {
final String id;
final int observatoryPort;
}
// An empty device log reader
class NoOpDeviceLogReader implements DeviceLogReader {
NoOpDeviceLogReader(this.name);
@override
final String name;
@override
int appPid;
@override
Stream<String> get logLines => const Stream<String>.empty();
}
// A portforwarder which does not support forwarding ports.
class NoOpDevicePortForwarder implements DevicePortForwarder {
const NoOpDevicePortForwarder();
@override
Future<int> forward(int devicePort, {int hostPort}) async => devicePort;
@override
List<ForwardedPort> get forwardedPorts => <ForwardedPort>[];
@override
Future<void> unforward(ForwardedPort forwardedPort) async {}
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../application_package.dart';
import '../base/os.dart';
import '../base/platform.dart';
import '../build_info.dart';
import '../device.dart';
import 'linux_workflow.dart';
/// A device that represents a desktop Linux target.
class LinuxDevice extends Device {
LinuxDevice() : super('Linux');
@override
void clearLogs() {}
@override
DeviceLogReader getLogReader({ApplicationPackage app}) => NoOpDeviceLogReader('linux');
@override
Future<bool> installApp(ApplicationPackage app) {
throw UnimplementedError();
}
@override
Future<bool> isAppInstalled(ApplicationPackage app) {
throw UnimplementedError();
}
@override
Future<bool> isLatestBuildInstalled(ApplicationPackage app) {
throw UnimplementedError();
}
@override
Future<bool> get isLocalEmulator async => false;
@override
bool isSupported() => true;
@override
String get name => 'Linux';
@override
DevicePortForwarder get portForwarder => const NoOpDevicePortForwarder();
@override
Future<String> get sdkNameAndVersion async => os.name;
@override
Future<LaunchResult> startApp(ApplicationPackage package, {
String mainPath,
String route,
DebuggingOptions debuggingOptions,
Map<String, dynamic> platformArgs,
bool prebuiltApplication = false,
bool applicationNeedsRebuild = false,
bool usesTerminalUi = true,
bool ipv6 = false,
}) {
throw UnimplementedError();
}
@override
Future<bool> stopApp(ApplicationPackage app) {
throw UnimplementedError();
}
@override
Future<TargetPlatform> get targetPlatform async => TargetPlatform.linux_x64;
@override
Future<bool> uninstallApp(ApplicationPackage app) {
throw UnimplementedError();
}
}
class LinuxDevices extends PollingDeviceDiscovery {
LinuxDevices() : super('linux devices');
@override
bool get supportsPlatform => platform.isLinux;
@override
bool get canListAnything => linuxWorkflow.canListDevices;
@override
Future<List<Device>> pollingGetDevices() async {
if (!canListAnything) {
return const <Device>[];
}
return <Device>[
LinuxDevice()
];
}
@override
Future<List<String>> getDiagnostics() async => const <String>[];
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../base/context.dart';
import '../base/platform.dart';
import '../desktop.dart';
import '../doctor.dart';
/// The [WindowsWorkflow] instance.
LinuxWorkflow get linuxWorkflow => context[LinuxWorkflow];
/// The windows-specific implementation of a [Workflow].
///
/// This workflow requires the flutter-desktop-embedding as a sibling
/// repository to the flutter repo.
class LinuxWorkflow implements Workflow {
const LinuxWorkflow();
@override
bool get appliesToHostPlatform => platform.isLinux;
@override
bool get canLaunchDevices => hasFlutterDesktopRepository;
@override
bool get canListDevices => hasFlutterDesktopRepository;
@override
bool get canListEmulators => false;
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../application_package.dart';
import '../base/os.dart';
import '../base/platform.dart';
import '../build_info.dart';
import '../device.dart';
import 'macos_workflow.dart';
/// A device that represents a desktop MacOS target.
class MacOSDevice extends Device {
MacOSDevice() : super('MacOS');
@override
void clearLogs() {}
@override
DeviceLogReader getLogReader({ApplicationPackage app}) => NoOpDeviceLogReader('macos');
@override
Future<bool> installApp(ApplicationPackage app) {
throw UnimplementedError();
}
@override
Future<bool> isAppInstalled(ApplicationPackage app) {
throw UnimplementedError();
}
@override
Future<bool> isLatestBuildInstalled(ApplicationPackage app) {
throw UnimplementedError();
}
@override
Future<bool> get isLocalEmulator async => false;
@override
bool isSupported() => true;
@override
String get name => 'MacOS';
@override
DevicePortForwarder get portForwarder => const NoOpDevicePortForwarder();
@override
Future<String> get sdkNameAndVersion async => os.name;
@override
Future<LaunchResult> startApp(ApplicationPackage package, {
String mainPath,
String route,
DebuggingOptions debuggingOptions,
Map<String, dynamic> platformArgs,
bool prebuiltApplication = false,
bool applicationNeedsRebuild = false,
bool usesTerminalUi = true,
bool ipv6 = false,
}) {
throw UnimplementedError();
}
@override
Future<bool> stopApp(ApplicationPackage app) {
throw UnimplementedError();
}
@override
Future<TargetPlatform> get targetPlatform async => TargetPlatform.darwin_x64;
@override
Future<bool> uninstallApp(ApplicationPackage app) {
throw UnimplementedError();
}
}
class MacOSDevices extends PollingDeviceDiscovery {
MacOSDevices() : super('macos devices');
@override
bool get supportsPlatform => platform.isMacOS;
@override
bool get canListAnything => macOSWorkflow.canListDevices;
@override
Future<List<Device>> pollingGetDevices() async {
if (!canListAnything) {
return const <Device>[];
}
return <Device>[
MacOSDevice()
];
}
@override
Future<List<String>> getDiagnostics() async => const <String>[];
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../base/context.dart';
import '../base/platform.dart';
import '../desktop.dart';
import '../doctor.dart';
/// The [MacOSWorkflow] instance.
MacOSWorkflow get macOSWorkflow => context[MacOSWorkflow];
/// The macos-specific implementation of a [Workflow].
///
/// This workflow requires the flutter-desktop-embedding as a sibling
/// repository to the flutter repo.
class MacOSWorkflow implements Workflow {
const MacOSWorkflow();
@override
bool get appliesToHostPlatform => platform.isMacOS;
@override
bool get canLaunchDevices => hasFlutterDesktopRepository;
@override
bool get canListDevices => hasFlutterDesktopRepository;
@override
bool get canListEmulators => false;
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../application_package.dart';
import '../base/os.dart';
import '../base/platform.dart';
import '../build_info.dart';
import '../device.dart';
import 'windows_workflow.dart';
/// A device that represents a desktop Windows target.
class WindowsDevice extends Device {
WindowsDevice() : super('Windows');
@override
void clearLogs() {}
@override
DeviceLogReader getLogReader({ApplicationPackage app}) => NoOpDeviceLogReader('windows');
@override
Future<bool> installApp(ApplicationPackage app) {
throw UnimplementedError();
}
@override
Future<bool> isAppInstalled(ApplicationPackage app) {
throw UnimplementedError();
}
@override
Future<bool> isLatestBuildInstalled(ApplicationPackage app) {
throw UnimplementedError();
}
@override
Future<bool> get isLocalEmulator async => false;
@override
bool isSupported() => true;
@override
String get name => 'Windows';
@override
DevicePortForwarder get portForwarder => const NoOpDevicePortForwarder();
@override
Future<String> get sdkNameAndVersion async => os.name;
@override
Future<LaunchResult> startApp(ApplicationPackage package, {
String mainPath,
String route,
DebuggingOptions debuggingOptions,
Map<String, dynamic> platformArgs,
bool prebuiltApplication = false,
bool applicationNeedsRebuild = false,
bool usesTerminalUi = true,
bool ipv6 = false,
}) {
throw UnimplementedError();
}
@override
Future<bool> stopApp(ApplicationPackage app) {
throw UnimplementedError();
}
@override
Future<TargetPlatform> get targetPlatform async => TargetPlatform.windows_x64;
@override
Future<bool> uninstallApp(ApplicationPackage app) {
throw UnimplementedError();
}
}
class WindowsDevices extends PollingDeviceDiscovery {
WindowsDevices() : super('windows devices');
@override
bool get supportsPlatform => platform.isWindows;
@override
bool get canListAnything => windowsWorkflow.canListDevices;
@override
Future<List<Device>> pollingGetDevices() async {
if (!canListAnything) {
return const <Device>[];
}
return <Device>[
WindowsDevice()
];
}
@override
Future<List<String>> getDiagnostics() async => const <String>[];
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../base/context.dart';
import '../base/platform.dart';
import '../desktop.dart';
import '../doctor.dart';
/// The [WindowsWorkflow] instance.
WindowsWorkflow get windowsWorkflow => context[WindowsWorkflow];
/// The windows-specific implementation of a [Workflow].
///
/// This workflow requires the flutter-desktop-embedding as a sibling
/// repository to the flutter repo.
class WindowsWorkflow implements Workflow {
const WindowsWorkflow();
@override
bool get appliesToHostPlatform => platform.isWindows;
@override
bool get canLaunchDevices => hasFlutterDesktopRepository;
@override
bool get canListDevices => hasFlutterDesktopRepository;
@override
bool get canListEmulators => false;
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/linux/linux_device.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:mockito/mockito.dart';
import '../src/common.dart';
import '../src/context.dart';
void main() {
group(LinuxDevice, () {
final LinuxDevice device = LinuxDevice();
final MockPlatform notLinux = MockPlatform();
when(notLinux.isLinux).thenReturn(false);
when(notLinux.environment).thenReturn(const <String, String>{});
test('defaults', () async {
expect(await device.targetPlatform, TargetPlatform.linux_x64);
expect(device.name, 'Linux');
});
test('unimplemented methods', () {
expect(() => device.installApp(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.uninstallApp(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.isLatestBuildInstalled(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.startApp(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.stopApp(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.isAppInstalled(null), throwsA(isInstanceOf<UnimplementedError>()));
});
test('noop port forwarding', () async {
final LinuxDevice device = LinuxDevice();
final DevicePortForwarder portForwarder = device.portForwarder;
final int result = await portForwarder.forward(2);
expect(result, 2);
expect(portForwarder.forwardedPorts.isEmpty, true);
});
testUsingContext('No devices listed if platform unsupported', () async {
expect(await LinuxDevices().devices, <Device>[]);
}, overrides: <Type, Generator>{
Platform: () => notLinux,
});
});
}
class MockPlatform extends Mock implements Platform {}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:mockito/mockito.dart';
import 'package:flutter_tools/src/linux/linux_workflow.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import '../src/common.dart';
import '../src/context.dart';
void main() {
group(LinuxWorkflow, () {
final MockPlatform linux = MockPlatform();
final MockPlatform notLinux = MockPlatform();
when(linux.isLinux).thenReturn(true);
when(notLinux.isLinux).thenReturn(false);
testUsingContext('Applies to linux platform', () {
expect(linuxWorkflow.appliesToHostPlatform, true);
}, overrides: <Type, Generator>{
Platform: () => linux,
});
testUsingContext('Does not apply to non-linux platform', () {
expect(linuxWorkflow.appliesToHostPlatform, false);
}, overrides: <Type, Generator>{
Platform: () => notLinux,
});
final MockFileSystem fileSystem = MockFileSystem();
final MockDirectory directory = MockDirectory();
Cache.flutterRoot = '';
when(fileSystem.directory(Cache.flutterRoot)).thenReturn(directory);
when(directory.parent).thenReturn(directory);
when(directory.childDirectory('flutter-desktop-embedding')).thenReturn(directory);
when(directory.existsSync()).thenReturn(true);
testUsingContext('defaults', () {
expect(linuxWorkflow.canListEmulators, false);
expect(linuxWorkflow.canLaunchDevices, true);
expect(linuxWorkflow.canListDevices, true);
}, overrides: <Type, Generator>{
Platform: () => linux,
FileSystem: () => fileSystem,
});
});
}
class MockFileSystem extends Mock implements FileSystem {}
class MockDirectory extends Mock implements Directory {}
class MockPlatform extends Mock implements Platform {
@override
Map<String, String> get environment => const <String, String>{};
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/macos/macos_device.dart';
import 'package:mockito/mockito.dart';
import '../src/common.dart';
import '../src/context.dart';
void main() {
group(MacOSDevice, () {
final MockPlatform notMac = MockPlatform();
final MacOSDevice device = MacOSDevice();
when(notMac.isMacOS).thenReturn(false);
when(notMac.environment).thenReturn(const <String, String>{});
test('defaults', () async {
expect(await device.targetPlatform, TargetPlatform.darwin_x64);
expect(device.name, 'MacOS');
});
test('unimplemented methods', () {
expect(() => device.installApp(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.uninstallApp(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.isLatestBuildInstalled(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.startApp(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.stopApp(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.isAppInstalled(null), throwsA(isInstanceOf<UnimplementedError>()));
});
test('noop port forwarding', () async {
final MacOSDevice device = MacOSDevice();
final DevicePortForwarder portForwarder = device.portForwarder;
final int result = await portForwarder.forward(2);
expect(result, 2);
expect(portForwarder.forwardedPorts.isEmpty, true);
});
testUsingContext('No devices listed if platform unsupported', () async {
expect(await MacOSDevices().devices, <Device>[]);
}, overrides: <Type, Generator>{
Platform: () => notMac,
});
});
}
class MockPlatform extends Mock implements Platform {}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:mockito/mockito.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/macos/macos_workflow.dart';
import '../src/common.dart';
import '../src/context.dart';
void main() {
group(MacOSWorkflow, () {
final MockPlatform mac = MockPlatform();
final MockPlatform notMac = MockPlatform();
when(mac.isMacOS).thenReturn(true);
when(notMac.isMacOS).thenReturn(false);
testUsingContext('Applies to mac platform', () {
expect(macOSWorkflow.appliesToHostPlatform, true);
}, overrides: <Type, Generator>{
Platform: () => mac,
});
testUsingContext('Does not apply to non-mac platform', () {
expect(macOSWorkflow.appliesToHostPlatform, false);
}, overrides: <Type, Generator>{
Platform: () => notMac,
});
final MockFileSystem fileSystem = MockFileSystem();
final MockDirectory directory = MockDirectory();
Cache.flutterRoot = '';
when(fileSystem.directory(Cache.flutterRoot)).thenReturn(directory);
when(directory.parent).thenReturn(directory);
when(directory.childDirectory('flutter-desktop-embedding')).thenReturn(directory);
when(directory.existsSync()).thenReturn(true);
testUsingContext('defaults', () {
expect(macOSWorkflow.canListEmulators, false);
expect(macOSWorkflow.canLaunchDevices, true);
expect(macOSWorkflow.canListDevices, true);
}, overrides: <Type, Generator>{
Platform: () => mac,
FileSystem: () => fileSystem,
});
});
}
class MockFileSystem extends Mock implements FileSystem {}
class MockDirectory extends Mock implements Directory {}
class MockPlatform extends Mock implements Platform {
@override
Map<String, String> get environment => const <String, String>{};
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/windows/windows_device.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:mockito/mockito.dart';
import '../src/common.dart';
import '../src/context.dart';
void main() {
group(WindowsDevice, () {
final WindowsDevice device = WindowsDevice();
final MockPlatform notWindows = MockPlatform();
when(notWindows.isWindows).thenReturn(false);
when(notWindows.environment).thenReturn(const <String, String>{});
test('defaults', () async {
expect(await device.targetPlatform, TargetPlatform.windows_x64);
expect(device.name, 'Windows');
});
test('unimplemented methods', () {
expect(() => device.installApp(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.uninstallApp(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.isLatestBuildInstalled(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.startApp(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.stopApp(null), throwsA(isInstanceOf<UnimplementedError>()));
expect(() => device.isAppInstalled(null), throwsA(isInstanceOf<UnimplementedError>()));
});
test('noop port forwarding', () async {
final WindowsDevice device = WindowsDevice();
final DevicePortForwarder portForwarder = device.portForwarder;
final int result = await portForwarder.forward(2);
expect(result, 2);
expect(portForwarder.forwardedPorts.isEmpty, true);
});
testUsingContext('No devices listed if platform unsupported', () async {
expect(await WindowsDevices().devices, <Device>[]);
}, overrides: <Type, Generator>{
Platform: () => notWindows,
});
});
}
class MockPlatform extends Mock implements Platform {}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:mockito/mockito.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/windows/windows_workflow.dart';
import '../src/common.dart';
import '../src/context.dart';
void main() {
group(WindowsWorkflow, () {
final MockPlatform windows = MockPlatform();
final MockPlatform notWindows = MockPlatform();
when(windows.isWindows).thenReturn(true);
when(notWindows.isWindows).thenReturn(false);
testUsingContext('Applies to windows platform', () {
expect(windowsWorkflow.appliesToHostPlatform, true);
}, overrides: <Type, Generator>{
Platform: () => windows,
});
testUsingContext('Does not apply to non-windows platform', () {
expect(windowsWorkflow.appliesToHostPlatform, false);
}, overrides: <Type, Generator>{
Platform: () => notWindows,
});
final MockFileSystem fileSystem = MockFileSystem();
final MockDirectory directory = MockDirectory();
Cache.flutterRoot = '';
when(fileSystem.directory(Cache.flutterRoot)).thenReturn(directory);
when(directory.parent).thenReturn(directory);
when(directory.childDirectory('flutter-desktop-embedding')).thenReturn(directory);
when(directory.existsSync()).thenReturn(true);
testUsingContext('defaults', () {
expect(windowsWorkflow.canListEmulators, false);
expect(windowsWorkflow.canLaunchDevices, true);
expect(windowsWorkflow.canListDevices, true);
}, overrides: <Type, Generator>{
Platform: () => windows,
FileSystem: () => fileSystem,
});
});
}
class MockFileSystem extends Mock implements FileSystem {}
class MockDirectory extends Mock implements Directory {}
class MockPlatform extends Mock implements Platform {
@override
Map<String, String> get environment => const <String, String>{};
}
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