diff --git a/packages/flutter_tools/lib/src/ios/ios_workflow.dart b/packages/flutter_tools/lib/src/ios/ios_workflow.dart index 07ebfb0e1b4..213f5051aaa 100644 --- a/packages/flutter_tools/lib/src/ios/ios_workflow.dart +++ b/packages/flutter_tools/lib/src/ios/ios_workflow.dart @@ -38,6 +38,8 @@ class IOSWorkflow extends DoctorValidator implements Workflow { String get iosDeployVersionText => runSync(['ios-deploy', '--version']).replaceAll('\n', ''); + bool get hasHomebrew => os.which('brew') != null; + bool get _iosDeployIsInstalledAndMeetsVersionCheck { if (!hasIosDeploy) return false; @@ -89,7 +91,7 @@ class IOSWorkflow extends DoctorValidator implements Workflow { } // brew installed - if (os.which('brew') != null) { + if (hasHomebrew) { brewStatus = ValidationType.installed; if (!exitsHappy(['ideviceinstaller', '-h'])) { @@ -132,9 +134,13 @@ class IOSWorkflow extends DoctorValidator implements Workflow { } return new ValidationResult( - xcodeStatus == brewStatus ? xcodeStatus : ValidationType.partial, + [xcodeStatus, brewStatus].reduce(_mergeValidationTypes), messages, statusInfo: xcodeVersionInfo ); } + + ValidationType _mergeValidationTypes(ValidationType t1, ValidationType t2) { + return t1 == t2 ? t1 : ValidationType.partial; + } } diff --git a/packages/flutter_tools/test/src/ios/ios_workflow_test.dart b/packages/flutter_tools/test/src/ios/ios_workflow_test.dart new file mode 100644 index 00000000000..1c077a6eb2f --- /dev/null +++ b/packages/flutter_tools/test/src/ios/ios_workflow_test.dart @@ -0,0 +1,118 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_tools/src/doctor.dart'; +import 'package:flutter_tools/src/ios/ios_workflow.dart'; +import 'package:flutter_tools/src/ios/mac.dart'; + +import 'package:mockito/mockito.dart'; +import 'package:test/test.dart'; + +import '../context.dart'; + +void main() { + group('iOS Workflow validation', () { + MockXCode xcode; + setUp(() { + xcode = new MockXCode(); + }); + + testUsingContext('Emit missing status when nothing is installed', () async { + when(xcode.isInstalled).thenReturn(false); + IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget() + ..hasHomebrew = false + ..hasIosDeploy = false; + ValidationResult result = await workflow.validate(); + expect(result.type, ValidationType.missing); + }, overrides: { XCode: () => xcode }); + + testUsingContext('Emits partial status when Xcode is not installed', () async { + when(xcode.isInstalled).thenReturn(false); + IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(); + ValidationResult result = await workflow.validate(); + expect(result.type, ValidationType.partial); + }, overrides: { XCode: () => xcode }); + + testUsingContext('Emits partial status when Xcode version too low', () async { + when(xcode.isInstalled).thenReturn(true); + when(xcode.xcodeVersionText) + .thenReturn('Xcode 7.0.1\nBuild version 7C1002\n'); + when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(false); + when(xcode.eulaSigned).thenReturn(true); + IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(); + ValidationResult result = await workflow.validate(); + expect(result.type, ValidationType.partial); + }, overrides: { XCode: () => xcode }); + + testUsingContext('Emits partial status when Xcode EULA not signed', () async { + when(xcode.isInstalled).thenReturn(true); + when(xcode.xcodeVersionText) + .thenReturn('Xcode 8.2.1\nBuild version 8C1002\n'); + when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true); + when(xcode.eulaSigned).thenReturn(false); + IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(); + ValidationResult result = await workflow.validate(); + expect(result.type, ValidationType.partial); + }, overrides: { XCode: () => xcode }); + + testUsingContext('Emits partial status when homebrew not installed', () async { + when(xcode.isInstalled).thenReturn(true); + when(xcode.xcodeVersionText) + .thenReturn('Xcode 8.2.1\nBuild version 8C1002\n'); + when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true); + when(xcode.eulaSigned).thenReturn(true); + IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget() + ..hasHomebrew = false; + ValidationResult result = await workflow.validate(); + expect(result.type, ValidationType.partial); + }, overrides: { XCode: () => xcode }); + + testUsingContext('Emits partial status when ios-deploy is not installed', () async { + when(xcode.isInstalled).thenReturn(true); + when(xcode.xcodeVersionText) + .thenReturn('Xcode 8.2.1\nBuild version 8C1002\n'); + when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true); + when(xcode.eulaSigned).thenReturn(true); + IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget() + ..hasIosDeploy = false; + ValidationResult result = await workflow.validate(); + expect(result.type, ValidationType.partial); + }, overrides: { XCode: () => xcode }); + + testUsingContext('Emits partial status when ios-deploy version is too low', () async { + when(xcode.isInstalled).thenReturn(true); + when(xcode.xcodeVersionText) + .thenReturn('Xcode 8.2.1\nBuild version 8C1002\n'); + when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true); + when(xcode.eulaSigned).thenReturn(true); + IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget() + ..iosDeployVersionText = '1.8.0'; + ValidationResult result = await workflow.validate(); + expect(result.type, ValidationType.partial); + }, overrides: { XCode: () => xcode }); + + testUsingContext('Succeeds when all checks pass', () async { + when(xcode.isInstalled).thenReturn(true); + when(xcode.xcodeVersionText) + .thenReturn('Xcode 8.2.1\nBuild version 8C1002\n'); + when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true); + when(xcode.eulaSigned).thenReturn(true); + ValidationResult result = await new IOSWorkflowTestTarget().validate(); + expect(result.type, ValidationType.installed); + }, overrides: { XCode: () => xcode }); + }); +} + +class MockXCode extends Mock implements XCode {} + +class IOSWorkflowTestTarget extends IOSWorkflow { + @override + bool hasHomebrew = true; + + @override + bool hasIosDeploy = true; + + @override + String iosDeployVersionText = '1.9.0'; +}