Unverified Commit 7c75c01f authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Add recommended Xcode version to doctor (#73808)

parent c65304bb
...@@ -139,8 +139,9 @@ class UserMessages { ...@@ -139,8 +139,9 @@ class UserMessages {
// Messages used in XcodeValidator // Messages used in XcodeValidator
String xcodeLocation(String location) => 'Xcode at $location'; String xcodeLocation(String location) => 'Xcode at $location';
String xcodeOutdated(int versionMajor, int versionMinor, int versionPatch) =>
'Flutter requires a minimum Xcode version of $versionMajor.$versionMinor.$versionPatch.\n' String xcodeOutdated(String currentVersion, String recommendedVersion) =>
'Xcode $currentVersion out of date ($recommendedVersion is recommended).\n'
'Download the latest version or update via the Mac App Store.'; 'Download the latest version or update via the Mac App Store.';
String get xcodeEula => "Xcode end user license agreement not signed; open Xcode or run the command 'sudo xcodebuild -license'."; String get xcodeEula => "Xcode end user license agreement not signed; open Xcode or run the command 'sudo xcodebuild -license'.";
String get xcodeMissingSimct => String get xcodeMissingSimct =>
......
...@@ -637,7 +637,7 @@ class XcodeBuildExecution { ...@@ -637,7 +637,7 @@ class XcodeBuildExecution {
final Map<String, String> buildSettings; final Map<String, String> buildSettings;
} }
const String _xcodeRequirement = 'Xcode $kXcodeRequiredVersionMajor.$kXcodeRequiredVersionMinor.$kXcodeRequiredVersionPatch or greater is required to develop for iOS.'; final String _xcodeRequirement = 'Xcode $xcodeRequiredVersion or greater is required to develop for iOS.';
bool _checkXcodeVersion() { bool _checkXcodeVersion() {
if (!globals.platform.isMacOS) { if (!globals.platform.isMacOS) {
...@@ -647,7 +647,7 @@ bool _checkXcodeVersion() { ...@@ -647,7 +647,7 @@ bool _checkXcodeVersion() {
globals.printError('Cannot find "xcodebuild". $_xcodeRequirement'); globals.printError('Cannot find "xcodebuild". $_xcodeRequirement');
return false; return false;
} }
if (!globals.xcode.isVersionSatisfactory) { if (!globals.xcode.isRequiredVersionSatisfactory) {
globals.printError('Found "${globals.xcodeProjectInterpreter.versionText}". $_xcodeRequirement'); globals.printError('Found "${globals.xcodeProjectInterpreter.versionText}". $_xcodeRequirement');
return false; return false;
} }
......
...@@ -6,6 +6,7 @@ import '../../base/common.dart'; ...@@ -6,6 +6,7 @@ import '../../base/common.dart';
import '../../base/file_system.dart'; import '../../base/file_system.dart';
import '../../base/logger.dart'; import '../../base/logger.dart';
import '../../base/project_migrator.dart'; import '../../base/project_migrator.dart';
import '../../base/version.dart';
import '../../macos/xcode.dart'; import '../../macos/xcode.dart';
import '../../project.dart'; import '../../project.dart';
import '../../reporting/reporting.dart'; import '../../reporting/reporting.dart';
...@@ -99,7 +100,7 @@ class RemoveFrameworkLinkAndEmbeddingMigration extends ProjectMigrator { ...@@ -99,7 +100,7 @@ class RemoveFrameworkLinkAndEmbeddingMigration extends ProjectMigrator {
if (line.contains('/* App.framework ') || line.contains('/* Flutter.framework ')) { if (line.contains('/* App.framework ') || line.contains('/* Flutter.framework ')) {
// Print scary message if the user is on Xcode 11.4 or greater, or if Xcode isn't installed. // Print scary message if the user is on Xcode 11.4 or greater, or if Xcode isn't installed.
final bool xcodeIsInstalled = _xcode.isInstalled; final bool xcodeIsInstalled = _xcode.isInstalled;
if(!xcodeIsInstalled || (_xcode.majorVersion > 11 || (_xcode.majorVersion == 11 && _xcode.minorVersion >= 4))) { if(!xcodeIsInstalled || _xcode.currentVersion >= Version(11, 4, 0)) {
UsageEvent('ios-migration', 'remove-frameworks', label: 'failure', flutterUsage: _usage).send(); UsageEvent('ios-migration', 'remove-frameworks', label: 'failure', flutterUsage: _usage).send();
throwToolExit('Your Xcode project requires migration. See https://flutter.dev/docs/development/ios-project-migration for details.'); throwToolExit('Your Xcode project requires migration. See https://flutter.dev/docs/development/ios-project-migration for details.');
} }
......
...@@ -73,7 +73,6 @@ class IOSSimulatorUtils { ...@@ -73,7 +73,6 @@ class IOSSimulatorUtils {
name: device.name, name: device.name,
simControl: _simControl, simControl: _simControl,
simulatorCategory: device.category, simulatorCategory: device.category,
xcode: _xcode,
); );
}).toList(); }).toList();
} }
...@@ -309,9 +308,7 @@ class IOSSimulator extends Device { ...@@ -309,9 +308,7 @@ class IOSSimulator extends Device {
this.name, this.name,
this.simulatorCategory, this.simulatorCategory,
@required SimControl simControl, @required SimControl simControl,
@required Xcode xcode,
}) : _simControl = simControl, }) : _simControl = simControl,
_xcode = xcode,
super( super(
id, id,
category: Category.mobile, category: Category.mobile,
...@@ -325,7 +322,6 @@ class IOSSimulator extends Device { ...@@ -325,7 +322,6 @@ class IOSSimulator extends Device {
final String simulatorCategory; final String simulatorCategory;
final SimControl _simControl; final SimControl _simControl;
final Xcode _xcode;
@override @override
DevFSWriter createDevFSWriter(covariant ApplicationPackage app, String userIdentifier) { DevFSWriter createDevFSWriter(covariant ApplicationPackage app, String userIdentifier) {
...@@ -610,12 +606,8 @@ class IOSSimulator extends Device { ...@@ -610,12 +606,8 @@ class IOSSimulator extends Device {
} }
} }
bool get _xcodeVersionSupportsScreenshot {
return _xcode.majorVersion > 8 || (_xcode.majorVersion == 8 && _xcode.minorVersion >= 2);
}
@override @override
bool get supportsScreenshot => _xcodeVersionSupportsScreenshot; bool get supportsScreenshot => true;
@override @override
Future<void> takeScreenshot(File outputFile) { Future<void> takeScreenshot(File outputFile) {
......
...@@ -14,6 +14,7 @@ import '../base/io.dart'; ...@@ -14,6 +14,7 @@ import '../base/io.dart';
import '../base/logger.dart'; import '../base/logger.dart';
import '../base/platform.dart'; import '../base/platform.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../base/version.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../cache.dart'; import '../cache.dart';
import '../convert.dart'; import '../convert.dart';
...@@ -25,9 +26,8 @@ import '../ios/mac.dart'; ...@@ -25,9 +26,8 @@ import '../ios/mac.dart';
import '../ios/xcodeproj.dart'; import '../ios/xcodeproj.dart';
import '../reporting/reporting.dart'; import '../reporting/reporting.dart';
const int kXcodeRequiredVersionMajor = 11; Version get xcodeRequiredVersion => Version(11, 0, 0, text: '11.0');
const int kXcodeRequiredVersionMinor = 0; Version get xcodeRecommendedVersion => Version(12, 0, 1, text: '12.0.1');
const int kXcodeRequiredVersionPatch = 0;
/// SDK name passed to `xcrun --sdk`. Corresponds to undocumented Xcode /// SDK name passed to `xcrun --sdk`. Corresponds to undocumented Xcode
/// SUPPORTED_PLATFORMS values. /// SUPPORTED_PLATFORMS values.
...@@ -60,7 +60,7 @@ class Xcode { ...@@ -60,7 +60,7 @@ class Xcode {
final FileSystem _fileSystem; final FileSystem _fileSystem;
final XcodeProjectInterpreter _xcodeProjectInterpreter; final XcodeProjectInterpreter _xcodeProjectInterpreter;
bool get isInstalledAndMeetsVersionCheck => _platform.isMacOS && isInstalled && isVersionSatisfactory; bool get isInstalledAndMeetsVersionCheck => _platform.isMacOS && isInstalled && isRequiredVersionSatisfactory;
String _xcodeSelectPath; String _xcodeSelectPath;
String get xcodeSelectPath { String get xcodeSelectPath {
...@@ -85,9 +85,13 @@ class Xcode { ...@@ -85,9 +85,13 @@ class Xcode {
return _xcodeProjectInterpreter.isInstalled; return _xcodeProjectInterpreter.isInstalled;
} }
int get majorVersion => _xcodeProjectInterpreter.majorVersion; Version get currentVersion => Version(
int get minorVersion => _xcodeProjectInterpreter.minorVersion; _xcodeProjectInterpreter.majorVersion,
int get patchVersion => _xcodeProjectInterpreter.patchVersion; _xcodeProjectInterpreter.minorVersion,
_xcodeProjectInterpreter.patchVersion,
text:
'${_xcodeProjectInterpreter.majorVersion}.${_xcodeProjectInterpreter.minorVersion}.${_xcodeProjectInterpreter.patchVersion}',
);
String get versionText => _xcodeProjectInterpreter.versionText; String get versionText => _xcodeProjectInterpreter.versionText;
...@@ -132,21 +136,19 @@ class Xcode { ...@@ -132,21 +136,19 @@ class Xcode {
return _isSimctlInstalled; return _isSimctlInstalled;
} }
bool get isVersionSatisfactory { bool get isRequiredVersionSatisfactory {
if (!_xcodeProjectInterpreter.isInstalled) { if (!_xcodeProjectInterpreter.isInstalled) {
return false; return false;
} }
if (majorVersion > kXcodeRequiredVersionMajor) { return currentVersion >= xcodeRequiredVersion;
return true;
}
if (majorVersion == kXcodeRequiredVersionMajor) {
if (minorVersion == kXcodeRequiredVersionMinor) {
return patchVersion >= kXcodeRequiredVersionPatch;
}
return minorVersion >= kXcodeRequiredVersionMinor;
} }
bool get isRecommendedVersionSatisfactory {
if (!_xcodeProjectInterpreter.isInstalled) {
return false; return false;
} }
return currentVersion >= xcodeRecommendedVersion;
}
/// See [XcodeProjectInterpreter.xcrunCommand]. /// See [XcodeProjectInterpreter.xcrunCommand].
List<String> xcrunCommand() => _xcodeProjectInterpreter.xcrunCommand(); List<String> xcrunCommand() => _xcodeProjectInterpreter.xcrunCommand();
......
...@@ -29,18 +29,20 @@ class XcodeValidator extends DoctorValidator { ...@@ -29,18 +29,20 @@ class XcodeValidator extends DoctorValidator {
xcodeStatus = ValidationType.installed; xcodeStatus = ValidationType.installed;
messages.add(ValidationMessage(_userMessages.xcodeLocation(_xcode.xcodeSelectPath))); messages.add(ValidationMessage(_userMessages.xcodeLocation(_xcode.xcodeSelectPath)));
xcodeVersionInfo = _xcode.versionText;
if (xcodeVersionInfo.contains(',')) {
xcodeVersionInfo = xcodeVersionInfo.substring(0, xcodeVersionInfo.indexOf(','));
}
messages.add(ValidationMessage(_xcode.versionText)); messages.add(ValidationMessage(_xcode.versionText));
if (!_xcode.isInstalledAndMeetsVersionCheck) { if (!_xcode.isInstalledAndMeetsVersionCheck) {
xcodeStatus = ValidationType.partial; xcodeStatus = ValidationType.partial;
messages.add(ValidationMessage.error( messages.add(ValidationMessage.error(_userMessages.xcodeOutdated(
_userMessages.xcodeOutdated(kXcodeRequiredVersionMajor, kXcodeRequiredVersionMinor, kXcodeRequiredVersionPatch) _xcode.currentVersion.toString(),
)); xcodeRecommendedVersion.toString(),
)));
} else if (!_xcode.isRecommendedVersionSatisfactory) {
xcodeStatus = ValidationType.partial;
messages.add(ValidationMessage.hint(_userMessages.xcodeOutdated(
_xcode.currentVersion.toString(),
xcodeRecommendedVersion.toString(),
)));
} }
if (!_xcode.eulaSigned) { if (!_xcode.eulaSigned) {
......
...@@ -101,7 +101,7 @@ void main() { ...@@ -101,7 +101,7 @@ void main() {
} }
); );
mockXcode = MockXcode(); mockXcode = MockXcode();
when(mockXcode.isVersionSatisfactory).thenReturn(true); when(mockXcode.isRequiredVersionSatisfactory).thenReturn(true);
when(mockXcode.xcrunCommand()).thenReturn(<String>['xcrun']); when(mockXcode.xcrunCommand()).thenReturn(<String>['xcrun']);
fileSystem.file('foo/.packages') fileSystem.file('foo/.packages')
..createSync(recursive: true) ..createSync(recursive: true)
......
...@@ -6,6 +6,7 @@ import 'package:file/file.dart'; ...@@ -6,6 +6,7 @@ import 'package:file/file.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/project_migrator.dart'; import 'package:flutter_tools/src/base/project_migrator.dart';
import 'package:flutter_tools/src/base/version.dart';
import 'package:flutter_tools/src/ios/migrations/project_base_configuration_migration.dart'; import 'package:flutter_tools/src/ios/migrations/project_base_configuration_migration.dart';
import 'package:flutter_tools/src/ios/migrations/project_build_location_migration.dart'; import 'package:flutter_tools/src/ios/migrations/project_build_location_migration.dart';
import 'package:flutter_tools/src/ios/migrations/remove_framework_link_and_embedding_migration.dart'; import 'package:flutter_tools/src/ios/migrations/remove_framework_link_and_embedding_migration.dart';
...@@ -145,8 +146,7 @@ keep this 2 ...@@ -145,8 +146,7 @@ keep this 2
746232531E83B71900CC1A5E /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 746232521E83B71900CC1A5E /* App.framework */; }; 746232531E83B71900CC1A5E /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 746232521E83B71900CC1A5E /* App.framework */; };
'''); ''');
when(mockXcode.isInstalled).thenReturn(true); when(mockXcode.isInstalled).thenReturn(true);
when(mockXcode.majorVersion).thenReturn(11); when(mockXcode.currentVersion).thenReturn(Version(11, 4, 0));
when(mockXcode.minorVersion).thenReturn(4);
final RemoveFrameworkLinkAndEmbeddingMigration iosProjectMigration = RemoveFrameworkLinkAndEmbeddingMigration( final RemoveFrameworkLinkAndEmbeddingMigration iosProjectMigration = RemoveFrameworkLinkAndEmbeddingMigration(
mockIosProject, mockIosProject,
...@@ -164,8 +164,7 @@ keep this 2 ...@@ -164,8 +164,7 @@ keep this 2
9705A1C71CF904A300538480 /* Flutter.framework in Embed Frameworks */, 9705A1C71CF904A300538480 /* Flutter.framework in Embed Frameworks */,
'''); ''');
when(mockXcode.isInstalled).thenReturn(true); when(mockXcode.isInstalled).thenReturn(true);
when(mockXcode.majorVersion).thenReturn(11); when(mockXcode.currentVersion).thenReturn(Version(11, 4, 0));
when(mockXcode.minorVersion).thenReturn(4);
final RemoveFrameworkLinkAndEmbeddingMigration iosProjectMigration = RemoveFrameworkLinkAndEmbeddingMigration( final RemoveFrameworkLinkAndEmbeddingMigration iosProjectMigration = RemoveFrameworkLinkAndEmbeddingMigration(
mockIosProject, mockIosProject,
...@@ -198,8 +197,7 @@ keep this 2 ...@@ -198,8 +197,7 @@ keep this 2
746232531E83B71900CC1A5E /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 746232521E83B71900CC1A5E /* App.framework */; }; 746232531E83B71900CC1A5E /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 746232521E83B71900CC1A5E /* App.framework */; };
'''); ''');
when(mockXcode.isInstalled).thenReturn(true); when(mockXcode.isInstalled).thenReturn(true);
when(mockXcode.majorVersion).thenReturn(11); when(mockXcode.currentVersion).thenReturn(Version(11, 3, 0));
when(mockXcode.minorVersion).thenReturn(3);
final RemoveFrameworkLinkAndEmbeddingMigration iosProjectMigration = RemoveFrameworkLinkAndEmbeddingMigration( final RemoveFrameworkLinkAndEmbeddingMigration iosProjectMigration = RemoveFrameworkLinkAndEmbeddingMigration(
mockIosProject, mockIosProject,
...@@ -217,8 +215,7 @@ keep this 2 ...@@ -217,8 +215,7 @@ keep this 2
746232531E83B71900CC1A5E /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 746232521E83B71900CC1A5E /* App.framework */; }; 746232531E83B71900CC1A5E /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 746232521E83B71900CC1A5E /* App.framework */; };
'''); ''');
when(mockXcode.isInstalled).thenReturn(true); when(mockXcode.isInstalled).thenReturn(true);
when(mockXcode.majorVersion).thenReturn(11); when(mockXcode.currentVersion).thenReturn(Version(11, 4, 0));
when(mockXcode.minorVersion).thenReturn(4);
final RemoveFrameworkLinkAndEmbeddingMigration iosProjectMigration = RemoveFrameworkLinkAndEmbeddingMigration( final RemoveFrameworkLinkAndEmbeddingMigration iosProjectMigration = RemoveFrameworkLinkAndEmbeddingMigration(
mockIosProject, mockIosProject,
...@@ -235,8 +232,7 @@ keep this 2 ...@@ -235,8 +232,7 @@ keep this 2
746232531E83B71900CC1A5E /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 746232521E83B71900CC1A5E /* App.framework */; }; 746232531E83B71900CC1A5E /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 746232521E83B71900CC1A5E /* App.framework */; };
'''); ''');
when(mockXcode.isInstalled).thenReturn(true); when(mockXcode.isInstalled).thenReturn(true);
when(mockXcode.majorVersion).thenReturn(12); when(mockXcode.currentVersion).thenReturn(Version(12, 0, 0));
when(mockXcode.minorVersion).thenReturn(0);
final RemoveFrameworkLinkAndEmbeddingMigration iosProjectMigration = RemoveFrameworkLinkAndEmbeddingMigration( final RemoveFrameworkLinkAndEmbeddingMigration iosProjectMigration = RemoveFrameworkLinkAndEmbeddingMigration(
mockIosProject, mockIosProject,
......
...@@ -70,7 +70,6 @@ void main() { ...@@ -70,7 +70,6 @@ void main() {
final IOSSimulator simulator = IOSSimulator( final IOSSimulator simulator = IOSSimulator(
'123', '123',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
final DevicePortForwarder portForwarder = simulator.portForwarder; final DevicePortForwarder portForwarder = simulator.portForwarder;
await portForwarder.forward(123); await portForwarder.forward(123);
...@@ -94,7 +93,6 @@ void main() { ...@@ -94,7 +93,6 @@ void main() {
final IOSSimulator simulator = IOSSimulator( final IOSSimulator simulator = IOSSimulator(
'123', '123',
simControl: MockSimControl(), simControl: MockSimControl(),
xcode: MockXcode(),
); );
expect(simulator.supportsRuntimeMode(BuildMode.debug), true); expect(simulator.supportsRuntimeMode(BuildMode.debug), true);
...@@ -109,11 +107,9 @@ void main() { ...@@ -109,11 +107,9 @@ void main() {
group('logFilePath', () { group('logFilePath', () {
MockSimControl mockSimControl; MockSimControl mockSimControl;
MockXcode mockXcode;
setUp(() { setUp(() {
mockSimControl = MockSimControl(); mockSimControl = MockSimControl();
mockXcode = MockXcode();
}); });
testUsingContext('defaults to rooted from HOME', () { testUsingContext('defaults to rooted from HOME', () {
...@@ -121,7 +117,6 @@ void main() { ...@@ -121,7 +117,6 @@ void main() {
final IOSSimulator simulator = IOSSimulator( final IOSSimulator simulator = IOSSimulator(
'123', '123',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
expect(simulator.logFilePath, '/foo/bar/Library/Logs/CoreSimulator/123/system.log'); expect(simulator.logFilePath, '/foo/bar/Library/Logs/CoreSimulator/123/system.log');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
...@@ -129,7 +124,6 @@ void main() { ...@@ -129,7 +124,6 @@ void main() {
FileSystemUtils: () => fsUtils, FileSystemUtils: () => fsUtils,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Xcode: () => mockXcode,
}, testOn: 'posix'); }, testOn: 'posix');
testUsingContext('respects IOS_SIMULATOR_LOG_FILE_PATH', () { testUsingContext('respects IOS_SIMULATOR_LOG_FILE_PATH', () {
...@@ -138,7 +132,6 @@ void main() { ...@@ -138,7 +132,6 @@ void main() {
final IOSSimulator simulator = IOSSimulator( final IOSSimulator simulator = IOSSimulator(
'456', '456',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
expect(simulator.logFilePath, '/baz/qux/456/system.log'); expect(simulator.logFilePath, '/baz/qux/456/system.log');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
...@@ -146,7 +139,6 @@ void main() { ...@@ -146,7 +139,6 @@ void main() {
FileSystemUtils: () => fsUtils, FileSystemUtils: () => fsUtils,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Xcode: () => mockXcode,
}); });
}); });
...@@ -201,11 +193,9 @@ void main() { ...@@ -201,11 +193,9 @@ void main() {
group('sdkMajorVersion', () { group('sdkMajorVersion', () {
MockSimControl mockSimControl; MockSimControl mockSimControl;
MockXcode mockXcode;
setUp(() { setUp(() {
mockSimControl = MockSimControl(); mockSimControl = MockSimControl();
mockXcode = MockXcode();
}); });
// This new version string appears in SimulatorApp-850 CoreSimulator-518.16 beta. // This new version string appears in SimulatorApp-850 CoreSimulator-518.16 beta.
...@@ -215,7 +205,6 @@ void main() { ...@@ -215,7 +205,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
expect(await device.sdkMajorVersion, 11); expect(await device.sdkMajorVersion, 11);
...@@ -227,7 +216,6 @@ void main() { ...@@ -227,7 +216,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.2', simulatorCategory: 'iOS 11.2',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
expect(await device.sdkMajorVersion, 11); expect(await device.sdkMajorVersion, 11);
...@@ -239,7 +227,6 @@ void main() { ...@@ -239,7 +227,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.2', simulatorCategory: 'iOS 11.2',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
expect(device.category, Category.mobile); expect(device.category, Category.mobile);
...@@ -248,11 +235,9 @@ void main() { ...@@ -248,11 +235,9 @@ void main() {
group('IOSSimulator.isSupported', () { group('IOSSimulator.isSupported', () {
MockSimControl mockSimControl; MockSimControl mockSimControl;
MockXcode mockXcode;
setUp(() { setUp(() {
mockSimControl = MockSimControl(); mockSimControl = MockSimControl();
mockXcode = MockXcode();
}); });
testUsingContext('Apple TV is unsupported', () { testUsingContext('Apple TV is unsupported', () {
...@@ -260,14 +245,12 @@ void main() { ...@@ -260,14 +245,12 @@ void main() {
'x', 'x',
name: 'Apple TV', name: 'Apple TV',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
expect(simulator.isSupported(), false); expect(simulator.isSupported(), false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Xcode: () => mockXcode,
}); });
testUsingContext('Apple Watch is unsupported', () { testUsingContext('Apple Watch is unsupported', () {
...@@ -275,13 +258,11 @@ void main() { ...@@ -275,13 +258,11 @@ void main() {
'x', 'x',
name: 'Apple Watch', name: 'Apple Watch',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
).isSupported(), false); ).isSupported(), false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Xcode: () => mockXcode,
}); });
testUsingContext('iPad 2 is supported', () { testUsingContext('iPad 2 is supported', () {
...@@ -289,13 +270,11 @@ void main() { ...@@ -289,13 +270,11 @@ void main() {
'x', 'x',
name: 'iPad 2', name: 'iPad 2',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Xcode: () => mockXcode,
}); });
testUsingContext('iPad Retina is supported', () { testUsingContext('iPad Retina is supported', () {
...@@ -303,13 +282,11 @@ void main() { ...@@ -303,13 +282,11 @@ void main() {
'x', 'x',
name: 'iPad Retina', name: 'iPad Retina',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Xcode: () => mockXcode,
}); });
testUsingContext('iPhone 5 is supported', () { testUsingContext('iPhone 5 is supported', () {
...@@ -317,13 +294,11 @@ void main() { ...@@ -317,13 +294,11 @@ void main() {
'x', 'x',
name: 'iPhone 5', name: 'iPhone 5',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Xcode: () => mockXcode,
}); });
testUsingContext('iPhone 5s is supported', () { testUsingContext('iPhone 5s is supported', () {
...@@ -331,13 +306,11 @@ void main() { ...@@ -331,13 +306,11 @@ void main() {
'x', 'x',
name: 'iPhone 5s', name: 'iPhone 5s',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Xcode: () => mockXcode,
}); });
testUsingContext('iPhone SE is supported', () { testUsingContext('iPhone SE is supported', () {
...@@ -345,13 +318,11 @@ void main() { ...@@ -345,13 +318,11 @@ void main() {
'x', 'x',
name: 'iPhone SE', name: 'iPhone SE',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Xcode: () => mockXcode,
}); });
testUsingContext('iPhone 7 Plus is supported', () { testUsingContext('iPhone 7 Plus is supported', () {
...@@ -359,13 +330,11 @@ void main() { ...@@ -359,13 +330,11 @@ void main() {
'x', 'x',
name: 'iPhone 7 Plus', name: 'iPhone 7 Plus',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Xcode: () => mockXcode,
}); });
testUsingContext('iPhone X is supported', () { testUsingContext('iPhone X is supported', () {
...@@ -373,13 +342,11 @@ void main() { ...@@ -373,13 +342,11 @@ void main() {
'x', 'x',
name: 'iPhone X', name: 'iPhone X',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Xcode: () => mockXcode,
}); });
}); });
...@@ -410,26 +377,14 @@ void main() { ...@@ -410,26 +377,14 @@ void main() {
'x', 'x',
name: 'iPhone SE', name: 'iPhone SE',
simControl: simControl, simControl: simControl,
xcode: mockXcode,
); );
when(mockXcode.xcrunCommand()).thenReturn(<String>['xcrun']); when(mockXcode.xcrunCommand()).thenReturn(<String>['xcrun']);
}); });
testWithoutContext(
"old Xcode doesn't support screenshot",
() {
when(mockXcode.majorVersion).thenReturn(7);
when(mockXcode.minorVersion).thenReturn(1);
expect(deviceUnderTest.supportsScreenshot, false);
},
);
testWithoutContext( testWithoutContext(
'Xcode 8.2+ supports screenshots', 'supports screenshots',
() async { () async {
when(mockXcode.majorVersion).thenReturn(8);
when(mockXcode.minorVersion).thenReturn(2);
expect(deviceUnderTest.supportsScreenshot, true);
final File screenshot = MemoryFileSystem.test().file('screenshot.png'); final File screenshot = MemoryFileSystem.test().file('screenshot.png');
await deviceUnderTest.takeScreenshot(screenshot); await deviceUnderTest.takeScreenshot(screenshot);
verify(mockProcessManager.run( verify(mockProcessManager.run(
...@@ -468,7 +423,6 @@ void main() { ...@@ -468,7 +423,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 9.3', simulatorCategory: 'iOS 9.3',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
await launchDeviceSystemLogTool(device); await launchDeviceSystemLogTool(device);
expect( expect(
...@@ -484,7 +438,6 @@ void main() { ...@@ -484,7 +438,6 @@ void main() {
fileSystem: fileSystem, fileSystem: fileSystem,
platform: macosPlatform, platform: macosPlatform,
), ),
Xcode: () => mockXcode,
}); });
testUsingContext('unified logging with app name', () async { testUsingContext('unified logging with app name', () async {
...@@ -493,7 +446,6 @@ void main() { ...@@ -493,7 +446,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.0', simulatorCategory: 'iOS 11.0',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
await launchDeviceUnifiedLogging(device, 'My Super Awesome App'); await launchDeviceUnifiedLogging(device, 'My Super Awesome App');
...@@ -530,7 +482,6 @@ void main() { ...@@ -530,7 +482,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.0', simulatorCategory: 'iOS 11.0',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
await launchDeviceUnifiedLogging(device, null); await launchDeviceUnifiedLogging(device, null);
...@@ -557,7 +508,6 @@ void main() { ...@@ -557,7 +508,6 @@ void main() {
overrides: <Type, Generator>{ overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
Xcode: () => mockXcode,
}); });
}); });
...@@ -597,7 +547,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' ...@@ -597,7 +547,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
'123456', '123456',
simulatorCategory: 'iOS 10.0', simulatorCategory: 'iOS 10.0',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
final DeviceLogReader logReader = device.getLogReader( final DeviceLogReader logReader = device.getLogReader(
app: await BuildableIOSApp.fromProject(mockIosProject, null), app: await BuildableIOSApp.fromProject(mockIosProject, null),
...@@ -632,7 +581,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' ...@@ -632,7 +581,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
'123456', '123456',
simulatorCategory: 'iOS 10.3', simulatorCategory: 'iOS 10.3',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
final DeviceLogReader logReader = device.getLogReader( final DeviceLogReader logReader = device.getLogReader(
app: await BuildableIOSApp.fromProject(mockIosProject, null), app: await BuildableIOSApp.fromProject(mockIosProject, null),
...@@ -680,7 +628,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' ...@@ -680,7 +628,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
'123456', '123456',
simulatorCategory: 'iOS 10.3', simulatorCategory: 'iOS 10.3',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
final DeviceLogReader logReader = device.getLogReader( final DeviceLogReader logReader = device.getLogReader(
app: await BuildableIOSApp.fromProject(mockIosProject, null), app: await BuildableIOSApp.fromProject(mockIosProject, null),
...@@ -746,7 +693,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' ...@@ -746,7 +693,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
'123456', '123456',
simulatorCategory: 'iOS 11.0', simulatorCategory: 'iOS 11.0',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
final DeviceLogReader logReader = device.getLogReader( final DeviceLogReader logReader = device.getLogReader(
app: await BuildableIOSApp.fromProject(mockIosProject, null), app: await BuildableIOSApp.fromProject(mockIosProject, null),
...@@ -761,7 +707,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' ...@@ -761,7 +707,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => fakeProcessManager, ProcessManager: () => fakeProcessManager,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
Xcode: () => mockXcode,
}); });
}); });
}); });
...@@ -864,7 +809,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' ...@@ -864,7 +809,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'Testo', name: 'Testo',
simulatorCategory: 'NaN', simulatorCategory: 'NaN',
simControl: simControl, simControl: simControl,
xcode: mockXcode,
); );
expect(await iosSimulatorA.sdkMajorVersion, 11); expect(await iosSimulatorA.sdkMajorVersion, 11);
...@@ -923,7 +867,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' ...@@ -923,7 +867,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.2', simulatorCategory: 'iOS 11.2',
simControl: simControl, simControl: simControl,
xcode: mockXcode,
); );
when(globals.plistParser.getValueFromFile(any, any)).thenReturn('correct'); when(globals.plistParser.getValueFromFile(any, any)).thenReturn('correct');
...@@ -948,7 +891,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' ...@@ -948,7 +891,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.2', simulatorCategory: 'iOS 11.2',
simControl: simControl, simControl: simControl,
xcode: mockXcode,
); );
final Directory mockDir = globals.fs.currentDirectory; final Directory mockDir = globals.fs.currentDirectory;
...@@ -991,7 +933,6 @@ flutter: ...@@ -991,7 +933,6 @@ flutter:
final IOSSimulator simulator = IOSSimulator( final IOSSimulator simulator = IOSSimulator(
'test', 'test',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
expect(simulator.isSupportedForProject(flutterProject), true); expect(simulator.isSupportedForProject(flutterProject), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
...@@ -1010,7 +951,6 @@ flutter: ...@@ -1010,7 +951,6 @@ flutter:
final IOSSimulator simulator = IOSSimulator( final IOSSimulator simulator = IOSSimulator(
'test', 'test',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
expect(simulator.isSupportedForProject(flutterProject), true); expect(simulator.isSupportedForProject(flutterProject), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
...@@ -1027,7 +967,6 @@ flutter: ...@@ -1027,7 +967,6 @@ flutter:
final IOSSimulator simulator = IOSSimulator( final IOSSimulator simulator = IOSSimulator(
'test', 'test',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
expect(simulator.isSupportedForProject(flutterProject), false); expect(simulator.isSupportedForProject(flutterProject), false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
...@@ -1040,7 +979,6 @@ flutter: ...@@ -1040,7 +979,6 @@ flutter:
final IOSSimulator simulator = IOSSimulator( final IOSSimulator simulator = IOSSimulator(
'test', 'test',
simControl: mockSimControl, simControl: mockSimControl,
xcode: mockXcode,
); );
expect(simulator.createDevFSWriter(null, ''), isA<LocalDevFSWriter>()); expect(simulator.createDevFSWriter(null, ''), isA<LocalDevFSWriter>());
......
...@@ -221,13 +221,13 @@ void main() { ...@@ -221,13 +221,13 @@ void main() {
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0); when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
when(mockXcodeProjectInterpreter.patchVersion).thenReturn(0); when(mockXcodeProjectInterpreter.patchVersion).thenReturn(0);
expect(xcode.isVersionSatisfactory, isFalse); expect(xcode.isRequiredVersionSatisfactory, isFalse);
}); });
testWithoutContext('xcodeVersionSatisfactory is false when xcodebuild tools are not installed', () { testWithoutContext('xcodeVersionSatisfactory is false when xcodebuild tools are not installed', () {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(false); when(mockXcodeProjectInterpreter.isInstalled).thenReturn(false);
expect(xcode.isVersionSatisfactory, isFalse); expect(xcode.isRequiredVersionSatisfactory, isFalse);
}); });
testWithoutContext('xcodeVersionSatisfactory is true when version meets minimum', () { testWithoutContext('xcodeVersionSatisfactory is true when version meets minimum', () {
...@@ -236,7 +236,7 @@ void main() { ...@@ -236,7 +236,7 @@ void main() {
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0); when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
when(mockXcodeProjectInterpreter.patchVersion).thenReturn(0); when(mockXcodeProjectInterpreter.patchVersion).thenReturn(0);
expect(xcode.isVersionSatisfactory, isTrue); expect(xcode.isRequiredVersionSatisfactory, isTrue);
}); });
testWithoutContext('xcodeVersionSatisfactory is true when major version exceeds minimum', () { testWithoutContext('xcodeVersionSatisfactory is true when major version exceeds minimum', () {
...@@ -245,7 +245,7 @@ void main() { ...@@ -245,7 +245,7 @@ void main() {
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0); when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
when(mockXcodeProjectInterpreter.patchVersion).thenReturn(0); when(mockXcodeProjectInterpreter.patchVersion).thenReturn(0);
expect(xcode.isVersionSatisfactory, isTrue); expect(xcode.isRequiredVersionSatisfactory, isTrue);
}); });
testWithoutContext('xcodeVersionSatisfactory is true when minor version exceeds minimum', () { testWithoutContext('xcodeVersionSatisfactory is true when minor version exceeds minimum', () {
...@@ -254,7 +254,7 @@ void main() { ...@@ -254,7 +254,7 @@ void main() {
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(3); when(mockXcodeProjectInterpreter.minorVersion).thenReturn(3);
when(mockXcodeProjectInterpreter.patchVersion).thenReturn(0); when(mockXcodeProjectInterpreter.patchVersion).thenReturn(0);
expect(xcode.isVersionSatisfactory, isTrue); expect(xcode.isRequiredVersionSatisfactory, isTrue);
}); });
testWithoutContext('xcodeVersionSatisfactory is true when patch version exceeds minimum', () { testWithoutContext('xcodeVersionSatisfactory is true when patch version exceeds minimum', () {
...@@ -263,7 +263,58 @@ void main() { ...@@ -263,7 +263,58 @@ void main() {
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0); when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
when(mockXcodeProjectInterpreter.patchVersion).thenReturn(1); when(mockXcodeProjectInterpreter.patchVersion).thenReturn(1);
expect(xcode.isVersionSatisfactory, isTrue); expect(xcode.isRequiredVersionSatisfactory, isTrue);
});
testWithoutContext('isRecommendedVersionSatisfactory is false when version is less than minimum', () {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(9);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
when(mockXcodeProjectInterpreter.patchVersion).thenReturn(0);
expect(xcode.isRecommendedVersionSatisfactory, isFalse);
});
testWithoutContext('isRecommendedVersionSatisfactory is false when xcodebuild tools are not installed', () {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(false);
expect(xcode.isRecommendedVersionSatisfactory, isFalse);
});
testWithoutContext('isRecommendedVersionSatisfactory is true when version meets minimum', () {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(12);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
when(mockXcodeProjectInterpreter.patchVersion).thenReturn(1);
expect(xcode.isRecommendedVersionSatisfactory, isTrue);
});
testWithoutContext('isRecommendedVersionSatisfactory is true when major version exceeds minimum', () {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(13);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
when(mockXcodeProjectInterpreter.patchVersion).thenReturn(0);
expect(xcode.isRecommendedVersionSatisfactory, isTrue);
});
testWithoutContext('isRecommendedVersionSatisfactory is true when minor version exceeds minimum', () {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(12);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(3);
when(mockXcodeProjectInterpreter.patchVersion).thenReturn(0);
expect(xcode.isRecommendedVersionSatisfactory, isTrue);
});
testWithoutContext('isRecommendedVersionSatisfactory is true when patch version exceeds minimum', () {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(12);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
when(mockXcodeProjectInterpreter.patchVersion).thenReturn(2);
expect(xcode.isRecommendedVersionSatisfactory, isTrue);
}); });
testWithoutContext('isInstalledAndMeetsVersionCheck is false when not installed', () { testWithoutContext('isInstalledAndMeetsVersionCheck is false when not installed', () {
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter_tools/src/base/user_messages.dart'; import 'package:flutter_tools/src/base/user_messages.dart';
import 'package:flutter_tools/src/base/version.dart';
import 'package:flutter_tools/src/doctor.dart'; import 'package:flutter_tools/src/doctor.dart';
import 'package:flutter_tools/src/macos/xcode.dart'; import 'package:flutter_tools/src/macos/xcode.dart';
import 'package:flutter_tools/src/macos/xcode_validator.dart'; import 'package:flutter_tools/src/macos/xcode_validator.dart';
...@@ -40,12 +41,32 @@ void main() { ...@@ -40,12 +41,32 @@ void main() {
when(xcode.isInstalled).thenReturn(true); when(xcode.isInstalled).thenReturn(true);
when(xcode.versionText) when(xcode.versionText)
.thenReturn('Xcode 7.0.1\nBuild version 7C1002\n'); .thenReturn('Xcode 7.0.1\nBuild version 7C1002\n');
when(xcode.currentVersion).thenReturn(Version(7, 0, 1));
when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(false); when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(false);
when(xcode.isRecommendedVersionSatisfactory).thenReturn(false);
when(xcode.eulaSigned).thenReturn(true); when(xcode.eulaSigned).thenReturn(true);
when(xcode.isSimctlInstalled).thenReturn(true); when(xcode.isSimctlInstalled).thenReturn(true);
final XcodeValidator validator = XcodeValidator(xcode: xcode, userMessages: UserMessages()); final XcodeValidator validator = XcodeValidator(xcode: xcode, userMessages: UserMessages());
final ValidationResult result = await validator.validate(); final ValidationResult result = await validator.validate();
expect(result.type, ValidationType.partial); expect(result.type, ValidationType.partial);
expect(result.messages.last.type, ValidationMessageType.error);
expect(result.messages.last.message, contains('Xcode 7.0.1 out of date (12.0.1 is recommended)'));
});
testWithoutContext('Emits partial status when Xcode below recommended version', () async {
when(xcode.isInstalled).thenReturn(true);
when(xcode.versionText)
.thenReturn('Xcode 11.0\nBuild version 11A420a\n');
when(xcode.currentVersion).thenReturn(Version(11, 0, 0));
when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
when(xcode.isRecommendedVersionSatisfactory).thenReturn(false);
when(xcode.eulaSigned).thenReturn(true);
when(xcode.isSimctlInstalled).thenReturn(true);
final XcodeValidator validator = XcodeValidator(xcode: xcode, userMessages: UserMessages());
final ValidationResult result = await validator.validate();
expect(result.type, ValidationType.partial);
expect(result.messages.last.type, ValidationMessageType.hint);
expect(result.messages.last.message, contains('Xcode 11.0.0 out of date (12.0.1 is recommended)'));
}); });
testWithoutContext('Emits partial status when Xcode EULA not signed', () async { testWithoutContext('Emits partial status when Xcode EULA not signed', () async {
...@@ -53,6 +74,7 @@ void main() { ...@@ -53,6 +74,7 @@ void main() {
when(xcode.versionText) when(xcode.versionText)
.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.isRecommendedVersionSatisfactory).thenReturn(true);
when(xcode.eulaSigned).thenReturn(false); when(xcode.eulaSigned).thenReturn(false);
when(xcode.isSimctlInstalled).thenReturn(true); when(xcode.isSimctlInstalled).thenReturn(true);
final XcodeValidator validator = XcodeValidator(xcode: xcode, userMessages: UserMessages()); final XcodeValidator validator = XcodeValidator(xcode: xcode, userMessages: UserMessages());
...@@ -65,6 +87,7 @@ void main() { ...@@ -65,6 +87,7 @@ void main() {
when(xcode.versionText) when(xcode.versionText)
.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.isRecommendedVersionSatisfactory).thenReturn(true);
when(xcode.eulaSigned).thenReturn(true); when(xcode.eulaSigned).thenReturn(true);
when(xcode.isSimctlInstalled).thenReturn(false); when(xcode.isSimctlInstalled).thenReturn(false);
final XcodeValidator validator = XcodeValidator(xcode: xcode, userMessages: UserMessages()); final XcodeValidator validator = XcodeValidator(xcode: xcode, userMessages: UserMessages());
...@@ -78,6 +101,7 @@ void main() { ...@@ -78,6 +101,7 @@ void main() {
when(xcode.versionText) when(xcode.versionText)
.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.isRecommendedVersionSatisfactory).thenReturn(true);
when(xcode.eulaSigned).thenReturn(true); when(xcode.eulaSigned).thenReturn(true);
when(xcode.isSimctlInstalled).thenReturn(true); when(xcode.isSimctlInstalled).thenReturn(true);
final XcodeValidator validator = XcodeValidator(xcode: xcode, userMessages: UserMessages()); final XcodeValidator validator = XcodeValidator(xcode: xcode, userMessages: UserMessages());
......
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