Summary: Installing has a convenient API, so should Uninstalling.

Reviewed By: migchez

Differential Revision: D3151068

fb-gh-sync-id: b59af6b1cb83849d232d930e3c30a468b3d50258
fbshipit-source-id: b59af6b1cb83849d232d930e3c30a468b3d50258
This commit is contained in:
Lawrence Lomax 2016-04-08 08:58:35 -07:00 коммит произвёл Facebook Github Bot 8
Родитель 7d3fc472ad
Коммит 75cddd62df
10 изменённых файлов: 93 добавлений и 3 удалений

Просмотреть файл

@ -9,19 +9,30 @@
#import <FBSimulatorControl/FBSimulatorInteraction.h>
NS_ASSUME_NONNULL_BEGIN
@class FBApplicationLaunchConfiguration;
@interface FBSimulatorInteraction (Applications)
/**
Installs the given Application.
Will Allways Succeed if the Application is a System Application.
Will always succeed if the Application is a System Application.
@param application the Application to Install.
@return the reciever, for chaining.
*/
- (instancetype)installApplication:(FBSimulatorApplication *)application;
/**
Uninstalls the given Application.
Will always fail if the Application is a System Application.
@param bundleID the Bundle ID of the application to uninstall.
@return the reciever, for chaining.
*/
- (instancetype)uninstallApplicationWithBundleID:(NSString *)bundleID;
/**
Launches the Application with the given Configuration.
If the Application is determined to allready be running, the interaction will fail.
@ -79,3 +90,5 @@
- (instancetype)terminateLastLaunchedApplication;
@end
NS_ASSUME_NONNULL_END

Просмотреть файл

@ -9,8 +9,6 @@
#import "FBSimulatorInteraction+Applications.h"
#import <CoreSimulator/SimDevice.h>
#import <FBControlCore/FBControlCore.h>
#import "FBProcessLaunchConfiguration+Helpers.h"
@ -56,6 +54,40 @@
}];
}
- (instancetype)uninstallApplicationWithBundleID:(NSString *)bundleID
{
NSParameterAssert(bundleID);
return [self interactWithBootedSimulator:^ BOOL (NSError **error, FBSimulator *simulator) {
// Confirm the app is suitable to be uninstalled.
if ([simulator isSystemApplicationWithBundleID:bundleID error:nil]) {
return [[[FBSimulatorError
describeFormat:@"Can't uninstall '%@' as it is a system Application", bundleID]
inSimulator:simulator]
failBool:error];
}
NSError *innerError = nil;
if (![simulator installedApplicationWithBundleID:bundleID error:&innerError]) {
return [[[[FBSimulatorError
describeFormat:@"Can't uninstall '%@' as it isn't installed", bundleID]
causedBy:innerError]
inSimulator:simulator]
failBool:error];
}
// Kill the app if it's running
[[simulator.interact terminateApplicationWithBundleID:bundleID] perform:nil];
// Then uninstall for real.
if (![simulator.simDeviceWrapper uninstallApplication:bundleID withOptions:nil error:&innerError]) {
return [[[[FBSimulatorError
describeFormat:@"Failed to uninstall '%@'", bundleID]
causedBy:innerError]
inSimulator:simulator]
failBool:error];
}
return YES;
}];
}
- (instancetype)launchApplication:(FBApplicationLaunchConfiguration *)appLaunch
{
NSParameterAssert(appLaunch);

Просмотреть файл

@ -24,6 +24,7 @@ typedef void (^FBSimDeviceWrapperCallback)(void);
Augments methods in CoreSimulator with:
- More informative return values.
- Implementations that are more resiliant to failure in CoreSimulator.
- Annotations of the expected arguments and return types of CoreSimulator.
*/
@interface FBSimDeviceWrapper : NSObject
@ -79,6 +80,16 @@ typedef void (^FBSimDeviceWrapperCallback)(void);
*/
- (BOOL)installApplication:(NSURL *)appURL withOptions:(NSDictionary *)options error:(NSError **)error;
/**
Uninstalls an Application on the Simulator.
@param bundleID the Bundle ID of the Application to uninstall.
@param options the Options to use in the launch.
@param error an error out for any error that occured.
@return YES if the Application was installed successfully, NO otherwise.
*/
- (BOOL)uninstallApplication:(NSString *)bundleID withOptions:(NSDictionary *)options error:(NSError **)error;
/**
Spawns an long-lived executable on the Simulator.
The Task should not terminate in less than a few seconds, as Process Info will be obtained.

Просмотреть файл

@ -223,6 +223,12 @@
return [self.simulator.device installApplication:appURL withOptions:options error:error];
}
- (BOOL)uninstallApplication:(NSString *)bundleID withOptions:(NSDictionary *)options error:(NSError **)error
{
// The options don't appear to do much, simctl itself doesn't use them.
return [self.simulator.device uninstallApplication:bundleID withOptions:nil error:error];
}
- (FBProcessInfo *)spawnLongRunningWithPath:(NSString *)launchPath options:(NSDictionary *)options terminationHandler:(FBSimDeviceWrapperCallback)terminationHandler error:(NSError **)error
{
return [self processInfoForProcessIdentifier:[self.simulator.device spawnWithPath:launchPath options:options terminationHandler:terminationHandler error:error] error:error];

Просмотреть файл

@ -148,4 +148,16 @@
[self testApplication:self.tableSearchApplication relaunches:self.tableSearchAppLaunch];
}
- (void)testCanUninstallApplication
{
FBSimulator *simulator = [self obtainSimulator];
FBSimulatorApplication *application = self.tableSearchApplication;
FBApplicationLaunchConfiguration *launch = self.tableSearchAppLaunch;
[self.assert consumeAllNotifications];
[self assertInteractionSuccessful:[[[simulator.interact bootSimulator:self.simulatorLaunchConfiguration] installApplication:application] launchApplication:launch]];
[self assertLastLaunchedApplicationIsRunning:simulator];
[self assertInteractionSuccessful:[simulator.interact uninstallApplicationWithBundleID:application.bundleID]];
}
@end

Просмотреть файл

@ -86,6 +86,7 @@ public enum Action {
case Shutdown
case Tap(Double, Double)
case Terminate(String)
case Uninstall(String)
case Upload([FBDiagnostic])
}
@ -174,6 +175,8 @@ public func == (left: Action, right: Action) -> Bool {
return leftX == rightX && leftY == rightY
case (.Terminate(let leftBundleID), .Terminate(let rightBundleID)):
return leftBundleID == rightBundleID
case (.Uninstall(let leftBundleID), .Uninstall(let rightBundleID)):
return leftBundleID == rightBundleID
case (.Upload(let leftPaths), .Upload(let rightPaths)):
return leftPaths == rightPaths
default:

Просмотреть файл

@ -304,6 +304,7 @@ extension Action : Parsable {
self.shutdownParser,
self.tapParser,
self.terminateParser,
self.uninstallParser,
self.uploadParser,
])
}}
@ -430,6 +431,12 @@ extension Action : Parsable {
.fmap { Action.Terminate($0) }
}}
static var uninstallParser: Parser<Action> { get {
return Parser
.succeeded(EventName.Uninstall.rawValue, Parser<Any>.ofBundleID)
.fmap { Action.Uninstall($0) }
}}
static var uploadParser: Parser<Action> { get {
return Parser
.succeeded(

Просмотреть файл

@ -37,6 +37,7 @@ public enum EventName : String {
case StateChange = "state"
case Tap = "tap"
case Terminate = "terminate"
case Uninstall = "uninstall"
case Upload = "upload"
}

Просмотреть файл

@ -259,6 +259,10 @@ private struct SimulatorRunner : Runner {
return SimulatorInteraction(reporter, EventName.Record, bundleID) { interaction in
interaction.terminateApplicationWithBundleID(bundleID)
}
case .Uninstall(let bundleID):
return SimulatorInteraction(reporter, EventName.Uninstall, bundleID) { interaction in
interaction.uninstallApplicationWithBundleID(bundleID)
}
case .Upload(let diagnostics):
return UploadInteraction(reporter, diagnostics)
default:

Просмотреть файл

@ -199,6 +199,7 @@ let validActions: [([String], Action)] = [
(["shutdown"], Action.Shutdown),
(["shutdown"], Action.Shutdown),
(["terminate", "com.foo.bar"], Action.Terminate("com.foo.bar")),
(["uninstall", "com.foo.bar"], Action.Uninstall("com.foo.bar")),
(["upload", Fixtures.photoPath, Fixtures.videoPath], Action.Upload([Fixtures.photoDiagnostic, Fixtures.videoDiagnostic])),
]