diff --git a/.swiftformat b/.swiftformat index f727bd2..9e09924 100644 --- a/.swiftformat +++ b/.swiftformat @@ -10,6 +10,7 @@ # Disabled rules --disable blankLinesAroundMark --disable consecutiveSpaces +--disable hoistAwait --disable hoistPatternLet --disable hoistTry --disable indent diff --git a/Tests/masTests/Commands/AccountSpec.swift b/Tests/masTests/Commands/AccountSpec.swift index 2021577..301f28b 100644 --- a/Tests/masTests/Commands/AccountSpec.swift +++ b/Tests/masTests/Commands/AccountSpec.swift @@ -18,12 +18,12 @@ public class AccountSpec: QuickSpec { Mas.initialize() } // account command disabled since macOS 12 Monterey https://github.com/mas-cli/mas#%EF%B8%8F-known-issues - xdescribe("Account command") { - xit("displays active account") { + describe("Account command") { + it("displays active account") { expect { try Mas.Account.parse([]).run() } - .toNot(throwError()) + .to(throwError(MASError.notSupported)) } } } diff --git a/Tests/masTests/Commands/HomeSpec.swift b/Tests/masTests/Commands/HomeSpec.swift index e366ee4..3e33524 100644 --- a/Tests/masTests/Commands/HomeSpec.swift +++ b/Tests/masTests/Commands/HomeSpec.swift @@ -13,11 +13,6 @@ import Quick public class HomeSpec: QuickSpec { override public static func spec() { - let result = SearchResult( - trackId: 1111, - trackViewUrl: "mas preview url", - version: "0.0" - ) let storeSearch = StoreSearchMock() let openCommand = OpenSystemCommandMock() @@ -41,13 +36,18 @@ public class HomeSpec: QuickSpec { .to(throwError(MASError.noSearchResultsFound)) } it("opens app on MAS Preview") { - storeSearch.apps[result.trackId] = result + let mockResult = SearchResult( + trackId: 1111, + trackViewUrl: "mas preview url", + version: "0.0" + ) + storeSearch.apps[mockResult.trackId] = mockResult expect { - try Mas.Home.parse([String(result.trackId)]).run(storeSearch: storeSearch, openCommand: openCommand) + try Mas.Home.parse([String(mockResult.trackId)]) + .run(storeSearch: storeSearch, openCommand: openCommand) + return openCommand.arguments } - .toNot(throwError()) - expect(openCommand.arguments).toNot(beNil()) - expect(openCommand.arguments!.first!) == result.trackViewUrl + == [mockResult.trackViewUrl] } } } diff --git a/Tests/masTests/Commands/InfoSpec.swift b/Tests/masTests/Commands/InfoSpec.swift index bbedfdd..4e787ba 100644 --- a/Tests/masTests/Commands/InfoSpec.swift +++ b/Tests/masTests/Commands/InfoSpec.swift @@ -13,27 +13,7 @@ import Quick public class InfoSpec: QuickSpec { override public static func spec() { - let result = SearchResult( - currentVersionReleaseDate: "2019-01-07T18:53:13Z", - fileSizeBytes: "1024", - minimumOsVersion: "10.14", - price: 2.0, - sellerName: "Awesome Dev", - trackId: 1111, - trackName: "Awesome App", - trackViewUrl: "https://awesome.app", - version: "1.0" - ) let storeSearch = StoreSearchMock() - let expectedOutput = """ - Awesome App 1.0 [2.0] - By: Awesome Dev - Released: 2019-01-07 - Minimum OS: 10.14 - Size: 1 KB - From: https://awesome.app - - """ beforeSuite { Mas.initialize() @@ -55,13 +35,32 @@ public class InfoSpec: QuickSpec { .to(throwError(MASError.noSearchResultsFound)) } it("displays app details") { - storeSearch.apps[result.trackId] = result + let mockResult = SearchResult( + currentVersionReleaseDate: "2019-01-07T18:53:13Z", + fileSizeBytes: "1024", + minimumOsVersion: "10.14", + price: 2.0, + sellerName: "Awesome Dev", + trackId: 1111, + trackName: "Awesome App", + trackViewUrl: "https://awesome.app", + version: "1.0" + ) + storeSearch.apps[mockResult.trackId] = mockResult let output = OutputListener() expect { - try Mas.Info.parse([String(result.trackId)]).run(storeSearch: storeSearch) + try Mas.Info.parse([String(mockResult.trackId)]).run(storeSearch: storeSearch) } .toNot(throwError()) - expect(output.contents) == expectedOutput + expect(output.contents) == """ + Awesome App 1.0 [2.0] + By: Awesome Dev + Released: 2019-01-07 + Minimum OS: 10.14 + Size: 1 KB + From: https://awesome.app + + """ } } } diff --git a/Tests/masTests/Commands/LuckySpec.swift b/Tests/masTests/Commands/LuckySpec.swift index 879c5dd..5a7adb0 100644 --- a/Tests/masTests/Commands/LuckySpec.swift +++ b/Tests/masTests/Commands/LuckySpec.swift @@ -19,7 +19,7 @@ public class LuckySpec: QuickSpec { beforeSuite { Mas.initialize() } - describe("lucky command") { + xdescribe("lucky command") { xit("installs the first app matching a search") { expect { try Mas.Lucky.parse(["Slack"]).run(appLibrary: AppLibraryMock(), storeSearch: storeSearch) diff --git a/Tests/masTests/Commands/OpenSpec.swift b/Tests/masTests/Commands/OpenSpec.swift index bedab44..610d91c 100644 --- a/Tests/masTests/Commands/OpenSpec.swift +++ b/Tests/masTests/Commands/OpenSpec.swift @@ -14,11 +14,6 @@ import Quick public class OpenSpec: QuickSpec { override public static func spec() { - let result = SearchResult( - trackId: 1111, - trackViewUrl: "fakescheme://some/url", - version: "0.0" - ) let storeSearch = StoreSearchMock() let openCommand = OpenSystemCommandMock() @@ -42,26 +37,25 @@ public class OpenSpec: QuickSpec { .to(throwError(MASError.noSearchResultsFound)) } it("opens app in MAS") { - storeSearch.apps[result.trackId] = result + let mockResult = SearchResult( + trackId: 1111, + trackViewUrl: "fakescheme://some/url", + version: "0.0" + ) + storeSearch.apps[mockResult.trackId] = mockResult expect { - try Mas.Open.parse([result.trackId.description]) + try Mas.Open.parse([mockResult.trackId.description]) .run(storeSearch: storeSearch, openCommand: openCommand) + return openCommand.arguments } - .toNot(throwError()) - expect(openCommand.arguments).toNot(beNil()) - let url = URL(string: openCommand.arguments!.first!) - expect(url).toNot(beNil()) - expect(url?.scheme) == "macappstore" + == ["macappstore://some/url"] } it("just opens MAS if no app specified") { expect { try Mas.Open.parse([]).run(storeSearch: storeSearch, openCommand: openCommand) + return openCommand.arguments } - .toNot(throwError()) - expect(openCommand.arguments).toNot(beNil()) - let url = URL(string: openCommand.arguments!.first!) - expect(url).toNot(beNil()) - expect(url) == URL(string: "macappstore://") + == ["macappstore://"] } } } diff --git a/Tests/masTests/Commands/OutdatedSpec.swift b/Tests/masTests/Commands/OutdatedSpec.swift index 6152645..71ef84b 100644 --- a/Tests/masTests/Commands/OutdatedSpec.swift +++ b/Tests/masTests/Commands/OutdatedSpec.swift @@ -19,8 +19,7 @@ public class OutdatedSpec: QuickSpec { describe("outdated command") { it("displays apps with pending updates") { expect { - try Mas.Outdated.parse(["--verbose"]) - .run(appLibrary: AppLibraryMock(), storeSearch: StoreSearchMock()) + try Mas.Outdated.parse([]).run(appLibrary: AppLibraryMock(), storeSearch: StoreSearchMock()) } .toNot(throwError()) } diff --git a/Tests/masTests/Commands/SearchSpec.swift b/Tests/masTests/Commands/SearchSpec.swift index fba2caf..6a1faa7 100644 --- a/Tests/masTests/Commands/SearchSpec.swift +++ b/Tests/masTests/Commands/SearchSpec.swift @@ -13,12 +13,6 @@ import Quick public class SearchSpec: QuickSpec { override public static func spec() { - let result = SearchResult( - trackId: 1111, - trackName: "slack", - trackViewUrl: "mas preview url", - version: "0.0" - ) let storeSearch = StoreSearchMock() beforeSuite { @@ -29,7 +23,13 @@ public class SearchSpec: QuickSpec { storeSearch.reset() } it("can find slack") { - storeSearch.apps[result.trackId] = result + let mockResult = SearchResult( + trackId: 1111, + trackName: "slack", + trackViewUrl: "mas preview url", + version: "0.0" + ) + storeSearch.apps[mockResult.trackId] = mockResult expect { try Mas.Search.parse(["slack"]).run(storeSearch: storeSearch) } diff --git a/Tests/masTests/Commands/SignInSpec.swift b/Tests/masTests/Commands/SignInSpec.swift index 5336c99..dca1e06 100644 --- a/Tests/masTests/Commands/SignInSpec.swift +++ b/Tests/masTests/Commands/SignInSpec.swift @@ -18,12 +18,12 @@ public class SignInSpec: QuickSpec { Mas.initialize() } // account command disabled since macOS 10.13 High Sierra https://github.com/mas-cli/mas#%EF%B8%8F-known-issues - xdescribe("signin command") { - xit("signs in") { + describe("signin command") { + it("signs in") { expect { try Mas.SignIn.parse(["", ""]).run() } - .toNot(throwError()) + .to(throwError(MASError.notSupported)) } } } diff --git a/Tests/masTests/Commands/VendorSpec.swift b/Tests/masTests/Commands/VendorSpec.swift index b5bf8e5..ac7bc84 100644 --- a/Tests/masTests/Commands/VendorSpec.swift +++ b/Tests/masTests/Commands/VendorSpec.swift @@ -13,11 +13,6 @@ import Quick public class VendorSpec: QuickSpec { override public static func spec() { - let result = SearchResult( - trackId: 1111, - trackViewUrl: "https://awesome.app", - version: "0.0" - ) let storeSearch = StoreSearchMock() let openCommand = OpenSystemCommandMock() @@ -41,14 +36,19 @@ public class VendorSpec: QuickSpec { .to(throwError(MASError.noSearchResultsFound)) } it("opens vendor app page in browser") { - storeSearch.apps[result.trackId] = result + let mockResult = SearchResult( + sellerUrl: "https://awesome.app", + trackId: 1111, + trackViewUrl: "https://apps.apple.com/us/app/awesome/id1111?mt=12&uo=4", + version: "0.0" + ) + storeSearch.apps[mockResult.trackId] = mockResult expect { - try Mas.Vendor.parse([String(result.trackId)]) + try Mas.Vendor.parse([String(mockResult.trackId)]) .run(storeSearch: storeSearch, openCommand: openCommand) + return openCommand.arguments } - .toNot(throwError()) - expect(openCommand.arguments).toNot(beNil()) - expect(openCommand.arguments!.first!) == result.sellerUrl + == [mockResult.sellerUrl] } } } diff --git a/Tests/masTests/Controllers/MasAppLibrarySpec.swift b/Tests/masTests/Controllers/MasAppLibrarySpec.swift index 6fe8628..4580b0f 100644 --- a/Tests/masTests/Controllers/MasAppLibrarySpec.swift +++ b/Tests/masTests/Controllers/MasAppLibrarySpec.swift @@ -20,12 +20,11 @@ public class MasAppLibrarySpec: QuickSpec { } describe("mas app library") { it("contains all installed apps") { - expect(library.installedApps.count) == apps.count + expect(library.installedApps).to(haveCount(apps.count)) expect(library.installedApps.first!.appName) == myApp.appName } it("can locate an app by bundle id") { - let app = library.installedApp(forBundleId: "com.example")! - expect(app.bundleIdentifier) == myApp.bundleIdentifier + expect(library.installedApp(forBundleId: "com.example")!.bundleIdentifier) == myApp.bundleIdentifier } } } diff --git a/Tests/masTests/Controllers/MasStoreSearchSpec.swift b/Tests/masTests/Controllers/MasStoreSearchSpec.swift index 938c82c..8d9c6f7 100644 --- a/Tests/masTests/Controllers/MasStoreSearchSpec.swift +++ b/Tests/masTests/Controllers/MasStoreSearchSpec.swift @@ -19,18 +19,16 @@ public class MasStoreSearchSpec: QuickSpec { describe("url string") { it("contains the app name") { let appName = "myapp" - let urlString = MasStoreSearch().searchURL(for: appName, inCountry: "US")?.absoluteString - expect(urlString) == """ - https://itunes.apple.com/search?media=software&entity=macSoftware&term=\(appName)&country=US - """ + expect { + MasStoreSearch().searchURL(for: appName, inCountry: "US")?.absoluteString + } + == "https://itunes.apple.com/search?media=software&entity=macSoftware&term=\(appName)&country=US" } it("contains the encoded app name") { - let appName = "My App" - let appNameEncoded = "My%20App" - let urlString = MasStoreSearch().searchURL(for: appName, inCountry: "US")?.absoluteString - expect(urlString) == """ - https://itunes.apple.com/search?media=software&entity=macSoftware&term=\(appNameEncoded)&country=US - """ + expect { + MasStoreSearch().searchURL(for: "My App", inCountry: "US")?.absoluteString + } + == "https://itunes.apple.com/search?media=software&entity=macSoftware&term=My%20App&country=US" } } describe("store") { @@ -39,16 +37,10 @@ public class MasStoreSearchSpec: QuickSpec { let networkSession = NetworkSessionMockFromFile(responseFile: "search/slack.json") let storeSearch = MasStoreSearch(networkManager: NetworkManager(session: networkSession)) - var results: [SearchResult] - do { - results = try storeSearch.search(for: "slack").wait() - expect(results.count) == 39 - } catch { - let maserror = error as! MASError - if case .jsonParsing(let nserror) = maserror { - fail("\(maserror) \(nserror!)") - } + expect { + try storeSearch.search(for: "slack").wait() } + .to(haveCount(39)) } } @@ -58,9 +50,9 @@ public class MasStoreSearchSpec: QuickSpec { let networkSession = NetworkSessionMockFromFile(responseFile: "lookup/slack.json") let storeSearch = MasStoreSearch(networkManager: NetworkManager(session: networkSession)) - var lookup: SearchResult? + var result: SearchResult? do { - lookup = try storeSearch.lookup(appID: appID).wait() + result = try storeSearch.lookup(appID: appID).wait() } catch { let maserror = error as! MASError if case .jsonParsing(let nserror) = maserror { @@ -68,7 +60,9 @@ public class MasStoreSearchSpec: QuickSpec { } } - guard let result = lookup else { fatalError("lookup result was nil") } + guard let result else { + fatalError("lookup result was nil") + } expect(result.trackId) == appID expect(result.bundleId) == "com.tinyspeck.slackmacgap" diff --git a/Tests/masTests/Controllers/StoreSearchMock.swift b/Tests/masTests/Controllers/StoreSearchMock.swift index 3b83df8..f97a1d3 100644 --- a/Tests/masTests/Controllers/StoreSearchMock.swift +++ b/Tests/masTests/Controllers/StoreSearchMock.swift @@ -14,9 +14,7 @@ class StoreSearchMock: StoreSearch { var apps: [AppID: SearchResult] = [:] func search(for appName: String) -> Promise<[SearchResult]> { - let filtered = apps.filter { $1.trackName.contains(appName) } - let results = filtered.map { $1 } - return .value(results) + .value(apps.filter { $1.trackName.contains(appName) }.map { $1 }) } func lookup(appID: AppID) -> Promise { diff --git a/Tests/masTests/ExternalCommands/OpenSystemCommandMock.swift b/Tests/masTests/ExternalCommands/OpenSystemCommandMock.swift index 95c409b..08d0f4b 100644 --- a/Tests/masTests/ExternalCommands/OpenSystemCommandMock.swift +++ b/Tests/masTests/ExternalCommands/OpenSystemCommandMock.swift @@ -13,7 +13,7 @@ import Foundation class OpenSystemCommandMock: ExternalCommand { // Stub out protocol logic var succeeded = true - var arguments: [String]? + var arguments: [String] = [] // unused var binaryPath = "/dev/null" diff --git a/Tests/masTests/ExternalCommands/OpenSystemCommandSpec.swift b/Tests/masTests/ExternalCommands/OpenSystemCommandSpec.swift index 41db44a..db3e484 100644 --- a/Tests/masTests/ExternalCommands/OpenSystemCommandSpec.swift +++ b/Tests/masTests/ExternalCommands/OpenSystemCommandSpec.swift @@ -19,12 +19,10 @@ public class OpenSystemCommandSpec: QuickSpec { describe("open system command") { context("binary path") { it("defaults to the macOS open command") { - let cmd = OpenSystemCommand() - expect(cmd.binaryPath) == "/usr/bin/open" + expect(OpenSystemCommand().binaryPath) == "/usr/bin/open" } it("can be overridden") { - let cmd = OpenSystemCommand(binaryPath: "/dev/null") - expect(cmd.binaryPath) == "/dev/null" + expect(OpenSystemCommand(binaryPath: "/dev/null").binaryPath) == "/dev/null" } } } diff --git a/Tests/masTests/Formatters/AppListFormatterSpec.swift b/Tests/masTests/Formatters/AppListFormatterSpec.swift index ebc9130..a9e23ab 100644 --- a/Tests/masTests/Formatters/AppListFormatterSpec.swift +++ b/Tests/masTests/Formatters/AppListFormatterSpec.swift @@ -25,8 +25,7 @@ public class AppListsFormatterSpec: QuickSpec { products = [] } it("formats nothing as empty string") { - let output = format(products) - expect(output) == "" + expect(format(products)) == "" } it("can format a single product") { let product = SoftwareProductMock( @@ -36,8 +35,7 @@ public class AppListsFormatterSpec: QuickSpec { bundleVersion: "19.2.1", itemIdentifier: 12345 ) - let output = format([product]) - expect(output) == "12345 Awesome App (19.2.1)" + expect(format([product])) == "12345 Awesome App (19.2.1)" } it("can format two products") { products = [ @@ -56,8 +54,8 @@ public class AppListsFormatterSpec: QuickSpec { itemIdentifier: 67890 ), ] - let output = format(products) - expect(output) == "12345 Awesome App (19.2.1)\n67890 Even Better App (1.2.0)" + expect(format(products)) + == "12345 Awesome App (19.2.1)\n67890 Even Better App (1.2.0)" } } } diff --git a/Tests/masTests/Formatters/SearchResultFormatterSpec.swift b/Tests/masTests/Formatters/SearchResultFormatterSpec.swift index 368e8e6..29ee188 100644 --- a/Tests/masTests/Formatters/SearchResultFormatterSpec.swift +++ b/Tests/masTests/Formatters/SearchResultFormatterSpec.swift @@ -25,8 +25,7 @@ public class SearchResultsFormatterSpec: QuickSpec { results = [] } it("formats nothing as empty string") { - let output = format(results, false) - expect(output) == "" + expect(format(results, false)) == "" } it("can format a single result") { let result = SearchResult( @@ -35,8 +34,7 @@ public class SearchResultsFormatterSpec: QuickSpec { trackName: "Awesome App", version: "19.2.1" ) - let output = format([result], false) - expect(output) == " 12345 Awesome App (19.2.1)" + expect(format([result], false)) == " 12345 Awesome App (19.2.1)" } it("can format a single result with price") { let result = SearchResult( @@ -45,8 +43,7 @@ public class SearchResultsFormatterSpec: QuickSpec { trackName: "Awesome App", version: "19.2.1" ) - let output = format([result], true) - expect(output) == " 12345 Awesome App $ 9.87 (19.2.1)" + expect(format([result], true)) == " 12345 Awesome App $ 9.87 (19.2.1)" } it("can format a two results") { results = [ @@ -63,8 +60,8 @@ public class SearchResultsFormatterSpec: QuickSpec { version: "1.2.0" ), ] - let output = format(results, false) - expect(output) == " 12345 Awesome App (19.2.1)\n 67890 Even Better App (1.2.0)" + expect(format(results, false)) + == " 12345 Awesome App (19.2.1)\n 67890 Even Better App (1.2.0)" } it("can format a two results with prices") { results = [ @@ -81,8 +78,7 @@ public class SearchResultsFormatterSpec: QuickSpec { version: "1.2.0" ), ] - let output = format(results, true) - expect(output) + expect(format(results, true)) == " 12345 Awesome App $ 9.87 (19.2.1)\n 67890 Even Better App $ 0.01 (1.2.0)" } } diff --git a/Tests/masTests/Models/SearchResultListSpec.swift b/Tests/masTests/Models/SearchResultListSpec.swift index 4f6f3e5..86b2575 100644 --- a/Tests/masTests/Models/SearchResultListSpec.swift +++ b/Tests/masTests/Models/SearchResultListSpec.swift @@ -19,18 +19,16 @@ public class SearchResultListSpec: QuickSpec { } describe("search result list") { it("can parse bbedit") { - let data = Data(from: "search/bbedit.json") - let decoder = JSONDecoder() - let results = try decoder.decode(SearchResultList.self, from: data) - - expect(results.resultCount) == 1 + expect( + try JSONDecoder().decode(SearchResultList.self, from: Data(from: "search/bbedit.json")).resultCount + ) + == 1 } it("can parse things") { - let data = Data(from: "search/things.json") - let decoder = JSONDecoder() - let results = try decoder.decode(SearchResultList.self, from: data) - - expect(results.resultCount) == 50 + expect( + try JSONDecoder().decode(SearchResultList.self, from: Data(from: "search/things.json")).resultCount + ) + == 50 } } } diff --git a/Tests/masTests/Models/SearchResultSpec.swift b/Tests/masTests/Models/SearchResultSpec.swift index b3ddc24..7330da8 100644 --- a/Tests/masTests/Models/SearchResultSpec.swift +++ b/Tests/masTests/Models/SearchResultSpec.swift @@ -19,11 +19,12 @@ public class SearchResultSpec: QuickSpec { } describe("search result") { it("can parse things") { - let data = Data(from: "search/things-that-go-bump.json") - let decoder = JSONDecoder() - let result = try decoder.decode(SearchResult.self, from: data) - - expect(result.bundleId) == "uikitformac.com.tinybop.thingamabops" + expect( + try JSONDecoder() + .decode(SearchResult.self, from: Data(from: "search/things-that-go-bump.json")) + .bundleId + ) + == "uikitformac.com.tinybop.thingamabops" } } } diff --git a/Tests/masTests/Network/NetworkSessionMockFromFile.swift b/Tests/masTests/Network/NetworkSessionMockFromFile.swift index 46d4ca2..a68220d 100644 --- a/Tests/masTests/Network/NetworkSessionMockFromFile.swift +++ b/Tests/masTests/Network/NetworkSessionMockFromFile.swift @@ -31,8 +31,7 @@ class NetworkSessionMockFromFile: NetworkSessionMock { else { fatalError("Unable to load file \(responseFile)") } do { - let data = try Data(contentsOf: fileURL, options: .mappedIfSafe) - return .value(data) + return .value(try Data(contentsOf: fileURL, options: .mappedIfSafe)) } catch { print("Error opening file: \(error)") return Promise(error: error)