Commit d6ec71d2 authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

Extract libimobiledevice tools interface (#10759)

Extract out IMobileDevice class, move class to idevice_id, ideviceinfo
(and eventually other libimobiledevice tools such as iproxy) behind this
interface.

Add tests for the case where libimobiledevice is not installed, the case
where it returns no devices, and the case where it returns device IDs.
parent 45446ae2
...@@ -43,7 +43,6 @@ class IOSDevice extends Device { ...@@ -43,7 +43,6 @@ class IOSDevice extends Device {
IOSDevice(String id, { this.name }) : super(id) { IOSDevice(String id, { this.name }) : super(id) {
_installerPath = _checkForCommand('ideviceinstaller'); _installerPath = _checkForCommand('ideviceinstaller');
_listerPath = _checkForCommand('idevice_id'); _listerPath = _checkForCommand('idevice_id');
_informerPath = _checkForCommand('ideviceinfo');
_iproxyPath = _checkForCommand('iproxy'); _iproxyPath = _checkForCommand('iproxy');
_debuggerPath = _checkForCommand('idevicedebug'); _debuggerPath = _checkForCommand('idevicedebug');
_loggerPath = _checkForCommand('idevicesyslog'); _loggerPath = _checkForCommand('idevicesyslog');
...@@ -62,9 +61,6 @@ class IOSDevice extends Device { ...@@ -62,9 +61,6 @@ class IOSDevice extends Device {
String _listerPath; String _listerPath;
String get listerPath => _listerPath; String get listerPath => _listerPath;
String _informerPath;
String get informerPath => _informerPath;
String _iproxyPath; String _iproxyPath;
String get iproxyPath => _iproxyPath; String get iproxyPath => _iproxyPath;
...@@ -97,32 +93,17 @@ class IOSDevice extends Device { ...@@ -97,32 +93,17 @@ class IOSDevice extends Device {
bool get supportsStartPaused => false; bool get supportsStartPaused => false;
static List<IOSDevice> getAttachedDevices() { static List<IOSDevice> getAttachedDevices() {
if (!iosWorkflow.hasIDeviceId) if (!iMobileDevice.isInstalled)
return <IOSDevice>[]; return <IOSDevice>[];
final List<IOSDevice> devices = <IOSDevice>[]; final List<IOSDevice> devices = <IOSDevice>[];
for (String id in _getAttachedDeviceIDs()) { for (String id in iMobileDevice.getAttachedDeviceIDs()) {
final String name = IOSDevice._getDeviceInfo(id, 'DeviceName'); final String name = iMobileDevice.getInfoForDevice(id, 'DeviceName');
devices.add(new IOSDevice(id, name: name)); devices.add(new IOSDevice(id, name: name));
} }
return devices; return devices;
} }
static Iterable<String> _getAttachedDeviceIDs() {
final String listerPath = _checkForCommand('idevice_id');
try {
final String output = runSync(<String>[listerPath, '-l']);
return output.trim().split('\n').where((String s) => s != null && s.isNotEmpty);
} catch (e) {
return <String>[];
}
}
static String _getDeviceInfo(String deviceID, String infoKey) {
final String informerPath = _checkForCommand('ideviceinfo');
return runSync(<String>[informerPath, '-k', infoKey, '-u', deviceID]).trim();
}
static String _checkForCommand( static String _checkForCommand(
String command, [ String command, [
String macInstructions = _kIdeviceinstallerInstructions String macInstructions = _kIdeviceinstallerInstructions
...@@ -353,9 +334,9 @@ class IOSDevice extends Device { ...@@ -353,9 +334,9 @@ class IOSDevice extends Device {
@override @override
Future<String> get sdkNameAndVersion async => 'iOS $_sdkVersion ($_buildVersion)'; Future<String> get sdkNameAndVersion async => 'iOS $_sdkVersion ($_buildVersion)';
String get _sdkVersion => _getDeviceInfo(id, 'ProductVersion'); String get _sdkVersion => iMobileDevice.getInfoForDevice(id, 'ProductVersion');
String get _buildVersion => _getDeviceInfo(id, 'BuildVersion'); String get _buildVersion => iMobileDevice.getInfoForDevice(id, 'BuildVersion');
@override @override
DeviceLogReader getLogReader({ApplicationPackage app}) { DeviceLogReader getLogReader({ApplicationPackage app}) {
......
...@@ -7,7 +7,6 @@ import 'dart:async'; ...@@ -7,7 +7,6 @@ import 'dart:async';
import '../base/common.dart'; 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/os.dart'; import '../base/os.dart';
import '../base/platform.dart'; import '../base/platform.dart';
import '../base/process.dart'; import '../base/process.dart';
...@@ -34,21 +33,6 @@ class IOSWorkflow extends DoctorValidator implements Workflow { ...@@ -34,21 +33,6 @@ class IOSWorkflow extends DoctorValidator implements Workflow {
@override @override
bool get canLaunchDevices => xcode.isInstalledAndMeetsVersionCheck; bool get canLaunchDevices => xcode.isInstalledAndMeetsVersionCheck;
bool get hasIDeviceId => exitsHappy(<String>['idevice_id', '-h']);
Future<bool> get hasWorkingLibimobiledevice async {
// Verify that libimobiledevice tools are installed.
if (!hasIDeviceId)
return false;
// If a device is attached, verify that we can get its name.
final ProcessResult result = (await runAsync(<String>['idevice_id', '-l'])).processResult;
if (result.exitCode == 0 && result.stdout.isNotEmpty && !await exitsHappyAsync(<String>['idevicename']))
return false;
return true;
}
Future<bool> get hasIDeviceInstaller => exitsHappyAsync(<String>['ideviceinstaller', '-h']); Future<bool> get hasIDeviceInstaller => exitsHappyAsync(<String>['ideviceinstaller', '-h']);
Future<bool> get hasIosDeploy => exitsHappyAsync(<String>['ios-deploy', '--version']); Future<bool> get hasIosDeploy => exitsHappyAsync(<String>['ios-deploy', '--version']);
...@@ -154,7 +138,7 @@ class IOSWorkflow extends DoctorValidator implements Workflow { ...@@ -154,7 +138,7 @@ class IOSWorkflow extends DoctorValidator implements Workflow {
if (hasHomebrew) { if (hasHomebrew) {
brewStatus = ValidationType.installed; brewStatus = ValidationType.installed;
if (!await hasWorkingLibimobiledevice) { if (!await iMobileDevice.isWorking) {
brewStatus = ValidationType.partial; brewStatus = ValidationType.partial;
messages.add(new ValidationMessage.error( messages.add(new ValidationMessage.error(
'libimobiledevice and ideviceinstaller are not installed or require updating. To update, run:\n' 'libimobiledevice and ideviceinstaller are not installed or require updating. To update, run:\n'
......
...@@ -33,6 +33,8 @@ const int kXcodeRequiredVersionMinor = 0; ...@@ -33,6 +33,8 @@ const int kXcodeRequiredVersionMinor = 0;
// Homebrew. // Homebrew.
const PythonModule kPythonSix = const PythonModule('six'); const PythonModule kPythonSix = const PythonModule('six');
IMobileDevice get iMobileDevice => context.putIfAbsent(IMobileDevice, () => const IMobileDevice());
class PythonModule { class PythonModule {
const PythonModule(this.name); const PythonModule(this.name);
...@@ -45,6 +47,43 @@ class PythonModule { ...@@ -45,6 +47,43 @@ class PythonModule {
'Install via \'pip install $name\' or \'sudo easy_install $name\'.'; 'Install via \'pip install $name\' or \'sudo easy_install $name\'.';
} }
class IMobileDevice {
const IMobileDevice();
bool get isInstalled => exitsHappy(<String>['idevice_id', '-h']);
/// Returns true if libimobiledevice is installed and working as expected.
///
/// Older releases of libimobiledevice fail to work with iOS 10.3 and above.
Future<bool> get isWorking async {
if (!isInstalled)
return false;
// If no device is attached, we're unable to detect any problems. Assume all is well.
final ProcessResult result = (await runAsync(<String>['idevice_id', '-l'])).processResult;
if (result.exitCode != 0 || result.stdout.isEmpty)
return true;
// Check that we can look up the names of any attached devices.
return await exitsHappyAsync(<String>['idevicename']);
}
List<String> getAttachedDeviceIDs() {
return runSync(<String>['idevice_id', '-l'])
.trim()
.split('\n')
.where((String line) => line.isNotEmpty)
.toList();
}
/// Returns the value associated with the specified `ideviceinfo` key for a device.
///
/// If either the specified key or device does not exist, returns the empty string.
String getInfoForDevice(String deviceID, String key) {
return runSync(<String>['ideviceinfo', '-k', key, '-u', deviceID]).trim();
}
}
class Xcode { class Xcode {
Xcode() { Xcode() {
_eulaSigned = false; _eulaSigned = false;
......
...@@ -8,6 +8,7 @@ import 'dart:io' show ProcessResult; ...@@ -8,6 +8,7 @@ import 'dart:io' show ProcessResult;
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/ios/devices.dart'; import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/mac.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
...@@ -16,12 +17,57 @@ import 'package:test/test.dart'; ...@@ -16,12 +17,57 @@ import 'package:test/test.dart';
import '../src/context.dart'; import '../src/context.dart';
class MockProcessManager extends Mock implements ProcessManager {} class MockProcessManager extends Mock implements ProcessManager {}
class MockIMobileDevice extends Mock implements IMobileDevice {}
class MockFile extends Mock implements File {} class MockFile extends Mock implements File {}
void main() { void main() {
final FakePlatform osx = new FakePlatform.fromPlatform(const LocalPlatform()); final FakePlatform osx = new FakePlatform.fromPlatform(const LocalPlatform());
osx.operatingSystem = 'macos'; osx.operatingSystem = 'macos';
group('getAttachedDevices', () {
MockIMobileDevice mockIMobileDevice;
setUp(() {
mockIMobileDevice = new MockIMobileDevice();
});
testUsingContext('return no devices if libimobiledevice is not installed', () async {
when(mockIMobileDevice.isInstalled).thenReturn(false);
expect(IOSDevice.getAttachedDevices(), isEmpty);
}, overrides: <Type, Generator>{
IMobileDevice: () => mockIMobileDevice,
});
testUsingContext('returns no devices if none are attached', () async {
when(mockIMobileDevice.isInstalled).thenReturn(true);
when(mockIMobileDevice.getAttachedDeviceIDs()).thenReturn(<String>[]);
final List<IOSDevice> devices = IOSDevice.getAttachedDevices();
expect(devices, isEmpty);
}, overrides: <Type, Generator>{
IMobileDevice: () => mockIMobileDevice,
});
testUsingContext('returns attached devices', () async {
when(mockIMobileDevice.isInstalled).thenReturn(true);
when(mockIMobileDevice.getAttachedDeviceIDs()).thenReturn(<String>[
'98206e7a4afd4aedaff06e687594e089dede3c44',
'f577a7903cc54959be2e34bc4f7f80b7009efcf4',
]);
when(mockIMobileDevice.getInfoForDevice('98206e7a4afd4aedaff06e687594e089dede3c44', 'DeviceName'))
.thenReturn('La tele me regarde');
when(mockIMobileDevice.getInfoForDevice('f577a7903cc54959be2e34bc4f7f80b7009efcf4', 'DeviceName'))
.thenReturn('Puits sans fond');
final List<IOSDevice> devices = IOSDevice.getAttachedDevices();
expect(devices, hasLength(2));
expect(devices[0].id, '98206e7a4afd4aedaff06e687594e089dede3c44');
expect(devices[0].name, 'La tele me regarde');
expect(devices[1].id, 'f577a7903cc54959be2e34bc4f7f80b7009efcf4');
expect(devices[1].name, 'Puits sans fond');
}, overrides: <Type, Generator>{
IMobileDevice: () => mockIMobileDevice,
});
});
group('screenshot', () { group('screenshot', () {
MockProcessManager mockProcessManager; MockProcessManager mockProcessManager;
MockFile mockOutputFile; MockFile mockOutputFile;
......
...@@ -19,11 +19,13 @@ import '../src/context.dart'; ...@@ -19,11 +19,13 @@ import '../src/context.dart';
void main() { void main() {
group('iOS Workflow validation', () { group('iOS Workflow validation', () {
MockIMobileDevice iMobileDevice;
MockXcode xcode; MockXcode xcode;
MockProcessManager processManager; MockProcessManager processManager;
FileSystem fs; FileSystem fs;
setUp(() { setUp(() {
iMobileDevice = new MockIMobileDevice();
xcode = new MockXcode(); xcode = new MockXcode();
processManager = new MockProcessManager(); processManager = new MockProcessManager();
fs = new MemoryFileSystem(); fs = new MemoryFileSystem();
...@@ -39,7 +41,10 @@ void main() { ...@@ -39,7 +41,10 @@ void main() {
); );
final ValidationResult result = await workflow.validate(); final ValidationResult result = await workflow.validate();
expect(result.type, ValidationType.missing); expect(result.type, ValidationType.missing);
}, overrides: <Type, Generator>{ Xcode: () => xcode }); }, overrides: <Type, Generator>{
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode,
});
testUsingContext('Emits partial status when Xcode is not installed', () async { testUsingContext('Emits partial status when Xcode is not installed', () async {
when(xcode.isInstalled).thenReturn(false); when(xcode.isInstalled).thenReturn(false);
...@@ -47,7 +52,10 @@ void main() { ...@@ -47,7 +52,10 @@ void main() {
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(); final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget();
final ValidationResult result = await workflow.validate(); final ValidationResult result = await workflow.validate();
expect(result.type, ValidationType.partial); expect(result.type, ValidationType.partial);
}, overrides: <Type, Generator>{ Xcode: () => xcode }); }, overrides: <Type, Generator>{
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode,
});
testUsingContext('Emits partial status when Xcode is partially installed', () async { testUsingContext('Emits partial status when Xcode is partially installed', () async {
when(xcode.isInstalled).thenReturn(false); when(xcode.isInstalled).thenReturn(false);
...@@ -55,7 +63,10 @@ void main() { ...@@ -55,7 +63,10 @@ void main() {
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(); final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget();
final ValidationResult result = await workflow.validate(); final ValidationResult result = await workflow.validate();
expect(result.type, ValidationType.partial); expect(result.type, ValidationType.partial);
}, overrides: <Type, Generator>{ Xcode: () => xcode }); }, overrides: <Type, Generator>{
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode,
});
testUsingContext('Emits partial status when Xcode version too low', () async { testUsingContext('Emits partial status when Xcode version too low', () async {
when(xcode.isInstalled).thenReturn(true); when(xcode.isInstalled).thenReturn(true);
...@@ -66,7 +77,10 @@ void main() { ...@@ -66,7 +77,10 @@ void main() {
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(); final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget();
final ValidationResult result = await workflow.validate(); final ValidationResult result = await workflow.validate();
expect(result.type, ValidationType.partial); expect(result.type, ValidationType.partial);
}, overrides: <Type, Generator>{ Xcode: () => xcode }); }, overrides: <Type, Generator>{
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode,
});
testUsingContext('Emits partial status when Xcode EULA not signed', () async { testUsingContext('Emits partial status when Xcode EULA not signed', () async {
when(xcode.isInstalled).thenReturn(true); when(xcode.isInstalled).thenReturn(true);
...@@ -77,7 +91,10 @@ void main() { ...@@ -77,7 +91,10 @@ void main() {
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(); final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget();
final ValidationResult result = await workflow.validate(); final ValidationResult result = await workflow.validate();
expect(result.type, ValidationType.partial); expect(result.type, ValidationType.partial);
}, overrides: <Type, Generator>{ Xcode: () => xcode }); }, overrides: <Type, Generator>{
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode,
});
testUsingContext('Emits partial status when python six not installed', () async { testUsingContext('Emits partial status when python six not installed', () async {
when(xcode.isInstalled).thenReturn(true); when(xcode.isInstalled).thenReturn(true);
...@@ -88,7 +105,10 @@ void main() { ...@@ -88,7 +105,10 @@ void main() {
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasPythonSixModule: false); final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasPythonSixModule: false);
final ValidationResult result = await workflow.validate(); final ValidationResult result = await workflow.validate();
expect(result.type, ValidationType.partial); expect(result.type, ValidationType.partial);
}, overrides: <Type, Generator>{ Xcode: () => xcode }); }, overrides: <Type, Generator>{
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode,
});
testUsingContext('Emits partial status when homebrew not installed', () async { testUsingContext('Emits partial status when homebrew not installed', () async {
when(xcode.isInstalled).thenReturn(true); when(xcode.isInstalled).thenReturn(true);
...@@ -99,7 +119,10 @@ void main() { ...@@ -99,7 +119,10 @@ void main() {
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasHomebrew: false); final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasHomebrew: false);
final ValidationResult result = await workflow.validate(); final ValidationResult result = await workflow.validate();
expect(result.type, ValidationType.partial); expect(result.type, ValidationType.partial);
}, overrides: <Type, Generator>{ Xcode: () => xcode }); }, overrides: <Type, Generator>{
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode,
});
testUsingContext('Emits partial status when libimobiledevice is not installed', () async { testUsingContext('Emits partial status when libimobiledevice is not installed', () async {
when(xcode.isInstalled).thenReturn(true); when(xcode.isInstalled).thenReturn(true);
...@@ -107,10 +130,13 @@ void main() { ...@@ -107,10 +130,13 @@ void main() {
.thenReturn('Xcode 8.2.1\nBuild version 8C1002\n'); .thenReturn('Xcode 8.2.1\nBuild version 8C1002\n');
when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true); when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
when(xcode.eulaSigned).thenReturn(true); when(xcode.eulaSigned).thenReturn(true);
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasWorkingLibimobiledevice: false); final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget();
final ValidationResult result = await workflow.validate(); final ValidationResult result = await workflow.validate();
expect(result.type, ValidationType.partial); expect(result.type, ValidationType.partial);
}, overrides: <Type, Generator>{ Xcode: () => xcode }); }, overrides: <Type, Generator>{
IMobileDevice: () => new MockIMobileDevice(isWorking: false),
Xcode: () => xcode,
});
testUsingContext('Emits partial status when ios-deploy is not installed', () async { testUsingContext('Emits partial status when ios-deploy is not installed', () async {
when(xcode.isInstalled).thenReturn(true); when(xcode.isInstalled).thenReturn(true);
...@@ -121,7 +147,10 @@ void main() { ...@@ -121,7 +147,10 @@ void main() {
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasIosDeploy: false); final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasIosDeploy: false);
final ValidationResult result = await workflow.validate(); final ValidationResult result = await workflow.validate();
expect(result.type, ValidationType.partial); expect(result.type, ValidationType.partial);
}, overrides: <Type, Generator>{ Xcode: () => xcode }); }, overrides: <Type, Generator>{
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode,
});
testUsingContext('Emits partial status when ios-deploy version is too low', () async { testUsingContext('Emits partial status when ios-deploy version is too low', () async {
when(xcode.isInstalled).thenReturn(true); when(xcode.isInstalled).thenReturn(true);
...@@ -132,7 +161,10 @@ void main() { ...@@ -132,7 +161,10 @@ void main() {
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(iosDeployVersionText: '1.8.0'); final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(iosDeployVersionText: '1.8.0');
final ValidationResult result = await workflow.validate(); final ValidationResult result = await workflow.validate();
expect(result.type, ValidationType.partial); expect(result.type, ValidationType.partial);
}, overrides: <Type, Generator>{ Xcode: () => xcode }); }, overrides: <Type, Generator>{
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode,
});
testUsingContext('Emits partial status when CocoaPods is not installed', () async { testUsingContext('Emits partial status when CocoaPods is not installed', () async {
when(xcode.isInstalled).thenReturn(true); when(xcode.isInstalled).thenReturn(true);
...@@ -143,7 +175,10 @@ void main() { ...@@ -143,7 +175,10 @@ void main() {
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasCocoaPods: false); final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasCocoaPods: false);
final ValidationResult result = await workflow.validate(); final ValidationResult result = await workflow.validate();
expect(result.type, ValidationType.partial); expect(result.type, ValidationType.partial);
}, overrides: <Type, Generator>{ Xcode: () => xcode }); }, overrides: <Type, Generator>{
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode,
});
testUsingContext('Emits partial status when CocoaPods version is too low', () async { testUsingContext('Emits partial status when CocoaPods version is too low', () async {
when(xcode.isInstalled).thenReturn(true); when(xcode.isInstalled).thenReturn(true);
...@@ -154,7 +189,10 @@ void main() { ...@@ -154,7 +189,10 @@ void main() {
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(cocoaPodsVersionText: '0.39.0'); final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(cocoaPodsVersionText: '0.39.0');
final ValidationResult result = await workflow.validate(); final ValidationResult result = await workflow.validate();
expect(result.type, ValidationType.partial); expect(result.type, ValidationType.partial);
}, overrides: <Type, Generator>{ Xcode: () => xcode }); }, overrides: <Type, Generator>{
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode,
});
testUsingContext('Emits partial status when CocoaPods is not initialized', () async { testUsingContext('Emits partial status when CocoaPods is not initialized', () async {
when(xcode.isInstalled).thenReturn(true); when(xcode.isInstalled).thenReturn(true);
...@@ -172,6 +210,7 @@ void main() { ...@@ -172,6 +210,7 @@ void main() {
expect(result.type, ValidationType.partial); expect(result.type, ValidationType.partial);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode, Xcode: () => xcode,
ProcessManager: () => processManager, ProcessManager: () => processManager,
}); });
...@@ -194,6 +233,7 @@ void main() { ...@@ -194,6 +233,7 @@ void main() {
expect(result.type, ValidationType.installed); expect(result.type, ValidationType.installed);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode, Xcode: () => xcode,
ProcessManager: () => processManager, ProcessManager: () => processManager,
}); });
...@@ -207,6 +247,13 @@ final ProcessResult exitsHappy = new ProcessResult( ...@@ -207,6 +247,13 @@ final ProcessResult exitsHappy = new ProcessResult(
'', // stderr '', // stderr
); );
class MockIMobileDevice extends IMobileDevice {
MockIMobileDevice({bool isWorking: true}) : isWorking = new Future<bool>.value(isWorking);
@override
final Future<bool> isWorking;
}
class MockXcode extends Mock implements Xcode {} class MockXcode extends Mock implements Xcode {}
class MockProcessManager extends Mock implements ProcessManager {} class MockProcessManager extends Mock implements ProcessManager {}
...@@ -214,14 +261,12 @@ class IOSWorkflowTestTarget extends IOSWorkflow { ...@@ -214,14 +261,12 @@ class IOSWorkflowTestTarget extends IOSWorkflow {
IOSWorkflowTestTarget({ IOSWorkflowTestTarget({
this.hasPythonSixModule: true, this.hasPythonSixModule: true,
this.hasHomebrew: true, this.hasHomebrew: true,
bool hasWorkingLibimobiledevice: true,
bool hasIosDeploy: true, bool hasIosDeploy: true,
String iosDeployVersionText: '1.9.0', String iosDeployVersionText: '1.9.0',
bool hasIDeviceInstaller: true, bool hasIDeviceInstaller: true,
bool hasCocoaPods: true, bool hasCocoaPods: true,
String cocoaPodsVersionText: '1.2.0', String cocoaPodsVersionText: '1.2.0',
}) : hasWorkingLibimobiledevice = new Future<bool>.value(hasWorkingLibimobiledevice), }) : hasIosDeploy = new Future<bool>.value(hasIosDeploy),
hasIosDeploy = new Future<bool>.value(hasIosDeploy),
iosDeployVersionText = new Future<String>.value(iosDeployVersionText), iosDeployVersionText = new Future<String>.value(iosDeployVersionText),
hasIDeviceInstaller = new Future<bool>.value(hasIDeviceInstaller), hasIDeviceInstaller = new Future<bool>.value(hasIDeviceInstaller),
hasCocoaPods = new Future<bool>.value(hasCocoaPods), hasCocoaPods = new Future<bool>.value(hasCocoaPods),
...@@ -233,9 +278,6 @@ class IOSWorkflowTestTarget extends IOSWorkflow { ...@@ -233,9 +278,6 @@ class IOSWorkflowTestTarget extends IOSWorkflow {
@override @override
final bool hasHomebrew; final bool hasHomebrew;
@override
final Future<bool> hasWorkingLibimobiledevice;
@override @override
final Future<bool> hasIosDeploy; final Future<bool> hasIosDeploy;
......
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