Unverified Commit 1eaa8c30 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Swap xcode_tests from MockProcessManager to FakeProcessManager (#56502)

parent 1aaf73fa
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart'; import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart' show ProcessException, ProcessResult; import 'package:flutter_tools/src/base/io.dart' show ProcessException, ProcessResult;
import 'package:flutter_tools/src/base/logger.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';
...@@ -20,267 +19,357 @@ import '../../src/common.dart'; ...@@ -20,267 +19,357 @@ import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/context.dart';
void main() { void main() {
ProcessManager processManager;
Logger logger; Logger logger;
setUp(() { setUp(() {
logger = BufferLogger.test(); logger = BufferLogger.test();
processManager = MockProcessManager();
}); });
group('Xcode', () { // Group exists to work around https://github.com/flutter/flutter/issues/56415.
Xcode xcode; // Do not add more `MockProcessManager` tests.
MockXcodeProjectInterpreter mockXcodeProjectInterpreter; group('MockProcessManager', () {
MockPlatform platform; ProcessManager processManager;
FileSystem fileSystem;
setUp(() { setUp(() {
fileSystem = MemoryFileSystem(); processManager = MockProcessManager();
mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
platform = MockPlatform();
xcode = Xcode(
logger: logger,
platform: platform,
fileSystem: fileSystem,
processManager: processManager,
xcodeProjectInterpreter: mockXcodeProjectInterpreter,
);
}); });
testWithoutContext('xcodeSelectPath returns null when xcode-select is not installed', () { group('Xcode', () {
when(processManager.runSync(<String>['/usr/bin/xcode-select', '--print-path'])) Xcode xcode;
setUp(() {
xcode = Xcode(
logger: logger,
platform: MockPlatform(),
fileSystem: MemoryFileSystem.test(),
processManager: processManager,
xcodeProjectInterpreter: MockXcodeProjectInterpreter(),
);
});
testWithoutContext('xcodeSelectPath returns null when xcode-select is not installed', () {
when(processManager.runSync(<String>['/usr/bin/xcode-select', '--print-path']))
.thenThrow(const ProcessException('/usr/bin/xcode-select', <String>['--print-path'])); .thenThrow(const ProcessException('/usr/bin/xcode-select', <String>['--print-path']));
expect(xcode.xcodeSelectPath, isNull); expect(xcode.xcodeSelectPath, isNull);
when(processManager.runSync(<String>['/usr/bin/xcode-select', '--print-path'])) when(processManager.runSync(<String>['/usr/bin/xcode-select', '--print-path']))
.thenThrow(ArgumentError('Invalid argument(s): Cannot find executable for /usr/bin/xcode-select')); .thenThrow(ArgumentError('Invalid argument(s): Cannot find executable for /usr/bin/xcode-select'));
expect(xcode.xcodeSelectPath, isNull); expect(xcode.xcodeSelectPath, isNull);
}); });
testWithoutContext('xcodeSelectPath returns path when xcode-select is installed', () { testWithoutContext('eulaSigned is false when clang is not installed', () {
const String xcodePath = '/Applications/Xcode8.0.app/Contents/Developer'; when(processManager.runSync(<String>['/usr/bin/xcrun', 'clang']))
when(processManager.runSync(<String>['/usr/bin/xcode-select', '--print-path'])) .thenThrow(const ProcessException('/usr/bin/xcrun', <String>['clang']));
.thenReturn(ProcessResult(1, 0, xcodePath, ''));
expect(xcode.xcodeSelectPath, xcodePath); expect(xcode.eulaSigned, isFalse);
});
}); });
testWithoutContext('xcodeVersionSatisfactory is false when version is less than minimum', () { group('xcdevice', () {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true); XCDevice xcdevice;
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(9); MockXcode mockXcode;
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
setUp(() {
expect(xcode.isVersionSatisfactory, isFalse); mockXcode = MockXcode();
}); xcdevice = XCDevice(
processManager: processManager,
logger: logger,
xcode: mockXcode,
platform: null,
artifacts: MockArtifacts(),
cache: MockCache(),
);
});
testWithoutContext('xcodeVersionSatisfactory is false when xcodebuild tools are not installed', () { testWithoutContext("xcrun can't find xcdevice", () {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(false); when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
expect(xcode.isVersionSatisfactory, isFalse); when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice']))
}); .thenThrow(const ProcessException('xcrun', <String>['--find', 'xcdevice']));
expect(xcdevice.isInstalled, false);
verify(processManager.runSync(any)).called(1);
});
testWithoutContext('xcodeVersionSatisfactory is true when version meets minimum', () { testWithoutContext('available devices xcdevice fails', () async {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true); when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(11);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
expect(xcode.isVersionSatisfactory, isTrue); when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice']))
}); .thenReturn(ProcessResult(1, 0, '/path/to/xcdevice', ''));
testWithoutContext('xcodeVersionSatisfactory is true when major version exceeds minimum', () { when(processManager.run(<String>['xcrun', 'xcdevice', 'list', '--timeout', '2']))
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true); .thenThrow(const ProcessException('xcrun', <String>['xcdevice', 'list', '--timeout', '2']));
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(12);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
expect(xcode.isVersionSatisfactory, isTrue); expect(await xcdevice.getAvailableTetheredIOSDevices(), isEmpty);
}); });
testWithoutContext('xcodeVersionSatisfactory is true when minor version exceeds minimum', () { testWithoutContext('diagnostics xcdevice fails', () async {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true); when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(11);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(3);
expect(xcode.isVersionSatisfactory, isTrue); when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice']))
}); .thenReturn(ProcessResult(1, 0, '/path/to/xcdevice', ''));
testWithoutContext('isInstalledAndMeetsVersionCheck is false when not macOS', () { when(processManager.run(<String>['xcrun', 'xcdevice', 'list', '--timeout', '2']))
when(platform.isMacOS).thenReturn(false); .thenThrow(const ProcessException('xcrun', <String>['xcdevice', 'list', '--timeout', '2']));
expect(xcode.isInstalledAndMeetsVersionCheck, isFalse); expect(await xcdevice.getDiagnostics(), isEmpty);
});
}); });
});
testWithoutContext('isInstalledAndMeetsVersionCheck is false when not installed', () { group('FakeProcessManager', () {
when(platform.isMacOS).thenReturn(true); FakeProcessManager fakeProcessManager;
const String xcodePath = '/Applications/Xcode8.0.app/Contents/Developer';
when(processManager.runSync(<String>['/usr/bin/xcode-select', '--print-path']))
.thenReturn(ProcessResult(1, 0, xcodePath, ''));
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(false);
expect(xcode.isInstalledAndMeetsVersionCheck, isFalse); setUp(() {
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
}); });
testWithoutContext('isInstalledAndMeetsVersionCheck is false when no xcode-select', () { group('Xcode', () {
when(platform.isMacOS).thenReturn(true); Xcode xcode;
when(processManager.runSync(<String>['/usr/bin/xcode-select', '--print-path'])) MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
.thenReturn(ProcessResult(1, 127, '', 'ERROR')); MockPlatform platform;
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(11); setUp(() {
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0); mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
platform = MockPlatform();
expect(xcode.isInstalledAndMeetsVersionCheck, isFalse); xcode = Xcode(
}); logger: logger,
platform: platform,
fileSystem: MemoryFileSystem.test(),
processManager: fakeProcessManager,
xcodeProjectInterpreter: mockXcodeProjectInterpreter,
);
});
testWithoutContext('isInstalledAndMeetsVersionCheck is false when version not satisfied', () { testWithoutContext('xcodeSelectPath returns path when xcode-select is installed', () {
when(platform.isMacOS).thenReturn(true); const String xcodePath = '/Applications/Xcode8.0.app/Contents/Developer';
const String xcodePath = '/Applications/Xcode8.0.app/Contents/Developer'; fakeProcessManager.addCommand(const FakeCommand(
when(processManager.runSync(<String>['/usr/bin/xcode-select', '--print-path'])) command: <String>['/usr/bin/xcode-select', '--print-path'],
.thenReturn(ProcessResult(1, 0, xcodePath, '')); stdout: xcodePath,
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true); ));
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(10);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(2);
expect(xcode.isInstalledAndMeetsVersionCheck, isFalse); expect(xcode.xcodeSelectPath, xcodePath);
}); expect(fakeProcessManager.hasRemainingExpectations, isFalse);
});
testWithoutContext('isInstalledAndMeetsVersionCheck is true when macOS and installed and version is satisfied', () { testWithoutContext('xcodeVersionSatisfactory is false when version is less than minimum', () {
when(platform.isMacOS).thenReturn(true); when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
const String xcodePath = '/Applications/Xcode8.0.app/Contents/Developer'; when(mockXcodeProjectInterpreter.majorVersion).thenReturn(9);
when(processManager.runSync(<String>['/usr/bin/xcode-select', '--print-path'])) when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
.thenReturn(ProcessResult(1, 0, xcodePath, ''));
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(11);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
expect(xcode.isInstalledAndMeetsVersionCheck, isTrue); expect(xcode.isVersionSatisfactory, isFalse);
}); });
testWithoutContext('eulaSigned is false when clang is not installed', () { testWithoutContext('xcodeVersionSatisfactory is false when xcodebuild tools are not installed', () {
when(processManager.runSync(<String>['/usr/bin/xcrun', 'clang'])) when(mockXcodeProjectInterpreter.isInstalled).thenReturn(false);
.thenThrow(const ProcessException('/usr/bin/xcrun', <String>['clang']));
expect(xcode.eulaSigned, isFalse); expect(xcode.isVersionSatisfactory, isFalse);
}); });
testWithoutContext('eulaSigned is false when clang output indicates EULA not yet accepted', () { testWithoutContext('xcodeVersionSatisfactory is true when version meets minimum', () {
when(processManager.runSync(<String>['/usr/bin/xcrun', 'clang'])) when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
.thenReturn(ProcessResult(1, 1, '', 'Xcode EULA has not been accepted.\nLaunch Xcode and accept the license.')); when(mockXcodeProjectInterpreter.majorVersion).thenReturn(11);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
expect(xcode.eulaSigned, isFalse); expect(xcode.isVersionSatisfactory, isTrue);
}); });
testWithoutContext('eulaSigned is true when clang output indicates EULA has been accepted', () { testWithoutContext('xcodeVersionSatisfactory is true when major version exceeds minimum', () {
when(processManager.runSync(<String>['/usr/bin/xcrun', 'clang'])) when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
.thenReturn(ProcessResult(1, 1, '', 'clang: error: no input files')); when(mockXcodeProjectInterpreter.majorVersion).thenReturn(12);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
expect(xcode.eulaSigned, isTrue); expect(xcode.isVersionSatisfactory, isTrue);
}); });
testWithoutContext('SDK name', () { testWithoutContext('xcodeVersionSatisfactory is true when minor version exceeds minimum', () {
expect(getNameForSdk(SdkType.iPhone), 'iphoneos'); when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
expect(getNameForSdk(SdkType.iPhoneSimulator), 'iphonesimulator'); when(mockXcodeProjectInterpreter.majorVersion).thenReturn(11);
expect(getNameForSdk(SdkType.macOS), 'macosx'); when(mockXcodeProjectInterpreter.minorVersion).thenReturn(3);
});
group('SDK location', () { expect(xcode.isVersionSatisfactory, isTrue);
const String sdkroot = 'Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk'; });
testWithoutContext('--show-sdk-path iphoneos', () async { testWithoutContext('isInstalledAndMeetsVersionCheck is false when not macOS', () {
when(processManager.run(<String>['xcrun', '--sdk', 'iphoneos', '--show-sdk-path'])).thenAnswer((_) => when(platform.isMacOS).thenReturn(false);
Future<ProcessResult>.value(ProcessResult(1, 0, sdkroot, '')));
expect(await xcode.sdkLocation(SdkType.iPhone), sdkroot); expect(xcode.isInstalledAndMeetsVersionCheck, isFalse);
}); });
testWithoutContext('--show-sdk-path macosx', () async { testWithoutContext('isInstalledAndMeetsVersionCheck is false when not installed', () {
when(processManager.run(<String>['xcrun', '--sdk', 'macosx', '--show-sdk-path'])).thenAnswer((_) => when(platform.isMacOS).thenReturn(true);
Future<ProcessResult>.value(ProcessResult(1, 0, sdkroot, ''))); fakeProcessManager.addCommand(const FakeCommand(
command: <String>['/usr/bin/xcode-select', '--print-path'],
stdout: '/Applications/Xcode8.0.app/Contents/Developer',
));
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(false);
expect(await xcode.sdkLocation(SdkType.macOS), sdkroot); expect(xcode.isInstalledAndMeetsVersionCheck, isFalse);
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
}); });
testWithoutContext('--show-sdk-path fails', () async { testWithoutContext('isInstalledAndMeetsVersionCheck is false when no xcode-select', () {
when(processManager.run(<String>['xcrun', '--sdk', 'iphoneos', '--show-sdk-path'])).thenAnswer((_) => when(platform.isMacOS).thenReturn(true);
Future<ProcessResult>.value(ProcessResult(1, 1, '', 'xcrun: error:'))); fakeProcessManager.addCommand(const FakeCommand(
command: <String>['/usr/bin/xcode-select', '--print-path'],
exitCode: 127,
stderr: 'ERROR',
));
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(11);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
expect(xcode.isInstalledAndMeetsVersionCheck, isFalse);
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
});
expect(() async => await xcode.sdkLocation(SdkType.iPhone), testWithoutContext('isInstalledAndMeetsVersionCheck is false when version not satisfied', () {
throwsToolExit(message: 'Could not find SDK location')); when(platform.isMacOS).thenReturn(true);
fakeProcessManager.addCommand(const FakeCommand(
command: <String>['/usr/bin/xcode-select', '--print-path'],
stdout: '/Applications/Xcode8.0.app/Contents/Developer',
));
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(10);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(2);
expect(xcode.isInstalledAndMeetsVersionCheck, isFalse);
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
}); });
});
});
group('xcdevice', () { testWithoutContext('isInstalledAndMeetsVersionCheck is true when macOS and installed and version is satisfied', () {
XCDevice xcdevice; when(platform.isMacOS).thenReturn(true);
MockXcode mockXcode; fakeProcessManager.addCommand(const FakeCommand(
MockArtifacts mockArtifacts; command: <String>['/usr/bin/xcode-select', '--print-path'],
MockCache mockCache; stdout: '/Applications/Xcode8.0.app/Contents/Developer',
));
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(11);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
expect(xcode.isInstalledAndMeetsVersionCheck, isTrue);
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
});
setUp(() { testWithoutContext('eulaSigned is false when clang output indicates EULA not yet accepted', () {
mockXcode = MockXcode(); fakeProcessManager.addCommand(const FakeCommand(
mockArtifacts = MockArtifacts(); command: <String>['/usr/bin/xcrun', 'clang'],
mockCache = MockCache(); exitCode: 1,
xcdevice = XCDevice( stderr: 'Xcode EULA has not been accepted.\nLaunch Xcode and accept the license.',
processManager: processManager, ));
logger: logger,
xcode: mockXcode,
platform: null,
artifacts: mockArtifacts,
cache: mockCache,
);
});
group('installed', () { expect(xcode.eulaSigned, isFalse);
testWithoutContext('Xcode not installed', () { expect(fakeProcessManager.hasRemainingExpectations, isFalse);
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(false);
expect(xcdevice.isInstalled, false);
}); });
testWithoutContext("xcrun can't find xcdevice", () { testWithoutContext('eulaSigned is true when clang output indicates EULA has been accepted', () {
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true); fakeProcessManager.addCommand(const FakeCommand(
command: <String>['/usr/bin/xcrun', 'clang'],
exitCode: 1,
stderr: 'clang: error: no input files',
));
when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice'])) expect(xcode.eulaSigned, isTrue);
.thenThrow(const ProcessException('xcrun', <String>['--find', 'xcdevice'])); expect(fakeProcessManager.hasRemainingExpectations, isFalse);
expect(xcdevice.isInstalled, false);
verify(processManager.runSync(any)).called(1);
}); });
testWithoutContext('is installed', () { testWithoutContext('SDK name', () {
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true); expect(getNameForSdk(SdkType.iPhone), 'iphoneos');
expect(getNameForSdk(SdkType.iPhoneSimulator), 'iphonesimulator');
expect(getNameForSdk(SdkType.macOS), 'macosx');
});
when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice'])) group('SDK location', () {
.thenReturn(ProcessResult(1, 0, '/path/to/xcdevice', '')); const String sdkroot = 'Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk';
expect(xcdevice.isInstalled, true);
testWithoutContext('--show-sdk-path iphoneos', () async {
fakeProcessManager.addCommand(const FakeCommand(
command: <String>['xcrun', '--sdk', 'iphoneos', '--show-sdk-path'],
stdout: sdkroot,
));
expect(await xcode.sdkLocation(SdkType.iPhone), sdkroot);
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
});
testWithoutContext('--show-sdk-path macosx', () async {
fakeProcessManager.addCommand(const FakeCommand(
command: <String>['xcrun', '--sdk', 'macosx', '--show-sdk-path'],
stdout: sdkroot,
));
expect(await xcode.sdkLocation(SdkType.macOS), sdkroot);
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
});
testWithoutContext('--show-sdk-path fails', () async {
fakeProcessManager.addCommand(const FakeCommand(
command: <String>['xcrun', '--sdk', 'iphoneos', '--show-sdk-path'],
exitCode: 1,
stderr: 'xcrun: error:',
));
expect(() async => await xcode.sdkLocation(SdkType.iPhone),
throwsToolExit(message: 'Could not find SDK location'));
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
});
}); });
}); });
group('available devices', () { group('xcdevice', () {
final FakePlatform macPlatform = FakePlatform(operatingSystem: 'macos'); XCDevice xcdevice;
MockXcode mockXcode;
testWithoutContext('Xcode not installed', () async { MockArtifacts mockArtifacts;
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(false); MockCache mockCache;
expect(await xcdevice.getAvailableTetheredIOSDevices(), isEmpty); setUp(() {
verifyNever(processManager.run(any)); mockXcode = MockXcode();
mockArtifacts = MockArtifacts();
mockCache = MockCache();
xcdevice = XCDevice(
processManager: fakeProcessManager,
logger: logger,
xcode: mockXcode,
platform: null,
artifacts: mockArtifacts,
cache: mockCache,
);
}); });
testWithoutContext('xcdevice fails', () async { group('installed', () {
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true); testWithoutContext('Xcode not installed', () {
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(false);
when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice'])) expect(xcdevice.isInstalled, false);
.thenReturn(ProcessResult(1, 0, '/path/to/xcdevice', '')); });
testWithoutContext('is installed', () {
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
fakeProcessManager.addCommand(const FakeCommand(
command: <String>['xcrun', '--find', 'xcdevice'],
stdout: '/path/to/xcdevice',
));
expect(xcdevice.isInstalled, true);
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
});
});
when(processManager.run(<String>['xcrun', 'xcdevice', 'list', '--timeout', '2'])) group('available devices', () {
.thenThrow(const ProcessException('xcrun', <String>['xcdevice', 'list', '--timeout', '2'])); final FakePlatform macPlatform = FakePlatform(operatingSystem: 'macos');
expect(await xcdevice.getAvailableTetheredIOSDevices(), isEmpty); testWithoutContext('Xcode not installed', () async {
}); when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(false);
testUsingContext('returns devices', () async { expect(await xcdevice.getAvailableTetheredIOSDevices(), isEmpty);
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true); });
when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice'])) testUsingContext('returns devices', () async {
.thenReturn(ProcessResult(1, 0, '/path/to/xcdevice', '')); when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
fakeProcessManager.addCommand(const FakeCommand(
command: <String>['xcrun', '--find', 'xcdevice'],
stdout: '/path/to/xcdevice',
));
const String devicesOutput = ''' const String devicesOutput = '''
[ [
{ {
"simulator" : true, "simulator" : true,
...@@ -373,45 +462,52 @@ void main() { ...@@ -373,45 +462,52 @@ void main() {
] ]
'''; ''';
when(processManager.run(<String>['xcrun', 'xcdevice', 'list', '--timeout', '2'])) fakeProcessManager.addCommand(const FakeCommand(
.thenAnswer((_) => Future<ProcessResult>.value(ProcessResult(1, 0, devicesOutput, ''))); command: <String>['xcrun', 'xcdevice', 'list', '--timeout', '2'],
final List<IOSDevice> devices = await xcdevice.getAvailableTetheredIOSDevices(); stdout: devicesOutput,
expect(devices, hasLength(3)); ));
expect(devices[0].id, 'd83d5bc53967baa0ee18626ba87b6254b2ab5418'); final List<IOSDevice> devices = await xcdevice.getAvailableTetheredIOSDevices();
expect(devices[0].name, 'An iPhone (Space Gray)'); expect(devices, hasLength(3));
expect(await devices[0].sdkNameAndVersion, 'iOS 13.3'); expect(devices[0].id, 'd83d5bc53967baa0ee18626ba87b6254b2ab5418');
expect(devices[0].cpuArchitecture, DarwinArch.arm64); expect(devices[0].name, 'An iPhone (Space Gray)');
expect(devices[1].id, '98206e7a4afd4aedaff06e687594e089dede3c44'); expect(await devices[0].sdkNameAndVersion, 'iOS 13.3');
expect(devices[1].name, 'iPad 1'); expect(devices[0].cpuArchitecture, DarwinArch.arm64);
expect(await devices[1].sdkNameAndVersion, 'iOS 10.1'); expect(devices[1].id, '98206e7a4afd4aedaff06e687594e089dede3c44');
expect(devices[1].cpuArchitecture, DarwinArch.armv7); expect(devices[1].name, 'iPad 1');
expect(devices[2].id, 'f577a7903cc54959be2e34bc4f7f80b7009efcf4'); expect(await devices[1].sdkNameAndVersion, 'iOS 10.1');
expect(devices[2].name, 'iPad 2'); expect(devices[1].cpuArchitecture, DarwinArch.armv7);
expect(await devices[2].sdkNameAndVersion, 'iOS 10.1'); expect(devices[2].id, 'f577a7903cc54959be2e34bc4f7f80b7009efcf4');
expect(devices[2].cpuArchitecture, DarwinArch.arm64); // Defaults to arm64 for unknown architecture. expect(devices[2].name, 'iPad 2');
}, overrides: <Type, Generator>{ expect(await devices[2].sdkNameAndVersion, 'iOS 10.1');
Platform: () => macPlatform, expect(devices[2].cpuArchitecture, DarwinArch.arm64); // Defaults to arm64 for unknown architecture.
}); expect(fakeProcessManager.hasRemainingExpectations, isFalse);
}, overrides: <Type, Generator>{
testWithoutContext('uses timeout', () async { Platform: () => macPlatform,
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true); });
when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice'])) testWithoutContext('uses timeout', () async {
.thenReturn(ProcessResult(1, 0, '/path/to/xcdevice', '')); when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
fakeProcessManager.addCommand(const FakeCommand(
when(processManager.run(any)) command: <String>['xcrun', '--find', 'xcdevice'],
.thenAnswer((_) => Future<ProcessResult>.value(ProcessResult(1, 0, '[]', ''))); stdout: '/path/to/xcdevice',
await xcdevice.getAvailableTetheredIOSDevices(timeout: const Duration(seconds: 20)); ));
verify(processManager.run(<String>['xcrun', 'xcdevice', 'list', '--timeout', '20'])).called(1);
}); fakeProcessManager.addCommand(const FakeCommand(
command: <String>['xcrun', 'xcdevice', 'list', '--timeout', '20'],
testUsingContext('ignores "Preparing debugger support for iPhone" error', () async { stdout: '[]',
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true); ));
await xcdevice.getAvailableTetheredIOSDevices(timeout: const Duration(seconds: 20));
when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice'])) expect(fakeProcessManager.hasRemainingExpectations, isFalse);
.thenReturn(ProcessResult(1, 0, '/path/to/xcdevice', '')); });
const String devicesOutput = ''' testUsingContext('ignores "Preparing debugger support for iPhone" error', () async {
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
fakeProcessManager.addCommand(const FakeCommand(
command: <String>['xcrun', '--find', 'xcdevice'],
stdout: '/path/to/xcdevice',
));
const String devicesOutput = '''
[ [
{ {
"simulator" : false, "simulator" : false,
...@@ -435,22 +531,26 @@ void main() { ...@@ -435,22 +531,26 @@ void main() {
] ]
'''; ''';
when(processManager.run(<String>['xcrun', 'xcdevice', 'list', '--timeout', '2'])) fakeProcessManager.addCommand(const FakeCommand(
.thenAnswer((_) => Future<ProcessResult>.value(ProcessResult(1, 0, devicesOutput, ''))); command: <String>['xcrun', 'xcdevice', 'list', '--timeout', '2'],
final List<IOSDevice> devices = await xcdevice.getAvailableTetheredIOSDevices(); stdout: devicesOutput,
expect(devices, hasLength(1)); ));
expect(devices[0].id, '43ad2fda7991b34fe1acbda82f9e2fd3d6ddc9f7'); final List<IOSDevice> devices = await xcdevice.getAvailableTetheredIOSDevices();
}, overrides: <Type, Generator>{ expect(devices, hasLength(1));
Platform: () => macPlatform, expect(devices[0].id, '43ad2fda7991b34fe1acbda82f9e2fd3d6ddc9f7');
}); expect(fakeProcessManager.hasRemainingExpectations, isFalse);
}, overrides: <Type, Generator>{
testUsingContext('handles unknown architectures', () async { Platform: () => macPlatform,
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true); });
when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice'])) testUsingContext('handles unknown architectures', () async {
.thenReturn(ProcessResult(1, 0, '/path/to/xcdevice', '')); when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
fakeProcessManager.addCommand(const FakeCommand(
const String devicesOutput = ''' command: <String>['xcrun', '--find', 'xcdevice'],
stdout: '/path/to/xcdevice',
));
const String devicesOutput = '''
[ [
{ {
"simulator" : false, "simulator" : false,
...@@ -479,45 +579,36 @@ void main() { ...@@ -479,45 +579,36 @@ void main() {
] ]
'''; ''';
when(processManager.run(<String>['xcrun', 'xcdevice', 'list', '--timeout', '2'])) fakeProcessManager.addCommand(const FakeCommand(
.thenAnswer((_) => Future<ProcessResult>.value(ProcessResult(1, 0, devicesOutput, ''))); command: <String>['xcrun', 'xcdevice', 'list', '--timeout', '2'],
final List<IOSDevice> devices = await xcdevice.getAvailableTetheredIOSDevices(); stdout: devicesOutput,
expect(devices[0].cpuArchitecture, DarwinArch.armv7); ));
expect(devices[1].cpuArchitecture, DarwinArch.arm64); final List<IOSDevice> devices = await xcdevice.getAvailableTetheredIOSDevices();
}, overrides: <Type, Generator>{ expect(devices[0].cpuArchitecture, DarwinArch.armv7);
Platform: () => macPlatform, expect(devices[1].cpuArchitecture, DarwinArch.arm64);
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
}, overrides: <Type, Generator>{
Platform: () => macPlatform,
});
}); });
});
group('diagnostics', () {
final FakePlatform macPlatform = FakePlatform(operatingSystem: 'macos');
testWithoutContext('Xcode not installed', () async {
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(false);
expect(await xcdevice.getDiagnostics(), isEmpty);
verifyNever(processManager.run(any));
});
testWithoutContext('xcdevice fails', () async {
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice'])) group('diagnostics', () {
.thenReturn(ProcessResult(1, 0, '/path/to/xcdevice', '')); final FakePlatform macPlatform = FakePlatform(operatingSystem: 'macos');
when(processManager.run(<String>['xcrun', 'xcdevice', 'list', '--timeout', '2']))
.thenThrow(const ProcessException('xcrun', <String>['xcdevice', 'list', '--timeout', '2']));
expect(await xcdevice.getDiagnostics(), isEmpty); testWithoutContext('Xcode not installed', () async {
}); when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(false);
testUsingContext('uses cache', () async { expect(await xcdevice.getDiagnostics(), isEmpty);
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true); });
when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice'])) testUsingContext('uses cache', () async {
.thenReturn(ProcessResult(1, 0, '/path/to/xcdevice', '')); when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
fakeProcessManager.addCommand(const FakeCommand(
command: <String>['xcrun', '--find', 'xcdevice'],
stdout: '/path/to/xcdevice',
));
const String devicesOutput = ''' const String devicesOutput = '''
[ [
{ {
"simulator" : false, "simulator" : false,
...@@ -538,24 +629,27 @@ void main() { ...@@ -538,24 +629,27 @@ void main() {
] ]
'''; ''';
when(processManager.run(<String>['xcrun', 'xcdevice', 'list', '--timeout', '2'])) fakeProcessManager.addCommand(const FakeCommand(
.thenAnswer((_) => Future<ProcessResult>.value(ProcessResult(1, 0, devicesOutput, ''))); command: <String>['xcrun', 'xcdevice', 'list', '--timeout', '2'],
await xcdevice.getAvailableTetheredIOSDevices(); stdout: devicesOutput,
final List<String> errors = await xcdevice.getDiagnostics(); ));
expect(errors, hasLength(1));
await xcdevice.getAvailableTetheredIOSDevices();
verify(processManager.run(any)).called(1); final List<String> errors = await xcdevice.getDiagnostics();
}, overrides: <Type, Generator>{ expect(errors, hasLength(1));
Platform: () => macPlatform, expect(fakeProcessManager.hasRemainingExpectations, isFalse);
}); }, overrides: <Type, Generator>{
Platform: () => macPlatform,
testUsingContext('returns error message', () async { });
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
testUsingContext('returns error message', () async {
when(processManager.runSync(<String>['xcrun', '--find', 'xcdevice'])) when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
.thenReturn(ProcessResult(1, 0, '/path/to/xcdevice', '')); fakeProcessManager.addCommand(const FakeCommand(
command: <String>['xcrun', '--find', 'xcdevice'],
const String devicesOutput = ''' stdout: '/path/to/xcdevice',
));
const String devicesOutput = '''
[ [
{ {
"simulator" : false, "simulator" : false,
...@@ -640,16 +734,21 @@ void main() { ...@@ -640,16 +734,21 @@ void main() {
] ]
'''; ''';
when(processManager.run(<String>['xcrun', 'xcdevice', 'list', '--timeout', '2'])) fakeProcessManager.addCommand(const FakeCommand(
.thenAnswer((_) => Future<ProcessResult>.value(ProcessResult(1, 0, devicesOutput, ''))); command: <String>['xcrun', 'xcdevice', 'list', '--timeout', '2'],
final List<String> errors = await xcdevice.getDiagnostics(); stdout: devicesOutput,
expect(errors, hasLength(4)); ));
expect(errors[0], 'Error: iPhone is not paired with your computer. To use iPhone with Xcode, unlock it and choose to trust this computer when prompted. (code -9)');
expect(errors[1], 'Error: iPhone is not paired with your computer.'); final List<String> errors = await xcdevice.getDiagnostics();
expect(errors[2], 'Error: Xcode pairing error. (code -13)'); expect(errors, hasLength(4));
expect(errors[3], 'Error: iPhone is busy: Preparing debugger support for iPhone. Xcode will continue when iPhone is finished. (code -10)'); expect(errors[0], 'Error: iPhone is not paired with your computer. To use iPhone with Xcode, unlock it and choose to trust this computer when prompted. (code -9)');
}, overrides: <Type, Generator>{ expect(errors[1], 'Error: iPhone is not paired with your computer.');
Platform: () => macPlatform, expect(errors[2], 'Error: Xcode pairing error. (code -13)');
expect(errors[3], 'Error: iPhone is busy: Preparing debugger support for iPhone. Xcode will continue when iPhone is finished. (code -10)');
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
}, overrides: <Type, Generator>{
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