mirror of
https://github.com/mas-cli/mas
synced 2024-11-21 19:23:01 +00:00
Do not return Result (or anything else) from command run(…) functions.
Throw when failure. Normal Void return when success. Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
This commit is contained in:
parent
3b86deb63e
commit
388d963cd1
34 changed files with 111 additions and 331 deletions
|
@ -17,24 +17,16 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = runInternal()
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
}
|
||||
|
||||
func runInternal() -> Result<Void, MASError> {
|
||||
if #available(macOS 12, *) {
|
||||
// Account information is no longer available as of Monterey.
|
||||
// https://github.com/mas-cli/mas/issues/417
|
||||
return .failure(.notSupported)
|
||||
throw MASError.notSupported
|
||||
}
|
||||
|
||||
do {
|
||||
print(try ISStoreAccount.primaryAccount.wait().identifier)
|
||||
return .success(())
|
||||
} catch {
|
||||
return .failure(error as? MASError ?? .failed(error: error as NSError))
|
||||
throw error as? MASError ?? MASError.failed(error: error as NSError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,38 +21,29 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = run(storeSearch: MasStoreSearch(), openCommand: OpenSystemCommand())
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
try run(storeSearch: MasStoreSearch(), openCommand: OpenSystemCommand())
|
||||
}
|
||||
|
||||
func run(storeSearch: StoreSearch, openCommand: ExternalCommand) -> Result<Void, MASError> {
|
||||
func run(storeSearch: StoreSearch, openCommand: ExternalCommand) throws {
|
||||
do {
|
||||
guard let result = try storeSearch.lookup(app: appId).wait() else {
|
||||
return .failure(.noSearchResultsFound)
|
||||
throw MASError.noSearchResultsFound
|
||||
}
|
||||
|
||||
do {
|
||||
try openCommand.run(arguments: result.trackViewUrl)
|
||||
} catch {
|
||||
printError("Unable to launch open command")
|
||||
return .failure(.searchFailed)
|
||||
throw MASError.searchFailed
|
||||
}
|
||||
if openCommand.failed {
|
||||
let reason = openCommand.process.terminationReason
|
||||
printError("Open failed: (\(reason)) \(openCommand.stderr)")
|
||||
return .failure(.searchFailed)
|
||||
throw MASError.searchFailed
|
||||
}
|
||||
} catch {
|
||||
// Bubble up MASErrors
|
||||
if let error = error as? MASError {
|
||||
return .failure(error)
|
||||
}
|
||||
return .failure(.searchFailed)
|
||||
throw error as? MASError ?? .searchFailed
|
||||
}
|
||||
|
||||
return .success(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,28 +22,19 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = run(storeSearch: MasStoreSearch())
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
try run(storeSearch: MasStoreSearch())
|
||||
}
|
||||
|
||||
func run(storeSearch: StoreSearch) -> Result<Void, MASError> {
|
||||
func run(storeSearch: StoreSearch) throws {
|
||||
do {
|
||||
guard let result = try storeSearch.lookup(app: appId).wait() else {
|
||||
return .failure(.noSearchResultsFound)
|
||||
throw MASError.noSearchResultsFound
|
||||
}
|
||||
|
||||
print(AppInfoFormatter.format(app: result))
|
||||
} catch {
|
||||
// Bubble up MASErrors
|
||||
if let error = error as? MASError {
|
||||
return .failure(error)
|
||||
}
|
||||
return .failure(.searchFailed)
|
||||
throw error as? MASError ?? .searchFailed
|
||||
}
|
||||
|
||||
return .success(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,13 +23,10 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = run(appLibrary: MasAppLibrary())
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
try run(appLibrary: MasAppLibrary())
|
||||
}
|
||||
|
||||
func run(appLibrary: AppLibrary) -> Result<Void, MASError> {
|
||||
func run(appLibrary: AppLibrary) throws {
|
||||
// Try to download applications with given identifiers and collect results
|
||||
let appIds = appIds.filter { appId in
|
||||
if let product = appLibrary.installedApp(forId: appId), !force {
|
||||
|
@ -43,10 +40,8 @@ extension Mas {
|
|||
do {
|
||||
try downloadAll(appIds).wait()
|
||||
} catch {
|
||||
return .failure(error as? MASError ?? .downloadFailed(error: error as NSError))
|
||||
throw error as? MASError ?? .downloadFailed(error: error as NSError)
|
||||
}
|
||||
|
||||
return .success(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,23 +17,16 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = run(appLibrary: MasAppLibrary())
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
try run(appLibrary: MasAppLibrary())
|
||||
}
|
||||
|
||||
func run(appLibrary: AppLibrary) -> Result<Void, MASError> {
|
||||
func run(appLibrary: AppLibrary) throws {
|
||||
let products = appLibrary.installedApps
|
||||
if products.isEmpty {
|
||||
printError("No installed apps found")
|
||||
return .success(())
|
||||
} else {
|
||||
print(AppListFormatter.format(products: products))
|
||||
}
|
||||
|
||||
let output = AppListFormatter.format(products: products)
|
||||
print(output)
|
||||
|
||||
return .success(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,34 +24,27 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = run(appLibrary: MasAppLibrary(), storeSearch: MasStoreSearch())
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
try run(appLibrary: MasAppLibrary(), storeSearch: MasStoreSearch())
|
||||
}
|
||||
|
||||
func run(appLibrary: AppLibrary, storeSearch: StoreSearch) -> Result<Void, MASError> {
|
||||
func run(appLibrary: AppLibrary, storeSearch: StoreSearch) throws {
|
||||
var appId: Int?
|
||||
|
||||
do {
|
||||
let results = try storeSearch.search(for: appName).wait()
|
||||
guard let result = results.first else {
|
||||
printError("No results found")
|
||||
return .failure(.noSearchResultsFound)
|
||||
throw MASError.noSearchResultsFound
|
||||
}
|
||||
|
||||
appId = result.trackId
|
||||
} catch {
|
||||
// Bubble up MASErrors
|
||||
if let error = error as? MASError {
|
||||
return .failure(error)
|
||||
}
|
||||
return .failure(.searchFailed)
|
||||
throw error as? MASError ?? .searchFailed
|
||||
}
|
||||
|
||||
guard let identifier = appId else { fatalError() }
|
||||
|
||||
return install(UInt64(identifier), appLibrary: appLibrary)
|
||||
try install(UInt64(identifier), appLibrary: appLibrary)
|
||||
}
|
||||
|
||||
/// Installs an app.
|
||||
|
@ -59,21 +52,17 @@ extension Mas {
|
|||
/// - Parameters:
|
||||
/// - appId: App identifier
|
||||
/// - appLibrary: Library of installed apps
|
||||
/// - Returns: Result of the operation.
|
||||
fileprivate func install(_ appId: UInt64, appLibrary: AppLibrary) -> Result<Void, MASError> {
|
||||
fileprivate func install(_ appId: UInt64, appLibrary: AppLibrary) throws {
|
||||
// Try to download applications with given identifiers and collect results
|
||||
if let product = appLibrary.installedApp(forId: appId), !force {
|
||||
printWarning("\(product.appName) is already installed")
|
||||
return .success(())
|
||||
} else {
|
||||
do {
|
||||
try downloadAll([appId]).wait()
|
||||
} catch {
|
||||
throw error as? MASError ?? .downloadFailed(error: error as NSError)
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
try downloadAll([appId]).wait()
|
||||
} catch {
|
||||
return .failure(error as? MASError ?? .downloadFailed(error: error as NSError))
|
||||
}
|
||||
|
||||
return .success(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,34 +25,31 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = run(storeSearch: MasStoreSearch(), openCommand: OpenSystemCommand())
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
try run(storeSearch: MasStoreSearch(), openCommand: OpenSystemCommand())
|
||||
}
|
||||
|
||||
func run(storeSearch: StoreSearch, openCommand: ExternalCommand) -> Result<Void, MASError> {
|
||||
func run(storeSearch: StoreSearch, openCommand: ExternalCommand) throws {
|
||||
do {
|
||||
if appId == markerValue {
|
||||
// If no app ID is given, just open the MAS GUI app
|
||||
try openCommand.run(arguments: masScheme + "://")
|
||||
return .success(())
|
||||
return
|
||||
}
|
||||
|
||||
guard let appId = Int(appId)
|
||||
else {
|
||||
printError("Invalid app ID")
|
||||
return .failure(.noSearchResultsFound)
|
||||
throw MASError.noSearchResultsFound
|
||||
}
|
||||
|
||||
guard let result = try storeSearch.lookup(app: appId).wait()
|
||||
else {
|
||||
return .failure(.noSearchResultsFound)
|
||||
throw MASError.noSearchResultsFound
|
||||
}
|
||||
|
||||
guard var url = URLComponents(string: result.trackViewUrl)
|
||||
else {
|
||||
return .failure(.searchFailed)
|
||||
throw MASError.searchFailed
|
||||
}
|
||||
url.scheme = masScheme
|
||||
|
||||
|
@ -60,22 +57,16 @@ extension Mas {
|
|||
try openCommand.run(arguments: url.string!)
|
||||
} catch {
|
||||
printError("Unable to launch open command")
|
||||
return .failure(.searchFailed)
|
||||
throw MASError.searchFailed
|
||||
}
|
||||
if openCommand.failed {
|
||||
let reason = openCommand.process.terminationReason
|
||||
printError("Open failed: (\(reason)) \(openCommand.stderr)")
|
||||
return .failure(.searchFailed)
|
||||
throw MASError.searchFailed
|
||||
}
|
||||
} catch {
|
||||
// Bubble up MASErrors
|
||||
if let error = error as? MASError {
|
||||
return .failure(error)
|
||||
}
|
||||
return .failure(.searchFailed)
|
||||
throw error as? MASError ?? .searchFailed
|
||||
}
|
||||
|
||||
return .success(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,13 +25,10 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = run(appLibrary: MasAppLibrary(), storeSearch: MasStoreSearch())
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
try run(appLibrary: MasAppLibrary(), storeSearch: MasStoreSearch())
|
||||
}
|
||||
|
||||
func run(appLibrary: AppLibrary, storeSearch: StoreSearch) -> Result<Void, MASError> {
|
||||
func run(appLibrary: AppLibrary, storeSearch: StoreSearch) throws {
|
||||
let promises = appLibrary.installedApps.map { installedApp in
|
||||
firstly {
|
||||
storeSearch.lookup(app: installedApp.itemIdentifier.intValue)
|
||||
|
@ -59,12 +56,11 @@ extension Mas {
|
|||
}
|
||||
}
|
||||
|
||||
return firstly {
|
||||
_ = firstly {
|
||||
when(fulfilled: promises)
|
||||
}.map {
|
||||
Result<Void, MASError>.success(())
|
||||
}.recover { error in
|
||||
// Bubble up MASErrors
|
||||
.value(Result<Void, MASError>.failure(error as? MASError ?? .searchFailed))
|
||||
}.wait()
|
||||
}
|
||||
|
|
|
@ -20,13 +20,10 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = run(appLibrary: MasAppLibrary())
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
try run(appLibrary: MasAppLibrary())
|
||||
}
|
||||
|
||||
func run(appLibrary: AppLibrary) -> Result<Void, MASError> {
|
||||
func run(appLibrary: AppLibrary) throws {
|
||||
// Try to download applications with given identifiers and collect results
|
||||
let appIds = appIds.filter { appId in
|
||||
if let product = appLibrary.installedApp(forId: appId) {
|
||||
|
@ -40,10 +37,8 @@ extension Mas {
|
|||
do {
|
||||
try downloadAll(appIds, purchase: true).wait()
|
||||
} catch {
|
||||
return .failure(error as? MASError ?? .downloadFailed(error: error as NSError))
|
||||
throw error as? MASError ?? .downloadFailed(error: error as NSError)
|
||||
}
|
||||
|
||||
return .success(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,13 +21,6 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = runInternal()
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
}
|
||||
|
||||
func runInternal() -> Result<Void, MASError> {
|
||||
// The "Reset Application" command in the Mac App Store debug menu performs
|
||||
// the following steps
|
||||
//
|
||||
|
@ -81,8 +74,6 @@ extension Mas {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return .success(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,29 +22,20 @@ extension Mas {
|
|||
var appName: String
|
||||
|
||||
func run() throws {
|
||||
let result = run(storeSearch: MasStoreSearch())
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
try run(storeSearch: MasStoreSearch())
|
||||
}
|
||||
|
||||
func run(storeSearch: StoreSearch) -> Result<Void, MASError> {
|
||||
func run(storeSearch: StoreSearch) throws {
|
||||
do {
|
||||
let results = try storeSearch.search(for: appName).wait()
|
||||
if results.isEmpty {
|
||||
return .failure(.noSearchResultsFound)
|
||||
throw MASError.noSearchResultsFound
|
||||
}
|
||||
|
||||
let output = SearchResultFormatter.format(results: results, includePrice: price)
|
||||
print(output)
|
||||
|
||||
return .success(())
|
||||
} catch {
|
||||
// Bubble up MASErrors
|
||||
if let error = error as? MASError {
|
||||
return .failure(error)
|
||||
}
|
||||
return .failure(.searchFailed)
|
||||
throw error as? MASError ?? .searchFailed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,18 +25,10 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = runInternal()
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
}
|
||||
|
||||
func runInternal() -> Result<Void, MASError> {
|
||||
do {
|
||||
_ = try ISStoreAccount.signIn(username: username, password: password, systemDialog: dialog).wait()
|
||||
return .success(())
|
||||
} catch {
|
||||
return .failure(error as? MASError ?? .signInFailed(error: error as NSError))
|
||||
throw error as? MASError ?? MASError.signInFailed(error: error as NSError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,13 +18,6 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = runInternal()
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
}
|
||||
|
||||
func runInternal() -> Result<Void, MASError> {
|
||||
if #available(macOS 10.13, *) {
|
||||
ISServiceProxy.genericShared().accountService.signOut()
|
||||
} else {
|
||||
|
@ -32,8 +25,6 @@ extension Mas {
|
|||
// https://github.com/mas-cli/mas/issues/129
|
||||
CKAccountStore.shared().signOut()
|
||||
}
|
||||
|
||||
return .success(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,33 +25,26 @@ extension Mas {
|
|||
|
||||
/// Runs the uninstall command.
|
||||
func run() throws {
|
||||
let result = run(appLibrary: MasAppLibrary())
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
try run(appLibrary: MasAppLibrary())
|
||||
}
|
||||
|
||||
func run(appLibrary: AppLibrary) -> Result<Void, MASError> {
|
||||
func run(appLibrary: AppLibrary) throws {
|
||||
let appId = UInt64(appId)
|
||||
|
||||
guard let product = appLibrary.installedApp(forId: appId) else {
|
||||
return .failure(.notInstalled)
|
||||
throw MASError.notInstalled
|
||||
}
|
||||
|
||||
if dryRun {
|
||||
printInfo("\(product.appName) \(product.bundlePath)")
|
||||
printInfo("(not removed, dry run)")
|
||||
|
||||
return .success(())
|
||||
} else {
|
||||
do {
|
||||
try appLibrary.uninstallApp(app: product)
|
||||
} catch {
|
||||
throw MASError.uninstallFailed
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
try appLibrary.uninstallApp(app: product)
|
||||
} catch {
|
||||
return .failure(.uninstallFailed)
|
||||
}
|
||||
|
||||
return .success(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@ import ArgumentParser
|
|||
import Foundation
|
||||
import PromiseKit
|
||||
|
||||
import enum Swift.Result
|
||||
|
||||
extension Mas {
|
||||
/// Command which upgrades apps with new versions available in the Mac App Store.
|
||||
struct Upgrade: ParsableCommand {
|
||||
|
@ -24,24 +22,20 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = run(appLibrary: MasAppLibrary(), storeSearch: MasStoreSearch())
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
try run(appLibrary: MasAppLibrary(), storeSearch: MasStoreSearch())
|
||||
}
|
||||
|
||||
func run(appLibrary: AppLibrary, storeSearch: StoreSearch) -> Result<Void, MASError> {
|
||||
func run(appLibrary: AppLibrary, storeSearch: StoreSearch) throws {
|
||||
let apps: [(installedApp: SoftwareProduct, storeApp: SearchResult)]
|
||||
do {
|
||||
apps = try findOutdatedApps(appLibrary: appLibrary, storeSearch: storeSearch)
|
||||
} catch {
|
||||
// Bubble up MASErrors
|
||||
return .failure(error as? MASError ?? .searchFailed)
|
||||
throw error as? MASError ?? .searchFailed
|
||||
}
|
||||
|
||||
guard apps.count > 0 else {
|
||||
printWarning("Nothing found to upgrade")
|
||||
return .success(())
|
||||
return
|
||||
}
|
||||
|
||||
print("Upgrading \(apps.count) outdated application\(apps.count > 1 ? "s" : ""):")
|
||||
|
@ -53,10 +47,8 @@ extension Mas {
|
|||
do {
|
||||
try downloadAll(appIds).wait()
|
||||
} catch {
|
||||
return .failure(error as? MASError ?? .downloadFailed(error: error as NSError))
|
||||
throw error as? MASError ?? .downloadFailed(error: error as NSError)
|
||||
}
|
||||
|
||||
return .success(())
|
||||
}
|
||||
|
||||
private func findOutdatedApps(
|
||||
|
|
|
@ -21,17 +21,14 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = run(storeSearch: MasStoreSearch(), openCommand: OpenSystemCommand())
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
try run(storeSearch: MasStoreSearch(), openCommand: OpenSystemCommand())
|
||||
}
|
||||
|
||||
func run(storeSearch: StoreSearch, openCommand: ExternalCommand) -> Result<Void, MASError> {
|
||||
func run(storeSearch: StoreSearch, openCommand: ExternalCommand) throws {
|
||||
do {
|
||||
guard let result = try storeSearch.lookup(app: appId).wait()
|
||||
else {
|
||||
return .failure(.noSearchResultsFound)
|
||||
throw MASError.noSearchResultsFound
|
||||
}
|
||||
|
||||
guard let vendorWebsite = result.sellerUrl
|
||||
|
@ -41,22 +38,16 @@ extension Mas {
|
|||
try openCommand.run(arguments: vendorWebsite)
|
||||
} catch {
|
||||
printError("Unable to launch open command")
|
||||
return .failure(.searchFailed)
|
||||
throw MASError.searchFailed
|
||||
}
|
||||
if openCommand.failed {
|
||||
let reason = openCommand.process.terminationReason
|
||||
printError("Open failed: (\(reason)) \(openCommand.stderr)")
|
||||
return .failure(.searchFailed)
|
||||
throw MASError.searchFailed
|
||||
}
|
||||
} catch {
|
||||
// Bubble up MASErrors
|
||||
if let error = error as? MASError {
|
||||
return .failure(error)
|
||||
}
|
||||
return .failure(.searchFailed)
|
||||
throw error as? MASError ?? .searchFailed
|
||||
}
|
||||
|
||||
return .success(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,15 +17,7 @@ extension Mas {
|
|||
|
||||
/// Runs the command.
|
||||
func run() throws {
|
||||
let result = runInternal()
|
||||
if case .failure = result {
|
||||
try result.get()
|
||||
}
|
||||
}
|
||||
|
||||
func runInternal() -> Result<Void, MASError> {
|
||||
print(Package.version)
|
||||
return .success(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@ public class AccountSpec: QuickSpec {
|
|||
xdescribe("Account command") {
|
||||
xit("displays active account") {
|
||||
expect {
|
||||
try Mas.Account.parse([]).runInternal()
|
||||
try Mas.Account.parse([]).run()
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,29 +32,20 @@ public class HomeSpec: QuickSpec {
|
|||
expect {
|
||||
try Mas.Home.parse(["--", "-999"]).run(storeSearch: storeSearch, openCommand: openCommand)
|
||||
}
|
||||
.to(
|
||||
beFailure { error in
|
||||
expect(error) == .searchFailed
|
||||
}
|
||||
)
|
||||
.to(throwError(MASError.searchFailed))
|
||||
}
|
||||
it("can't find app with unknown ID") {
|
||||
expect {
|
||||
try Mas.Home.parse(["999"]).run(storeSearch: storeSearch, openCommand: openCommand)
|
||||
}
|
||||
.to(
|
||||
beFailure { error in
|
||||
expect(error) == .noSearchResultsFound
|
||||
}
|
||||
)
|
||||
.to(throwError(MASError.noSearchResultsFound))
|
||||
}
|
||||
it("opens app on MAS Preview") {
|
||||
storeSearch.apps[result.trackId] = result
|
||||
|
||||
expect {
|
||||
try Mas.Home.parse([String(result.trackId)]).run(storeSearch: storeSearch, openCommand: openCommand)
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
expect(openCommand.arguments).toNot(beNil())
|
||||
expect(openCommand.arguments!.first!) == result.trackViewUrl
|
||||
}
|
||||
|
|
|
@ -46,30 +46,21 @@ public class InfoSpec: QuickSpec {
|
|||
expect {
|
||||
try Mas.Info.parse(["--", "-999"]).run(storeSearch: storeSearch)
|
||||
}
|
||||
.to(
|
||||
beFailure { error in
|
||||
expect(error) == .searchFailed
|
||||
}
|
||||
)
|
||||
.to(throwError(MASError.searchFailed))
|
||||
}
|
||||
it("can't find app with unknown ID") {
|
||||
expect {
|
||||
try Mas.Info.parse(["999"]).run(storeSearch: storeSearch)
|
||||
}
|
||||
.to(
|
||||
beFailure { error in
|
||||
expect(error) == .noSearchResultsFound
|
||||
}
|
||||
)
|
||||
.to(throwError(MASError.noSearchResultsFound))
|
||||
}
|
||||
it("displays app details") {
|
||||
storeSearch.apps[result.trackId] = result
|
||||
let output = OutputListener()
|
||||
|
||||
expect {
|
||||
try Mas.Info.parse([String(result.trackId)]).run(storeSearch: storeSearch)
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
expect(output.contents) == expectedOutput
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public class InstallSpec: QuickSpec {
|
|||
expect {
|
||||
try Mas.Install.parse([]).run(appLibrary: AppLibraryMock())
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public class ListSpec: QuickSpec {
|
|||
expect {
|
||||
try Mas.List.parse([]).run(appLibrary: AppLibraryMock())
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ public class LuckySpec: QuickSpec {
|
|||
expect {
|
||||
try Mas.Lucky.parse(["Slack"]).run(appLibrary: AppLibraryMock(), storeSearch: storeSearch)
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,30 +33,21 @@ public class OpenSpec: QuickSpec {
|
|||
expect {
|
||||
try Mas.Open.parse(["--", "-999"]).run(storeSearch: storeSearch, openCommand: openCommand)
|
||||
}
|
||||
.to(
|
||||
beFailure { error in
|
||||
expect(error) == .searchFailed
|
||||
}
|
||||
)
|
||||
.to(throwError(MASError.searchFailed))
|
||||
}
|
||||
it("can't find app with unknown ID") {
|
||||
expect {
|
||||
try Mas.Open.parse(["999"]).run(storeSearch: storeSearch, openCommand: openCommand)
|
||||
}
|
||||
.to(
|
||||
beFailure { error in
|
||||
expect(error) == .noSearchResultsFound
|
||||
}
|
||||
)
|
||||
.to(throwError(MASError.noSearchResultsFound))
|
||||
}
|
||||
it("opens app in MAS") {
|
||||
storeSearch.apps[result.trackId] = result
|
||||
|
||||
expect {
|
||||
try Mas.Open.parse([result.trackId.description])
|
||||
.run(storeSearch: storeSearch, openCommand: openCommand)
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
expect(openCommand.arguments).toNot(beNil())
|
||||
let url = URL(string: openCommand.arguments!.first!)
|
||||
expect(url).toNot(beNil())
|
||||
|
@ -66,7 +57,7 @@ public class OpenSpec: QuickSpec {
|
|||
expect {
|
||||
try Mas.Open.parse(["appstore"]).run(storeSearch: storeSearch, openCommand: openCommand)
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
expect(openCommand.arguments).toNot(beNil())
|
||||
let url = URL(string: openCommand.arguments!.first!)
|
||||
expect(url).toNot(beNil())
|
||||
|
|
|
@ -22,7 +22,7 @@ public class OutdatedSpec: QuickSpec {
|
|||
try Mas.Outdated.parse(["--verbose"])
|
||||
.run(appLibrary: AppLibraryMock(), storeSearch: StoreSearchMock())
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ public class ResetSpec: QuickSpec {
|
|||
describe("reset command") {
|
||||
it("resets the App Store state") {
|
||||
expect {
|
||||
try Mas.Reset.parse([]).runInternal()
|
||||
try Mas.Reset.parse([]).run()
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,17 +33,13 @@ public class SearchSpec: QuickSpec {
|
|||
expect {
|
||||
try Mas.Search.parse(["slack"]).run(storeSearch: storeSearch)
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
}
|
||||
it("fails when searching for nonexistent app") {
|
||||
expect {
|
||||
try Mas.Search.parse(["nonexistent"]).run(storeSearch: storeSearch)
|
||||
}
|
||||
.to(
|
||||
beFailure { error in
|
||||
expect(error) == .noSearchResultsFound
|
||||
}
|
||||
)
|
||||
.to(throwError(MASError.noSearchResultsFound))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@ public class SignInSpec: QuickSpec {
|
|||
xdescribe("signin command") {
|
||||
xit("signs in") {
|
||||
expect {
|
||||
try Mas.SignIn.parse(["", ""]).runInternal()
|
||||
try Mas.SignIn.parse(["", ""]).run()
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ public class SignOutSpec: QuickSpec {
|
|||
describe("signout command") {
|
||||
it("signs out") {
|
||||
expect {
|
||||
try Mas.SignOut.parse([]).runInternal()
|
||||
try Mas.SignOut.parse([]).run()
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,21 +36,16 @@ public class UninstallSpec: QuickSpec {
|
|||
}
|
||||
it("can't remove a missing app") {
|
||||
expect {
|
||||
uninstall.run(appLibrary: mockLibrary)
|
||||
try uninstall.run(appLibrary: mockLibrary)
|
||||
}
|
||||
.to(
|
||||
beFailure { error in
|
||||
expect(error) == .notInstalled
|
||||
}
|
||||
)
|
||||
.to(throwError(MASError.notInstalled))
|
||||
}
|
||||
it("finds an app") {
|
||||
mockLibrary.installedApps.append(app)
|
||||
|
||||
expect {
|
||||
uninstall.run(appLibrary: mockLibrary)
|
||||
try uninstall.run(appLibrary: mockLibrary)
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
}
|
||||
}
|
||||
context("wet run") {
|
||||
|
@ -61,35 +56,25 @@ public class UninstallSpec: QuickSpec {
|
|||
}
|
||||
it("can't remove a missing app") {
|
||||
expect {
|
||||
uninstall.run(appLibrary: mockLibrary)
|
||||
try uninstall.run(appLibrary: mockLibrary)
|
||||
}
|
||||
.to(
|
||||
beFailure { error in
|
||||
expect(error) == .notInstalled
|
||||
}
|
||||
)
|
||||
.to(throwError(MASError.notInstalled))
|
||||
}
|
||||
it("removes an app") {
|
||||
mockLibrary.installedApps.append(app)
|
||||
|
||||
expect {
|
||||
uninstall.run(appLibrary: mockLibrary)
|
||||
try uninstall.run(appLibrary: mockLibrary)
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
}
|
||||
it("fails if there is a problem with the trash command") {
|
||||
var brokenUninstall = app // make mutable copy
|
||||
brokenUninstall.bundlePath = "/dev/null"
|
||||
mockLibrary.installedApps.append(brokenUninstall)
|
||||
|
||||
expect {
|
||||
uninstall.run(appLibrary: mockLibrary)
|
||||
try uninstall.run(appLibrary: mockLibrary)
|
||||
}
|
||||
.to(
|
||||
beFailure { error in
|
||||
expect(error) == .uninstallFailed
|
||||
}
|
||||
)
|
||||
.to(throwError(MASError.uninstallFailed))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public class UpgradeSpec: QuickSpec {
|
|||
expect {
|
||||
try Mas.Upgrade.parse([]).run(appLibrary: AppLibraryMock(), storeSearch: StoreSearchMock())
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,21 +32,13 @@ public class VendorSpec: QuickSpec {
|
|||
expect {
|
||||
try Mas.Vendor.parse(["--", "-999"]).run(storeSearch: storeSearch, openCommand: openCommand)
|
||||
}
|
||||
.to(
|
||||
beFailure { error in
|
||||
expect(error) == .searchFailed
|
||||
}
|
||||
)
|
||||
.to(throwError(MASError.searchFailed))
|
||||
}
|
||||
it("can't find app with unknown ID") {
|
||||
expect {
|
||||
try Mas.Vendor.parse(["999"]).run(storeSearch: storeSearch, openCommand: openCommand)
|
||||
}
|
||||
.to(
|
||||
beFailure { error in
|
||||
expect(error) == .noSearchResultsFound
|
||||
}
|
||||
)
|
||||
.to(throwError(MASError.noSearchResultsFound))
|
||||
}
|
||||
it("opens vendor app page in browser") {
|
||||
storeSearch.apps[result.trackId] = result
|
||||
|
@ -54,7 +46,7 @@ public class VendorSpec: QuickSpec {
|
|||
try Mas.Vendor.parse([String(result.trackId)])
|
||||
.run(storeSearch: storeSearch, openCommand: openCommand)
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
expect(openCommand.arguments).toNot(beNil())
|
||||
expect(openCommand.arguments!.first!) == result.sellerUrl
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ public class VersionSpec: QuickSpec {
|
|||
describe("version command") {
|
||||
it("displays the current version") {
|
||||
expect {
|
||||
try Mas.Version.parse([]).runInternal()
|
||||
try Mas.Version.parse([]).run()
|
||||
}
|
||||
.to(beSuccess())
|
||||
.toNot(throwError())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
//
|
||||
// ResultPredicates.swift
|
||||
// masTests
|
||||
//
|
||||
// Created by Ben Chatelain on 12/27/18.
|
||||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
import Nimble
|
||||
|
||||
@testable import mas
|
||||
|
||||
/// Nimble predicate for result enum success case, no associated value
|
||||
func beSuccess() -> Predicate<Result<Void, MASError>> {
|
||||
Predicate.define("be <success>") { expression, message in
|
||||
if case .success = try expression.evaluate() {
|
||||
return PredicateResult(status: .matches, message: message)
|
||||
}
|
||||
return PredicateResult(status: .fail, message: message)
|
||||
}
|
||||
}
|
||||
|
||||
/// Nimble predicate for result enum failure with associated error
|
||||
func beFailure(test: @escaping (MASError) -> Void = { _ in }) -> Predicate<Result<Void, MASError>> {
|
||||
Predicate.define("be <failure>") { expression, message in
|
||||
if case .failure(let error) = try expression.evaluate() {
|
||||
test(error)
|
||||
return PredicateResult(status: .matches, message: message)
|
||||
}
|
||||
return PredicateResult(status: .fail, message: message)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue