blob: fbba4531769d2255c524c664619d62fb56308fb0 [file] [log] [blame]
Ian Hickson449f4a62019-11-27 15:04:02 -08001// Copyright 2014 The Flutter Authors. All rights reserved.
xster6a494192017-07-12 18:35:08 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:async';
6
7import 'package:file/file.dart';
8import 'package:file/memory.dart';
Jonah Williamsee7a37f2020-01-06 11:04:20 -08009import 'package:platform/platform.dart';
10import 'package:mockito/mockito.dart';
11import 'package:process/process.dart';
12
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +010013import 'package:flutter_tools/src/base/common.dart';
xster6a494192017-07-12 18:35:08 -070014import 'package:flutter_tools/src/base/io.dart';
Mikkel Nygaard Ravnc2e1bc02018-02-15 22:55:36 +010015import 'package:flutter_tools/src/cache.dart';
Zachary Anderson390ed1c2020-02-03 14:33:03 -080016import 'package:flutter_tools/src/globals.dart' as globals;
stuartmorgan81c38b22019-05-24 22:51:02 -040017import 'package:flutter_tools/src/ios/xcodeproj.dart';
18import 'package:flutter_tools/src/macos/cocoapods.dart';
KyleWong60aa49e2019-01-30 12:33:16 +080019import 'package:flutter_tools/src/plugins.dart';
Sigurd Meldgaard1e8ef602018-06-28 14:35:00 +020020import 'package:flutter_tools/src/project.dart';
xster6a494192017-07-12 18:35:08 -070021
Ian Hicksond919e692019-07-13 11:51:44 -070022import '../../src/common.dart';
23import '../../src/context.dart';
xster6a494192017-07-12 18:35:08 -070024
Alexandre Ardhuina07d3712018-09-14 21:06:19 +020025typedef InvokeProcess = Future<ProcessResult> Function();
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +020026
xster6a494192017-07-12 18:35:08 -070027void main() {
28 FileSystem fs;
29 ProcessManager mockProcessManager;
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +010030 MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +020031 FlutterProject projectUnderTest;
xster6a494192017-07-12 18:35:08 -070032 CocoaPods cocoaPodsUnderTest;
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +020033 InvokeProcess resultOfPodVersion;
34
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +020035 void pretendPodVersionFails() {
36 resultOfPodVersion = () async => exitsWithError();
37 }
38
39 void pretendPodVersionIs(String versionText) {
40 resultOfPodVersion = () async => exitsHappy(versionText);
41 }
xster6a494192017-07-12 18:35:08 -070042
Dan Field704814c2019-02-05 16:03:37 -080043 void podsIsInHomeDir() {
Zachary Anderson390ed1c2020-02-03 14:33:03 -080044 fs.directory(fs.path.join(
45 globals.fsUtils.homeDirPath,
46 '.cocoapods',
47 'repos',
48 'master',
49 )).createSync(recursive: true);
Dan Field704814c2019-02-05 16:03:37 -080050 }
51
52 String podsIsInCustomDir({String cocoapodsReposDir}) {
Zachary Anderson390ed1c2020-02-03 14:33:03 -080053 cocoapodsReposDir ??= fs.path.join(
54 globals.fsUtils.homeDirPath,
55 'cache',
56 'cocoapods',
57 'repos',
58 );
Dan Field704814c2019-02-05 16:03:37 -080059 fs.directory(fs.path.join(cocoapodsReposDir, 'master')).createSync(recursive: true);
60 return cocoapodsReposDir;
61 }
62
Mikkel Nygaard Ravnb2800742018-08-02 14:12:25 +020063 setUp(() async {
xster6a494192017-07-12 18:35:08 -070064 Cache.flutterRoot = 'flutter';
Alexandre Ardhuind927c932018-09-12 08:29:29 +020065 fs = MemoryFileSystem();
66 mockProcessManager = MockProcessManager();
67 mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
Jonah Williams4ff46712019-04-29 08:21:32 -070068 projectUnderTest = FlutterProject.fromDirectory(fs.directory('project'));
Mikkel Nygaard Ravna600fe72018-09-25 21:21:13 +020069 projectUnderTest.ios.xcodeProject.createSync(recursive: true);
Alexandre Ardhuind927c932018-09-12 08:29:29 +020070 cocoaPodsUnderTest = CocoaPods();
Jenn Magdera14ac4e2020-03-06 12:14:42 -080071 pretendPodVersionIs('1.8.0');
xster6a494192017-07-12 18:35:08 -070072 fs.file(fs.path.join(
stuartmorgan3ebebeb2019-05-31 13:19:44 -070073 Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-ios-objc',
xster6a494192017-07-12 18:35:08 -070074 ))
75 ..createSync(recursive: true)
stuartmorgan3ebebeb2019-05-31 13:19:44 -070076 ..writeAsStringSync('Objective-C iOS podfile template');
xster6a494192017-07-12 18:35:08 -070077 fs.file(fs.path.join(
stuartmorgan3ebebeb2019-05-31 13:19:44 -070078 Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-ios-swift',
xster6a494192017-07-12 18:35:08 -070079 ))
80 ..createSync(recursive: true)
stuartmorgan3ebebeb2019-05-31 13:19:44 -070081 ..writeAsStringSync('Swift iOS podfile template');
82 fs.file(fs.path.join(
83 Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-macos',
84 ))
85 ..createSync(recursive: true)
86 ..writeAsStringSync('macOS podfile template');
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +020087 when(mockProcessManager.run(
88 <String>['pod', '--version'],
Sam Rawlinsfba81d02018-05-31 08:24:26 -070089 workingDirectory: anyNamed('workingDirectory'),
90 environment: anyNamed('environment'),
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +020091 )).thenAnswer((_) => resultOfPodVersion());
xster6a494192017-07-12 18:35:08 -070092 when(mockProcessManager.run(
93 <String>['pod', 'install', '--verbose'],
94 workingDirectory: 'project/ios',
Dan Field088fa242019-12-02 13:26:32 -080095 environment: <String, String>{'FLUTTER_FRAMEWORK_DIR': 'engine/path', 'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +020096 )).thenAnswer((_) async => exitsHappy());
stuartmorgan3ebebeb2019-05-31 13:19:44 -070097 when(mockProcessManager.run(
98 <String>['pod', 'install', '--verbose'],
99 workingDirectory: 'project/macos',
Dan Field088fa242019-12-02 13:26:32 -0800100 environment: <String, String>{'FLUTTER_FRAMEWORK_DIR': 'engine/path', 'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700101 )).thenAnswer((_) async => exitsHappy());
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200102 });
103
Christopher Fujinod1e02732019-08-23 09:21:09 -0700104 void pretendPodIsNotInstalled() {
105 when(mockProcessManager.run(
106 <String>['which', 'pod'],
107 workingDirectory: anyNamed('workingDirectory'),
108 environment: anyNamed('environment'),
109 )).thenAnswer((_) async => exitsWithError());
110 }
111
Christopher Fujino2c846af2020-03-03 17:55:02 -0800112 void pretendPodIsBroken() {
113 // it is present
114 when(mockProcessManager.run(
115 <String>['which', 'pod'],
116 workingDirectory: anyNamed('workingDirectory'),
117 environment: anyNamed('environment'),
118 )).thenAnswer((_) async => exitsHappy());
119
120 // but is not working
121 when(mockProcessManager.run(
122 <String>['pod', '--version'],
123 workingDirectory: anyNamed('workingDirectory'),
124 environment: anyNamed('environment'),
125 )).thenAnswer((_) async => exitsWithError());
126 }
127
Christopher Fujinod1e02732019-08-23 09:21:09 -0700128 void pretendPodIsInstalled() {
129 when(mockProcessManager.run(
130 <String>['which', 'pod'],
131 workingDirectory: anyNamed('workingDirectory'),
132 environment: anyNamed('environment'),
133 )).thenAnswer((_) async => exitsHappy());
134 }
135
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200136 group('Evaluate installation', () {
Christopher Fujino7d1fbca2020-03-20 13:05:19 -0700137 setUp(() {
138 // Assume all binaries can run
139 when(mockProcessManager.canRun(any)).thenReturn(true);
140 });
141
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200142 testUsingContext('detects not installed, if pod exec does not exist', () async {
143 pretendPodIsNotInstalled();
144 expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.notInstalled);
145 }, overrides: <Type, Generator>{
146 ProcessManager: () => mockProcessManager,
147 });
148
Christopher Fujinod1e02732019-08-23 09:21:09 -0700149 testUsingContext('detects not installed, if pod is installed but version fails', () async {
150 pretendPodIsInstalled();
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200151 pretendPodVersionFails();
Christopher Fujinod1e02732019-08-23 09:21:09 -0700152 expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.brokenInstall);
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200153 }, overrides: <Type, Generator>{
154 ProcessManager: () => mockProcessManager,
155 });
156
157 testUsingContext('detects installed', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700158 pretendPodIsInstalled();
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200159 pretendPodVersionIs('0.0.1');
160 expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, isNot(CocoaPodsStatus.notInstalled));
161 }, overrides: <Type, Generator>{
162 ProcessManager: () => mockProcessManager,
163 });
164
KyleWong85ded442019-01-03 11:57:03 +0800165 testUsingContext('detects unknown version', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700166 pretendPodIsInstalled();
KyleWong85ded442019-01-03 11:57:03 +0800167 pretendPodVersionIs('Plugin loaded.\n1.5.3');
168 expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.unknownVersion);
169 }, overrides: <Type, Generator>{
170 ProcessManager: () => mockProcessManager,
171 });
172
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200173 testUsingContext('detects below minimum version', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700174 pretendPodIsInstalled();
Jenn Magderc8bf7ab2019-06-10 14:30:28 -0700175 pretendPodVersionIs('1.5.0');
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200176 expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.belowMinimumVersion);
177 }, overrides: <Type, Generator>{
178 ProcessManager: () => mockProcessManager,
179 });
180
Jenn Magdera14ac4e2020-03-06 12:14:42 -0800181 testUsingContext('detects below recommended version', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700182 pretendPodIsInstalled();
Jenn Magderc8bf7ab2019-06-10 14:30:28 -0700183 pretendPodVersionIs('1.6.0');
Jenn Magdera14ac4e2020-03-06 12:14:42 -0800184 expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.belowRecommendedVersion);
185 }, overrides: <Type, Generator>{
186 ProcessManager: () => mockProcessManager,
187 });
188
189 testUsingContext('detects at recommended version', () async {
190 pretendPodIsInstalled();
191 pretendPodVersionIs('1.8.0');
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200192 expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.recommended);
193 }, overrides: <Type, Generator>{
194 ProcessManager: () => mockProcessManager,
195 });
196
197 testUsingContext('detects above recommended version', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700198 pretendPodIsInstalled();
Jenn Magdera14ac4e2020-03-06 12:14:42 -0800199 pretendPodVersionIs('1.8.1');
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200200 expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.recommended);
201 }, overrides: <Type, Generator>{
202 ProcessManager: () => mockProcessManager,
203 });
Jenn Magder1eb1e222019-09-30 13:14:42 -0700204
205 testUsingContext('detects initialized over 1.8.0', () async {
206 pretendPodIsInstalled();
207 pretendPodVersionIs('1.8.0');
208 expect(await cocoaPodsUnderTest.isCocoaPodsInitialized, isTrue);
209 }, overrides: <Type, Generator>{
Jenn Magder1eb1e222019-09-30 13:14:42 -0700210 Platform: () => FakePlatform(),
211 FileSystem: () => fs,
Ian Hickson08643c42019-10-11 11:23:12 -0700212 ProcessManager: () => mockProcessManager,
Jenn Magder1eb1e222019-09-30 13:14:42 -0700213 });
xster6a494192017-07-12 18:35:08 -0700214 });
215
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100216 group('Setup Podfile', () {
Sigurd Meldgaard6a8f9042018-07-16 16:21:20 +0200217 testUsingContext('creates objective-c Podfile when not present', () async {
Zachary Andersonb7c714e2019-08-28 10:03:53 -0700218 await cocoaPodsUnderTest.setupPodfile(projectUnderTest.ios);
Sigurd Meldgaard6a8f9042018-07-16 16:21:20 +0200219
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700220 expect(projectUnderTest.ios.podfile.readAsStringSync(), 'Objective-C iOS podfile template');
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100221 }, overrides: <Type, Generator>{
222 FileSystem: () => fs,
Jonah Williams4c677e42019-10-22 22:05:00 -0700223 ProcessManager: () => FakeProcessManager.any(),
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100224 });
225
Sigurd Meldgaard1e8ef602018-06-28 14:35:00 +0200226 testUsingContext('creates swift Podfile if swift', () async {
Mikkel Nygaard Ravn0d596792018-03-07 08:41:23 +0100227 when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
Zachary Anderson8a33d242019-09-16 07:51:50 -0700228 when(mockXcodeProjectInterpreter.getBuildSettings(any, any))
Alexandre Ardhuinf11c3412019-09-27 10:46:45 +0200229 .thenAnswer((_) async => <String, String>{
Jenn Magderdda74a12019-10-15 12:37:13 -0700230 'SWIFT_VERSION': '5.0',
Alexandre Ardhuinf11c3412019-09-27 10:46:45 +0200231 });
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100232
Jonah Williams4ff46712019-04-29 08:21:32 -0700233 final FlutterProject project = FlutterProject.fromPath('project');
Zachary Andersonb7c714e2019-08-28 10:03:53 -0700234 await cocoaPodsUnderTest.setupPodfile(project.ios);
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100235
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700236 expect(projectUnderTest.ios.podfile.readAsStringSync(), 'Swift iOS podfile template');
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100237 }, overrides: <Type, Generator>{
238 FileSystem: () => fs,
Jonah Williams4c677e42019-10-22 22:05:00 -0700239 ProcessManager: () => FakeProcessManager.any(),
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100240 XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
241 });
242
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700243 testUsingContext('creates macOS Podfile when not present', () async {
244 projectUnderTest.macos.xcodeProject.createSync(recursive: true);
Zachary Andersonb7c714e2019-08-28 10:03:53 -0700245 await cocoaPodsUnderTest.setupPodfile(projectUnderTest.macos);
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700246
247 expect(projectUnderTest.macos.podfile.readAsStringSync(), 'macOS podfile template');
248 }, overrides: <Type, Generator>{
249 FileSystem: () => fs,
Jonah Williams4c677e42019-10-22 22:05:00 -0700250 ProcessManager: () => FakeProcessManager.any(),
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700251 });
252
Sigurd Meldgaard1e8ef602018-06-28 14:35:00 +0200253 testUsingContext('does not recreate Podfile when already present', () async {
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200254 projectUnderTest.ios.podfile..createSync()..writeAsStringSync('Existing Podfile');
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100255
Jonah Williams4ff46712019-04-29 08:21:32 -0700256 final FlutterProject project = FlutterProject.fromPath('project');
Zachary Andersonb7c714e2019-08-28 10:03:53 -0700257 await cocoaPodsUnderTest.setupPodfile(project.ios);
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100258
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200259 expect(projectUnderTest.ios.podfile.readAsStringSync(), 'Existing Podfile');
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100260 }, overrides: <Type, Generator>{
261 FileSystem: () => fs,
Jonah Williams4c677e42019-10-22 22:05:00 -0700262 ProcessManager: () => FakeProcessManager.any(),
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100263 });
264
Sigurd Meldgaard1e8ef602018-06-28 14:35:00 +0200265 testUsingContext('does not create Podfile when we cannot interpret Xcode projects', () async {
Mikkel Nygaard Ravn0d596792018-03-07 08:41:23 +0100266 when(mockXcodeProjectInterpreter.isInstalled).thenReturn(false);
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100267
Jonah Williams4ff46712019-04-29 08:21:32 -0700268 final FlutterProject project = FlutterProject.fromPath('project');
Zachary Andersonb7c714e2019-08-28 10:03:53 -0700269 await cocoaPodsUnderTest.setupPodfile(project.ios);
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100270
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200271 expect(projectUnderTest.ios.podfile.existsSync(), false);
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100272 }, overrides: <Type, Generator>{
273 FileSystem: () => fs,
Jonah Williams4c677e42019-10-22 22:05:00 -0700274 ProcessManager: () => FakeProcessManager.any(),
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100275 XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
276 });
277
Sigurd Meldgaard1e8ef602018-06-28 14:35:00 +0200278 testUsingContext('includes Pod config in xcconfig files, if not present', () async {
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200279 projectUnderTest.ios.podfile..createSync()..writeAsStringSync('Existing Podfile');
280 projectUnderTest.ios.xcodeConfigFor('Debug')
281 ..createSync(recursive: true)
282 ..writeAsStringSync('Existing debug config');
283 projectUnderTest.ios.xcodeConfigFor('Release')
284 ..createSync(recursive: true)
285 ..writeAsStringSync('Existing release config');
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100286
Jonah Williams4ff46712019-04-29 08:21:32 -0700287 final FlutterProject project = FlutterProject.fromPath('project');
Zachary Andersonb7c714e2019-08-28 10:03:53 -0700288 await cocoaPodsUnderTest.setupPodfile(project.ios);
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100289
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200290 final String debugContents = projectUnderTest.ios.xcodeConfigFor('Debug').readAsStringSync();
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100291 expect(debugContents, contains(
292 '#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"\n'));
293 expect(debugContents, contains('Existing debug config'));
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200294 final String releaseContents = projectUnderTest.ios.xcodeConfigFor('Release').readAsStringSync();
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100295 expect(releaseContents, contains(
296 '#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"\n'));
297 expect(releaseContents, contains('Existing release config'));
298 }, overrides: <Type, Generator>{
299 FileSystem: () => fs,
Jonah Williams4c677e42019-10-22 22:05:00 -0700300 ProcessManager: () => FakeProcessManager.any(),
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100301 });
302 });
303
KyleWong60aa49e2019-01-30 12:33:16 +0800304 group('Update xcconfig', () {
305 testUsingContext('includes Pod config in xcconfig files, if the user manually added Pod dependencies without using Flutter plugins', () async {
306 projectUnderTest.ios.podfile..createSync()..writeAsStringSync('Custom Podfile');
307 projectUnderTest.ios.podfileLock..createSync()..writeAsStringSync('Podfile.lock from user executed `pod install`');
308 projectUnderTest.packagesFile..createSync()..writeAsStringSync('');
309 projectUnderTest.ios.xcodeConfigFor('Debug')
310 ..createSync(recursive: true)
311 ..writeAsStringSync('Existing debug config');
312 projectUnderTest.ios.xcodeConfigFor('Release')
313 ..createSync(recursive: true)
314 ..writeAsStringSync('Existing release config');
315
Jonah Williams4ff46712019-04-29 08:21:32 -0700316 final FlutterProject project = FlutterProject.fromPath('project');
Emmanuel Garcia0a93f4e2019-10-16 12:47:04 -0700317 await injectPlugins(project, checkProjects: true);
KyleWong60aa49e2019-01-30 12:33:16 +0800318
319 final String debugContents = projectUnderTest.ios.xcodeConfigFor('Debug').readAsStringSync();
320 expect(debugContents, contains(
321 '#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"\n'));
322 expect(debugContents, contains('Existing debug config'));
323 final String releaseContents = projectUnderTest.ios.xcodeConfigFor('Release').readAsStringSync();
324 expect(releaseContents, contains(
325 '#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"\n'));
326 expect(releaseContents, contains('Existing release config'));
327 }, overrides: <Type, Generator>{
328 FileSystem: () => fs,
Jonah Williams4c677e42019-10-22 22:05:00 -0700329 ProcessManager: () => FakeProcessManager.any(),
KyleWong60aa49e2019-01-30 12:33:16 +0800330 });
331 });
332
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100333 group('Process pods', () {
Dan Field704814c2019-02-05 16:03:37 -0800334 setUp(() {
335 podsIsInHomeDir();
Christopher Fujino7d1fbca2020-03-20 13:05:19 -0700336 // Assume all binaries can run
337 when(mockProcessManager.canRun(any)).thenReturn(true);
Dan Field704814c2019-02-05 16:03:37 -0800338 });
339
Christopher Fujino2c846af2020-03-03 17:55:02 -0800340 testUsingContext('throwsToolExit if CocoaPods is not installed', () async {
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200341 pretendPodIsNotInstalled();
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200342 projectUnderTest.ios.podfile.createSync();
Christopher Fujino2c846af2020-03-03 17:55:02 -0800343 final Function invokeProcessPods = () async => await cocoaPodsUnderTest.processPods(
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700344 xcodeProject: projectUnderTest.ios,
345 engineDir: 'engine/path',
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100346 );
Christopher Fujino2c846af2020-03-03 17:55:02 -0800347 expect(invokeProcessPods, throwsToolExit());
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100348 verifyNever(mockProcessManager.run(
Sam Rawlins9f8a70b2018-06-21 16:23:47 -0700349 argThat(containsAllInOrder(<String>['pod', 'install'])),
Sam Rawlinsfba81d02018-05-31 08:24:26 -0700350 workingDirectory: anyNamed('workingDirectory'),
Sam Rawlins1f76f7f2018-05-16 10:19:05 -0700351 environment: anyNamed('environment'),
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100352 ));
Christopher Fujino2c846af2020-03-03 17:55:02 -0800353 }, overrides: <Type, Generator>{
354 FileSystem: () => fs,
355 ProcessManager: () => mockProcessManager,
356 });
357
358 testUsingContext('throwsToolExit if CocoaPods install is broken', () async {
359 pretendPodIsBroken();
360 projectUnderTest.ios.podfile.createSync();
361 final Function invokeProcessPods = () async => await cocoaPodsUnderTest.processPods(
362 xcodeProject: projectUnderTest.ios,
363 engineDir: 'engine/path',
364 );
365 expect(invokeProcessPods, throwsToolExit());
366 verifyNever(mockProcessManager.run(
367 argThat(containsAllInOrder(<String>['pod', 'install'])),
368 workingDirectory: anyNamed('workingDirectory'),
369 environment: anyNamed('environment'),
370 ));
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100371 }, overrides: <Type, Generator>{
372 FileSystem: () => fs,
373 ProcessManager: () => mockProcessManager,
374 });
375
Jenn Magder357d02c2019-10-15 15:33:55 -0700376 testUsingContext('prints warning, if Podfile is out of date', () async {
377 pretendPodIsInstalled();
378
379 fs.file(fs.path.join('project', 'ios', 'Podfile'))
380 ..createSync()
381 ..writeAsStringSync('Existing Podfile');
382
383 final Directory symlinks = projectUnderTest.ios.symlinks
384 ..createSync(recursive: true);
385 symlinks.childLink('flutter').createSync('cache');
386
387 await cocoaPodsUnderTest.processPods(
388 xcodeProject: projectUnderTest.ios,
389 engineDir: 'engine/path',
390 );
391 expect(testLogger.errorText, contains('Warning: Podfile is out of date'));
392 }, overrides: <Type, Generator>{
393 FileSystem: () => fs,
394 ProcessManager: () => mockProcessManager,
395 });
396
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100397 testUsingContext('throws, if Podfile is missing.', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700398 pretendPodIsInstalled();
xster6a494192017-07-12 18:35:08 -0700399 try {
400 await cocoaPodsUnderTest.processPods(
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700401 xcodeProject: projectUnderTest.ios,
402 engineDir: 'engine/path',
xster6a494192017-07-12 18:35:08 -0700403 );
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100404 fail('ToolExit expected');
Zachary Anderson6c408a02020-03-06 10:22:12 -0800405 } on Exception catch (e) {
Dan Field8b299332020-01-27 14:36:02 -0800406 expect(e, isA<ToolExit>());
xster6a494192017-07-12 18:35:08 -0700407 verifyNever(mockProcessManager.run(
Sam Rawlins9f8a70b2018-06-21 16:23:47 -0700408 argThat(containsAllInOrder(<String>['pod', 'install'])),
Sam Rawlinsfba81d02018-05-31 08:24:26 -0700409 workingDirectory: anyNamed('workingDirectory'),
Sam Rawlins1f76f7f2018-05-16 10:19:05 -0700410 environment: anyNamed('environment'),
xster6a494192017-07-12 18:35:08 -0700411 ));
412 }
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100413 }, overrides: <Type, Generator>{
xster6a494192017-07-12 18:35:08 -0700414 FileSystem: () => fs,
415 ProcessManager: () => mockProcessManager,
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100416 });
xstere9403812017-11-10 12:41:58 -0800417
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100418 testUsingContext('throws, if specs repo is outdated.', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700419 pretendPodIsInstalled();
xstere9403812017-11-10 12:41:58 -0800420 fs.file(fs.path.join('project', 'ios', 'Podfile'))
421 ..createSync()
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200422 ..writeAsStringSync('Existing Podfile');
xstere9403812017-11-10 12:41:58 -0800423
424 when(mockProcessManager.run(
425 <String>['pod', 'install', '--verbose'],
426 workingDirectory: 'project/ios',
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100427 environment: <String, String>{
428 'FLUTTER_FRAMEWORK_DIR': 'engine/path',
429 'COCOAPODS_DISABLE_STATS': 'true',
Dan Field088fa242019-12-02 13:26:32 -0800430 'LANG': 'en_US.UTF-8',
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100431 },
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200432 )).thenAnswer((_) async => exitsWithError(
xstere9403812017-11-10 12:41:58 -0800433 '''
434[!] Unable to satisfy the following requirements:
435
436- `Firebase/Auth` required by `Podfile`
437- `Firebase/Auth (= 4.0.0)` required by `Podfile.lock`
438
439None of your spec sources contain a spec satisfying the dependencies: `Firebase/Auth, Firebase/Auth (= 4.0.0)`.
440
441You have either:
442 * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
443 * mistyped the name or version.
444 * not added the source repo that hosts the Podspec to your Podfile.
445
446Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.''',
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200447 ));
xstere9403812017-11-10 12:41:58 -0800448 try {
449 await cocoaPodsUnderTest.processPods(
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700450 xcodeProject: projectUnderTest.ios,
451 engineDir: 'engine/path',
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100452 );
453 fail('ToolExit expected');
Zachary Anderson6c408a02020-03-06 10:22:12 -0800454 } on Exception catch (e) {
Dan Field8b299332020-01-27 14:36:02 -0800455 expect(e, isA<ToolExit>());
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100456 expect(
457 testLogger.errorText,
458 contains("CocoaPods's specs repository is too out-of-date to satisfy dependencies"),
459 );
xstere9403812017-11-10 12:41:58 -0800460 }
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100461 }, overrides: <Type, Generator>{
xstere9403812017-11-10 12:41:58 -0800462 FileSystem: () => fs,
463 ProcessManager: () => mockProcessManager,
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100464 });
xster4d2c2aa2017-12-27 07:30:31 -0800465
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100466 testUsingContext('run pod install, if Podfile.lock is missing', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700467 pretendPodIsInstalled();
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200468 projectUnderTest.ios.podfile
xster4d2c2aa2017-12-27 07:30:31 -0800469 ..createSync()
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200470 ..writeAsStringSync('Existing Podfile');
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200471 projectUnderTest.ios.podManifestLock
xster4d2c2aa2017-12-27 07:30:31 -0800472 ..createSync(recursive: true)
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200473 ..writeAsStringSync('Existing lock file.');
Chris Brackencdbdafa2018-05-03 19:40:16 -0700474 final bool didInstall = await cocoaPodsUnderTest.processPods(
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700475 xcodeProject: projectUnderTest.ios,
476 engineDir: 'engine/path',
Chris Brackencdbdafa2018-05-03 19:40:16 -0700477 dependenciesChanged: false,
xster4d2c2aa2017-12-27 07:30:31 -0800478 );
Chris Brackencdbdafa2018-05-03 19:40:16 -0700479 expect(didInstall, isTrue);
xster4d2c2aa2017-12-27 07:30:31 -0800480 verify(mockProcessManager.run(
481 <String>['pod', 'install', '--verbose'],
482 workingDirectory: 'project/ios',
Dan Field088fa242019-12-02 13:26:32 -0800483 environment: <String, String>{'FLUTTER_FRAMEWORK_DIR': 'engine/path', 'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
xster4d2c2aa2017-12-27 07:30:31 -0800484 ));
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100485 }, overrides: <Type, Generator>{
xster4d2c2aa2017-12-27 07:30:31 -0800486 FileSystem: () => fs,
487 ProcessManager: () => mockProcessManager,
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100488 });
xster4d2c2aa2017-12-27 07:30:31 -0800489
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100490 testUsingContext('runs pod install, if Manifest.lock is missing', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700491 pretendPodIsInstalled();
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200492 projectUnderTest.ios.podfile
xster4d2c2aa2017-12-27 07:30:31 -0800493 ..createSync()
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200494 ..writeAsStringSync('Existing Podfile');
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200495 projectUnderTest.ios.podfileLock
xster4d2c2aa2017-12-27 07:30:31 -0800496 ..createSync()
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200497 ..writeAsStringSync('Existing lock file.');
Chris Brackencdbdafa2018-05-03 19:40:16 -0700498 final bool didInstall = await cocoaPodsUnderTest.processPods(
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700499 xcodeProject: projectUnderTest.ios,
500 engineDir: 'engine/path',
Chris Brackencdbdafa2018-05-03 19:40:16 -0700501 dependenciesChanged: false,
Mikkel Nygaard Ravnb3e49762018-02-15 22:17:12 +0100502 );
Chris Brackencdbdafa2018-05-03 19:40:16 -0700503 expect(didInstall, isTrue);
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100504 verify(mockProcessManager.run(
Mikkel Nygaard Ravnc2e1bc02018-02-15 22:55:36 +0100505 <String>['pod', 'install', '--verbose'],
506 workingDirectory: 'project/ios',
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100507 environment: <String, String>{
508 'FLUTTER_FRAMEWORK_DIR': 'engine/path',
509 'COCOAPODS_DISABLE_STATS': 'true',
Dan Field088fa242019-12-02 13:26:32 -0800510 'LANG': 'en_US.UTF-8',
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100511 },
Mikkel Nygaard Ravnb3e49762018-02-15 22:17:12 +0100512 ));
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100513 }, overrides: <Type, Generator>{
Mikkel Nygaard Ravnb3e49762018-02-15 22:17:12 +0100514 FileSystem: () => fs,
515 ProcessManager: () => mockProcessManager,
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100516 });
517
518 testUsingContext('runs pod install, if Manifest.lock different from Podspec.lock', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700519 pretendPodIsInstalled();
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200520 projectUnderTest.ios.podfile
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100521 ..createSync()
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200522 ..writeAsStringSync('Existing Podfile');
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200523 projectUnderTest.ios.podfileLock
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100524 ..createSync()
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200525 ..writeAsStringSync('Existing lock file.');
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200526 projectUnderTest.ios.podManifestLock
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100527 ..createSync(recursive: true)
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200528 ..writeAsStringSync('Different lock file.');
Chris Brackencdbdafa2018-05-03 19:40:16 -0700529 final bool didInstall = await cocoaPodsUnderTest.processPods(
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700530 xcodeProject: projectUnderTest.ios,
531 engineDir: 'engine/path',
Chris Brackencdbdafa2018-05-03 19:40:16 -0700532 dependenciesChanged: false,
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100533 );
Chris Brackencdbdafa2018-05-03 19:40:16 -0700534 expect(didInstall, isTrue);
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100535 verify(mockProcessManager.run(
536 <String>['pod', 'install', '--verbose'],
537 workingDirectory: 'project/ios',
538 environment: <String, String>{
539 'FLUTTER_FRAMEWORK_DIR': 'engine/path',
540 'COCOAPODS_DISABLE_STATS': 'true',
Dan Field088fa242019-12-02 13:26:32 -0800541 'LANG': 'en_US.UTF-8',
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100542 },
543 ));
544 }, overrides: <Type, Generator>{
545 FileSystem: () => fs,
546 ProcessManager: () => mockProcessManager,
547 });
548
549 testUsingContext('runs pod install, if flutter framework changed', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700550 pretendPodIsInstalled();
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200551 projectUnderTest.ios.podfile
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100552 ..createSync()
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200553 ..writeAsStringSync('Existing Podfile');
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200554 projectUnderTest.ios.podfileLock
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100555 ..createSync()
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200556 ..writeAsStringSync('Existing lock file.');
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200557 projectUnderTest.ios.podManifestLock
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100558 ..createSync(recursive: true)
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200559 ..writeAsStringSync('Existing lock file.');
Chris Brackencdbdafa2018-05-03 19:40:16 -0700560 final bool didInstall = await cocoaPodsUnderTest.processPods(
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700561 xcodeProject: projectUnderTest.ios,
562 engineDir: 'engine/path',
Chris Brackencdbdafa2018-05-03 19:40:16 -0700563 dependenciesChanged: true,
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100564 );
Chris Brackencdbdafa2018-05-03 19:40:16 -0700565 expect(didInstall, isTrue);
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100566 verify(mockProcessManager.run(
567 <String>['pod', 'install', '--verbose'],
568 workingDirectory: 'project/ios',
569 environment: <String, String>{
570 'FLUTTER_FRAMEWORK_DIR': 'engine/path',
571 'COCOAPODS_DISABLE_STATS': 'true',
Dan Field088fa242019-12-02 13:26:32 -0800572 'LANG': 'en_US.UTF-8',
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100573 },
574 ));
575 }, overrides: <Type, Generator>{
576 FileSystem: () => fs,
577 ProcessManager: () => mockProcessManager,
578 });
579
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200580 testUsingContext('runs pod install, if Podfile.lock is older than Podfile', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700581 pretendPodIsInstalled();
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200582 projectUnderTest.ios.podfile
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200583 ..createSync()
584 ..writeAsStringSync('Existing Podfile');
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200585 projectUnderTest.ios.podfileLock
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200586 ..createSync()
587 ..writeAsStringSync('Existing lock file.');
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200588 projectUnderTest.ios.podManifestLock
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200589 ..createSync(recursive: true)
590 ..writeAsStringSync('Existing lock file.');
Alexandre Ardhuind927c932018-09-12 08:29:29 +0200591 await Future<void>.delayed(const Duration(milliseconds: 10));
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200592 projectUnderTest.ios.podfile
Alexandre Ardhuinc2ae6542020-03-05 08:03:26 +0100593 .writeAsStringSync('Updated Podfile');
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200594 await cocoaPodsUnderTest.processPods(
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700595 xcodeProject: projectUnderTest.ios,
596 engineDir: 'engine/path',
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200597 dependenciesChanged: false,
598 );
599 verify(mockProcessManager.run(
600 <String>['pod', 'install', '--verbose'],
601 workingDirectory: 'project/ios',
602 environment: <String, String>{
603 'FLUTTER_FRAMEWORK_DIR': 'engine/path',
604 'COCOAPODS_DISABLE_STATS': 'true',
Dan Field088fa242019-12-02 13:26:32 -0800605 'LANG': 'en_US.UTF-8',
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200606 },
607 ));
608 }, overrides: <Type, Generator>{
609 FileSystem: () => fs,
610 ProcessManager: () => mockProcessManager,
611 });
612
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100613 testUsingContext('skips pod install, if nothing changed', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700614 pretendPodIsInstalled();
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200615 projectUnderTest.ios.podfile
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100616 ..createSync()
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200617 ..writeAsStringSync('Existing Podfile');
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200618 projectUnderTest.ios.podfileLock
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100619 ..createSync()
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200620 ..writeAsStringSync('Existing lock file.');
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200621 projectUnderTest.ios.podManifestLock
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100622 ..createSync(recursive: true)
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200623 ..writeAsStringSync('Existing lock file.');
Chris Brackencdbdafa2018-05-03 19:40:16 -0700624 final bool didInstall = await cocoaPodsUnderTest.processPods(
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700625 xcodeProject: projectUnderTest.ios,
626 engineDir: 'engine/path',
Chris Brackencdbdafa2018-05-03 19:40:16 -0700627 dependenciesChanged: false,
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100628 );
Chris Brackencdbdafa2018-05-03 19:40:16 -0700629 expect(didInstall, isFalse);
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100630 verifyNever(mockProcessManager.run(
Sam Rawlins9f8a70b2018-06-21 16:23:47 -0700631 argThat(containsAllInOrder(<String>['pod', 'install'])),
Sam Rawlinsfba81d02018-05-31 08:24:26 -0700632 workingDirectory: anyNamed('workingDirectory'),
Sam Rawlins1f76f7f2018-05-16 10:19:05 -0700633 environment: anyNamed('environment'),
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100634 ));
635 }, overrides: <Type, Generator>{
636 FileSystem: () => fs,
637 ProcessManager: () => mockProcessManager,
638 });
xsterf7f16852018-02-16 16:05:16 -0800639
640 testUsingContext('a failed pod install deletes Pods/Manifest.lock', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700641 pretendPodIsInstalled();
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200642 projectUnderTest.ios.podfile
xsterf7f16852018-02-16 16:05:16 -0800643 ..createSync()
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200644 ..writeAsStringSync('Existing Podfile');
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200645 projectUnderTest.ios.podfileLock
xsterf7f16852018-02-16 16:05:16 -0800646 ..createSync()
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200647 ..writeAsStringSync('Existing lock file.');
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200648 projectUnderTest.ios.podManifestLock
xsterf7f16852018-02-16 16:05:16 -0800649 ..createSync(recursive: true)
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200650 ..writeAsStringSync('Existing lock file.');
xsterf7f16852018-02-16 16:05:16 -0800651
652 when(mockProcessManager.run(
653 <String>['pod', 'install', '--verbose'],
654 workingDirectory: 'project/ios',
655 environment: <String, String>{
656 'FLUTTER_FRAMEWORK_DIR': 'engine/path',
657 'COCOAPODS_DISABLE_STATS': 'true',
Dan Field088fa242019-12-02 13:26:32 -0800658 'LANG': 'en_US.UTF-8',
xsterf7f16852018-02-16 16:05:16 -0800659 },
Matan Lurey81070892018-03-19 11:45:44 -0700660 )).thenAnswer(
Mikkel Nygaard Ravn61c71712018-05-08 08:02:39 +0200661 (_) async => exitsWithError()
Matan Lurey81070892018-03-19 11:45:44 -0700662 );
xsterf7f16852018-02-16 16:05:16 -0800663
664 try {
665 await cocoaPodsUnderTest.processPods(
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700666 xcodeProject: projectUnderTest.ios,
667 engineDir: 'engine/path',
Chris Brackencdbdafa2018-05-03 19:40:16 -0700668 dependenciesChanged: true,
xsterf7f16852018-02-16 16:05:16 -0800669 );
670 fail('Tool throw expected when pod install fails');
671 } on ToolExit {
Sigurd Meldgaard2d3a5c72018-07-20 08:00:30 +0200672 expect(projectUnderTest.ios.podManifestLock.existsSync(), isFalse);
xsterf7f16852018-02-16 16:05:16 -0800673 }
674 }, overrides: <Type, Generator>{
675 FileSystem: () => fs,
676 ProcessManager: () => mockProcessManager,
677 });
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100678 });
Dan Field704814c2019-02-05 16:03:37 -0800679
680 group('Pods repos dir is custom', () {
681 String cocoapodsRepoDir;
682 Map<String, String> environment;
683 setUp(() {
Christopher Fujino7d1fbca2020-03-20 13:05:19 -0700684 // Assume binaries exist and can run
685 when(mockProcessManager.canRun(any)).thenReturn(true);
Dan Field704814c2019-02-05 16:03:37 -0800686 cocoapodsRepoDir = podsIsInCustomDir();
687 environment = <String, String>{
688 'FLUTTER_FRAMEWORK_DIR': 'engine/path',
689 'COCOAPODS_DISABLE_STATS': 'true',
690 'CP_REPOS_DIR': cocoapodsRepoDir,
Dan Field088fa242019-12-02 13:26:32 -0800691 'LANG': 'en_US.UTF8',
Dan Field704814c2019-02-05 16:03:37 -0800692 };
693 });
694
695 testUsingContext('succeeds, if specs repo is in CP_REPOS_DIR.', () async {
Christopher Fujinod1e02732019-08-23 09:21:09 -0700696 pretendPodIsInstalled();
Dan Field704814c2019-02-05 16:03:37 -0800697 fs.file(fs.path.join('project', 'ios', 'Podfile'))
698 ..createSync()
699 ..writeAsStringSync('Existing Podfile');
Dan Field704814c2019-02-05 16:03:37 -0800700 when(mockProcessManager.run(
701 <String>['pod', 'install', '--verbose'],
702 workingDirectory: 'project/ios',
703 environment: environment,
704 )).thenAnswer((_) async => exitsHappy());
705 final bool success = await cocoaPodsUnderTest.processPods(
stuartmorgan3ebebeb2019-05-31 13:19:44 -0700706 xcodeProject: projectUnderTest.ios,
707 engineDir: 'engine/path',
Dan Field704814c2019-02-05 16:03:37 -0800708 );
709 expect(success, true);
710 }, overrides: <Type, Generator>{
711 FileSystem: () => fs,
712 ProcessManager: () => mockProcessManager,
713 Platform: () => FakePlatform(environment: environment),
714 });
715 });
xster6a494192017-07-12 18:35:08 -0700716}
717
718class MockProcessManager extends Mock implements ProcessManager {}
Mikkel Nygaard Ravn20004352018-02-16 10:17:28 +0100719class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
xster6a494192017-07-12 18:35:08 -0700720
Alexandre Ardhuin5169ab52019-02-21 09:27:07 +0100721ProcessResult exitsWithError([ String stdout = '' ]) => ProcessResult(1, 1, stdout, '');
722ProcessResult exitsHappy([ String stdout = '' ]) => ProcessResult(1, 0, stdout, '');