Flutter `emulator launch` crash running in dart-2-mode (#19454)
* Only printError on our simple messages
Any other type is a real error that should be a normal crash (to get a proper error log).
See #19453.
* Add toList() to convert Iterable<String> -> List<String>
This code previously throw in Dart-2 mode.
Fixes #19453.
* Move getSimulatorPath into Xcode
* Add a test that we tried to launch the simulator
* Remove unused import
diff --git a/packages/flutter_tools/lib/src/commands/emulators.dart b/packages/flutter_tools/lib/src/commands/emulators.dart
index 0904bc4..e1ab0dd 100644
--- a/packages/flutter_tools/lib/src/commands/emulators.dart
+++ b/packages/flutter_tools/lib/src/commands/emulators.dart
@@ -72,7 +72,11 @@
await emulators.first.launch();
}
catch (e) {
- printError(e);
+ if (e is String) {
+ printError(e);
+ } else {
+ rethrow;
+ }
}
}
}
diff --git a/packages/flutter_tools/lib/src/ios/ios_emulators.dart b/packages/flutter_tools/lib/src/ios/ios_emulators.dart
index 0916a3c..f9c3a57 100644
--- a/packages/flutter_tools/lib/src/ios/ios_emulators.dart
+++ b/packages/flutter_tools/lib/src/ios/ios_emulators.dart
@@ -4,7 +4,6 @@
import 'dart:async';
-import '../base/file_system.dart';
import '../base/platform.dart';
import '../base/process.dart';
import '../emulator.dart';
@@ -40,7 +39,8 @@
Future<bool> launchSimulator(List<String> additionalArgs) async {
final List<String> args = <String>['open']
.followedBy(additionalArgs)
- .followedBy(<String>['-a', getSimulatorPath()]);
+ .followedBy(<String>['-a', xcode.getSimulatorPath()])
+ .toList();
final RunResult launchResult = await runAsync(args);
if (launchResult.exitCode != 0) {
@@ -62,22 +62,10 @@
/// Return the list of iOS Simulators (there can only be zero or one).
List<IOSEmulator> getEmulators() {
- final String simulatorPath = getSimulatorPath();
+ final String simulatorPath = xcode.getSimulatorPath();
if (simulatorPath == null) {
return <IOSEmulator>[];
}
return <IOSEmulator>[new IOSEmulator('apple_ios_simulator')];
}
-
-String getSimulatorPath() {
- if (xcode.xcodeSelectPath == null)
- return null;
- final List<String> searchPaths = <String>[
- fs.path.join(xcode.xcodeSelectPath, 'Applications', 'Simulator.app'),
- ];
- return searchPaths.where((String p) => p != null).firstWhere(
- (String p) => fs.directory(p).existsSync(),
- orElse: () => null,
- );
-}
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index d5a2c6b..85d4d87 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -167,6 +167,18 @@
Future<RunResult> clang(List<String> args) {
return runCheckedAsync(<String>['xcrun', 'clang']..addAll(args));
}
+
+ String getSimulatorPath() {
+ if (xcodeSelectPath == null)
+ return null;
+ final List<String> searchPaths = <String>[
+ fs.path.join(xcodeSelectPath, 'Applications', 'Simulator.app'),
+ ];
+ return searchPaths.where((String p) => p != null).firstWhere(
+ (String p) => fs.directory(p).existsSync(),
+ orElse: () => null,
+ );
+ }
}
Future<XcodeBuildResult> buildXcodeProject({
diff --git a/packages/flutter_tools/test/emulator_test.dart b/packages/flutter_tools/test/emulator_test.dart
index 9aad551..4286019 100644
--- a/packages/flutter_tools/test/emulator_test.dart
+++ b/packages/flutter_tools/test/emulator_test.dart
@@ -10,6 +10,8 @@
import 'package:flutter_tools/src/base/config.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/emulator.dart';
+import 'package:flutter_tools/src/ios/ios_emulators.dart';
+import 'package:flutter_tools/src/ios/mac.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';
import 'package:test/test.dart';
@@ -21,11 +23,13 @@
MockProcessManager mockProcessManager;
MockConfig mockConfig;
MockAndroidSdk mockSdk;
+ MockXcode mockXcode;
setUp(() {
mockProcessManager = new MockProcessManager();
mockConfig = new MockConfig();
mockSdk = new MockAndroidSdk();
+ mockXcode = new MockXcode();
when(mockSdk.avdManagerPath).thenReturn('avdmanager');
when(mockSdk.emulatorPath).thenReturn('emulator');
@@ -121,6 +125,30 @@
AndroidSdk: () => mockSdk,
});
});
+
+ group('ios_emulators', () {
+ bool didAttemptToRunSimulator = false;
+ setUp(() {
+ when(mockXcode.xcodeSelectPath).thenReturn('/fake/Xcode.app/Contents/Developer');
+ when(mockXcode.getSimulatorPath()).thenAnswer((_) => '/fake/simulator.app');
+ when(mockProcessManager.run(any)).thenAnswer((Invocation invocation) async {
+ final List<String> args = invocation.positionalArguments[0];
+ if (args.length >= 3 && args[0] == 'open' && args[1] == '-a' && args[2] == '/fake/simulator.app') {
+ didAttemptToRunSimulator = true;
+ }
+ return new ProcessResult(101, 0, '', '');
+ });
+ });
+ testUsingContext('runs correct launch commands', () async {
+ final Emulator emulator = new IOSEmulator('ios');
+ await emulator.launch();
+ expect(didAttemptToRunSimulator, equals(true));
+ }, overrides: <Type, Generator>{
+ ProcessManager: () => mockProcessManager,
+ Config: () => mockConfig,
+ Xcode: () => mockXcode,
+ });
+ });
}
class TestEmulatorManager extends EmulatorManager {
@@ -230,3 +258,5 @@
throw new ProcessException('emulator', args);
}
}
+
+class MockXcode extends Mock implements Xcode {}