Only show iOS simulators, reduce output spew in verbose (#108345)
This commit is contained in:
parent
fe16c206ea
commit
167655e8a7
@ -25,7 +25,7 @@ class IOSWorkflow implements Workflow {
|
|||||||
|
|
||||||
// We need xcode (+simctl) to list simulator devices, and libimobiledevice to list real devices.
|
// We need xcode (+simctl) to list simulator devices, and libimobiledevice to list real devices.
|
||||||
@override
|
@override
|
||||||
bool get canListDevices => appliesToHostPlatform && _xcode.isInstalledAndMeetsVersionCheck && _xcode.isSimctlInstalled;
|
bool get canListDevices => appliesToHostPlatform && _xcode.isSimctlInstalled;
|
||||||
|
|
||||||
// We need xcode to launch simulator devices, and ios-deploy
|
// We need xcode to launch simulator devices, and ios-deploy
|
||||||
// for real devices.
|
// for real devices.
|
||||||
|
@ -71,8 +71,8 @@ class IOSSimulatorUtils {
|
|||||||
return <IOSSimulator>[];
|
return <IOSSimulator>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<SimDevice> connected = await _simControl.getConnectedDevices();
|
final List<BootedSimDevice> connected = await _simControl.getConnectedDevices();
|
||||||
return connected.map<IOSSimulator?>((SimDevice device) {
|
return connected.map<IOSSimulator?>((BootedSimDevice device) {
|
||||||
final String? udid = device.udid;
|
final String? udid = device.udid;
|
||||||
final String? name = device.name;
|
final String? name = device.name;
|
||||||
if (udid == null) {
|
if (udid == null) {
|
||||||
@ -109,30 +109,45 @@ class SimControl {
|
|||||||
|
|
||||||
/// Runs `simctl list --json` and returns the JSON of the corresponding
|
/// Runs `simctl list --json` and returns the JSON of the corresponding
|
||||||
/// [section].
|
/// [section].
|
||||||
Future<Map<String, Object?>> _list(SimControlListSection section) async {
|
Future<Map<String, Object?>> _listBootedDevices() async {
|
||||||
// Sample output from `simctl list --json`:
|
// Sample output from `simctl list available booted --json`:
|
||||||
//
|
//
|
||||||
// {
|
// {
|
||||||
// "devicetypes": { ... },
|
|
||||||
// "runtimes": { ... },
|
|
||||||
// "devices" : {
|
// "devices" : {
|
||||||
// "com.apple.CoreSimulator.SimRuntime.iOS-8-2" : [
|
// "com.apple.CoreSimulator.SimRuntime.iOS-14-0" : [
|
||||||
// {
|
// {
|
||||||
// "state" : "Shutdown",
|
// "lastBootedAt" : "2022-07-26T01:46:23Z",
|
||||||
// "availability" : " (unavailable, runtime profile not found)",
|
// "dataPath" : "\/Users\/magder\/Library\/Developer\/CoreSimulator\/Devices\/9EC90A99-6924-472D-8CDD-4D8234AB4779\/data",
|
||||||
// "name" : "iPhone 4s",
|
// "dataPathSize" : 1620578304,
|
||||||
// "udid" : "1913014C-6DCB-485D-AC6B-7CD76D322F5B"
|
// "logPath" : "\/Users\/magder\/Library\/Logs\/CoreSimulator\/9EC90A99-6924-472D-8CDD-4D8234AB4779",
|
||||||
// },
|
// "udid" : "9EC90A99-6924-472D-8CDD-4D8234AB4779",
|
||||||
// ...
|
// "isAvailable" : true,
|
||||||
// },
|
// "logPathSize" : 9740288,
|
||||||
// "pairs": { ... },
|
// "deviceTypeIdentifier" : "com.apple.CoreSimulator.SimDeviceType.iPhone-11",
|
||||||
|
// "state" : "Booted",
|
||||||
|
// "name" : "iPhone 11"
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "com.apple.CoreSimulator.SimRuntime.iOS-13-0" : [
|
||||||
|
//
|
||||||
|
// ],
|
||||||
|
// "com.apple.CoreSimulator.SimRuntime.iOS-12-4" : [
|
||||||
|
//
|
||||||
|
// ],
|
||||||
|
// "com.apple.CoreSimulator.SimRuntime.iOS-16-0" : [
|
||||||
|
//
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
final List<String> command = <String>[
|
final List<String> command = <String>[
|
||||||
..._xcode.xcrunCommand(),
|
..._xcode.xcrunCommand(),
|
||||||
'simctl',
|
'simctl',
|
||||||
'list',
|
'list',
|
||||||
|
'devices',
|
||||||
|
'booted',
|
||||||
|
'iOS',
|
||||||
'--json',
|
'--json',
|
||||||
section.name,
|
|
||||||
];
|
];
|
||||||
_logger.printTrace(command.join(' '));
|
_logger.printTrace(command.join(' '));
|
||||||
final RunResult results = await _processUtils.run(command);
|
final RunResult results = await _processUtils.run(command);
|
||||||
@ -141,7 +156,7 @@ class SimControl {
|
|||||||
return <String, Map<String, Object?>>{};
|
return <String, Map<String, Object?>>{};
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final Object? decodeResult = (json.decode(results.stdout) as Map<String, Object?>)[section.name];
|
final Object? decodeResult = (json.decode(results.stdout) as Map<String, Object?>)['devices'];
|
||||||
if (decodeResult is Map<String, Object?>) {
|
if (decodeResult is Map<String, Object?>) {
|
||||||
return decodeResult;
|
return decodeResult;
|
||||||
}
|
}
|
||||||
@ -156,17 +171,17 @@ class SimControl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of all available devices, both potential and connected.
|
/// Returns all the connected simulator devices.
|
||||||
Future<List<SimDevice>> getDevices() async {
|
Future<List<BootedSimDevice>> getConnectedDevices() async {
|
||||||
final List<SimDevice> devices = <SimDevice>[];
|
final List<BootedSimDevice> devices = <BootedSimDevice>[];
|
||||||
|
|
||||||
final Map<String, Object?> devicesSection = await _list(SimControlListSection.devices);
|
final Map<String, Object?> devicesSection = await _listBootedDevices();
|
||||||
|
|
||||||
for (final String deviceCategory in devicesSection.keys) {
|
for (final String deviceCategory in devicesSection.keys) {
|
||||||
final Object? devicesData = devicesSection[deviceCategory];
|
final Object? devicesData = devicesSection[deviceCategory];
|
||||||
if (devicesData != null && devicesData is List<Object?>) {
|
if (devicesData != null && devicesData is List<Object?>) {
|
||||||
for (final Map<String, Object?> data in devicesData.map<Map<String, Object?>?>(castStringKeyedMap).whereType<Map<String, Object?>>()) {
|
for (final Map<String, Object?> data in devicesData.map<Map<String, Object?>?>(castStringKeyedMap).whereType<Map<String, Object?>>()) {
|
||||||
devices.add(SimDevice(deviceCategory, data));
|
devices.add(BootedSimDevice(deviceCategory, data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,12 +189,6 @@ class SimControl {
|
|||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all the connected simulator devices.
|
|
||||||
Future<List<SimDevice>> getConnectedDevices() async {
|
|
||||||
final List<SimDevice> simDevices = await getDevices();
|
|
||||||
return simDevices.where((SimDevice device) => device.isBooted).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> isInstalled(String deviceId, String appId) {
|
Future<bool> isInstalled(String deviceId, String appId) {
|
||||||
return _processUtils.exitsHappy(<String>[
|
return _processUtils.exitsHappy(<String>[
|
||||||
..._xcode.xcrunCommand(),
|
..._xcode.xcrunCommand(),
|
||||||
@ -267,54 +276,15 @@ class SimControl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enumerates all data sections of `xcrun simctl list --json` command.
|
|
||||||
class SimControlListSection {
|
|
||||||
const SimControlListSection._(this.name);
|
|
||||||
|
|
||||||
final String name;
|
class BootedSimDevice {
|
||||||
|
BootedSimDevice(this.category, this.data);
|
||||||
static const SimControlListSection devices = SimControlListSection._('devices');
|
|
||||||
static const SimControlListSection devicetypes = SimControlListSection._('devicetypes');
|
|
||||||
static const SimControlListSection runtimes = SimControlListSection._('runtimes');
|
|
||||||
static const SimControlListSection pairs = SimControlListSection._('pairs');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A simulated device type.
|
|
||||||
///
|
|
||||||
/// Simulated device types can be listed using the command
|
|
||||||
/// `xcrun simctl list devicetypes`.
|
|
||||||
class SimDeviceType {
|
|
||||||
SimDeviceType(this.name, this.identifier);
|
|
||||||
|
|
||||||
/// The name of the device type.
|
|
||||||
///
|
|
||||||
/// Examples:
|
|
||||||
///
|
|
||||||
/// "iPhone 6s"
|
|
||||||
/// "iPhone 6 Plus"
|
|
||||||
final String name;
|
|
||||||
|
|
||||||
/// The identifier of the device type.
|
|
||||||
///
|
|
||||||
/// Examples:
|
|
||||||
///
|
|
||||||
/// "com.apple.CoreSimulator.SimDeviceType.iPhone-6s"
|
|
||||||
/// "com.apple.CoreSimulator.SimDeviceType.iPhone-6-Plus"
|
|
||||||
final String identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
class SimDevice {
|
|
||||||
SimDevice(this.category, this.data);
|
|
||||||
|
|
||||||
final String category;
|
final String category;
|
||||||
final Map<String, Object?> data;
|
final Map<String, Object?> data;
|
||||||
|
|
||||||
String? get state => data['state']?.toString();
|
|
||||||
String? get availability => data['availability']?.toString();
|
|
||||||
String? get name => data['name']?.toString();
|
String? get name => data['name']?.toString();
|
||||||
String? get udid => data['udid']?.toString();
|
String? get udid => data['udid']?.toString();
|
||||||
|
|
||||||
bool get isBooted => state == 'Booted';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class IOSSimulator extends Device {
|
class IOSSimulator extends Device {
|
||||||
|
@ -136,7 +136,7 @@ class Xcode {
|
|||||||
// This command will error if additional components need to be installed in
|
// This command will error if additional components need to be installed in
|
||||||
// xcode 9.2 and above.
|
// xcode 9.2 and above.
|
||||||
final RunResult result = _processUtils.runSync(
|
final RunResult result = _processUtils.runSync(
|
||||||
<String>[...xcrunCommand(), 'simctl', 'list'],
|
<String>[...xcrunCommand(), 'simctl', 'list', 'devices', 'booted'],
|
||||||
);
|
);
|
||||||
_isSimctlInstalled = result.exitCode == 0;
|
_isSimctlInstalled = result.exitCode == 0;
|
||||||
} on ProcessException {
|
} on ProcessException {
|
||||||
|
@ -49,10 +49,18 @@ void main() {
|
|||||||
expect(iosWorkflow.canListDevices, false);
|
expect(iosWorkflow.canListDevices, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('iOS workflow applies on macOS, no Xcode', () {
|
testWithoutContext('iOS workflow applies on macOS, no Xcode or simctl', () {
|
||||||
|
final FakeProcessManager xcodeProcessManager = FakeProcessManager.list(<FakeCommand>[
|
||||||
|
const FakeCommand(
|
||||||
|
command: <String>[
|
||||||
|
'xcrun', 'simctl', 'list', 'devices', 'booted',
|
||||||
|
],
|
||||||
|
exitCode: 1,
|
||||||
|
),
|
||||||
|
]);
|
||||||
final IOSWorkflow iosWorkflow = IOSWorkflow(
|
final IOSWorkflow iosWorkflow = IOSWorkflow(
|
||||||
platform: FakePlatform(operatingSystem: 'macos'),
|
platform: FakePlatform(operatingSystem: 'macos'),
|
||||||
xcode: Xcode.test(processManager: FakeProcessManager.any(),
|
xcode: Xcode.test(processManager: xcodeProcessManager,
|
||||||
xcodeProjectInterpreter: XcodeProjectInterpreter.test(
|
xcodeProjectInterpreter: XcodeProjectInterpreter.test(
|
||||||
processManager: FakeProcessManager.any(),
|
processManager: FakeProcessManager.any(),
|
||||||
version: null,
|
version: null,
|
||||||
@ -65,9 +73,33 @@ void main() {
|
|||||||
expect(iosWorkflow.canLaunchDevices, false);
|
expect(iosWorkflow.canLaunchDevices, false);
|
||||||
expect(iosWorkflow.canListDevices, false);
|
expect(iosWorkflow.canListDevices, false);
|
||||||
expect(iosWorkflow.canListEmulators, false);
|
expect(iosWorkflow.canListEmulators, false);
|
||||||
|
expect(xcodeProcessManager, hasNoRemainingExpectations);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('iOS workflow can launch and list devices when Xcode is set up', () {
|
testWithoutContext('iOS workflow can list devices even when Xcode version is too low', () {
|
||||||
|
final Xcode xcode = Xcode.test(
|
||||||
|
processManager: FakeProcessManager.any(),
|
||||||
|
xcodeProjectInterpreter: XcodeProjectInterpreter.test(
|
||||||
|
processManager: FakeProcessManager.any(),
|
||||||
|
version: Version(1, 0, 0)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final IOSWorkflow iosWorkflow = IOSWorkflow(
|
||||||
|
platform: FakePlatform(operatingSystem: 'macos'),
|
||||||
|
xcode: xcode,
|
||||||
|
featureFlags: TestFeatureFlags(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Make sure we're testing the right Xcode state.
|
||||||
|
// expect(xcode.isInstalledAndMeetsVersionCheck, true);
|
||||||
|
expect(xcode.isSimctlInstalled, true);
|
||||||
|
expect(iosWorkflow.canLaunchDevices, false);
|
||||||
|
expect(iosWorkflow.canListDevices, true);
|
||||||
|
expect(iosWorkflow.canListEmulators, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('iOS workflow can launch devices when Xcode is set up', () {
|
||||||
final Xcode xcode = Xcode.test(
|
final Xcode xcode = Xcode.test(
|
||||||
processManager: FakeProcessManager.any(),
|
processManager: FakeProcessManager.any(),
|
||||||
xcodeProjectInterpreter: XcodeProjectInterpreter.test(
|
xcodeProjectInterpreter: XcodeProjectInterpreter.test(
|
||||||
|
@ -724,28 +724,43 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
const String validSimControlOutput = '''
|
const String validSimControlOutput = '''
|
||||||
{
|
{
|
||||||
"devices" : {
|
"devices" : {
|
||||||
"watchOS 4.3" : [
|
"com.apple.CoreSimulator.SimRuntime.iOS-14-0" : [
|
||||||
{
|
|
||||||
"state" : "Shutdown",
|
|
||||||
"availability" : "(available)",
|
|
||||||
"name" : "Apple Watch - 38mm",
|
|
||||||
"udid" : "TEST-WATCH-UDID"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"iOS 11.4" : [
|
|
||||||
{
|
{
|
||||||
|
"dataPathSize" : 1734569984,
|
||||||
|
"udid" : "iPhone 11-UDID",
|
||||||
|
"isAvailable" : true,
|
||||||
|
"logPathSize" : 9506816,
|
||||||
|
"deviceTypeIdentifier" : "com.apple.CoreSimulator.SimDeviceType.iPhone-11",
|
||||||
"state" : "Booted",
|
"state" : "Booted",
|
||||||
"availability" : "(available)",
|
"name" : "iPhone 11"
|
||||||
"name" : "iPhone 5s",
|
|
||||||
"udid" : "TEST-PHONE-UDID"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tvOS 11.4" : [
|
"com.apple.CoreSimulator.SimRuntime.iOS-13-0" : [
|
||||||
|
],
|
||||||
|
"com.apple.CoreSimulator.SimRuntime.iOS-12-4" : [
|
||||||
|
],
|
||||||
|
"com.apple.CoreSimulator.SimRuntime.tvOS-16-0" : [
|
||||||
|
],
|
||||||
|
"com.apple.CoreSimulator.SimRuntime.watchOS-9-0" : [
|
||||||
|
],
|
||||||
|
"com.apple.CoreSimulator.SimRuntime.iOS-16-0" : [
|
||||||
{
|
{
|
||||||
"state" : "Shutdown",
|
"dataPathSize" : 552366080,
|
||||||
"availability" : "(available)",
|
"udid" : "Phone w Watch-UDID",
|
||||||
"name" : "Apple TV",
|
"isAvailable" : true,
|
||||||
"udid" : "TEST-TV-UDID"
|
"logPathSize" : 90112,
|
||||||
|
"deviceTypeIdentifier" : "com.apple.CoreSimulator.SimDeviceType.iPhone-11",
|
||||||
|
"state" : "Booted",
|
||||||
|
"name" : "Phone w Watch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"dataPathSize" : 2186457088,
|
||||||
|
"udid" : "iPhone 13-UDID",
|
||||||
|
"isAvailable" : true,
|
||||||
|
"logPathSize" : 151552,
|
||||||
|
"deviceTypeIdentifier" : "com.apple.CoreSimulator.SimDeviceType.iPhone-13",
|
||||||
|
"state" : "Booted",
|
||||||
|
"name" : "iPhone 13"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -768,59 +783,54 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('getDevices succeeds', () async {
|
testWithoutContext('getConnectedDevices succeeds', () async {
|
||||||
fakeProcessManager.addCommand(const FakeCommand(
|
fakeProcessManager.addCommand(const FakeCommand(
|
||||||
command: <String>[
|
command: <String>[
|
||||||
'xcrun',
|
'xcrun',
|
||||||
'simctl',
|
'simctl',
|
||||||
'list',
|
'list',
|
||||||
'--json',
|
|
||||||
'devices',
|
'devices',
|
||||||
|
'booted',
|
||||||
|
'iOS',
|
||||||
|
'--json',
|
||||||
],
|
],
|
||||||
stdout: validSimControlOutput,
|
stdout: validSimControlOutput,
|
||||||
));
|
));
|
||||||
|
|
||||||
final List<SimDevice> devices = await simControl.getDevices();
|
final List<BootedSimDevice> devices = await simControl.getConnectedDevices();
|
||||||
|
|
||||||
final SimDevice watch = devices[0];
|
final BootedSimDevice phone1 = devices[0];
|
||||||
expect(watch.category, 'watchOS 4.3');
|
expect(phone1.category, 'com.apple.CoreSimulator.SimRuntime.iOS-14-0');
|
||||||
expect(watch.state, 'Shutdown');
|
expect(phone1.name, 'iPhone 11');
|
||||||
expect(watch.availability, '(available)');
|
expect(phone1.udid, 'iPhone 11-UDID');
|
||||||
expect(watch.name, 'Apple Watch - 38mm');
|
|
||||||
expect(watch.udid, 'TEST-WATCH-UDID');
|
|
||||||
expect(watch.isBooted, isFalse);
|
|
||||||
|
|
||||||
final SimDevice phone = devices[1];
|
final BootedSimDevice phone2 = devices[1];
|
||||||
expect(phone.category, 'iOS 11.4');
|
expect(phone2.category, 'com.apple.CoreSimulator.SimRuntime.iOS-16-0');
|
||||||
expect(phone.state, 'Booted');
|
expect(phone2.name, 'Phone w Watch');
|
||||||
expect(phone.availability, '(available)');
|
expect(phone2.udid, 'Phone w Watch-UDID');
|
||||||
expect(phone.name, 'iPhone 5s');
|
|
||||||
expect(phone.udid, 'TEST-PHONE-UDID');
|
|
||||||
expect(phone.isBooted, isTrue);
|
|
||||||
|
|
||||||
final SimDevice tv = devices[2];
|
final BootedSimDevice phone3 = devices[2];
|
||||||
expect(tv.category, 'tvOS 11.4');
|
expect(phone3.category, 'com.apple.CoreSimulator.SimRuntime.iOS-16-0');
|
||||||
expect(tv.state, 'Shutdown');
|
expect(phone3.name, 'iPhone 13');
|
||||||
expect(tv.availability, '(available)');
|
expect(phone3.udid, 'iPhone 13-UDID');
|
||||||
expect(tv.name, 'Apple TV');
|
|
||||||
expect(tv.udid, 'TEST-TV-UDID');
|
|
||||||
expect(tv.isBooted, isFalse);
|
|
||||||
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('getDevices handles bad simctl output', () async {
|
testWithoutContext('getConnectedDevices handles bad simctl output', () async {
|
||||||
fakeProcessManager.addCommand(const FakeCommand(
|
fakeProcessManager.addCommand(const FakeCommand(
|
||||||
command: <String>[
|
command: <String>[
|
||||||
'xcrun',
|
'xcrun',
|
||||||
'simctl',
|
'simctl',
|
||||||
'list',
|
'list',
|
||||||
'--json',
|
|
||||||
'devices',
|
'devices',
|
||||||
|
'booted',
|
||||||
|
'iOS',
|
||||||
|
'--json',
|
||||||
],
|
],
|
||||||
stdout: 'Install Started',
|
stdout: 'Install Started',
|
||||||
));
|
));
|
||||||
|
|
||||||
final List<SimDevice> devices = await simControl.getDevices();
|
final List<BootedSimDevice> devices = await simControl.getConnectedDevices();
|
||||||
|
|
||||||
expect(devices, isEmpty);
|
expect(devices, isEmpty);
|
||||||
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||||
|
@ -59,6 +59,8 @@ void main() {
|
|||||||
'xcrun',
|
'xcrun',
|
||||||
'simctl',
|
'simctl',
|
||||||
'list',
|
'list',
|
||||||
|
'devices',
|
||||||
|
'booted',
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -78,6 +80,8 @@ void main() {
|
|||||||
'xcrun',
|
'xcrun',
|
||||||
'simctl',
|
'simctl',
|
||||||
'list',
|
'list',
|
||||||
|
'devices',
|
||||||
|
'booted',
|
||||||
],
|
],
|
||||||
exitCode: 1,
|
exitCode: 1,
|
||||||
),
|
),
|
||||||
|
@ -98,7 +98,7 @@ void main() {
|
|||||||
'Xcode EULA has not been accepted.\nLaunch Xcode and accept the license.',
|
'Xcode EULA has not been accepted.\nLaunch Xcode and accept the license.',
|
||||||
),
|
),
|
||||||
const FakeCommand(
|
const FakeCommand(
|
||||||
command: <String>['xcrun', 'simctl', 'list'],
|
command: <String>['xcrun', 'simctl', 'list', 'devices', 'booted'],
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
final Xcode xcode = Xcode.test(
|
final Xcode xcode = Xcode.test(
|
||||||
@ -135,7 +135,7 @@ void main() {
|
|||||||
command: <String>['xcrun', 'clang'],
|
command: <String>['xcrun', 'clang'],
|
||||||
),
|
),
|
||||||
const FakeCommand(
|
const FakeCommand(
|
||||||
command: <String>['xcrun', 'simctl', 'list'],
|
command: <String>['xcrun', 'simctl', 'list', 'devices', 'booted'],
|
||||||
exitCode: 1,
|
exitCode: 1,
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
@ -173,7 +173,7 @@ void main() {
|
|||||||
command: <String>['xcrun', 'clang'],
|
command: <String>['xcrun', 'clang'],
|
||||||
),
|
),
|
||||||
const FakeCommand(
|
const FakeCommand(
|
||||||
command: <String>['xcrun', 'simctl', 'list'],
|
command: <String>['xcrun', 'simctl', 'list', 'devices', 'booted'],
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
final Xcode xcode = Xcode.test(
|
final Xcode xcode = Xcode.test(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user