Unverified Commit dc30327a authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Replace MockProcessManager with FakeProcessManager in cocoapods_test (#74956)

parent cca9592f
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/platform.dart';
...@@ -28,20 +27,29 @@ typedef InvokeProcess = Future<ProcessResult> Function(); ...@@ -28,20 +27,29 @@ typedef InvokeProcess = Future<ProcessResult> Function();
void main() { void main() {
FileSystem fileSystem; FileSystem fileSystem;
ProcessManager mockProcessManager; FakeProcessManager fakeProcessManager;
MockXcodeProjectInterpreter mockXcodeProjectInterpreter; MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
FlutterProject projectUnderTest; FlutterProject projectUnderTest;
CocoaPods cocoaPodsUnderTest; CocoaPods cocoaPodsUnderTest;
InvokeProcess resultOfPodVersion;
BufferLogger logger; BufferLogger logger;
TestUsage usage; TestUsage usage;
void pretendPodVersionFails() { void pretendPodVersionFails() {
resultOfPodVersion = () async => exitsWithError(); fakeProcessManager.addCommand(
const FakeCommand(
command: <String>['pod', '--version'],
exitCode: 1,
),
);
} }
void pretendPodVersionIs(String versionText) { void pretendPodVersionIs(String versionText) {
resultOfPodVersion = () async => exitsHappy(versionText); fakeProcessManager.addCommand(
FakeCommand(
command: const <String>['pod', '--version'],
stdout: versionText,
),
);
} }
void podsIsInHomeDir() { void podsIsInHomeDir() {
...@@ -52,20 +60,10 @@ void main() { ...@@ -52,20 +60,10 @@ void main() {
)).createSync(recursive: true); )).createSync(recursive: true);
} }
String podsIsInCustomDir({String cocoapodsReposDir}) {
cocoapodsReposDir ??= fileSystem.path.join(
'cache',
'cocoapods',
'repos',
);
fileSystem.directory(fileSystem.path.join(cocoapodsReposDir, 'master')).createSync(recursive: true);
return cocoapodsReposDir;
}
setUp(() async { setUp(() async {
Cache.flutterRoot = 'flutter'; Cache.flutterRoot = 'flutter';
fileSystem = MemoryFileSystem.test(); fileSystem = MemoryFileSystem.test();
mockProcessManager = MockProcessManager(); fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
logger = BufferLogger.test(); logger = BufferLogger.test();
mockXcodeProjectInterpreter = MockXcodeProjectInterpreter(); mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
projectUnderTest = FlutterProject.fromDirectory(fileSystem.directory('project')); projectUnderTest = FlutterProject.fromDirectory(fileSystem.directory('project'));
...@@ -74,13 +72,12 @@ void main() { ...@@ -74,13 +72,12 @@ void main() {
usage = TestUsage(); usage = TestUsage();
cocoaPodsUnderTest = CocoaPods( cocoaPodsUnderTest = CocoaPods(
fileSystem: fileSystem, fileSystem: fileSystem,
processManager: mockProcessManager, processManager: fakeProcessManager,
logger: logger, logger: logger,
platform: FakePlatform(operatingSystem: 'macos'), platform: FakePlatform(operatingSystem: 'macos'),
xcodeProjectInterpreter: mockXcodeProjectInterpreter, xcodeProjectInterpreter: mockXcodeProjectInterpreter,
usage: usage, usage: usage,
); );
pretendPodVersionIs('1.10.0');
fileSystem.file(fileSystem.path.join( fileSystem.file(fileSystem.path.join(
Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-ios-objc', Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-ios-objc',
)) ))
...@@ -96,62 +93,40 @@ void main() { ...@@ -96,62 +93,40 @@ void main() {
)) ))
..createSync(recursive: true) ..createSync(recursive: true)
..writeAsStringSync('macOS podfile template'); ..writeAsStringSync('macOS podfile template');
when(mockProcessManager.run(
<String>['pod', '--version'],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).thenAnswer((_) => resultOfPodVersion());
when(mockProcessManager.run(
<String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios',
environment: <String, String>{'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
)).thenAnswer((_) async => exitsHappy());
when(mockProcessManager.run(
<String>['pod', 'install', '--verbose'],
workingDirectory: 'project/macos',
environment: <String, String>{'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
)).thenAnswer((_) async => exitsHappy());
fileSystem.file('.packages').writeAsStringSync('\n');
}); });
void pretendPodIsNotInstalled() { void pretendPodIsNotInstalled() {
when(mockProcessManager.run( fakeProcessManager.addCommand(
<String>['which', 'pod'], const FakeCommand(
workingDirectory: anyNamed('workingDirectory'), command: <String>['which', 'pod'],
environment: anyNamed('environment'), exitCode: 1,
)).thenAnswer((_) async => exitsWithError()); ),
);
} }
void pretendPodIsBroken() { void pretendPodIsBroken() {
// it is present fakeProcessManager.addCommands(<FakeCommand>[
when(mockProcessManager.run( // it is present
<String>['which', 'pod'], const FakeCommand(
workingDirectory: anyNamed('workingDirectory'), command: <String>['which', 'pod'],
environment: anyNamed('environment'), ),
)).thenAnswer((_) async => exitsHappy()); // but is not working
const FakeCommand(
// but is not working command: <String>['pod', '--version'],
when(mockProcessManager.run( exitCode: 1,
<String>['pod', '--version'], ),
workingDirectory: anyNamed('workingDirectory'), ]);
environment: anyNamed('environment'),
)).thenAnswer((_) async => exitsWithError());
} }
void pretendPodIsInstalled() { void pretendPodIsInstalled() {
when(mockProcessManager.run( fakeProcessManager.addCommands(<FakeCommand>[
<String>['which', 'pod'], const FakeCommand(
workingDirectory: anyNamed('workingDirectory'), command: <String>['which', 'pod'],
environment: anyNamed('environment'), ),
)).thenAnswer((_) async => exitsHappy()); ]);
} }
group('Evaluate installation', () { group('Evaluate installation', () {
setUp(() {
// Assume all binaries can run
when(mockProcessManager.canRun(any)).thenReturn(true);
});
testWithoutContext('detects not installed, if pod exec does not exist', () async { testWithoutContext('detects not installed, if pod exec does not exist', () async {
pretendPodIsNotInstalled(); pretendPodIsNotInstalled();
expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.notInstalled); expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.notInstalled);
...@@ -322,42 +297,36 @@ void main() { ...@@ -322,42 +297,36 @@ void main() {
group('Process pods', () { group('Process pods', () {
setUp(() { setUp(() {
podsIsInHomeDir(); podsIsInHomeDir();
// Assume all binaries can run
when(mockProcessManager.canRun(any)).thenReturn(true);
}); });
testWithoutContext('throwsToolExit if CocoaPods is not installed', () async { testWithoutContext('throwsToolExit if CocoaPods is not installed', () async {
pretendPodIsNotInstalled(); pretendPodIsNotInstalled();
projectUnderTest.ios.podfile.createSync(); projectUnderTest.ios.podfile.createSync();
final Function invokeProcessPods = () async => await cocoaPodsUnderTest.processPods( await expectLater(cocoaPodsUnderTest.processPods(
xcodeProject: projectUnderTest.ios, xcodeProject: projectUnderTest.ios,
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
); ), throwsToolExit(message: 'CocoaPods not installed or not in valid state'));
expect(invokeProcessPods, throwsToolExit()); expect(fakeProcessManager.hasRemainingExpectations, isFalse);
verifyNever(mockProcessManager.run(
argThat(containsAllInOrder(<String>['pod', 'install'])),
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
));
}); });
testWithoutContext('throwsToolExit if CocoaPods install is broken', () async { testWithoutContext('throwsToolExit if CocoaPods install is broken', () async {
pretendPodIsBroken(); pretendPodIsBroken();
projectUnderTest.ios.podfile.createSync(); projectUnderTest.ios.podfile.createSync();
final Function invokeProcessPods = () async => await cocoaPodsUnderTest.processPods( await expectLater(cocoaPodsUnderTest.processPods(
xcodeProject: projectUnderTest.ios, xcodeProject: projectUnderTest.ios,
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
); ), throwsToolExit(message: 'CocoaPods not installed or not in valid state'));
expect(invokeProcessPods, throwsToolExit()); expect(fakeProcessManager.hasRemainingExpectations, isFalse);
verifyNever(mockProcessManager.run(
argThat(containsAllInOrder(<String>['pod', 'install'])),
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
));
}); });
testWithoutContext('exits if Podfile creates the Flutter engine symlink', () async { testWithoutContext('exits if Podfile creates the Flutter engine symlink', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
pretendPodVersionIs('1.10.0');
fakeProcessManager.addCommand(
const FakeCommand(
command: <String>['pod', 'install', '--verbose'],
),
);
fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile')) fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile'))
..createSync() ..createSync()
...@@ -375,6 +344,12 @@ void main() { ...@@ -375,6 +344,12 @@ void main() {
testWithoutContext('exits if iOS Podfile parses .flutter-plugins', () async { testWithoutContext('exits if iOS Podfile parses .flutter-plugins', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
pretendPodVersionIs('1.10.0');
fakeProcessManager.addCommand(
const FakeCommand(
command: <String>['pod', 'install', '--verbose'],
),
);
fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile')) fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile'))
..createSync() ..createSync()
...@@ -388,6 +363,12 @@ void main() { ...@@ -388,6 +363,12 @@ void main() {
testWithoutContext('prints warning if macOS Podfile parses .flutter-plugins', () async { testWithoutContext('prints warning if macOS Podfile parses .flutter-plugins', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
pretendPodVersionIs('1.10.0');
fakeProcessManager.addCommand(
const FakeCommand(
command: <String>['pod', 'install', '--verbose'],
),
);
fileSystem.file(fileSystem.path.join('project', 'macos', 'Podfile')) fileSystem.file(fileSystem.path.join('project', 'macos', 'Podfile'))
..createSync() ..createSync()
...@@ -403,38 +384,30 @@ void main() { ...@@ -403,38 +384,30 @@ void main() {
}); });
testWithoutContext('throws, if Podfile is missing.', () async { testWithoutContext('throws, if Podfile is missing.', () async {
pretendPodIsInstalled(); await expectLater(cocoaPodsUnderTest.processPods(
try { xcodeProject: projectUnderTest.ios,
await cocoaPodsUnderTest.processPods( buildMode: BuildMode.debug,
xcodeProject: projectUnderTest.ios, ), throwsToolExit(message: 'Podfile missing'));
buildMode: BuildMode.debug, expect(fakeProcessManager.hasRemainingExpectations, isFalse);
);
fail('ToolExit expected');
} on Exception catch (e) {
expect(e, isA<ToolExit>());
verifyNever(mockProcessManager.run(
argThat(containsAllInOrder(<String>['pod', 'install'])),
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
));
}
}); });
testWithoutContext('throws, if specs repo is outdated.', () async { testWithoutContext('throws, if specs repo is outdated.', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
pretendPodVersionIs('1.10.0');
fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile')) fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile'))
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
when(mockProcessManager.run( fakeProcessManager.addCommand(
<String>['pod', 'install', '--verbose'], const FakeCommand(
workingDirectory: 'project/ios', command: <String>['pod', 'install', '--verbose'],
environment: <String, String>{ workingDirectory: 'project/ios',
'COCOAPODS_DISABLE_STATS': 'true', environment: <String, String>{
'LANG': 'en_US.UTF-8', 'COCOAPODS_DISABLE_STATS': 'true',
}, 'LANG': 'en_US.UTF-8',
)).thenAnswer((_) async => exitsWithError( },
''' exitCode: 1,
stdout: '''
[!] Unable to satisfy the following requirements: [!] Unable to satisfy the following requirements:
- `Firebase/Auth` required by `Podfile` - `Firebase/Auth` required by `Podfile`
...@@ -448,43 +421,46 @@ You have either: ...@@ -448,43 +421,46 @@ You have either:
* not added the source repo that hosts the Podspec to your Podfile. * 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.''', Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.''',
)); ),
try { );
await cocoaPodsUnderTest.processPods(
xcodeProject: projectUnderTest.ios, await expectLater(cocoaPodsUnderTest.processPods(
buildMode: BuildMode.debug, xcodeProject: projectUnderTest.ios,
); buildMode: BuildMode.debug,
fail('ToolExit expected'); ), throwsToolExit());
} on Exception catch (e) { expect(
expect(e, isA<ToolExit>()); logger.errorText,
expect( contains(
logger.errorText, "CocoaPods's specs repository is too out-of-date to satisfy dependencies"),
contains("CocoaPods's specs repository is too out-of-date to satisfy dependencies"), );
);
}
}); });
testWithoutContext('ffi failure on ARM macOS prompts gem install', () async { testWithoutContext('ffi failure on ARM macOS prompts gem install', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
pretendPodVersionIs('1.10.0');
fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile')) fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile'))
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
when(mockProcessManager.runSync(<String>['which', 'sysctl'])) fakeProcessManager.addCommands(<FakeCommand>[
.thenReturn(ProcessResult(0, 0, '', '')); const FakeCommand(
when(mockProcessManager.runSync(<String>['sysctl', 'hw.optional.arm64'])) command: <String>['pod', 'install', '--verbose'],
.thenReturn(ProcessResult(0, 0, 'hw.optional.arm64: 1', '')); workingDirectory: 'project/ios',
environment: <String, String>{
when(mockProcessManager.run( 'COCOAPODS_DISABLE_STATS': 'true',
<String>['pod', 'install', '--verbose'], 'LANG': 'en_US.UTF-8',
workingDirectory: 'project/ios', },
environment: <String, String>{ exitCode: 1,
'COCOAPODS_DISABLE_STATS': 'true', stdout: 'LoadError - dlsym(0x7fbbeb6837d0, Init_ffi_c): symbol not found - /Library/Ruby/Gems/2.6.0/gems/ffi-1.13.1/lib/ffi_c.bundle',
'LANG': 'en_US.UTF-8', ),
}, const FakeCommand(
)).thenAnswer((_) async => exitsWithError( command: <String>['which', 'sysctl'],
'LoadError - dlsym(0x7fbbeb6837d0, Init_ffi_c): symbol not found - /Library/Ruby/Gems/2.6.0/gems/ffi-1.13.1/lib/ffi_c.bundle', ),
)); const FakeCommand(
command: <String>['sysctl', 'hw.optional.arm64'],
stdout: 'hw.optional.arm64: 1',
),
]);
await expectToolExitLater( await expectToolExitLater(
cocoaPodsUnderTest.processPods( cocoaPodsUnderTest.processPods(
...@@ -502,25 +478,30 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by ...@@ -502,25 +478,30 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
testWithoutContext('ffi failure on x86 macOS does not prompt gem install', () async { testWithoutContext('ffi failure on x86 macOS does not prompt gem install', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
pretendPodVersionIs('1.10.0');
fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile')) fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile'))
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
when(mockProcessManager.runSync(<String>['which', 'sysctl'])) fakeProcessManager.addCommands(<FakeCommand>[
.thenReturn(ProcessResult(0, 0, '', '')); const FakeCommand(
when(mockProcessManager.runSync(<String>['sysctl', 'hw.optional.arm64'])) command: <String>['pod', 'install', '--verbose'],
.thenReturn(ProcessResult(0, 1, '', '')); workingDirectory: 'project/ios',
environment: <String, String>{
when(mockProcessManager.run( 'COCOAPODS_DISABLE_STATS': 'true',
<String>['pod', 'install', '--verbose'], 'LANG': 'en_US.UTF-8',
workingDirectory: 'project/ios', },
environment: <String, String>{ exitCode: 1,
'COCOAPODS_DISABLE_STATS': 'true', stderr: 'LoadError - dlsym(0x7fbbeb6837d0, Init_ffi_c): symbol not found - /Library/Ruby/Gems/2.6.0/gems/ffi-1.13.1/lib/ffi_c.bundle',
'LANG': 'en_US.UTF-8', ),
}, const FakeCommand(
)).thenAnswer((_) async => exitsWithError( command: <String>['which', 'sysctl'],
'LoadError - dlsym(0x7fbbeb6837d0, Init_ffi_c): symbol not found - /Library/Ruby/Gems/2.6.0/gems/ffi-1.13.1/lib/ffi_c.bundle', ),
)); const FakeCommand(
command: <String>['sysctl', 'hw.optional.arm64'],
exitCode: 1,
),
]);
// Capture Usage.test() events. // Capture Usage.test() events.
final StringBuffer buffer = final StringBuffer buffer =
...@@ -540,75 +521,83 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by ...@@ -540,75 +521,83 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
testWithoutContext('run pod install, if Podfile.lock is missing', () async { testWithoutContext('run pod install, if Podfile.lock is missing', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
pretendPodVersionIs('1.10.0');
projectUnderTest.ios.podfile projectUnderTest.ios.podfile
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
projectUnderTest.ios.podManifestLock projectUnderTest.ios.podManifestLock
..createSync(recursive: true) ..createSync(recursive: true)
..writeAsStringSync('Existing lock file.'); ..writeAsStringSync('Existing lock file.');
fakeProcessManager.addCommand(
const FakeCommand(
command: <String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios',
environment: <String, String>{'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
),
);
final bool didInstall = await cocoaPodsUnderTest.processPods( final bool didInstall = await cocoaPodsUnderTest.processPods(
xcodeProject: projectUnderTest.ios, xcodeProject: projectUnderTest.ios,
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
dependenciesChanged: false, dependenciesChanged: false,
); );
expect(didInstall, isTrue); expect(didInstall, isTrue);
verify(mockProcessManager.run( expect(fakeProcessManager.hasRemainingExpectations, isFalse);
<String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios',
environment: <String, String>{'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
));
}); });
testWithoutContext('runs iOS pod install, if Manifest.lock is missing', () async { testWithoutContext('runs iOS pod install, if Manifest.lock is missing', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
pretendPodVersionIs('1.10.0');
projectUnderTest.ios.podfile projectUnderTest.ios.podfile
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
projectUnderTest.ios.podfileLock projectUnderTest.ios.podfileLock
..createSync() ..createSync()
..writeAsStringSync('Existing lock file.'); ..writeAsStringSync('Existing lock file.');
fakeProcessManager.addCommand(
const FakeCommand(
command: <String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios',
environment: <String, String>{'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
),
);
final bool didInstall = await cocoaPodsUnderTest.processPods( final bool didInstall = await cocoaPodsUnderTest.processPods(
xcodeProject: projectUnderTest.ios, xcodeProject: projectUnderTest.ios,
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
dependenciesChanged: false, dependenciesChanged: false,
); );
expect(didInstall, isTrue); expect(didInstall, isTrue);
verify(mockProcessManager.run( expect(fakeProcessManager.hasRemainingExpectations, isFalse);
<String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios',
environment: <String, String>{
'COCOAPODS_DISABLE_STATS': 'true',
'LANG': 'en_US.UTF-8',
},
));
}); });
testWithoutContext('runs macOS pod install, if Manifest.lock is missing', () async { testWithoutContext('runs macOS pod install, if Manifest.lock is missing', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
pretendPodVersionIs('1.10.0');
projectUnderTest.macos.podfile projectUnderTest.macos.podfile
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
projectUnderTest.macos.podfileLock projectUnderTest.macos.podfileLock
..createSync() ..createSync()
..writeAsStringSync('Existing lock file.'); ..writeAsStringSync('Existing lock file.');
fakeProcessManager.addCommand(
const FakeCommand(
command: <String>['pod', 'install', '--verbose'],
workingDirectory: 'project/macos',
environment: <String, String>{'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
),
);
final bool didInstall = await cocoaPodsUnderTest.processPods( final bool didInstall = await cocoaPodsUnderTest.processPods(
xcodeProject: projectUnderTest.macos, xcodeProject: projectUnderTest.macos,
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
dependenciesChanged: false, dependenciesChanged: false,
); );
expect(didInstall, isTrue); expect(didInstall, isTrue);
verify(mockProcessManager.run( expect(fakeProcessManager.hasRemainingExpectations, isFalse);
<String>['pod', 'install', '--verbose'],
workingDirectory: 'project/macos',
environment: <String, String>{
'COCOAPODS_DISABLE_STATS': 'true',
'LANG': 'en_US.UTF-8',
},
));
}); });
testWithoutContext('runs pod install, if Manifest.lock different from Podspec.lock', () async { testWithoutContext('runs pod install, if Manifest.lock different from Podspec.lock', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
pretendPodVersionIs('1.10.0');
projectUnderTest.ios.podfile projectUnderTest.ios.podfile
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
...@@ -618,24 +607,25 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by ...@@ -618,24 +607,25 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
projectUnderTest.ios.podManifestLock projectUnderTest.ios.podManifestLock
..createSync(recursive: true) ..createSync(recursive: true)
..writeAsStringSync('Different lock file.'); ..writeAsStringSync('Different lock file.');
fakeProcessManager.addCommand(
const FakeCommand(
command: <String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios',
environment: <String, String>{'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
),
);
final bool didInstall = await cocoaPodsUnderTest.processPods( final bool didInstall = await cocoaPodsUnderTest.processPods(
xcodeProject: projectUnderTest.ios, xcodeProject: projectUnderTest.ios,
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
dependenciesChanged: false, dependenciesChanged: false,
); );
expect(didInstall, isTrue); expect(didInstall, isTrue);
verify(mockProcessManager.run( expect(fakeProcessManager.hasRemainingExpectations, isFalse);
<String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios',
environment: <String, String>{
'COCOAPODS_DISABLE_STATS': 'true',
'LANG': 'en_US.UTF-8',
},
));
}); });
testWithoutContext('runs pod install, if flutter framework changed', () async { testWithoutContext('runs pod install, if flutter framework changed', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
pretendPodVersionIs('1.10.0');
projectUnderTest.ios.podfile projectUnderTest.ios.podfile
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
...@@ -645,24 +635,25 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by ...@@ -645,24 +635,25 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
projectUnderTest.ios.podManifestLock projectUnderTest.ios.podManifestLock
..createSync(recursive: true) ..createSync(recursive: true)
..writeAsStringSync('Existing lock file.'); ..writeAsStringSync('Existing lock file.');
fakeProcessManager.addCommand(
const FakeCommand(
command: <String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios',
environment: <String, String>{'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
),
);
final bool didInstall = await cocoaPodsUnderTest.processPods( final bool didInstall = await cocoaPodsUnderTest.processPods(
xcodeProject: projectUnderTest.ios, xcodeProject: projectUnderTest.ios,
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
dependenciesChanged: true, dependenciesChanged: true,
); );
expect(didInstall, isTrue); expect(didInstall, isTrue);
verify(mockProcessManager.run( expect(fakeProcessManager.hasRemainingExpectations, isFalse);
<String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios',
environment: <String, String>{
'COCOAPODS_DISABLE_STATS': 'true',
'LANG': 'en_US.UTF-8',
},
));
}); });
testWithoutContext('runs pod install, if Podfile.lock is older than Podfile', () async { testWithoutContext('runs pod install, if Podfile.lock is older than Podfile', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
pretendPodVersionIs('1.10.0');
projectUnderTest.ios.podfile projectUnderTest.ios.podfile
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
...@@ -675,23 +666,22 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by ...@@ -675,23 +666,22 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
await Future<void>.delayed(const Duration(milliseconds: 10)); await Future<void>.delayed(const Duration(milliseconds: 10));
projectUnderTest.ios.podfile projectUnderTest.ios.podfile
.writeAsStringSync('Updated Podfile'); .writeAsStringSync('Updated Podfile');
fakeProcessManager.addCommand(
const FakeCommand(
command: <String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios',
environment: <String, String>{'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
),
);
await cocoaPodsUnderTest.processPods( await cocoaPodsUnderTest.processPods(
xcodeProject: projectUnderTest.ios, xcodeProject: projectUnderTest.ios,
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
dependenciesChanged: false, dependenciesChanged: false,
); );
verify(mockProcessManager.run( expect(fakeProcessManager.hasRemainingExpectations, isFalse);
<String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios',
environment: <String, String>{
'COCOAPODS_DISABLE_STATS': 'true',
'LANG': 'en_US.UTF-8',
},
));
}); });
testWithoutContext('skips pod install, if nothing changed', () async { testWithoutContext('skips pod install, if nothing changed', () async {
pretendPodIsInstalled();
projectUnderTest.ios.podfile projectUnderTest.ios.podfile
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
...@@ -707,15 +697,12 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by ...@@ -707,15 +697,12 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
dependenciesChanged: false, dependenciesChanged: false,
); );
expect(didInstall, isFalse); expect(didInstall, isFalse);
verifyNever(mockProcessManager.run( expect(fakeProcessManager.hasRemainingExpectations, isFalse);
argThat(containsAllInOrder(<String>['pod', 'install'])),
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
));
}); });
testWithoutContext('a failed pod install deletes Pods/Manifest.lock', () async { testWithoutContext('a failed pod install deletes Pods/Manifest.lock', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
pretendPodVersionIs('1.10.0');
projectUnderTest.ios.podfile projectUnderTest.ios.podfile
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
...@@ -725,66 +712,22 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by ...@@ -725,66 +712,22 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
projectUnderTest.ios.podManifestLock projectUnderTest.ios.podManifestLock
..createSync(recursive: true) ..createSync(recursive: true)
..writeAsStringSync('Existing lock file.'); ..writeAsStringSync('Existing lock file.');
fakeProcessManager.addCommand(
when(mockProcessManager.run( const FakeCommand(
<String>['pod', 'install', '--verbose'], command: <String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios', workingDirectory: 'project/ios',
environment: <String, String>{ environment: <String, String>{'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
'COCOAPODS_DISABLE_STATS': 'true', exitCode: 1,
'LANG': 'en_US.UTF-8', ),
},
)).thenAnswer(
(_) async => exitsWithError()
); );
try { await expectLater(cocoaPodsUnderTest.processPods(
await cocoaPodsUnderTest.processPods(
xcodeProject: projectUnderTest.ios,
buildMode: BuildMode.debug,
dependenciesChanged: true,
);
fail('Tool throw expected when pod install fails');
} on ToolExit {
expect(projectUnderTest.ios.podManifestLock.existsSync(), isFalse);
}
});
});
group('Pods repos dir is custom', () {
String cocoapodsRepoDir;
Map<String, String> environment;
setUp(() {
// Assume binaries exist and can run
when(mockProcessManager.canRun(any)).thenReturn(true);
cocoapodsRepoDir = podsIsInCustomDir();
environment = <String, String>{
'COCOAPODS_DISABLE_STATS': 'true',
'CP_REPOS_DIR': cocoapodsRepoDir,
'LANG': 'en_US.UTF8',
};
});
testWithoutContext('succeeds, if specs repo is in CP_REPOS_DIR.', () async {
pretendPodIsInstalled();
fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile'))
..createSync()
..writeAsStringSync('Existing Podfile');
when(mockProcessManager.run(
<String>['pod', 'install', '--verbose'],
workingDirectory: 'project/ios',
environment: environment,
)).thenAnswer((_) async => exitsHappy());
final bool success = await cocoaPodsUnderTest.processPods(
xcodeProject: projectUnderTest.ios, xcodeProject: projectUnderTest.ios,
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
); ), throwsToolExit(message: 'Error running pod install'));
expect(success, true); expect(projectUnderTest.ios.podManifestLock.existsSync(), isFalse);
}); });
}); });
} }
class MockProcessManager extends Mock implements ProcessManager {}
class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {} class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
ProcessResult exitsWithError([ String stdout = '' ]) => ProcessResult(1, 1, stdout, '');
ProcessResult exitsHappy([ String stdout = '' ]) => ProcessResult(1, 0, stdout, '');
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