Unverified Commit 9bd2e400 authored by Christopher Fujino's avatar Christopher Fujino Committed by GitHub

Throw exception if instantiating IOSDevice on non-mac os platform (#36288)

parent a52f0f77
...@@ -125,14 +125,12 @@ class IOSDevice extends Device { ...@@ -125,14 +125,12 @@ class IOSDevice extends Device {
ephemeral: true, ephemeral: true,
) { ) {
if (!platform.isMacOS) { if (!platform.isMacOS) {
printError('Cannot control iOS devices or simulators. ideviceinstaller and iproxy are not available on your platform.'); assert(false, 'Control of iOS devices or simulators only supported on Mac OS.');
_installerPath = null;
_iproxyPath = null;
return; return;
} }
_installerPath = artifacts.getArtifactPath( _installerPath = artifacts.getArtifactPath(
Artifact.ideviceinstaller, Artifact.ideviceinstaller,
platform: TargetPlatform.ios platform: TargetPlatform.ios,
) ?? 'ideviceinstaller'; // TODO(fujino): remove fallback once g3 updated ) ?? 'ideviceinstaller'; // TODO(fujino): remove fallback once g3 updated
_iproxyPath = artifacts.getArtifactPath( _iproxyPath = artifacts.getArtifactPath(
Artifact.iproxy, Artifact.iproxy,
...@@ -168,6 +166,9 @@ class IOSDevice extends Device { ...@@ -168,6 +166,9 @@ class IOSDevice extends Device {
bool get supportsStartPaused => false; bool get supportsStartPaused => false;
static Future<List<IOSDevice>> getAttachedDevices() async { static Future<List<IOSDevice>> getAttachedDevices() async {
if (!platform.isMacOS) {
throw UnsupportedError('Control of iOS devices or simulators only supported on Mac OS.');
}
if (!iMobileDevice.isInstalled) if (!iMobileDevice.isInstalled)
return <IOSDevice>[]; return <IOSDevice>[];
......
...@@ -38,6 +38,30 @@ class MockProcess extends Mock implements Process {} ...@@ -38,6 +38,30 @@ class MockProcess extends Mock implements Process {}
void main() { void main() {
final FakePlatform macPlatform = FakePlatform.fromPlatform(const LocalPlatform()); final FakePlatform macPlatform = FakePlatform.fromPlatform(const LocalPlatform());
macPlatform.operatingSystem = 'macos'; macPlatform.operatingSystem = 'macos';
final FakePlatform linuxPlatform = FakePlatform.fromPlatform(const LocalPlatform());
linuxPlatform.operatingSystem = 'linux';
final FakePlatform windowsPlatform = FakePlatform.fromPlatform(const LocalPlatform());
windowsPlatform.operatingSystem = 'windows';
group('IOSDevice', () {
final List<Platform> unsupportedPlatforms = <Platform>[linuxPlatform, windowsPlatform];
testUsingContext('successfully instantiates on Mac OS', () {
IOSDevice('device-123');
}, overrides: <Type, Generator>{
Platform: () => macPlatform,
});
for (Platform platform in unsupportedPlatforms) {
testUsingContext('throws UnsupportedError exception if instantiated on ${platform.operatingSystem}', () {
expect(
() { IOSDevice('device-123'); },
throwsA(isInstanceOf<AssertionError>())
);
}, overrides: <Type, Generator>{
Platform: () => platform,
});
}
group('Process calls', () { group('Process calls', () {
MockIOSApp mockApp; MockIOSApp mockApp;
...@@ -126,6 +150,7 @@ void main() { ...@@ -126,6 +150,7 @@ void main() {
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
}); });
}); });
});
group('getAttachedDevices', () { group('getAttachedDevices', () {
MockIMobileDevice mockIMobileDevice; MockIMobileDevice mockIMobileDevice;
...@@ -139,6 +164,7 @@ void main() { ...@@ -139,6 +164,7 @@ void main() {
expect(await IOSDevice.getAttachedDevices(), isEmpty); expect(await IOSDevice.getAttachedDevices(), isEmpty);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
IMobileDevice: () => mockIMobileDevice, IMobileDevice: () => mockIMobileDevice,
Platform: () => macPlatform,
}); });
testUsingContext('returns no devices if none are attached', () async { testUsingContext('returns no devices if none are attached', () async {
...@@ -149,8 +175,25 @@ void main() { ...@@ -149,8 +175,25 @@ void main() {
expect(devices, isEmpty); expect(devices, isEmpty);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
IMobileDevice: () => mockIMobileDevice, IMobileDevice: () => mockIMobileDevice,
Platform: () => macPlatform,
}); });
final List<Platform> unsupportedPlatforms = <Platform>[linuxPlatform, windowsPlatform];
for (Platform platform in unsupportedPlatforms) {
testUsingContext('throws Unsupported Operation exception on ${platform.operatingSystem}', () async {
when(iMobileDevice.isInstalled).thenReturn(false);
when(iMobileDevice.getAvailableDeviceIDs())
.thenAnswer((Invocation invocation) => Future<String>.value(''));
expect(
() async { await IOSDevice.getAttachedDevices(); },
throwsA(isInstanceOf<UnsupportedError>()),
);
}, overrides: <Type, Generator>{
IMobileDevice: () => mockIMobileDevice,
Platform: () => platform,
});
}
testUsingContext('returns attached devices', () async { testUsingContext('returns attached devices', () async {
when(iMobileDevice.isInstalled).thenReturn(true); when(iMobileDevice.isInstalled).thenReturn(true);
when(iMobileDevice.getAvailableDeviceIDs()) when(iMobileDevice.getAvailableDeviceIDs())
...@@ -174,6 +217,7 @@ f577a7903cc54959be2e34bc4f7f80b7009efcf4 ...@@ -174,6 +217,7 @@ f577a7903cc54959be2e34bc4f7f80b7009efcf4
expect(devices[1].name, 'Puits sans fond'); expect(devices[1].name, 'Puits sans fond');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
IMobileDevice: () => mockIMobileDevice, IMobileDevice: () => mockIMobileDevice,
Platform: () => macPlatform,
}); });
testUsingContext('returns attached devices and ignores devices that cannot be found by ideviceinfo', () async { testUsingContext('returns attached devices and ignores devices that cannot be found by ideviceinfo', () async {
...@@ -193,6 +237,7 @@ f577a7903cc54959be2e34bc4f7f80b7009efcf4 ...@@ -193,6 +237,7 @@ f577a7903cc54959be2e34bc4f7f80b7009efcf4
expect(devices[0].name, 'La tele me regarde'); expect(devices[0].name, 'La tele me regarde');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
IMobileDevice: () => mockIMobileDevice, IMobileDevice: () => mockIMobileDevice,
Platform: () => macPlatform,
}); });
}); });
...@@ -244,8 +289,8 @@ f577a7903cc54959be2e34bc4f7f80b7009efcf4 ...@@ -244,8 +289,8 @@ f577a7903cc54959be2e34bc4f7f80b7009efcf4
expect(lines, <String>['A is for ari', 'I is for ichigo']); expect(lines, <String>['A is for ari', 'I is for ichigo']);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
IMobileDevice: () => mockIMobileDevice, IMobileDevice: () => mockIMobileDevice,
Platform: () => macPlatform,
}); });
testUsingContext('includes multi-line Flutter logs in the output', () async { testUsingContext('includes multi-line Flutter logs in the output', () async {
when(mockIMobileDevice.startLogger('123456')).thenAnswer((Invocation invocation) { when(mockIMobileDevice.startLogger('123456')).thenAnswer((Invocation invocation) {
final Process mockProcess = MockProcess(); final Process mockProcess = MockProcess();
...@@ -280,9 +325,9 @@ f577a7903cc54959be2e34bc4f7f80b7009efcf4 ...@@ -280,9 +325,9 @@ f577a7903cc54959be2e34bc4f7f80b7009efcf4
expect(device.category, Category.mobile); expect(device.category, Category.mobile);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
IMobileDevice: () => mockIMobileDevice, IMobileDevice: () => mockIMobileDevice,
Platform: () => macPlatform,
}); });
}); });
testUsingContext('IOSDevice.isSupportedForProject is true on module project', () async { testUsingContext('IOSDevice.isSupportedForProject is true on module project', () async {
fs.file('pubspec.yaml') fs.file('pubspec.yaml')
..createSync() ..createSync()
...@@ -298,8 +343,8 @@ flutter: ...@@ -298,8 +343,8 @@ flutter:
expect(IOSDevice('test').isSupportedForProject(flutterProject), true); expect(IOSDevice('test').isSupportedForProject(flutterProject), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem(), FileSystem: () => MemoryFileSystem(),
Platform: () => macPlatform,
}); });
testUsingContext('IOSDevice.isSupportedForProject is true with editable host app', () async { testUsingContext('IOSDevice.isSupportedForProject is true with editable host app', () async {
fs.file('pubspec.yaml').createSync(); fs.file('pubspec.yaml').createSync();
fs.file('.packages').createSync(); fs.file('.packages').createSync();
...@@ -309,6 +354,7 @@ flutter: ...@@ -309,6 +354,7 @@ flutter:
expect(IOSDevice('test').isSupportedForProject(flutterProject), true); expect(IOSDevice('test').isSupportedForProject(flutterProject), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem(), FileSystem: () => MemoryFileSystem(),
Platform: () => macPlatform,
}); });
testUsingContext('IOSDevice.isSupportedForProject is false with no host app and no module', () async { testUsingContext('IOSDevice.isSupportedForProject is false with no host app and no module', () async {
...@@ -319,5 +365,6 @@ flutter: ...@@ -319,5 +365,6 @@ flutter:
expect(IOSDevice('test').isSupportedForProject(flutterProject), false); expect(IOSDevice('test').isSupportedForProject(flutterProject), false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem(), FileSystem: () => MemoryFileSystem(),
Platform: () => macPlatform,
}); });
} }
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