mirror of
https://github.com/flutter/flutter
synced 2024-10-13 03:32:55 +00:00
Add timeout flag to devices command, pipe through discovery (#51678)
This commit is contained in:
parent
0a09b78297
commit
2f216ceee5
|
@ -62,7 +62,7 @@ class AndroidDevices extends PollingDeviceDiscovery {
|
|||
bool get canListAnything => androidWorkflow.canListDevices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> pollingGetDevices() async => getAdbDevices();
|
||||
Future<List<Device>> pollingGetDevices({ Duration timeout }) async => getAdbDevices();
|
||||
|
||||
@override
|
||||
Future<List<String>> getDiagnostics() async => getAdbDeviceDiagnostics();
|
||||
|
|
|
@ -12,12 +12,36 @@ import '../globals.dart' as globals;
|
|||
import '../runner/flutter_command.dart';
|
||||
|
||||
class DevicesCommand extends FlutterCommand {
|
||||
DevicesCommand() {
|
||||
argParser.addOption(
|
||||
'timeout',
|
||||
abbr: 't',
|
||||
defaultsTo: null,
|
||||
help: 'Time in seconds to wait for devices to attach. Longer timeouts may be necessary for networked devices.'
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
final String name = 'devices';
|
||||
|
||||
@override
|
||||
final String description = 'List all connected devices.';
|
||||
|
||||
Duration get timeout {
|
||||
if (argResults['timeout'] == null) {
|
||||
return null;
|
||||
}
|
||||
if (_timeout == null) {
|
||||
final int timeoutSeconds = int.tryParse(stringArg('timeout'));
|
||||
if (timeoutSeconds == null) {
|
||||
throwToolExit( 'Could not parse -t/--timeout argument. It must be an integer.');
|
||||
}
|
||||
_timeout = Duration(seconds: timeoutSeconds);
|
||||
}
|
||||
return _timeout;
|
||||
}
|
||||
Duration _timeout;
|
||||
|
||||
@override
|
||||
Future<FlutterCommandResult> runCommand() async {
|
||||
if (!doctor.canListAnything) {
|
||||
|
@ -27,14 +51,21 @@ class DevicesCommand extends FlutterCommand {
|
|||
exitCode: 1);
|
||||
}
|
||||
|
||||
final List<Device> devices = await deviceManager.getAllConnectedDevices();
|
||||
final List<Device> devices = await deviceManager.refreshAllConnectedDevices(timeout: timeout);
|
||||
|
||||
if (devices.isEmpty) {
|
||||
globals.printStatus(
|
||||
'No devices detected.\n\n'
|
||||
"Run 'flutter emulators' to list and start any available device emulators.\n\n"
|
||||
'Or, if you expected your device to be detected, please run "flutter doctor" to diagnose '
|
||||
'potential issues, or visit https://flutter.dev/setup/ for troubleshooting tips.');
|
||||
final StringBuffer status = StringBuffer('No devices detected.');
|
||||
status.writeln();
|
||||
status.writeln();
|
||||
status.writeln('Run "flutter emulators" to list and start any available device emulators.');
|
||||
status.writeln();
|
||||
status.write('If you expected your device to be detected, please run "flutter doctor" to diagnose potential issues. ');
|
||||
if (timeout == null) {
|
||||
status.write('You may also try increasing the time to wait for connected devices with the --timeout flag. ');
|
||||
}
|
||||
status.write('Visit https://flutter.dev/setup/ for troubleshooting tips.');
|
||||
|
||||
globals.printStatus(status.toString());
|
||||
final List<String> diagnostics = await deviceManager.getDeviceDiagnostics();
|
||||
if (diagnostics.isNotEmpty) {
|
||||
globals.printStatus('');
|
||||
|
|
|
@ -124,7 +124,7 @@ class DeviceManager {
|
|||
return devices.where(startsWithDeviceId).toList();
|
||||
}
|
||||
|
||||
/// Return the list of connected devices, filtered by any user-specified device id.
|
||||
/// Returns the list of connected devices, filtered by any user-specified device id.
|
||||
Future<List<Device>> getDevices() {
|
||||
return hasSpecifiedDeviceId
|
||||
? getDevicesById(specifiedDeviceId)
|
||||
|
@ -135,7 +135,7 @@ class DeviceManager {
|
|||
return deviceDiscoverers.where((DeviceDiscovery discoverer) => discoverer.supportsPlatform);
|
||||
}
|
||||
|
||||
/// Return the list of all connected devices.
|
||||
/// Returns the list of all connected devices.
|
||||
Future<List<Device>> getAllConnectedDevices() async {
|
||||
final List<List<Device>> devices = await Future.wait<List<Device>>(<Future<List<Device>>>[
|
||||
for (final DeviceDiscovery discoverer in _platformDiscoverers)
|
||||
|
@ -145,6 +145,16 @@ class DeviceManager {
|
|||
return devices.expand<Device>((List<Device> deviceList) => deviceList).toList();
|
||||
}
|
||||
|
||||
/// Returns the list of all connected devices. Discards existing cache of devices.
|
||||
Future<List<Device>> refreshAllConnectedDevices({ Duration timeout }) async {
|
||||
final List<List<Device>> devices = await Future.wait<List<Device>>(<Future<List<Device>>>[
|
||||
for (final DeviceDiscovery discoverer in _platformDiscoverers)
|
||||
discoverer.discoverDevices(timeout: timeout),
|
||||
]);
|
||||
|
||||
return devices.expand<Device>((List<Device> deviceList) => deviceList).toList();
|
||||
}
|
||||
|
||||
/// Whether we're capable of listing any devices given the current environment configuration.
|
||||
bool get canListAnything {
|
||||
return _platformDiscoverers.any((DeviceDiscovery discoverer) => discoverer.canListAnything);
|
||||
|
@ -237,8 +247,12 @@ abstract class DeviceDiscovery {
|
|||
/// current environment configuration.
|
||||
bool get canListAnything;
|
||||
|
||||
/// Return all connected devices, cached on subsequent calls.
|
||||
Future<List<Device>> get devices;
|
||||
|
||||
/// Return all connected devices. Discards existing cache of devices.
|
||||
Future<List<Device>> discoverDevices({ Duration timeout });
|
||||
|
||||
/// Gets a list of diagnostic messages pertaining to issues with any connected
|
||||
/// devices (will be an empty list if there are no issues).
|
||||
Future<List<String>> getDiagnostics() => Future<List<String>>.value(<String>[]);
|
||||
|
@ -256,7 +270,7 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
|
|||
ItemListNotifier<Device> _items;
|
||||
Timer _timer;
|
||||
|
||||
Future<List<Device>> pollingGetDevices();
|
||||
Future<List<Device>> pollingGetDevices({ Duration timeout });
|
||||
|
||||
void startPolling() {
|
||||
if (_timer == null) {
|
||||
|
@ -268,7 +282,7 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
|
|||
Timer _initTimer() {
|
||||
return Timer(_pollingInterval, () async {
|
||||
try {
|
||||
final List<Device> devices = await pollingGetDevices().timeout(_pollingTimeout);
|
||||
final List<Device> devices = await pollingGetDevices(timeout: _pollingTimeout);
|
||||
_items.updateWithNewList(devices);
|
||||
} on TimeoutException {
|
||||
globals.printTrace('Device poll timed out. Will retry.');
|
||||
|
@ -284,7 +298,17 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
|
|||
|
||||
@override
|
||||
Future<List<Device>> get devices async {
|
||||
_items ??= ItemListNotifier<Device>.from(await pollingGetDevices());
|
||||
return _populateDevices();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Device>> discoverDevices({ Duration timeout }) async {
|
||||
_items = null;
|
||||
return _populateDevices(timeout: timeout);
|
||||
}
|
||||
|
||||
Future<List<Device>> _populateDevices({ Duration timeout }) async {
|
||||
_items ??= ItemListNotifier<Device>.from(await pollingGetDevices(timeout: timeout));
|
||||
return _items.items;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class FuchsiaDevFinder {
|
|||
/// Returns a list of attached devices as a list of strings with entries
|
||||
/// formatted as follows:
|
||||
/// 192.168.42.172 scare-cable-skip-joy
|
||||
Future<List<String>> list() async {
|
||||
Future<List<String>> list({ Duration timeout }) async {
|
||||
if (fuchsiaArtifacts.devFinder == null ||
|
||||
!fuchsiaArtifacts.devFinder.existsSync()) {
|
||||
throwToolExit('Fuchsia device-finder tool not found.');
|
||||
|
@ -31,6 +31,8 @@ class FuchsiaDevFinder {
|
|||
fuchsiaArtifacts.devFinder.path,
|
||||
'list',
|
||||
'-full',
|
||||
if (timeout != null)
|
||||
...<String>['-timeout', '${timeout.inMilliseconds}ms']
|
||||
];
|
||||
final RunResult result = await processUtils.run(command);
|
||||
if (result.exitCode != 0) {
|
||||
|
|
|
@ -145,11 +145,11 @@ class FuchsiaDevices extends PollingDeviceDiscovery {
|
|||
bool get canListAnything => fuchsiaWorkflow.canListDevices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> pollingGetDevices() async {
|
||||
Future<List<Device>> pollingGetDevices({ Duration timeout }) async {
|
||||
if (!fuchsiaWorkflow.canListDevices) {
|
||||
return <Device>[];
|
||||
}
|
||||
final String text = await fuchsiaSdk.listDevices();
|
||||
final String text = await fuchsiaSdk.listDevices(timeout: timeout);
|
||||
if (text == null || text.isEmpty) {
|
||||
return <Device>[];
|
||||
}
|
||||
|
|
|
@ -47,12 +47,12 @@ class FuchsiaSdk {
|
|||
/// Example output:
|
||||
/// $ device-finder list -full
|
||||
/// > 192.168.42.56 paper-pulp-bush-angel
|
||||
Future<String> listDevices() async {
|
||||
Future<String> listDevices({ Duration timeout }) async {
|
||||
if (fuchsiaArtifacts.devFinder == null ||
|
||||
!fuchsiaArtifacts.devFinder.existsSync()) {
|
||||
return null;
|
||||
}
|
||||
final List<String> devices = await fuchsiaDevFinder.list();
|
||||
final List<String> devices = await fuchsiaDevFinder.list(timeout: timeout);
|
||||
if (devices == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,10 @@ class IOSDevices extends PollingDeviceDiscovery {
|
|||
bool get canListAnything => globals.iosWorkflow.canListDevices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> pollingGetDevices() => IOSDevice.getAttachedDevices(globals.platform, globals.xcdevice);
|
||||
Future<List<Device>> pollingGetDevices({ Duration timeout }) {
|
||||
return IOSDevice.getAttachedDevices(
|
||||
globals.platform, globals.xcdevice, timeout: timeout);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<String>> getDiagnostics() => IOSDevice.getDiagnostics(globals.platform, globals.xcdevice);
|
||||
|
@ -109,12 +112,12 @@ class IOSDevice extends Device {
|
|||
@override
|
||||
bool get supportsStartPaused => false;
|
||||
|
||||
static Future<List<IOSDevice>> getAttachedDevices(Platform platform, XCDevice xcdevice) async {
|
||||
static Future<List<IOSDevice>> getAttachedDevices(Platform platform, XCDevice xcdevice, { Duration timeout }) async {
|
||||
if (!platform.isMacOS) {
|
||||
throw UnsupportedError('Control of iOS devices or simulators only supported on macOS.');
|
||||
}
|
||||
|
||||
return await xcdevice.getAvailableTetheredIOSDevices();
|
||||
return await xcdevice.getAvailableTetheredIOSDevices(timeout: timeout);
|
||||
}
|
||||
|
||||
static Future<List<String>> getDiagnostics(Platform platform, XCDevice xcdevice) async {
|
||||
|
|
|
@ -43,7 +43,7 @@ class IOSSimulators extends PollingDeviceDiscovery {
|
|||
bool get canListAnything => globals.iosWorkflow.canListDevices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> pollingGetDevices() async => _iosSimulatorUtils.getAttachedDevices();
|
||||
Future<List<Device>> pollingGetDevices({ Duration timeout }) async => _iosSimulatorUtils.getAttachedDevices();
|
||||
}
|
||||
|
||||
class IOSSimulatorUtils {
|
||||
|
|
|
@ -76,7 +76,7 @@ class LinuxDevices extends PollingDeviceDiscovery {
|
|||
bool get canListAnything => _linuxWorkflow.canListDevices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> pollingGetDevices() async {
|
||||
Future<List<Device>> pollingGetDevices({ Duration timeout }) async {
|
||||
if (!canListAnything) {
|
||||
return const <Device>[];
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ class MacOSDevices extends PollingDeviceDiscovery {
|
|||
bool get canListAnything => macOSWorkflow.canListDevices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> pollingGetDevices() async {
|
||||
Future<List<Device>> pollingGetDevices({ Duration timeout }) async {
|
||||
if (!canListAnything) {
|
||||
return const <Device>[];
|
||||
}
|
||||
|
|
|
@ -228,7 +228,10 @@ class XCDevice {
|
|||
return _xcdevicePath;
|
||||
}
|
||||
|
||||
Future<List<dynamic>> _getAllDevices({bool useCache = false}) async {
|
||||
Future<List<dynamic>> _getAllDevices({
|
||||
bool useCache = false,
|
||||
@required Duration timeout
|
||||
}) async {
|
||||
if (!isInstalled) {
|
||||
_logger.printTrace("Xcode not found. Run 'flutter doctor' for more information.");
|
||||
return null;
|
||||
|
@ -244,7 +247,7 @@ class XCDevice {
|
|||
'xcdevice',
|
||||
'list',
|
||||
'--timeout',
|
||||
'1',
|
||||
timeout.inSeconds.toString(),
|
||||
],
|
||||
throwOnError: true,
|
||||
);
|
||||
|
@ -265,9 +268,9 @@ class XCDevice {
|
|||
|
||||
List<dynamic> _cachedListResults;
|
||||
|
||||
/// List of devices available over USB.
|
||||
Future<List<IOSDevice>> getAvailableTetheredIOSDevices() async {
|
||||
final List<dynamic> allAvailableDevices = await _getAllDevices();
|
||||
/// [timeout] defaults to 1 second.
|
||||
Future<List<IOSDevice>> getAvailableTetheredIOSDevices({ Duration timeout }) async {
|
||||
final List<dynamic> allAvailableDevices = await _getAllDevices(timeout: timeout ?? const Duration(seconds: 1));
|
||||
|
||||
if (allAvailableDevices == null) {
|
||||
return const <IOSDevice>[];
|
||||
|
@ -501,7 +504,10 @@ class XCDevice {
|
|||
|
||||
/// List of all devices reporting errors.
|
||||
Future<List<String>> getDiagnostics() async {
|
||||
final List<dynamic> allAvailableDevices = await _getAllDevices(useCache: true);
|
||||
final List<dynamic> allAvailableDevices = await _getAllDevices(
|
||||
useCache: true,
|
||||
timeout: const Duration(seconds: 1)
|
||||
);
|
||||
|
||||
if (allAvailableDevices == null) {
|
||||
return const <String>[];
|
||||
|
|
|
@ -246,7 +246,7 @@ class FlutterTesterDevices extends PollingDeviceDiscovery {
|
|||
bool get supportsPlatform => true;
|
||||
|
||||
@override
|
||||
Future<List<Device>> pollingGetDevices() async {
|
||||
Future<List<Device>> pollingGetDevices({ Duration timeout }) async {
|
||||
return showFlutterTesterDevice ? <Device>[_testerDevice] : <Device>[];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -185,7 +185,7 @@ class WebDevices extends PollingDeviceDiscovery {
|
|||
bool get canListAnything => featureFlags.isWebEnabled;
|
||||
|
||||
@override
|
||||
Future<List<Device>> pollingGetDevices() async {
|
||||
Future<List<Device>> pollingGetDevices({ Duration timeout }) async {
|
||||
return <Device>[
|
||||
if (_chromeIsAvailable)
|
||||
_webDevice,
|
||||
|
|
|
@ -66,7 +66,7 @@ class WindowsDevices extends PollingDeviceDiscovery {
|
|||
bool get canListAnything => windowsWorkflow.canListDevices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> pollingGetDevices() async {
|
||||
Future<List<Device>> pollingGetDevices({ Duration timeout }) async {
|
||||
if (!canListAnything) {
|
||||
return const <Device>[];
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import 'package:mockito/mockito.dart';
|
|||
|
||||
import '../src/common.dart';
|
||||
import '../src/context.dart';
|
||||
import '../src/mocks.dart';
|
||||
|
||||
void main() {
|
||||
group('DeviceManager', () {
|
||||
|
@ -39,6 +40,26 @@ void main() {
|
|||
await expectDevice('0553790', <Device>[device1]);
|
||||
await expectDevice('Nexus', <Device>[device1, device2]);
|
||||
});
|
||||
|
||||
testUsingContext('getAllConnectedDevices caches', () async {
|
||||
final _MockDevice device1 = _MockDevice('Nexus 5', '0553790d0a4e726f');
|
||||
final TestDeviceManager deviceManager = TestDeviceManager(<Device>[device1]);
|
||||
expect(await deviceManager.getAllConnectedDevices(), <Device>[device1]);
|
||||
|
||||
final _MockDevice device2 = _MockDevice('Nexus 5X', '01abfc49119c410e');
|
||||
deviceManager.resetDevices(<Device>[device2]);
|
||||
expect(await deviceManager.getAllConnectedDevices(), <Device>[device1]);
|
||||
});
|
||||
|
||||
testUsingContext('refreshAllConnectedDevices does not cache', () async {
|
||||
final _MockDevice device1 = _MockDevice('Nexus 5', '0553790d0a4e726f');
|
||||
final TestDeviceManager deviceManager = TestDeviceManager(<Device>[device1]);
|
||||
expect(await deviceManager.refreshAllConnectedDevices(), <Device>[device1]);
|
||||
|
||||
final _MockDevice device2 = _MockDevice('Nexus 5X', '01abfc49119c410e');
|
||||
deviceManager.resetDevices(<Device>[device2]);
|
||||
expect(await deviceManager.refreshAllConnectedDevices(), <Device>[device2]);
|
||||
});
|
||||
});
|
||||
|
||||
group('Filter devices', () {
|
||||
|
@ -164,13 +185,19 @@ void main() {
|
|||
}
|
||||
|
||||
class TestDeviceManager extends DeviceManager {
|
||||
TestDeviceManager(this.allDevices);
|
||||
|
||||
final List<Device> allDevices;
|
||||
bool isAlwaysSupportedOverride;
|
||||
|
||||
TestDeviceManager(List<Device> allDevices) {
|
||||
_deviceDiscoverer = MockPollingDeviceDiscovery();
|
||||
resetDevices(allDevices);
|
||||
}
|
||||
@override
|
||||
Future<List<Device>> getAllConnectedDevices() async => allDevices;
|
||||
List<DeviceDiscovery> get deviceDiscoverers => <DeviceDiscovery>[_deviceDiscoverer];
|
||||
MockPollingDeviceDiscovery _deviceDiscoverer;
|
||||
|
||||
void resetDevices(List<Device> allDevices) {
|
||||
_deviceDiscoverer.setDevices(allDevices);
|
||||
}
|
||||
|
||||
bool isAlwaysSupportedOverride;
|
||||
|
||||
@override
|
||||
bool isDeviceSupportedForProject(Device device, FlutterProject flutterProject) {
|
||||
|
|
|
@ -1344,7 +1344,7 @@ class FailingKernelCompiler implements FuchsiaKernelCompiler {
|
|||
|
||||
class FakeFuchsiaDevFinder implements FuchsiaDevFinder {
|
||||
@override
|
||||
Future<List<String>> list() async {
|
||||
Future<List<String>> list({ Duration timeout }) async {
|
||||
return <String>['192.168.42.172 scare-cable-skip-joy'];
|
||||
}
|
||||
|
||||
|
@ -1356,7 +1356,7 @@ class FakeFuchsiaDevFinder implements FuchsiaDevFinder {
|
|||
|
||||
class FailingDevFinder implements FuchsiaDevFinder {
|
||||
@override
|
||||
Future<List<String>> list() async {
|
||||
Future<List<String>> list({ Duration timeout }) async {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
import 'package:flutter_tools/src/features.dart';
|
||||
import 'package:flutter_tools/src/linux/application_package.dart';
|
||||
import 'package:flutter_tools/src/linux/linux_device.dart';
|
||||
import 'package:flutter_tools/src/device.dart';
|
||||
|
@ -17,14 +16,17 @@ import 'package:platform/platform.dart';
|
|||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
import '../../src/testbed.dart';
|
||||
|
||||
void main() {
|
||||
final LinuxDevice device = LinuxDevice();
|
||||
final MockPlatform notLinux = MockPlatform();
|
||||
|
||||
when(notLinux.isLinux).thenReturn(false);
|
||||
|
||||
testUsingContext('LinuxDevice defaults', () async {
|
||||
final MockPlatform mockLinuxPlatform = MockPlatform();
|
||||
when(mockLinuxPlatform.isLinux).thenReturn(true);
|
||||
|
||||
testWithoutContext('LinuxDevice defaults', () async {
|
||||
final PrebuiltLinuxApp linuxApp = PrebuiltLinuxApp(executable: 'foo');
|
||||
expect(await device.targetPlatform, TargetPlatform.linux_x64);
|
||||
expect(device.name, 'Linux');
|
||||
|
@ -36,13 +38,36 @@ void main() {
|
|||
expect(device.category, Category.desktop);
|
||||
});
|
||||
|
||||
testUsingContext('LinuxDevice: no devices listed if platform unsupported', () async {
|
||||
testWithoutContext('LinuxDevice: no devices listed if platform unsupported', () async {
|
||||
expect(await LinuxDevices(
|
||||
platform: notLinux,
|
||||
featureFlags: featureFlags,
|
||||
featureFlags: TestFeatureFlags(isLinuxEnabled: true),
|
||||
).devices, <Device>[]);
|
||||
});
|
||||
|
||||
testWithoutContext('LinuxDevice: no devices listed if Linux feature flag disabled', () async {
|
||||
expect(await LinuxDevices(
|
||||
platform: mockLinuxPlatform,
|
||||
featureFlags: TestFeatureFlags(isLinuxEnabled: false),
|
||||
).devices, <Device>[]);
|
||||
});
|
||||
|
||||
testWithoutContext('LinuxDevice: devices', () async {
|
||||
expect(await LinuxDevices(
|
||||
platform: mockLinuxPlatform,
|
||||
featureFlags: TestFeatureFlags(isLinuxEnabled: true),
|
||||
).devices, hasLength(1));
|
||||
});
|
||||
|
||||
testWithoutContext('LinuxDevice: discoverDevices', () async {
|
||||
// Timeout ignored.
|
||||
final List<Device> devices = await LinuxDevices(
|
||||
platform: mockLinuxPlatform,
|
||||
featureFlags: TestFeatureFlags(isLinuxEnabled: true),
|
||||
).discoverDevices(timeout: const Duration(seconds: 10));
|
||||
expect(devices, hasLength(1));
|
||||
});
|
||||
|
||||
testUsingContext('LinuxDevice.isSupportedForProject is true with editable host app', () async {
|
||||
globals.fs.file('pubspec.yaml').createSync();
|
||||
globals.fs.file('.packages').createSync();
|
||||
|
|
|
@ -13,20 +13,27 @@ import 'package:flutter_tools/src/base/file_system.dart';
|
|||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
import 'package:flutter_tools/src/device.dart';
|
||||
import 'package:flutter_tools/src/features.dart';
|
||||
import 'package:flutter_tools/src/macos/application_package.dart';
|
||||
import 'package:flutter_tools/src/macos/macos_device.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
import '../../src/testbed.dart';
|
||||
|
||||
void main() {
|
||||
group(MacOSDevice, () {
|
||||
final MockPlatform notMac = MockPlatform();
|
||||
final MacOSDevice device = MacOSDevice();
|
||||
final MockProcessManager mockProcessManager = MockProcessManager();
|
||||
|
||||
final MockPlatform notMac = MockPlatform();
|
||||
when(notMac.isMacOS).thenReturn(false);
|
||||
when(notMac.environment).thenReturn(const <String, String>{});
|
||||
|
||||
final MockPlatform mockMacPlatform = MockPlatform();
|
||||
when(mockMacPlatform.isMacOS).thenReturn(true);
|
||||
|
||||
when(mockProcessManager.run(any)).thenAnswer((Invocation invocation) async {
|
||||
return ProcessResult(0, 1, '', '');
|
||||
});
|
||||
|
@ -48,6 +55,22 @@ void main() {
|
|||
Platform: () => notMac,
|
||||
});
|
||||
|
||||
testUsingContext('devices', () async {
|
||||
expect(await MacOSDevices().devices, hasLength(1));
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => mockMacPlatform,
|
||||
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
|
||||
});
|
||||
|
||||
testUsingContext('discoverDevices', () async {
|
||||
// Timeout ignored.
|
||||
final List<Device> devices = await MacOSDevices().discoverDevices(timeout: const Duration(seconds: 10));
|
||||
expect(devices, hasLength(1));
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => mockMacPlatform,
|
||||
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
|
||||
});
|
||||
|
||||
testUsingContext('isSupportedForProject is true with editable host app', () async {
|
||||
globals.fs.file('pubspec.yaml').createSync();
|
||||
globals.fs.file('.packages').createSync();
|
||||
|
|
|
@ -359,6 +359,18 @@ void main() {
|
|||
Platform: () => macPlatform,
|
||||
});
|
||||
|
||||
testWithoutContext('uses timeout', () async {
|
||||
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
|
||||
|
||||
when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice']))
|
||||
.thenReturn(ProcessResult(1, 0, '/path/to/xcdevice', ''));
|
||||
|
||||
when(processManager.run(any))
|
||||
.thenAnswer((_) => Future<ProcessResult>.value(ProcessResult(1, 0, '[]', '')));
|
||||
await xcdevice.getAvailableTetheredIOSDevices(timeout: const Duration(seconds: 20));
|
||||
verify(processManager.run(<String>['xcrun', 'xcdevice', 'list', '--timeout', '20'])).called(1);
|
||||
});
|
||||
|
||||
testUsingContext('ignores "Preparing debugger support for iPhone" error', () async {
|
||||
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
|
||||
|
||||
|
|
|
@ -64,6 +64,15 @@ void main() {
|
|||
expect(device, isA<FlutterTesterDevice>());
|
||||
expect(device.id, 'flutter-tester');
|
||||
});
|
||||
|
||||
testUsingContext('discoverDevices', () async {
|
||||
FlutterTesterDevices.showFlutterTesterDevice = true;
|
||||
final FlutterTesterDevices discoverer = FlutterTesterDevices();
|
||||
|
||||
// Timeout ignored.
|
||||
final List<Device> devices = await discoverer.discoverDevices(timeout: const Duration(seconds: 10));
|
||||
expect(devices, hasLength(1));
|
||||
});
|
||||
});
|
||||
|
||||
group('FlutterTesterDevice', () {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
import 'package:flutter_tools/src/features.dart';
|
||||
import 'package:flutter_tools/src/project.dart';
|
||||
import 'package:flutter_tools/src/windows/application_package.dart';
|
||||
import 'package:flutter_tools/src/windows/windows_device.dart';
|
||||
|
@ -15,15 +16,19 @@ import 'package:platform/platform.dart';
|
|||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
import '../../src/testbed.dart';
|
||||
|
||||
void main() {
|
||||
group(WindowsDevice, () {
|
||||
final WindowsDevice device = WindowsDevice();
|
||||
final MockPlatform notWindows = MockPlatform();
|
||||
|
||||
final MockPlatform notWindows = MockPlatform();
|
||||
when(notWindows.isWindows).thenReturn(false);
|
||||
when(notWindows.environment).thenReturn(const <String, String>{});
|
||||
|
||||
final MockPlatform mockWindowsPlatform = MockPlatform();
|
||||
when(mockWindowsPlatform.isWindows).thenReturn(true);
|
||||
|
||||
testUsingContext('defaults', () async {
|
||||
final PrebuiltWindowsApp windowsApp = PrebuiltWindowsApp(executable: 'foo');
|
||||
expect(await device.targetPlatform, TargetPlatform.windows_x64);
|
||||
|
@ -41,6 +46,22 @@ void main() {
|
|||
Platform: () => notWindows,
|
||||
});
|
||||
|
||||
testUsingContext('WindowsDevices: devices', () async {
|
||||
expect(await WindowsDevices().devices, hasLength(1));
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => mockWindowsPlatform,
|
||||
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
||||
});
|
||||
|
||||
testUsingContext('WindowsDevices: discoverDevices', () async {
|
||||
// Timeout ignored.
|
||||
final List<Device> devices = await WindowsDevices().discoverDevices(timeout: const Duration(seconds: 10));
|
||||
expect(devices, hasLength(1));
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => mockWindowsPlatform,
|
||||
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
||||
});
|
||||
|
||||
testUsingContext('isSupportedForProject is true with editable host app', () async {
|
||||
globals.fs.file('pubspec.yaml').createSync();
|
||||
globals.fs.file('.packages').createSync();
|
||||
|
|
|
@ -218,6 +218,9 @@ class FakeDeviceManager implements DeviceManager {
|
|||
@override
|
||||
Future<List<Device>> getAllConnectedDevices() async => devices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> refreshAllConnectedDevices({ Duration timeout }) async => devices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> getDevicesById(String deviceId) async {
|
||||
return devices.where((Device device) => device.id == deviceId).toList();
|
||||
|
|
|
@ -526,7 +526,12 @@ class MockPollingDeviceDiscovery extends PollingDeviceDiscovery {
|
|||
final StreamController<Device> _onRemovedController = StreamController<Device>.broadcast();
|
||||
|
||||
@override
|
||||
Future<List<Device>> pollingGetDevices() async => _devices;
|
||||
Future<List<Device>> pollingGetDevices({ Duration timeout }) async {
|
||||
lastPollingTimeout = timeout;
|
||||
return _devices;
|
||||
}
|
||||
|
||||
Duration lastPollingTimeout;
|
||||
|
||||
@override
|
||||
bool get supportsPlatform => true;
|
||||
|
@ -534,14 +539,22 @@ class MockPollingDeviceDiscovery extends PollingDeviceDiscovery {
|
|||
@override
|
||||
bool get canListAnything => true;
|
||||
|
||||
void addDevice(MockAndroidDevice device) {
|
||||
void addDevice(Device device) {
|
||||
_devices.add(device);
|
||||
|
||||
_onAddedController.add(device);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Device>> get devices async => _devices;
|
||||
void _removeDevice(Device device) {
|
||||
_devices.remove(device);
|
||||
_onRemovedController.add(device);
|
||||
}
|
||||
|
||||
void setDevices(List<Device> devices) {
|
||||
while(_devices.isNotEmpty) {
|
||||
_removeDevice(_devices.first);
|
||||
}
|
||||
devices.forEach(addDevice);
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<Device> get onAdded => _onAddedController.stream;
|
||||
|
|
Loading…
Reference in a new issue