Revert "Flutter tools recommend using Cocoapods 1.5.0 (#16971)" (#17110)

This reverts commit 6e26cc28ba4558ac35dcac8eaea3df4fd37a41e1.
diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart
index dda3512..fb1f650 100644
--- a/packages/flutter_tools/lib/src/context_runner.dart
+++ b/packages/flutter_tools/lib/src/context_runner.dart
@@ -52,7 +52,7 @@
       BotDetector: () => const BotDetector(),
       Cache: () => new Cache(),
       Clock: () => const Clock(),
-      CocoaPods: () => new CocoaPods(),
+      CocoaPods: () => const CocoaPods(),
       Config: () => new Config(),
       DevFSConfig: () => new DevFSConfig(),
       DeviceManager: () => new DeviceManager(),
diff --git a/packages/flutter_tools/lib/src/ios/cocoapods.dart b/packages/flutter_tools/lib/src/ios/cocoapods.dart
index 2a3d119..665c0b6 100644
--- a/packages/flutter_tools/lib/src/ios/cocoapods.dart
+++ b/packages/flutter_tools/lib/src/ios/cocoapods.dart
@@ -33,46 +33,25 @@
 
 CocoaPods get cocoaPods => context[CocoaPods];
 
-/// Result of evaluating the CocoaPods installation.
-enum CocoaPodsStatus {
-  /// iOS plugins will not work, installation required.
-  notInstalled,
-  /// iOS plugins will not work, upgrade required.
-  belowMinimumVersion,
-  /// iOS plugins may not work in certain situations (Swift, static libraries),
-  /// upgrade recommended.
-  belowRecommendedVersion,
-  /// Everything should be fine.
-  recommended,
-}
-
 class CocoaPods {
-  Future<String> _versionText;
+  const CocoaPods();
 
+  Future<bool> get hasCocoaPods => exitsHappyAsync(<String>['pod', '--version']);
+
+  // TODO(mravn): Insist on 1.5.0 once build bots have that installed.
+  // Earlier versions do not work with Swift and static libraries.
   String get cocoaPodsMinimumVersion => '1.0.0';
-  String get cocoaPodsRecommendedVersion => '1.5.0';
 
-  Future<String> get cocoaPodsVersionText {
-    _versionText ??= runAsync(<String>['pod', '--version']).then<String>((RunResult result) {
-      return result.exitCode == 0 ? result.stdout.trim() : null;
-    });
-    return _versionText;
-  }
+  Future<String> get cocoaPodsVersionText async => (await runAsync(<String>['pod', '--version'])).processResult.stdout.trim();
 
-  Future<CocoaPodsStatus> get evaluateCocoaPodsInstallation async {
-    final String versionText = await cocoaPodsVersionText;
-    if (versionText == null)
-      return CocoaPodsStatus.notInstalled;
+  Future<bool> get isCocoaPodsInstalledAndMeetsVersionCheck async {
+    if (!await hasCocoaPods)
+      return false;
     try {
-      final Version installedVersion = new Version.parse(versionText);
-      if (installedVersion < new Version.parse(cocoaPodsMinimumVersion))
-        return CocoaPodsStatus.belowMinimumVersion;
-      else if (installedVersion < new Version.parse(cocoaPodsRecommendedVersion))
-        return CocoaPodsStatus.belowRecommendedVersion;
-      else
-        return CocoaPodsStatus.recommended;
+      final Version installedVersion = new Version.parse(await cocoaPodsVersionText);
+      return installedVersion >= new Version.parse(cocoaPodsMinimumVersion);
     } on FormatException {
-      return CocoaPodsStatus.notInstalled;
+      return false;
     }
   }
 
@@ -98,37 +77,16 @@
 
   /// Make sure the CocoaPods tools are in the right states.
   Future<bool> _checkPodCondition() async {
-    final CocoaPodsStatus installation = await evaluateCocoaPodsInstallation;
-    switch (installation) {
-      case CocoaPodsStatus.notInstalled:
-        printError(
-          'Warning: CocoaPods not installed. Skipping pod install.\n'
-          '$noCocoaPodsConsequence\n'
-          'To install:\n'
-          '$cocoaPodsInstallInstructions\n',
-          emphasis: true,
-        );
-        return false;
-      case CocoaPodsStatus.belowMinimumVersion:
-        printError(
-          'Warning: CocoaPods minimum required version $cocoaPodsMinimumVersion or greater not installed. Skipping pod install.\n'
-          '$noCocoaPodsConsequence\n'
-          'To upgrade:\n'
-          '$cocoaPodsUpgradeInstructions\n',
-          emphasis: true,
-        );
-        return false;
-      case CocoaPodsStatus.belowRecommendedVersion:
-        printError(
-          'Warning: CocoaPods recommended version $cocoaPodsRecommendedVersion or greater not installed.\n'
-          'Pods handling may fail on some projects involving plugins.\n'
-          'To upgrade:\n'
-          '$cocoaPodsUpgradeInstructions\n',
-          emphasis: true,
-        );
-        break;
-      default:
-        break;
+    if (!await isCocoaPodsInstalledAndMeetsVersionCheck) {
+      final String minimumVersion = cocoaPodsMinimumVersion;
+      printError(
+        'Warning: CocoaPods version $minimumVersion or greater not installed. Skipping pod install.\n'
+        '$noCocoaPodsConsequence\n'
+        'To install:\n'
+        '$cocoaPodsInstallInstructions\n',
+        emphasis: true,
+      );
+      return false;
     }
     if (!await isCocoaPodsInitialized) {
       printError(
@@ -196,19 +154,18 @@
   // Check if you need to run pod install.
   // The pod install will run if any of below is true.
   // 1. The flutter.framework has changed (debug/release/profile)
-  // 2. The Podfile.lock doesn't exist or is older than Podfile
+  // 2. The podfile.lock doesn't exist
   // 3. The Pods/Manifest.lock doesn't exist (It is deleted when plugins change)
-  // 4. The Podfile.lock doesn't match Pods/Manifest.lock.
+  // 4. The podfile.lock doesn't match Pods/Manifest.lock.
   bool _shouldRunPodInstall(Directory appIosDirectory, bool flutterPodChanged) {
     if (flutterPodChanged)
       return true;
-    final File podfileFile = appIosDirectory.childFile('Podfile');
+    // Check if podfile.lock and Pods/Manifest.lock exist and match.
     final File podfileLockFile = appIosDirectory.childFile('Podfile.lock');
     final File manifestLockFile =
         appIosDirectory.childFile(fs.path.join('Pods', 'Manifest.lock'));
     return !podfileLockFile.existsSync()
         || !manifestLockFile.existsSync()
-        || podfileLockFile.statSync().modified.isBefore(podfileFile.statSync().modified)
         || podfileLockFile.readAsStringSync() != manifestLockFile.readAsStringSync();
   }
 
diff --git a/packages/flutter_tools/lib/src/ios/ios_workflow.dart b/packages/flutter_tools/lib/src/ios/ios_workflow.dart
index 01bee03..2411f82 100644
--- a/packages/flutter_tools/lib/src/ios/ios_workflow.dart
+++ b/packages/flutter_tools/lib/src/ios/ios_workflow.dart
@@ -171,9 +171,7 @@
         }
       }
 
-      final CocoaPodsStatus cocoaPodsStatus = await cocoaPods.evaluateCocoaPodsInstallation;
-
-      if (cocoaPodsStatus == CocoaPodsStatus.recommended) {
+      if (await cocoaPods.isCocoaPodsInstalledAndMeetsVersionCheck) {
         if (await cocoaPods.isCocoaPodsInitialized) {
           messages.add(new ValidationMessage('CocoaPods version ${await cocoaPods.cocoaPodsVersionText}'));
         } else {
@@ -188,7 +186,7 @@
         }
       } else {
         brewStatus = ValidationType.partial;
-        if (cocoaPodsStatus == CocoaPodsStatus.notInstalled) {
+        if (!await cocoaPods.hasCocoaPods) {
           messages.add(new ValidationMessage.error(
             'CocoaPods not installed.\n'
             '$noCocoaPodsConsequence\n'
@@ -197,7 +195,7 @@
           ));
         } else {
           messages.add(new ValidationMessage.error(
-            'CocoaPods out of date (${cocoaPods.cocoaPodsRecommendedVersion} is recommended).\n'
+            'CocoaPods out of date ($cocoaPods.cocoaPodsMinimumVersion is required).\n'
             '$noCocoaPodsConsequence\n'
             'To upgrade:\n'
             '$cocoaPodsUpgradeInstructions'
diff --git a/packages/flutter_tools/lib/src/plugins.dart b/packages/flutter_tools/lib/src/plugins.dart
index 51a7f0d..61989c8 100644
--- a/packages/flutter_tools/lib/src/plugins.dart
+++ b/packages/flutter_tools/lib/src/plugins.dart
@@ -238,7 +238,7 @@
     _writeAndroidPluginRegistrant(directory, plugins);
   if (fs.isDirectorySync(fs.path.join(directory, 'ios'))) {
     _writeIOSPluginRegistrant(directory, plugins);
-    final CocoaPods cocoaPods = new CocoaPods();
+    const CocoaPods cocoaPods = const CocoaPods();
     if (plugins.isNotEmpty)
       cocoaPods.setupPodfile(directory);
     if (changed)
diff --git a/packages/flutter_tools/test/ios/cocoapods_test.dart b/packages/flutter_tools/test/ios/cocoapods_test.dart
index f7d252c..5b37675 100644
--- a/packages/flutter_tools/test/ios/cocoapods_test.dart
+++ b/packages/flutter_tools/test/ios/cocoapods_test.dart
@@ -23,7 +23,6 @@
   MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
   Directory projectUnderTest;
   CocoaPods cocoaPodsUnderTest;
-  ProcessResult resultOfPodVersion;
 
   setUp(() {
     Cache.flutterRoot = 'flutter';
@@ -31,8 +30,7 @@
     mockProcessManager = new MockProcessManager();
     mockXcodeProjectInterpreter = new MockXcodeProjectInterpreter();
     projectUnderTest = fs.directory(fs.path.join('project', 'ios'))..createSync(recursive: true);
-    cocoaPodsUnderTest = new CocoaPods();
-    resultOfPodVersion = exitsHappy('1.5.0');
+
     fs.file(fs.path.join(
       Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-objc'
     ))
@@ -43,86 +41,30 @@
     ))
         ..createSync(recursive: true)
         ..writeAsStringSync('Swift podfile template');
-    fs.directory(fs.path.join(homeDirPath, '.cocoapods', 'repos', 'master')).createSync(recursive: true);
-    when(mockProcessManager.run(
-      <String>['pod', '--version'],
-      workingDirectory: any,
-      environment: any,
-    )).thenAnswer((_) async => resultOfPodVersion);
+    cocoaPodsUnderTest = const TestCocoaPods();
+
     when(mockProcessManager.run(
       <String>['pod', 'install', '--verbose'],
       workingDirectory: 'project/ios',
       environment: <String, String>{'FLUTTER_FRAMEWORK_DIR': 'engine/path', 'COCOAPODS_DISABLE_STATS': 'true'},
-    )).thenAnswer((_) async => exitsHappy());
-  });
-
-  void pretendPodIsNotInstalled() {
-    resultOfPodVersion = exitsWithError();
-  }
-
-  void pretendPodVersionIs(String versionText) {
-    resultOfPodVersion = exitsHappy(versionText);
-  }
-
-  group('Evaluate installation', () {
-    testUsingContext('detects not installed', () async {
-      pretendPodIsNotInstalled();
-      expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.notInstalled);
-    }, overrides: <Type, Generator>{
-      ProcessManager: () => mockProcessManager,
-    });
-
-    testUsingContext('detects installed', () async {
-      pretendPodVersionIs('0.0.1');
-      expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, isNot(CocoaPodsStatus.notInstalled));
-    }, overrides: <Type, Generator>{
-      ProcessManager: () => mockProcessManager,
-    });
-
-    testUsingContext('detects below minimum version', () async {
-      pretendPodVersionIs('0.39.8');
-      expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.belowMinimumVersion);
-    }, overrides: <Type, Generator>{
-      ProcessManager: () => mockProcessManager,
-    });
-
-    testUsingContext('detects below recommended version', () async {
-      pretendPodVersionIs('1.4.99');
-      expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.belowRecommendedVersion);
-    }, overrides: <Type, Generator>{
-      ProcessManager: () => mockProcessManager,
-    });
-
-    testUsingContext('detects at recommended version', () async {
-      pretendPodVersionIs('1.5.0');
-      expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.recommended);
-    }, overrides: <Type, Generator>{
-      ProcessManager: () => mockProcessManager,
-    });
-
-    testUsingContext('detects above recommended version', () async {
-      pretendPodVersionIs('1.5.1');
-      expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.recommended);
-    }, overrides: <Type, Generator>{
-      ProcessManager: () => mockProcessManager,
-    });
+    )).thenAnswer((_) => new Future<ProcessResult>.value(exitsHappy));
   });
 
   group('Setup Podfile', () {
-    File podFile;
+    File podfile;
     File debugConfigFile;
     File releaseConfigFile;
 
     setUp(() {
       debugConfigFile = fs.file(fs.path.join('project', 'ios', 'Flutter', 'Debug.xcconfig'));
       releaseConfigFile = fs.file(fs.path.join('project', 'ios', 'Flutter', 'Release.xcconfig'));
-      podFile = fs.file(fs.path.join('project', 'ios', 'Podfile'));
+      podfile = fs.file(fs.path.join('project', 'ios', 'Podfile'));
     });
 
     testUsingContext('creates objective-c Podfile when not present', () {
       cocoaPodsUnderTest.setupPodfile('project');
 
-      expect(podFile.readAsStringSync(), 'Objective-C podfile template');
+      expect(podfile.readAsStringSync(), 'Objective-C podfile template');
     }, overrides: <Type, Generator>{
       FileSystem: () => fs,
     });
@@ -135,18 +77,18 @@
 
       cocoaPodsUnderTest.setupPodfile('project');
 
-      expect(podFile.readAsStringSync(), 'Swift podfile template');
+      expect(podfile.readAsStringSync(), 'Swift podfile template');
     }, overrides: <Type, Generator>{
       FileSystem: () => fs,
       XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
     });
 
     testUsingContext('does not recreate Podfile when already present', () {
-      podFile..createSync()..writeAsStringSync('Existing Podfile');
+      podfile..createSync()..writeAsStringSync('Existing Podfile');
 
       cocoaPodsUnderTest.setupPodfile('project');
 
-      expect(podFile.readAsStringSync(), 'Existing Podfile');
+      expect(podfile.readAsStringSync(), 'Existing Podfile');
     }, overrides: <Type, Generator>{
       FileSystem: () => fs,
     });
@@ -156,14 +98,14 @@
 
       cocoaPodsUnderTest.setupPodfile('project');
 
-      expect(podFile.existsSync(), false);
+      expect(podfile.existsSync(), false);
     }, overrides: <Type, Generator>{
       FileSystem: () => fs,
       XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
     });
 
     testUsingContext('includes Pod config in xcconfig files, if not present', () {
-      podFile..createSync()..writeAsStringSync('Existing Podfile');
+      podfile..createSync()..writeAsStringSync('Existing Podfile');
       debugConfigFile..createSync(recursive: true)..writeAsStringSync('Existing debug config');
       releaseConfigFile..createSync(recursive: true)..writeAsStringSync('Existing release config');
 
@@ -184,14 +126,14 @@
 
   group('Process pods', () {
     testUsingContext('prints error, if CocoaPods is not installed', () async {
-      pretendPodIsNotInstalled();
       projectUnderTest.childFile('Podfile').createSync();
+      cocoaPodsUnderTest = const TestCocoaPods(false);
       await cocoaPodsUnderTest.processPods(
         appIosDirectory: projectUnderTest,
         iosEngineDir: 'engine/path',
       );
       verifyNever(mockProcessManager.run(
-        argThat(containsAllInOrder(<String>['pod', 'install'])),
+        typed<List<String>>(any),
         workingDirectory: any,
         environment: typed<Map<String, String>>(any, named: 'environment'),
       ));
@@ -203,6 +145,7 @@
     });
 
     testUsingContext('throws, if Podfile is missing.', () async {
+      cocoaPodsUnderTest = const TestCocoaPods(true);
       try {
         await cocoaPodsUnderTest.processPods(
           appIosDirectory: projectUnderTest,
@@ -212,7 +155,7 @@
       } catch(e) {
         expect(e, const isInstanceOf<ToolExit>());
         verifyNever(mockProcessManager.run(
-          argThat(containsAllInOrder(<String>['pod', 'install'])),
+          typed<List<String>>(any),
           workingDirectory: any,
           environment: typed<Map<String, String>>(any, named: 'environment'),
         ));
@@ -225,7 +168,7 @@
     testUsingContext('throws, if specs repo is outdated.', () async {
       fs.file(fs.path.join('project', 'ios', 'Podfile'))
         ..createSync()
-        ..writeAsStringSync('Existing Podfile');
+        ..writeAsString('Existing Podfile');
 
       when(mockProcessManager.run(
         <String>['pod', 'install', '--verbose'],
@@ -234,7 +177,9 @@
           'FLUTTER_FRAMEWORK_DIR': 'engine/path',
           'COCOAPODS_DISABLE_STATS': 'true',
         },
-      )).thenAnswer((_) async => exitsWithError(
+      )).thenAnswer((_) => new Future<ProcessResult>.value(new ProcessResult(
+        1,
+        1,
         '''
 [!] Unable to satisfy the following requirements:
 
@@ -249,7 +194,8 @@
  * not added the source repo that hosts the Podspec to your Podfile.
 
 Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.''',
-      ));
+        '',
+      )));
       try {
         await cocoaPodsUnderTest.processPods(
           appIosDirectory: projectUnderTest,
@@ -271,10 +217,10 @@
     testUsingContext('run pod install, if Podfile.lock is missing', () async {
       projectUnderTest.childFile('Podfile')
         ..createSync()
-        ..writeAsStringSync('Existing Podfile');
+        ..writeAsString('Existing Podfile');
       projectUnderTest.childFile('Pods/Manifest.lock')
         ..createSync(recursive: true)
-        ..writeAsStringSync('Existing lock file.');
+        ..writeAsString('Existing lock file.');
       await cocoaPodsUnderTest.processPods(
         appIosDirectory: projectUnderTest,
         iosEngineDir: 'engine/path',
@@ -293,10 +239,10 @@
     testUsingContext('runs pod install, if Manifest.lock is missing', () async {
       projectUnderTest.childFile('Podfile')
         ..createSync()
-        ..writeAsStringSync('Existing Podfile');
+        ..writeAsString('Existing Podfile');
       projectUnderTest.childFile('Podfile.lock')
         ..createSync()
-        ..writeAsStringSync('Existing lock file.');
+        ..writeAsString('Existing lock file.');
       await cocoaPodsUnderTest.processPods(
         appIosDirectory: projectUnderTest,
         iosEngineDir: 'engine/path',
@@ -318,13 +264,13 @@
     testUsingContext('runs pod install, if Manifest.lock different from Podspec.lock', () async {
       projectUnderTest.childFile('Podfile')
         ..createSync()
-        ..writeAsStringSync('Existing Podfile');
+        ..writeAsString('Existing Podfile');
       projectUnderTest.childFile('Podfile.lock')
         ..createSync()
-        ..writeAsStringSync('Existing lock file.');
+        ..writeAsString('Existing lock file.');
       projectUnderTest.childFile('Pods/Manifest.lock')
         ..createSync(recursive: true)
-        ..writeAsStringSync('Different lock file.');
+        ..writeAsString('Different lock file.');
       await cocoaPodsUnderTest.processPods(
         appIosDirectory: projectUnderTest,
         iosEngineDir: 'engine/path',
@@ -346,13 +292,13 @@
     testUsingContext('runs pod install, if flutter framework changed', () async {
       projectUnderTest.childFile('Podfile')
         ..createSync()
-        ..writeAsStringSync('Existing Podfile');
+        ..writeAsString('Existing Podfile');
       projectUnderTest.childFile('Podfile.lock')
         ..createSync()
-        ..writeAsStringSync('Existing lock file.');
+        ..writeAsString('Existing lock file.');
       projectUnderTest.childFile('Pods/Manifest.lock')
         ..createSync(recursive: true)
-        ..writeAsStringSync('Existing lock file.');
+        ..writeAsString('Existing lock file.');
       await cocoaPodsUnderTest.processPods(
         appIosDirectory: projectUnderTest,
         iosEngineDir: 'engine/path',
@@ -371,54 +317,23 @@
       ProcessManager: () => mockProcessManager,
     });
 
-    testUsingContext('runs pod install, if Podfile.lock is older than Podfile', () async {
-      projectUnderTest.childFile('Podfile')
-        ..createSync()
-        ..writeAsStringSync('Existing Podfile');
-      projectUnderTest.childFile('Podfile.lock')
-        ..createSync()
-        ..writeAsStringSync('Existing lock file.');
-      projectUnderTest.childFile('Pods/Manifest.lock')
-        ..createSync(recursive: true)
-        ..writeAsStringSync('Existing lock file.');
-      await new Future<void>.delayed(const Duration(milliseconds: 10));
-      projectUnderTest.childFile('Podfile')
-        ..writeAsStringSync('Updated Podfile');
-      await cocoaPodsUnderTest.processPods(
-        appIosDirectory: projectUnderTest,
-        iosEngineDir: 'engine/path',
-        flutterPodChanged: false,
-      );
-      verify(mockProcessManager.run(
-        <String>['pod', 'install', '--verbose'],
-        workingDirectory: 'project/ios',
-        environment: <String, String>{
-          'FLUTTER_FRAMEWORK_DIR': 'engine/path',
-          'COCOAPODS_DISABLE_STATS': 'true',
-        },
-      ));
-    }, overrides: <Type, Generator>{
-      FileSystem: () => fs,
-      ProcessManager: () => mockProcessManager,
-    });
-
     testUsingContext('skips pod install, if nothing changed', () async {
       projectUnderTest.childFile('Podfile')
         ..createSync()
-        ..writeAsStringSync('Existing Podfile');
+        ..writeAsString('Existing Podfile');
       projectUnderTest.childFile('Podfile.lock')
         ..createSync()
-        ..writeAsStringSync('Existing lock file.');
+        ..writeAsString('Existing lock file.');
       projectUnderTest.childFile('Pods/Manifest.lock')
         ..createSync(recursive: true)
-        ..writeAsStringSync('Existing lock file.');
+        ..writeAsString('Existing lock file.');
       await cocoaPodsUnderTest.processPods(
         appIosDirectory: projectUnderTest,
         iosEngineDir: 'engine/path',
         flutterPodChanged: false,
       );
       verifyNever(mockProcessManager.run(
-        argThat(containsAllInOrder(<String>['pod', 'install'])),
+        typed<List<String>>(any),
         workingDirectory: any,
         environment: typed<Map<String, String>>(any, named: 'environment'),
       ));
@@ -430,13 +345,13 @@
     testUsingContext('a failed pod install deletes Pods/Manifest.lock', () async {
       projectUnderTest.childFile('Podfile')
         ..createSync()
-        ..writeAsStringSync('Existing Podfile');
+        ..writeAsString('Existing Podfile');
       projectUnderTest.childFile('Podfile.lock')
         ..createSync()
-        ..writeAsStringSync('Existing lock file.');
+        ..writeAsString('Existing lock file.');
       projectUnderTest.childFile('Pods/Manifest.lock')
         ..createSync(recursive: true)
-        ..writeAsStringSync('Existing lock file.');
+        ..writeAsString('Existing lock file.');
 
       when(mockProcessManager.run(
         <String>['pod', 'install', '--verbose'],
@@ -446,7 +361,9 @@
           'COCOAPODS_DISABLE_STATS': 'true',
         },
       )).thenAnswer(
-        (_) async => exitsWithError()
+        (_) => new Future<ProcessResult>.value(
+          new ProcessResult(1, 1, 'fails for some reason', '')
+        )
       );
 
       try {
@@ -469,5 +386,24 @@
 class MockProcessManager extends Mock implements ProcessManager {}
 class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
 
-ProcessResult exitsWithError([String stdout = '']) => new ProcessResult(1, 1, stdout, '');
-ProcessResult exitsHappy([String stdout = '']) => new ProcessResult(1, 0, stdout, '');
\ No newline at end of file
+class TestCocoaPods extends CocoaPods {
+  const TestCocoaPods([this._hasCocoaPods = true]);
+
+  final bool _hasCocoaPods;
+
+  @override
+  Future<bool> get hasCocoaPods => new Future<bool>.value(_hasCocoaPods);
+
+  @override
+  Future<String> get cocoaPodsVersionText async => new Future<String>.value('1.5.0');
+
+  @override
+  Future<bool> get isCocoaPodsInitialized => new Future<bool>.value(true);
+}
+
+final ProcessResult exitsHappy = new ProcessResult(
+  1, // pid
+  0, // exitCode
+  '', // stdout
+  '', // stderr
+);
\ No newline at end of file
diff --git a/packages/flutter_tools/test/ios/ios_workflow_test.dart b/packages/flutter_tools/test/ios/ios_workflow_test.dart
index fb71785..6ee3c24 100644
--- a/packages/flutter_tools/test/ios/ios_workflow_test.dart
+++ b/packages/flutter_tools/test/ios/ios_workflow_test.dart
@@ -33,10 +33,10 @@
       cocoaPods = new MockCocoaPods();
       fs = new MemoryFileSystem();
 
-      when(cocoaPods.evaluateCocoaPodsInstallation)
-          .thenAnswer((_) async => CocoaPodsStatus.recommended);
-      when(cocoaPods.isCocoaPodsInitialized).thenAnswer((_) async => true);
-      when(cocoaPods.cocoaPodsVersionText).thenAnswer((_) async => '1.8.0');
+      when(cocoaPods.isCocoaPodsInstalledAndMeetsVersionCheck)
+          .thenAnswer((_) => new Future<bool>.value(true));
+      when(cocoaPods.isCocoaPodsInitialized)
+          .thenAnswer((_) => new Future<bool>.value(true));
     });
 
     testUsingContext('Emit missing status when nothing is installed', () async {
@@ -213,8 +213,9 @@
           .thenReturn('Xcode 8.2.1\nBuild version 8C1002\n');
       when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
       when(xcode.eulaSigned).thenReturn(true);
-      when(cocoaPods.evaluateCocoaPodsInstallation)
-          .thenAnswer((_) async => CocoaPodsStatus.notInstalled);
+      when(cocoaPods.isCocoaPodsInstalledAndMeetsVersionCheck)
+          .thenAnswer((_) => new Future<bool>.value(false));
+      when(cocoaPods.hasCocoaPods).thenAnswer((_) => new Future<bool>.value(false));
       when(xcode.isSimctlInstalled).thenReturn(true);
       final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget();
       final ValidationResult result = await workflow.validate();
@@ -231,8 +232,11 @@
           .thenReturn('Xcode 8.2.1\nBuild version 8C1002\n');
       when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
       when(xcode.eulaSigned).thenReturn(true);
-      when(cocoaPods.evaluateCocoaPodsInstallation)
-          .thenAnswer((_) async => CocoaPodsStatus.belowRecommendedVersion);
+      when(cocoaPods.isCocoaPodsInstalledAndMeetsVersionCheck)
+          .thenAnswer((_) => new Future<bool>.value(false));
+      when(cocoaPods.hasCocoaPods).thenAnswer((_) => new Future<bool>.value(true));
+      when(cocoaPods.cocoaPodsVersionText)
+          .thenAnswer((_) => new Future<String>.value('0.39.0'));
       when(xcode.isSimctlInstalled).thenReturn(true);
       final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget();
       final ValidationResult result = await workflow.validate();
@@ -249,6 +253,8 @@
           .thenReturn('Xcode 8.2.1\nBuild version 8C1002\n');
       when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
       when(xcode.eulaSigned).thenReturn(true);
+      when(cocoaPods.isCocoaPodsInstalledAndMeetsVersionCheck).thenAnswer((_) async => false);
+      when(cocoaPods.hasCocoaPods).thenAnswer((_) async => true);
       when(cocoaPods.isCocoaPodsInitialized).thenAnswer((_) async => false);
       when(xcode.isSimctlInstalled).thenReturn(true);