flutter/packages/flutter_tools/test/ios/cocoapods_test.dart

204 lines
6.8 KiB
Dart

// 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 'dart:async';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/ios/cocoapods.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';
import 'package:test/test.dart';
import '../src/context.dart';
void main() {
FileSystem fs;
ProcessManager mockProcessManager;
Directory projectUnderTest;
CocoaPods cocoaPodsUnderTest;
setUp(() {
Cache.flutterRoot = 'flutter';
fs = new MemoryFileSystem();
mockProcessManager = new MockProcessManager();
projectUnderTest = fs.directory(fs.path.join('project', 'ios'))..createSync(recursive: true);
fs.file(fs.path.join(
Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-objc'
))
..createSync(recursive: true)
..writeAsStringSync('Objective-C podfile template');
fs.file(fs.path.join(
Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-swift'
))
..createSync(recursive: true)
..writeAsStringSync('Swift podfile template');
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'},
)).thenReturn(exitsHappy);
});
testUsingContext(
'create objective-c Podfile when not present',
() async {
await cocoaPodsUnderTest.processPods(
appIosDir: projectUnderTest,
iosEngineDir: 'engine/path',
);
expect(fs.file(fs.path.join('project', 'ios', 'Podfile')).readAsStringSync() , 'Objective-C podfile template');
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(
'create swift Podfile if swift',
() async {
await cocoaPodsUnderTest.processPods(
appIosDir: projectUnderTest,
iosEngineDir: 'engine/path',
isSwift: true,
);
expect(fs.file(fs.path.join('project', 'ios', 'Podfile')).readAsStringSync() , 'Swift podfile template');
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(
'do not recreate Podfile when present',
() async {
fs.file(fs.path.join('project', 'ios', 'Podfile'))
..createSync()
..writeAsString('Existing Podfile');
await cocoaPodsUnderTest.processPods(
appIosDir: projectUnderTest,
iosEngineDir: 'engine/path',
); expect(fs.file(fs.path.join('project', 'ios', 'Podfile')).readAsStringSync() , 'Existing Podfile');
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(
'missing CocoaPods throws',
() async {
cocoaPodsUnderTest = const TestCocoaPods(false);
try {
await cocoaPodsUnderTest.processPods(
appIosDir: projectUnderTest,
iosEngineDir: 'engine/path',
);
fail('Expected tool error');
} catch (ToolExit) {
verifyNever(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(
'outdated specs repo should print error',
() async {
fs.file(fs.path.join('project', 'ios', 'Podfile'))
..createSync()
..writeAsString('Existing Podfile');
when(mockProcessManager.run(
<String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios',
environment: <String, String>{'FLUTTER_FRAMEWORK_DIR': 'engine/path', 'COCOAPODS_DISABLE_STATS': 'true'},
)).thenReturn(new ProcessResult(
1,
1,
'''
[!] Unable to satisfy the following requirements:
- `Firebase/Auth` required by `Podfile`
- `Firebase/Auth (= 4.0.0)` required by `Podfile.lock`
None of your spec sources contain a spec satisfying the dependencies: `Firebase/Auth, Firebase/Auth (= 4.0.0)`.
You have either:
* out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
* mistyped the name or version.
* 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(
appIosDir: projectUnderTest,
iosEngineDir: 'engine/path',
); expect(fs.file(fs.path.join('project', 'ios', 'Podfile')).readAsStringSync() , 'Existing Podfile');
fail('Exception expected');
} catch (ToolExit) {
expect(testLogger.errorText, contains("CocoaPods's specs repository is too out-of-date to satisfy dependencies"));
}
},
overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => mockProcessManager,
},
);
}
class MockProcessManager extends Mock implements ProcessManager {}
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
);