From f077898d8bcace57da5cc5b9b1aa4f47d9d0e69a Mon Sep 17 00:00:00 2001 From: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> Date: Tue, 31 Dec 2024 17:34:17 -0500 Subject: [PATCH 1/9] Pass through arguments for `script/test` to its `swift test` call. Partial #596 Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> --- script/test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/test b/script/test index 5f3a5e1a..9930ce97 100755 --- a/script/test +++ b/script/test @@ -12,5 +12,5 @@ printf $'==> ✅ Testing mas %s\n' "$(script/version)" script/generate_version_info_for_swift -script -q /dev/null swift test | +script -q /dev/null swift test "${@}" | (grep -vxE $'Test Suite \'.+\' (?:started|passed) at \\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3}\\.?\\r|Test Case \'-\\[.+\\]\' (?:started|passed \\(\\d+\\.\\d+ seconds\\))\\.\\r|\\t Executed \\d+ tests?, with 0 failures \\(0 unexpected\\) in \\d+\\.\\d+ \\(\\d+\\.\\d+\\) seconds\\r' || true) From 33efcd4c6b830f55d535613c68934356c335c9e1 Mon Sep 17 00:00:00 2001 From: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:06:16 -0500 Subject: [PATCH 2/9] Rename XCTest files & classes in preparation for migrating them to Quick. Partial #596 Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> --- .../Errors/{MASErrorTestCase.swift => MASErrorSpec.swift} | 4 ++-- .../{NetworkManagerTests.swift => NetworkManagerSpec.swift} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename Tests/masTests/Errors/{MASErrorTestCase.swift => MASErrorSpec.swift} (97%) rename Tests/masTests/Network/{NetworkManagerTests.swift => NetworkManagerSpec.swift} (96%) diff --git a/Tests/masTests/Errors/MASErrorTestCase.swift b/Tests/masTests/Errors/MASErrorSpec.swift similarity index 97% rename from Tests/masTests/Errors/MASErrorTestCase.swift rename to Tests/masTests/Errors/MASErrorSpec.swift index 4959b874..30e5bd17 100644 --- a/Tests/masTests/Errors/MASErrorTestCase.swift +++ b/Tests/masTests/Errors/MASErrorSpec.swift @@ -1,5 +1,5 @@ // -// MASErrorTestCase.swift +// MASErrorSpec.swift // masTests // // Created by Ben Chatelain on 2/11/18. @@ -11,7 +11,7 @@ import XCTest @testable import mas -class MASErrorTestCase: XCTestCase { +class MASErrorSpec: XCTestCase { private static let error = NSError(domain: "MAS", code: 999, userInfo: [NSLocalizedDescriptionKey: "foo"]) override func setUp() { diff --git a/Tests/masTests/Network/NetworkManagerTests.swift b/Tests/masTests/Network/NetworkManagerSpec.swift similarity index 96% rename from Tests/masTests/Network/NetworkManagerTests.swift rename to Tests/masTests/Network/NetworkManagerSpec.swift index 560f7ce9..a6cc69fa 100644 --- a/Tests/masTests/Network/NetworkManagerTests.swift +++ b/Tests/masTests/Network/NetworkManagerSpec.swift @@ -1,5 +1,5 @@ // -// NetworkManagerTests.swift +// NetworkManagerSpec.swift // masTests // // Created by Ben Chatelain on 1/5/19. @@ -10,7 +10,7 @@ import XCTest @testable import mas -class NetworkManagerTests: XCTestCase { +class NetworkManagerSpec: XCTestCase { override func setUp() { super.setUp() MAS.initialize() From ad68b6ea5ea4c08573613e933cc731e09fb126e3 Mon Sep 17 00:00:00 2001 From: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:09:52 -0500 Subject: [PATCH 3/9] Migrate all vestigial XCTest tests to Quick. Partial #596 Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> --- .swiftlint.yml | 2 - Tests/masTests/Errors/MASErrorSpec.swift | 153 +++++++++--------- .../masTests/Network/NetworkManagerSpec.swift | 75 +++------ 3 files changed, 101 insertions(+), 129 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index da0b8857..9dba4d3e 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -8,7 +8,6 @@ opt_in_rules: - all disabled_rules: - - balanced_xctest_lifecycle - closure_body_length - contrasted_opening_brace - explicit_acl @@ -26,7 +25,6 @@ disabled_rules: - no_grouping_extension - number_separator - one_declaration_per_file - - prefer_nimble - prefixed_toplevel_constant - quick_discouraged_call - quick_discouraged_pending_test diff --git a/Tests/masTests/Errors/MASErrorSpec.swift b/Tests/masTests/Errors/MASErrorSpec.swift index 30e5bd17..5f80f810 100644 --- a/Tests/masTests/Errors/MASErrorSpec.swift +++ b/Tests/masTests/Errors/MASErrorSpec.swift @@ -7,86 +7,87 @@ // import Foundation -import XCTest +import Nimble +import Quick @testable import mas -class MASErrorSpec: XCTestCase { +public class MASErrorSpec: QuickSpec { private static let error = NSError(domain: "MAS", code: 999, userInfo: [NSLocalizedDescriptionKey: "foo"]) - override func setUp() { - super.setUp() - MAS.initialize() - } - - func testNotSignedIn() { - XCTAssertEqual(MASError.notSignedIn.description, "Not signed in") - } - - func testSignInFailed() { - XCTAssertEqual(MASError.signInFailed(error: nil).description, "Sign in failed") - } - - func testSignInFailedError() { - XCTAssertEqual(MASError.signInFailed(error: Self.error).description, "Sign in failed: foo") - } - - func testAlreadySignedIn() { - XCTAssertEqual( - MASError.alreadySignedIn(asAppleID: "person@example.com").description, - "Already signed in as person@example.com" - ) - } - - func testPurchaseFailed() { - XCTAssertEqual(MASError.purchaseFailed(error: nil).description, "Download request failed") - } - - func testPurchaseFailedError() { - XCTAssertEqual(MASError.purchaseFailed(error: Self.error).description, "Download request failed: foo") - } - - func testDownloadFailed() { - XCTAssertEqual(MASError.downloadFailed(error: nil).description, "Download failed") - } - - func testDownloadFailedError() { - XCTAssertEqual(MASError.downloadFailed(error: Self.error).description, "Download failed: foo") - } - - func testNoDownloads() { - XCTAssertEqual(MASError.noDownloads.description, "No downloads began") - } - - func testCancelled() { - XCTAssertEqual(MASError.cancelled.description, "Download cancelled") - } - - func testSearchFailed() { - XCTAssertEqual(MASError.searchFailed.description, "Search failed") - } - - func testNoSearchResultsFound() { - XCTAssertEqual(MASError.noSearchResultsFound.description, "No apps found") - } - - func testNoVendorWebsite() { - XCTAssertEqual(MASError.noVendorWebsite.description, "App does not have a vendor website") - } - - func testNotInstalled() { - XCTAssertEqual(MASError.notInstalled(appID: 123).description, "No apps installed with app ID 123") - } - - func testUninstallFailed() { - XCTAssertEqual(MASError.uninstallFailed(error: nil).description, "Uninstall failed") - } - - func testNoData() { - XCTAssertEqual(MASError.noData.description, "Service did not return data") - } - - func testJsonParsing() { - XCTAssertEqual(MASError.jsonParsing(data: Data()).description, "Unable to parse response as JSON:\n") + override public func spec() { + beforeSuite { + MAS.initialize() + } + describe("mas error") { + it("NotSignedIn") { + expect(MASError.notSignedIn.description) == "Not signed in" + } + + it("SignInFailed") { + expect(MASError.signInFailed(error: nil).description) == "Sign in failed" + } + + it("SignInFailedError") { + expect(MASError.signInFailed(error: Self.error).description) == "Sign in failed: foo" + } + + it("AlreadySignedIn") { + expect(MASError.alreadySignedIn(asAppleID: "person@example.com").description) + == "Already signed in as person@example.com" + } + + it("PurchaseFailed") { + expect(MASError.purchaseFailed(error: nil).description) == "Download request failed" + } + + it("PurchaseFailedError") { + expect(MASError.purchaseFailed(error: Self.error).description) == "Download request failed: foo" + } + + it("DownloadFailed") { + expect(MASError.downloadFailed(error: nil).description) == "Download failed" + } + + it("DownloadFailedError") { + expect(MASError.downloadFailed(error: Self.error).description) == "Download failed: foo" + } + + it("NoDownloads") { + expect(MASError.noDownloads.description) == "No downloads began" + } + + it("Cancelled") { + expect(MASError.cancelled.description) == "Download cancelled" + } + + it("SearchFailed") { + expect(MASError.searchFailed.description) == "Search failed" + } + + it("NoSearchResultsFound") { + expect(MASError.noSearchResultsFound.description) == "No apps found" + } + + it("NoVendorWebsite") { + expect(MASError.noVendorWebsite.description) == "App does not have a vendor website" + } + + it("NotInstalled") { + expect(MASError.notInstalled(appID: 123).description) == "No apps installed with app ID 123" + } + + it("UninstallFailed") { + expect(MASError.uninstallFailed(error: nil).description) == "Uninstall failed" + } + + it("NoData") { + expect(MASError.noData.description) == "Service did not return data" + } + + it("JsonParsing") { + expect(MASError.jsonParsing(data: Data()).description) == "Unable to parse response as JSON:\n" + } + } } } diff --git a/Tests/masTests/Network/NetworkManagerSpec.swift b/Tests/masTests/Network/NetworkManagerSpec.swift index a6cc69fa..015943e5 100644 --- a/Tests/masTests/Network/NetworkManagerSpec.swift +++ b/Tests/masTests/Network/NetworkManagerSpec.swift @@ -6,63 +6,36 @@ // Copyright © 2019 mas-cli. All rights reserved. // -import XCTest +import Foundation +import Nimble +import Quick @testable import mas -class NetworkManagerSpec: XCTestCase { - override func setUp() { - super.setUp() - MAS.initialize() - } - - func testSuccessfulAsyncResponse() throws { - let data = Data([0, 1, 0, 1]) - XCTAssertEqual( - try NetworkManager(session: MockNetworkSession(data: data)) - .loadData(from: URL(fileURLWithPath: "url")) - .wait(), - data - ) - } - - func testSuccessfulSyncResponse() throws { - let data = Data([0, 1, 0, 1]) - XCTAssertEqual( - try NetworkManager(session: MockNetworkSession(data: data)) - .loadData(from: URL(fileURLWithPath: "url")) - .wait(), - data - ) - } - - func testFailureAsyncResponse() { - XCTAssertThrowsError( - try NetworkManager(session: MockNetworkSession(error: MASError.noData)) - .loadData(from: URL(fileURLWithPath: "url")) - .wait() - ) { error in - guard let masError = error as? MASError else { - XCTFail("Error is of unexpected type.") - return - } - - XCTAssertEqual(masError, MASError.noData) +public class NetworkManagerSpec: QuickSpec { + override public func spec() { + beforeSuite { + MAS.initialize() } - } - - func testFailureSyncResponse() { - XCTAssertThrowsError( - try NetworkManager(session: MockNetworkSession(error: MASError.noData)) - .loadData(from: URL(fileURLWithPath: "url")) - .wait() - ) { error in - guard let error = error as? MASError else { - XCTFail("Error is of unexpected type.") - return + describe("network manager") { + it("returns data") { + let data = Data([0, 1, 0, 1]) + expect( + try NetworkManager(session: MockNetworkSession(data: data)) + .loadData(from: URL(fileURLWithPath: "url")) + .wait() + ) + == data } - XCTAssertEqual(error, MASError.noData) + it("throws no data error") { + expect( + try NetworkManager(session: MockNetworkSession(error: MASError.noData)) + .loadData(from: URL(fileURLWithPath: "url")) + .wait() + ) + .to(throwError(MASError.noData)) + } } } } From ecb1070f2a98757ca9b341d8678d929512c1e6bf Mon Sep 17 00:00:00 2001 From: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:12:07 -0500 Subject: [PATCH 4/9] Remove useless tests. Partial #596 Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> --- Tests/masTests/Commands/ResetSpec.swift | 28 ------ .../SoftwareMapAppLibrarySpec.swift | 47 ---------- Tests/masTests/Errors/MASErrorSpec.swift | 93 ------------------- .../masTests/Network/MockNetworkSession.swift | 38 -------- .../masTests/Network/NetworkManagerSpec.swift | 41 -------- 5 files changed, 247 deletions(-) delete mode 100644 Tests/masTests/Commands/ResetSpec.swift delete mode 100644 Tests/masTests/Controllers/SoftwareMapAppLibrarySpec.swift delete mode 100644 Tests/masTests/Errors/MASErrorSpec.swift delete mode 100644 Tests/masTests/Network/MockNetworkSession.swift delete mode 100644 Tests/masTests/Network/NetworkManagerSpec.swift diff --git a/Tests/masTests/Commands/ResetSpec.swift b/Tests/masTests/Commands/ResetSpec.swift deleted file mode 100644 index 96e8adb2..00000000 --- a/Tests/masTests/Commands/ResetSpec.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// ResetSpec.swift -// masTests -// -// Created by Ben Chatelain on 2018-12-28. -// Copyright © 2018 mas-cli. All rights reserved. -// - -import Nimble -import Quick - -@testable import mas - -public class ResetSpec: QuickSpec { - override public func spec() { - beforeSuite { - MAS.initialize() - } - describe("reset command") { - it("resets the App Store state") { - expect { - try MAS.Reset.parse([]).run() - } - .toNot(throwError()) - } - } - } -} diff --git a/Tests/masTests/Controllers/SoftwareMapAppLibrarySpec.swift b/Tests/masTests/Controllers/SoftwareMapAppLibrarySpec.swift deleted file mode 100644 index a2e1f6a5..00000000 --- a/Tests/masTests/Controllers/SoftwareMapAppLibrarySpec.swift +++ /dev/null @@ -1,47 +0,0 @@ -// -// SoftwareMapAppLibrarySpec.swift -// masTests -// -// Created by Ben Chatelain on 3/1/20. -// Copyright © 2020 mas-cli. All rights reserved. -// - -import Nimble -import Quick - -@testable import mas - -public class SoftwareMapAppLibrarySpec: QuickSpec { - override public func spec() { - let myApp = MockSoftwareProduct( - appName: "MyApp", - bundleIdentifier: "com.example", - bundlePath: "/Applications/MyApp.app", - bundleVersion: "1.0.0", - itemIdentifier: 1234 - ) - - let apps = [myApp] - - let library = SoftwareMapAppLibrary(softwareMap: MockSoftwareMap(products: apps)) - - beforeSuite { - MAS.initialize() - } - describe("mas app library") { - it("contains all installed apps") { - expect(library.installedApps).to(haveCount(apps.count)) - expect(library.installedApps.first!.appName) == myApp.appName - } - } - } -} - -// MARK: - MockSoftwareMap -struct MockSoftwareMap: SoftwareMap { - let products: [SoftwareProduct] - - func allSoftwareProducts() -> [SoftwareProduct] { - products - } -} diff --git a/Tests/masTests/Errors/MASErrorSpec.swift b/Tests/masTests/Errors/MASErrorSpec.swift deleted file mode 100644 index 5f80f810..00000000 --- a/Tests/masTests/Errors/MASErrorSpec.swift +++ /dev/null @@ -1,93 +0,0 @@ -// -// MASErrorSpec.swift -// masTests -// -// Created by Ben Chatelain on 2/11/18. -// Copyright © 2018 Andrew Naylor. All rights reserved. -// - -import Foundation -import Nimble -import Quick - -@testable import mas - -public class MASErrorSpec: QuickSpec { - private static let error = NSError(domain: "MAS", code: 999, userInfo: [NSLocalizedDescriptionKey: "foo"]) - - override public func spec() { - beforeSuite { - MAS.initialize() - } - describe("mas error") { - it("NotSignedIn") { - expect(MASError.notSignedIn.description) == "Not signed in" - } - - it("SignInFailed") { - expect(MASError.signInFailed(error: nil).description) == "Sign in failed" - } - - it("SignInFailedError") { - expect(MASError.signInFailed(error: Self.error).description) == "Sign in failed: foo" - } - - it("AlreadySignedIn") { - expect(MASError.alreadySignedIn(asAppleID: "person@example.com").description) - == "Already signed in as person@example.com" - } - - it("PurchaseFailed") { - expect(MASError.purchaseFailed(error: nil).description) == "Download request failed" - } - - it("PurchaseFailedError") { - expect(MASError.purchaseFailed(error: Self.error).description) == "Download request failed: foo" - } - - it("DownloadFailed") { - expect(MASError.downloadFailed(error: nil).description) == "Download failed" - } - - it("DownloadFailedError") { - expect(MASError.downloadFailed(error: Self.error).description) == "Download failed: foo" - } - - it("NoDownloads") { - expect(MASError.noDownloads.description) == "No downloads began" - } - - it("Cancelled") { - expect(MASError.cancelled.description) == "Download cancelled" - } - - it("SearchFailed") { - expect(MASError.searchFailed.description) == "Search failed" - } - - it("NoSearchResultsFound") { - expect(MASError.noSearchResultsFound.description) == "No apps found" - } - - it("NoVendorWebsite") { - expect(MASError.noVendorWebsite.description) == "App does not have a vendor website" - } - - it("NotInstalled") { - expect(MASError.notInstalled(appID: 123).description) == "No apps installed with app ID 123" - } - - it("UninstallFailed") { - expect(MASError.uninstallFailed(error: nil).description) == "Uninstall failed" - } - - it("NoData") { - expect(MASError.noData.description) == "Service did not return data" - } - - it("JsonParsing") { - expect(MASError.jsonParsing(data: Data()).description) == "Unable to parse response as JSON:\n" - } - } - } -} diff --git a/Tests/masTests/Network/MockNetworkSession.swift b/Tests/masTests/Network/MockNetworkSession.swift deleted file mode 100644 index 3bd3b82c..00000000 --- a/Tests/masTests/Network/MockNetworkSession.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// MockNetworkSession -// masTests -// -// Created by Ben Chatelain on 11/13/18. -// Copyright © 2018 mas-cli. All rights reserved. -// - -import Foundation -import PromiseKit - -@testable import mas - -/// Mock NetworkSession for testing. -struct MockNetworkSession: NetworkSession { - // Properties that enable us to set exactly what data or error - // we want our mocked URLSession to return for any request. - private let data: Data? - private let error: Error? - - init(data: Data) { - self.data = data - error = nil - } - - init(error: Error) { - self.error = error - data = nil - } - - func loadData(from _: URL) -> Promise { - guard let data else { - return Promise(error: error ?? MASError.noData) - } - - return .value(data) - } -} diff --git a/Tests/masTests/Network/NetworkManagerSpec.swift b/Tests/masTests/Network/NetworkManagerSpec.swift deleted file mode 100644 index 015943e5..00000000 --- a/Tests/masTests/Network/NetworkManagerSpec.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// NetworkManagerSpec.swift -// masTests -// -// Created by Ben Chatelain on 1/5/19. -// Copyright © 2019 mas-cli. All rights reserved. -// - -import Foundation -import Nimble -import Quick - -@testable import mas - -public class NetworkManagerSpec: QuickSpec { - override public func spec() { - beforeSuite { - MAS.initialize() - } - describe("network manager") { - it("returns data") { - let data = Data([0, 1, 0, 1]) - expect( - try NetworkManager(session: MockNetworkSession(data: data)) - .loadData(from: URL(fileURLWithPath: "url")) - .wait() - ) - == data - } - - it("throws no data error") { - expect( - try NetworkManager(session: MockNetworkSession(error: MASError.noData)) - .loadData(from: URL(fileURLWithPath: "url")) - .wait() - ) - .to(throwError(MASError.noData)) - } - } - } -} From ad3898a404d44246e75fe5b8b876534e6d427007 Mon Sep 17 00:00:00 2001 From: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> Date: Tue, 31 Dec 2024 19:18:28 -0500 Subject: [PATCH 5/9] Make all test classes `final`. Partial #596 Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> --- .swiftlint.yml | 1 - Tests/masTests/Commands/AccountSpec.swift | 2 +- Tests/masTests/Commands/HomeSpec.swift | 2 +- Tests/masTests/Commands/InfoSpec.swift | 2 +- Tests/masTests/Commands/InstallSpec.swift | 2 +- Tests/masTests/Commands/ListSpec.swift | 2 +- Tests/masTests/Commands/LuckySpec.swift | 2 +- Tests/masTests/Commands/OpenSpec.swift | 2 +- Tests/masTests/Commands/OutdatedSpec.swift | 2 +- Tests/masTests/Commands/PurchaseSpec.swift | 2 +- Tests/masTests/Commands/SearchSpec.swift | 2 +- Tests/masTests/Commands/SignInSpec.swift | 2 +- Tests/masTests/Commands/SignOutSpec.swift | 2 +- Tests/masTests/Commands/UninstallSpec.swift | 2 +- Tests/masTests/Commands/UpgradeSpec.swift | 2 +- Tests/masTests/Commands/VendorSpec.swift | 2 +- Tests/masTests/Commands/VersionSpec.swift | 2 +- .../masTests/Controllers/ITunesSearchAppStoreSearcherSpec.swift | 2 +- Tests/masTests/Formatters/AppListFormatterSpec.swift | 2 +- Tests/masTests/Formatters/SearchResultFormatterSpec.swift | 2 +- Tests/masTests/Models/SearchResultListSpec.swift | 2 +- Tests/masTests/Models/SearchResultSpec.swift | 2 +- Tests/masTests/Models/SoftwareProductSpec.swift | 2 +- 23 files changed, 22 insertions(+), 23 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 9dba4d3e..8a2f55e7 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -16,7 +16,6 @@ disabled_rules: - explicit_type_interface - file_header - file_name - - final_test_case - force_unwrapping - function_body_length - inert_defer diff --git a/Tests/masTests/Commands/AccountSpec.swift b/Tests/masTests/Commands/AccountSpec.swift index 8885916f..2b12090b 100644 --- a/Tests/masTests/Commands/AccountSpec.swift +++ b/Tests/masTests/Commands/AccountSpec.swift @@ -12,7 +12,7 @@ import Quick @testable import mas /// Deprecated test. -public class AccountSpec: QuickSpec { +public final class AccountSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/HomeSpec.swift b/Tests/masTests/Commands/HomeSpec.swift index 63aba535..341cffb1 100644 --- a/Tests/masTests/Commands/HomeSpec.swift +++ b/Tests/masTests/Commands/HomeSpec.swift @@ -11,7 +11,7 @@ import Quick @testable import mas -public class HomeSpec: QuickSpec { +public final class HomeSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/InfoSpec.swift b/Tests/masTests/Commands/InfoSpec.swift index 423c1d4d..45f24050 100644 --- a/Tests/masTests/Commands/InfoSpec.swift +++ b/Tests/masTests/Commands/InfoSpec.swift @@ -12,7 +12,7 @@ import Quick @testable import mas -public class InfoSpec: QuickSpec { +public final class InfoSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/InstallSpec.swift b/Tests/masTests/Commands/InstallSpec.swift index ea253f79..e04fa5c4 100644 --- a/Tests/masTests/Commands/InstallSpec.swift +++ b/Tests/masTests/Commands/InstallSpec.swift @@ -11,7 +11,7 @@ import Quick @testable import mas -public class InstallSpec: QuickSpec { +public final class InstallSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/ListSpec.swift b/Tests/masTests/Commands/ListSpec.swift index e9c02d60..5b5760a2 100644 --- a/Tests/masTests/Commands/ListSpec.swift +++ b/Tests/masTests/Commands/ListSpec.swift @@ -12,7 +12,7 @@ import Quick @testable import mas -public class ListSpec: QuickSpec { +public final class ListSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/LuckySpec.swift b/Tests/masTests/Commands/LuckySpec.swift index e2887390..9227d219 100644 --- a/Tests/masTests/Commands/LuckySpec.swift +++ b/Tests/masTests/Commands/LuckySpec.swift @@ -11,7 +11,7 @@ import Quick @testable import mas -public class LuckySpec: QuickSpec { +public final class LuckySpec: QuickSpec { override public func spec() { let networkSession = MockFromFileNetworkSession(responseFile: "search/slack.json") let searcher = ITunesSearchAppStoreSearcher(networkManager: NetworkManager(session: networkSession)) diff --git a/Tests/masTests/Commands/OpenSpec.swift b/Tests/masTests/Commands/OpenSpec.swift index 16a46665..74085314 100644 --- a/Tests/masTests/Commands/OpenSpec.swift +++ b/Tests/masTests/Commands/OpenSpec.swift @@ -12,7 +12,7 @@ import Quick @testable import mas -public class OpenSpec: QuickSpec { +public final class OpenSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/OutdatedSpec.swift b/Tests/masTests/Commands/OutdatedSpec.swift index ff696a8b..f88bf544 100644 --- a/Tests/masTests/Commands/OutdatedSpec.swift +++ b/Tests/masTests/Commands/OutdatedSpec.swift @@ -12,7 +12,7 @@ import Quick @testable import mas -public class OutdatedSpec: QuickSpec { +public final class OutdatedSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/PurchaseSpec.swift b/Tests/masTests/Commands/PurchaseSpec.swift index 1ab423ba..f2a6d20d 100644 --- a/Tests/masTests/Commands/PurchaseSpec.swift +++ b/Tests/masTests/Commands/PurchaseSpec.swift @@ -11,7 +11,7 @@ import Quick @testable import mas -public class PurchaseSpec: QuickSpec { +public final class PurchaseSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/SearchSpec.swift b/Tests/masTests/Commands/SearchSpec.swift index afc6637a..715ca1ab 100644 --- a/Tests/masTests/Commands/SearchSpec.swift +++ b/Tests/masTests/Commands/SearchSpec.swift @@ -12,7 +12,7 @@ import Quick @testable import mas -public class SearchSpec: QuickSpec { +public final class SearchSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/SignInSpec.swift b/Tests/masTests/Commands/SignInSpec.swift index 57b8292d..22724562 100644 --- a/Tests/masTests/Commands/SignInSpec.swift +++ b/Tests/masTests/Commands/SignInSpec.swift @@ -12,7 +12,7 @@ import Quick @testable import mas /// Deprecated test. -public class SignInSpec: QuickSpec { +public final class SignInSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/SignOutSpec.swift b/Tests/masTests/Commands/SignOutSpec.swift index 7aeaa01b..bc7cfcdf 100644 --- a/Tests/masTests/Commands/SignOutSpec.swift +++ b/Tests/masTests/Commands/SignOutSpec.swift @@ -11,7 +11,7 @@ import Quick @testable import mas -public class SignOutSpec: QuickSpec { +public final class SignOutSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/UninstallSpec.swift b/Tests/masTests/Commands/UninstallSpec.swift index 24de94da..7bfae829 100644 --- a/Tests/masTests/Commands/UninstallSpec.swift +++ b/Tests/masTests/Commands/UninstallSpec.swift @@ -12,7 +12,7 @@ import Quick @testable import mas -public class UninstallSpec: QuickSpec { +public final class UninstallSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/UpgradeSpec.swift b/Tests/masTests/Commands/UpgradeSpec.swift index c3a805f9..f1d4b844 100644 --- a/Tests/masTests/Commands/UpgradeSpec.swift +++ b/Tests/masTests/Commands/UpgradeSpec.swift @@ -12,7 +12,7 @@ import Quick @testable import mas -public class UpgradeSpec: QuickSpec { +public final class UpgradeSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/VendorSpec.swift b/Tests/masTests/Commands/VendorSpec.swift index 753b86cc..ffade499 100644 --- a/Tests/masTests/Commands/VendorSpec.swift +++ b/Tests/masTests/Commands/VendorSpec.swift @@ -11,7 +11,7 @@ import Quick @testable import mas -public class VendorSpec: QuickSpec { +public final class VendorSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Commands/VersionSpec.swift b/Tests/masTests/Commands/VersionSpec.swift index ec66b558..fe456ed1 100644 --- a/Tests/masTests/Commands/VersionSpec.swift +++ b/Tests/masTests/Commands/VersionSpec.swift @@ -12,7 +12,7 @@ import Quick @testable import mas -public class VersionSpec: QuickSpec { +public final class VersionSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Controllers/ITunesSearchAppStoreSearcherSpec.swift b/Tests/masTests/Controllers/ITunesSearchAppStoreSearcherSpec.swift index 3107aa2e..1537542c 100644 --- a/Tests/masTests/Controllers/ITunesSearchAppStoreSearcherSpec.swift +++ b/Tests/masTests/Controllers/ITunesSearchAppStoreSearcherSpec.swift @@ -11,7 +11,7 @@ import Quick @testable import mas -public class ITunesSearchAppStoreSearcherSpec: QuickSpec { +public final class ITunesSearchAppStoreSearcherSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Formatters/AppListFormatterSpec.swift b/Tests/masTests/Formatters/AppListFormatterSpec.swift index a44730ca..d68a5878 100644 --- a/Tests/masTests/Formatters/AppListFormatterSpec.swift +++ b/Tests/masTests/Formatters/AppListFormatterSpec.swift @@ -11,7 +11,7 @@ import Quick @testable import mas -public class AppListFormatterSpec: QuickSpec { +public final class AppListFormatterSpec: QuickSpec { override public func spec() { // static func reference let format = AppListFormatter.format(products:) diff --git a/Tests/masTests/Formatters/SearchResultFormatterSpec.swift b/Tests/masTests/Formatters/SearchResultFormatterSpec.swift index bff6201e..15d13e8e 100644 --- a/Tests/masTests/Formatters/SearchResultFormatterSpec.swift +++ b/Tests/masTests/Formatters/SearchResultFormatterSpec.swift @@ -11,7 +11,7 @@ import Quick @testable import mas -public class SearchResultFormatterSpec: QuickSpec { +public final class SearchResultFormatterSpec: QuickSpec { override public func spec() { // static func reference let format = SearchResultFormatter.format(results:includePrice:) diff --git a/Tests/masTests/Models/SearchResultListSpec.swift b/Tests/masTests/Models/SearchResultListSpec.swift index 7895b1c6..ac6e3118 100644 --- a/Tests/masTests/Models/SearchResultListSpec.swift +++ b/Tests/masTests/Models/SearchResultListSpec.swift @@ -12,7 +12,7 @@ import Quick @testable import mas -public class SearchResultListSpec: QuickSpec { +public final class SearchResultListSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Models/SearchResultSpec.swift b/Tests/masTests/Models/SearchResultSpec.swift index 50436ceb..d800c748 100644 --- a/Tests/masTests/Models/SearchResultSpec.swift +++ b/Tests/masTests/Models/SearchResultSpec.swift @@ -12,7 +12,7 @@ import Quick @testable import mas -public class SearchResultSpec: QuickSpec { +public final class SearchResultSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() diff --git a/Tests/masTests/Models/SoftwareProductSpec.swift b/Tests/masTests/Models/SoftwareProductSpec.swift index c8e81cde..8598a229 100644 --- a/Tests/masTests/Models/SoftwareProductSpec.swift +++ b/Tests/masTests/Models/SoftwareProductSpec.swift @@ -12,7 +12,7 @@ import Quick @testable import mas -public class SoftwareProductSpec: QuickSpec { +public final class SoftwareProductSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() From 6a37882311a2e64efd9950365a7c488a91a69a9b Mon Sep 17 00:00:00 2001 From: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> Date: Tue, 31 Dec 2024 19:29:06 -0500 Subject: [PATCH 6/9] Move test variable declarations & assignments to proper places. Partial #596 Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> --- Tests/masTests/Commands/UninstallSpec.swift | 18 ++++++------ .../masTests/Models/SoftwareProductSpec.swift | 29 ++++++++----------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/Tests/masTests/Commands/UninstallSpec.swift b/Tests/masTests/Commands/UninstallSpec.swift index 7bfae829..212c7d83 100644 --- a/Tests/masTests/Commands/UninstallSpec.swift +++ b/Tests/masTests/Commands/UninstallSpec.swift @@ -14,19 +14,19 @@ import Quick public final class UninstallSpec: QuickSpec { override public func spec() { + let appID: AppID = 12345 + let app = MockSoftwareProduct( + appName: "Some App", + bundleIdentifier: "com.some.app", + bundlePath: "/tmp/Some.app", + bundleVersion: "1.0", + itemIdentifier: NSNumber(value: appID) + ) + beforeSuite { MAS.initialize() } xdescribe("uninstall command") { - let appID: AppID = 12345 - let app = MockSoftwareProduct( - appName: "Some App", - bundleIdentifier: "com.some.app", - bundlePath: "/tmp/Some.app", - bundleVersion: "1.0", - itemIdentifier: NSNumber(value: appID) - ) - context("dry run") { let uninstall = try! MAS.Uninstall.parse(["--dry-run", String(appID)]) diff --git a/Tests/masTests/Models/SoftwareProductSpec.swift b/Tests/masTests/Models/SoftwareProductSpec.swift index 8598a229..44cd4838 100644 --- a/Tests/masTests/Models/SoftwareProductSpec.swift +++ b/Tests/masTests/Models/SoftwareProductSpec.swift @@ -14,34 +14,29 @@ import Quick public final class SoftwareProductSpec: QuickSpec { override public func spec() { + let app = MockSoftwareProduct( + appName: "App", + bundleIdentifier: "", + bundlePath: "", + bundleVersion: "1.0.0", + itemIdentifier: 111 + ) + beforeSuite { MAS.initialize() } describe("software product") { - let app = MockSoftwareProduct( - appName: "App", - bundleIdentifier: "", - bundlePath: "", - bundleVersion: "1.0.0", - itemIdentifier: 111 - ) - - let currentApp = SearchResult(version: "1.0.0") - let appUpdate = SearchResult(version: "2.0.0") - let higherOs = SearchResult(minimumOsVersion: "99.0.0", version: "3.0.0") - let updateIos = SearchResult(minimumOsVersion: "99.0.0", version: "3.0.0") - it("is not outdated when there is no new version available") { - expect(app.isOutdated(comparedTo: currentApp)) == false + expect(app.isOutdated(comparedTo: SearchResult(version: "1.0.0"))) == false } it("is outdated when there is a new version available") { - expect(app.isOutdated(comparedTo: appUpdate)) == true + expect(app.isOutdated(comparedTo: SearchResult(version: "2.0.0"))) == true } it("is not outdated when the new version of mac-software requires a higher OS version") { - expect(app.isOutdated(comparedTo: higherOs)) == false + expect(app.isOutdated(comparedTo: SearchResult(minimumOsVersion: "99.0.0", version: "3.0.0"))) == false } it("is not outdated when the new version of software requires a higher OS version") { - expect(app.isOutdated(comparedTo: updateIos)) == false + expect(app.isOutdated(comparedTo: SearchResult(minimumOsVersion: "99.0.0", version: "3.0.0"))) == false } } } From f49d63a4f33a091adcb943f5834f5da440e5a695 Mon Sep 17 00:00:00 2001 From: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> Date: Wed, 1 Jan 2025 07:12:06 -0500 Subject: [PATCH 7/9] Simplify test exclusion. Partial #596 Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> --- Tests/masTests/Commands/InstallSpec.swift | 2 +- Tests/masTests/Commands/LuckySpec.swift | 2 +- Tests/masTests/Commands/PurchaseSpec.swift | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/masTests/Commands/InstallSpec.swift b/Tests/masTests/Commands/InstallSpec.swift index e04fa5c4..61d25078 100644 --- a/Tests/masTests/Commands/InstallSpec.swift +++ b/Tests/masTests/Commands/InstallSpec.swift @@ -17,7 +17,7 @@ public final class InstallSpec: QuickSpec { MAS.initialize() } xdescribe("install command") { - xit("installs apps") { + it("installs apps") { expect { try MAS.Install.parse([]).run(appLibrary: MockAppLibrary(), searcher: MockAppStoreSearcher()) } diff --git a/Tests/masTests/Commands/LuckySpec.swift b/Tests/masTests/Commands/LuckySpec.swift index 9227d219..741efeb8 100644 --- a/Tests/masTests/Commands/LuckySpec.swift +++ b/Tests/masTests/Commands/LuckySpec.swift @@ -20,7 +20,7 @@ public final class LuckySpec: QuickSpec { MAS.initialize() } xdescribe("lucky command") { - xit("installs the first app matching a search") { + it("installs the first app matching a search") { expect { try MAS.Lucky.parse(["Slack"]).run(appLibrary: MockAppLibrary(), searcher: searcher) } diff --git a/Tests/masTests/Commands/PurchaseSpec.swift b/Tests/masTests/Commands/PurchaseSpec.swift index f2a6d20d..6df46025 100644 --- a/Tests/masTests/Commands/PurchaseSpec.swift +++ b/Tests/masTests/Commands/PurchaseSpec.swift @@ -17,7 +17,7 @@ public final class PurchaseSpec: QuickSpec { MAS.initialize() } xdescribe("purchase command") { - xit("purchases apps") { + it("purchases apps") { expect { try MAS.Purchase.parse(["999"]).run(appLibrary: MockAppLibrary(), searcher: MockAppStoreSearcher()) } From 905c4f79826a86c7d6cac0941afb581ee4a6b1af Mon Sep 17 00:00:00 2001 From: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> Date: Tue, 31 Dec 2024 22:56:41 -0500 Subject: [PATCH 8/9] Improve value, error & captured stream comparisons. Partial #596 Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> --- Tests/masTests/.swiftlint.yml | 1 + Tests/masTests/Commands/AccountSpec.swift | 12 +-- Tests/masTests/Commands/HomeSpec.swift | 6 +- Tests/masTests/Commands/InfoSpec.swift | 35 ++++---- Tests/masTests/Commands/InstallSpec.swift | 10 ++- Tests/masTests/Commands/ListSpec.swift | 9 +- Tests/masTests/Commands/LuckySpec.swift | 8 +- Tests/masTests/Commands/OpenSpec.swift | 7 +- Tests/masTests/Commands/OutdatedSpec.swift | 10 +-- Tests/masTests/Commands/PurchaseSpec.swift | 11 ++- Tests/masTests/Commands/SearchSpec.swift | 17 ++-- Tests/masTests/Commands/SignInSpec.swift | 7 +- Tests/masTests/Commands/SignOutSpec.swift | 6 +- Tests/masTests/Commands/UninstallSpec.swift | 36 +++----- Tests/masTests/Commands/UpgradeSpec.swift | 11 ++- Tests/masTests/Commands/VendorSpec.swift | 6 +- Tests/masTests/Commands/VersionSpec.swift | 9 +- .../ITunesSearchAppStoreSearcherSpec.swift | 71 +++++++++------ .../Formatters/AppListFormatterSpec.swift | 42 ++++----- .../SearchResultFormatterSpec.swift | 84 ++++++++++-------- .../Models/SearchResultListSpec.swift | 16 +++- Tests/masTests/Models/SearchResultSpec.swift | 10 ++- .../masTests/Models/SoftwareProductSpec.swift | 20 ++++- Tests/masTests/Utilities/Streams.swift | 87 +++++++++++++++---- 24 files changed, 299 insertions(+), 232 deletions(-) diff --git a/Tests/masTests/.swiftlint.yml b/Tests/masTests/.swiftlint.yml index bc2a0087..53a7d0f5 100644 --- a/Tests/masTests/.swiftlint.yml +++ b/Tests/masTests/.swiftlint.yml @@ -9,4 +9,5 @@ disabled_rules: - force_cast - force_try - implicitly_unwrapped_optional + - large_tuple - no_magic_numbers diff --git a/Tests/masTests/Commands/AccountSpec.swift b/Tests/masTests/Commands/AccountSpec.swift index 2b12090b..c134facb 100644 --- a/Tests/masTests/Commands/AccountSpec.swift +++ b/Tests/masTests/Commands/AccountSpec.swift @@ -11,19 +11,15 @@ import Quick @testable import mas -/// Deprecated test. public final class AccountSpec: QuickSpec { override public func spec() { beforeSuite { MAS.initialize() } - // account command disabled since macOS 12 Monterey https://github.com/mas-cli/mas#known-issues - describe("Account command") { - it("displays active account") { - expect { - try MAS.Account.parse([]).run() - } - .to(throwError(MASError.notSupported)) + describe("account command") { + it("displays not supported warning") { + expect(consequencesOf(try MAS.Account.parse([]).run())) + == (error: MASError.notSupported, stdout: "", stderr: "") } } } diff --git a/Tests/masTests/Commands/HomeSpec.swift b/Tests/masTests/Commands/HomeSpec.swift index 341cffb1..b25fe089 100644 --- a/Tests/masTests/Commands/HomeSpec.swift +++ b/Tests/masTests/Commands/HomeSpec.swift @@ -18,10 +18,8 @@ public final class HomeSpec: QuickSpec { } describe("home command") { it("can't find app with unknown ID") { - expect { - try MAS.Home.parse(["999"]).run(searcher: MockAppStoreSearcher()) - } - .to(throwError(MASError.unknownAppID(999))) + expect(consequencesOf(try MAS.Home.parse(["999"]).run(searcher: MockAppStoreSearcher()))) + == (MASError.unknownAppID(999), "", "") } } } diff --git a/Tests/masTests/Commands/InfoSpec.swift b/Tests/masTests/Commands/InfoSpec.swift index 45f24050..27b82249 100644 --- a/Tests/masTests/Commands/InfoSpec.swift +++ b/Tests/masTests/Commands/InfoSpec.swift @@ -6,7 +6,6 @@ // Copyright © 2018 mas-cli. All rights reserved. // -import Foundation import Nimble import Quick @@ -19,10 +18,8 @@ public final class InfoSpec: QuickSpec { } describe("Info command") { it("can't find app with unknown ID") { - expect { - try MAS.Info.parse(["999"]).run(searcher: MockAppStoreSearcher()) - } - .to(throwError(MASError.unknownAppID(999))) + expect(consequencesOf(try MAS.Info.parse(["999"]).run(searcher: MockAppStoreSearcher()))) + == (MASError.unknownAppID(999), "", "") } it("displays app details") { let mockResult = SearchResult( @@ -36,21 +33,25 @@ public final class InfoSpec: QuickSpec { trackViewUrl: "https://awesome.app", version: "1.0" ) - expect { - try captureStream(stdout) { + expect( + consequencesOf( try MAS.Info.parse([String(mockResult.trackId)]) .run(searcher: MockAppStoreSearcher([mockResult.trackId: mockResult])) - } - } - == """ - Awesome App 1.0 [$2.00] - By: Awesome Dev - Released: 2019-01-07 - Minimum OS: 10.14 - Size: 1 KB - From: https://awesome.app + ) + ) + == ( + nil, + """ + Awesome App 1.0 [$2.00] + By: Awesome Dev + Released: 2019-01-07 + Minimum OS: 10.14 + Size: 1 KB + From: https://awesome.app - """ + """, + "" + ) } } } diff --git a/Tests/masTests/Commands/InstallSpec.swift b/Tests/masTests/Commands/InstallSpec.swift index 61d25078..d89e04ec 100644 --- a/Tests/masTests/Commands/InstallSpec.swift +++ b/Tests/masTests/Commands/InstallSpec.swift @@ -18,10 +18,12 @@ public final class InstallSpec: QuickSpec { } xdescribe("install command") { it("installs apps") { - expect { - try MAS.Install.parse([]).run(appLibrary: MockAppLibrary(), searcher: MockAppStoreSearcher()) - } - .toNot(throwError()) + expect( + consequencesOf( + try MAS.Install.parse([]).run(appLibrary: MockAppLibrary(), searcher: MockAppStoreSearcher()) + ) + ) + == (nil, "", "") } } } diff --git a/Tests/masTests/Commands/ListSpec.swift b/Tests/masTests/Commands/ListSpec.swift index 5b5760a2..59b1204d 100644 --- a/Tests/masTests/Commands/ListSpec.swift +++ b/Tests/masTests/Commands/ListSpec.swift @@ -6,7 +6,6 @@ // Copyright © 2018 mas-cli. All rights reserved. // -import Foundation import Nimble import Quick @@ -19,12 +18,8 @@ public final class ListSpec: QuickSpec { } describe("list command") { it("lists apps") { - expect { - try captureStream(stderr) { - try MAS.List.parse([]).run(appLibrary: MockAppLibrary()) - } - } - == "Error: No installed apps found\n" + expect(consequencesOf(try MAS.List.parse([]).run(appLibrary: MockAppLibrary()))) + == (nil, "", "Error: No installed apps found\n") } } } diff --git a/Tests/masTests/Commands/LuckySpec.swift b/Tests/masTests/Commands/LuckySpec.swift index 741efeb8..9fa79ed2 100644 --- a/Tests/masTests/Commands/LuckySpec.swift +++ b/Tests/masTests/Commands/LuckySpec.swift @@ -21,10 +21,10 @@ public final class LuckySpec: QuickSpec { } xdescribe("lucky command") { it("installs the first app matching a search") { - expect { - try MAS.Lucky.parse(["Slack"]).run(appLibrary: MockAppLibrary(), searcher: searcher) - } - .toNot(throwError()) + expect( + consequencesOf(try MAS.Lucky.parse(["Slack"]).run(appLibrary: MockAppLibrary(), searcher: searcher)) + ) + == (nil, "", "") } } } diff --git a/Tests/masTests/Commands/OpenSpec.swift b/Tests/masTests/Commands/OpenSpec.swift index 74085314..bc8eadb0 100644 --- a/Tests/masTests/Commands/OpenSpec.swift +++ b/Tests/masTests/Commands/OpenSpec.swift @@ -6,7 +6,6 @@ // Copyright © 2019 mas-cli. All rights reserved. // -import Foundation import Nimble import Quick @@ -19,10 +18,8 @@ public final class OpenSpec: QuickSpec { } describe("open command") { it("can't find app with unknown ID") { - expect { - try MAS.Open.parse(["999"]).run(searcher: MockAppStoreSearcher()) - } - .to(throwError(MASError.unknownAppID(999))) + expect(consequencesOf(try MAS.Open.parse(["999"]).run(searcher: MockAppStoreSearcher()))) + == (MASError.unknownAppID(999), "", "") } } } diff --git a/Tests/masTests/Commands/OutdatedSpec.swift b/Tests/masTests/Commands/OutdatedSpec.swift index f88bf544..5440a621 100644 --- a/Tests/masTests/Commands/OutdatedSpec.swift +++ b/Tests/masTests/Commands/OutdatedSpec.swift @@ -32,8 +32,8 @@ public final class OutdatedSpec: QuickSpec { version: "1.28" ) - expect { - try captureStream(stdout) { + expect( + consequencesOf( try MAS.Outdated.parse([]) .run( appLibrary: MockAppLibrary( @@ -47,9 +47,9 @@ public final class OutdatedSpec: QuickSpec { ), searcher: MockAppStoreSearcher([mockSearchResult.trackId: mockSearchResult]) ) - } - } - == "490461369 Bandwidth+ (1.27 -> 1.28)\n" + ) + ) + == (nil, "490461369 Bandwidth+ (1.27 -> 1.28)\n", "") } } } diff --git a/Tests/masTests/Commands/PurchaseSpec.swift b/Tests/masTests/Commands/PurchaseSpec.swift index 6df46025..bafb7341 100644 --- a/Tests/masTests/Commands/PurchaseSpec.swift +++ b/Tests/masTests/Commands/PurchaseSpec.swift @@ -18,10 +18,13 @@ public final class PurchaseSpec: QuickSpec { } xdescribe("purchase command") { it("purchases apps") { - expect { - try MAS.Purchase.parse(["999"]).run(appLibrary: MockAppLibrary(), searcher: MockAppStoreSearcher()) - } - .toNot(throwError()) + expect( + consequencesOf( + try MAS.Purchase.parse(["999"]) + .run(appLibrary: MockAppLibrary(), searcher: MockAppStoreSearcher()) + ) + ) + == (nil, "", "") } } } diff --git a/Tests/masTests/Commands/SearchSpec.swift b/Tests/masTests/Commands/SearchSpec.swift index 715ca1ab..260192a4 100644 --- a/Tests/masTests/Commands/SearchSpec.swift +++ b/Tests/masTests/Commands/SearchSpec.swift @@ -6,7 +6,6 @@ // Copyright © 2018 mas-cli. All rights reserved. // -import Foundation import Nimble import Quick @@ -25,19 +24,17 @@ public final class SearchSpec: QuickSpec { trackViewUrl: "mas preview url", version: "0.0" ) - expect { - try captureStream(stdout) { + expect( + consequencesOf( try MAS.Search.parse(["slack"]) .run(searcher: MockAppStoreSearcher([mockResult.trackId: mockResult])) - } - } - == " 1111 slack (0.0)\n" + ) + ) + == (nil, " 1111 slack (0.0)\n", "") } it("fails when searching for nonexistent app") { - expect { - try MAS.Search.parse(["nonexistent"]).run(searcher: MockAppStoreSearcher()) - } - .to(throwError(MASError.noSearchResultsFound)) + expect(consequencesOf(try MAS.Search.parse(["nonexistent"]).run(searcher: MockAppStoreSearcher()))) + == (MASError.noSearchResultsFound, "", "") } } } diff --git a/Tests/masTests/Commands/SignInSpec.swift b/Tests/masTests/Commands/SignInSpec.swift index 22724562..174dc3ee 100644 --- a/Tests/masTests/Commands/SignInSpec.swift +++ b/Tests/masTests/Commands/SignInSpec.swift @@ -17,13 +17,10 @@ public final class SignInSpec: QuickSpec { beforeSuite { MAS.initialize() } - // signin command disabled since macOS 10.13 High Sierra: https://github.com/mas-cli/mas#known-issues describe("signin command") { it("signs in") { - expect { - try MAS.SignIn.parse(["", ""]).run() - } - .to(throwError(MASError.notSupported)) + expect(consequencesOf(try MAS.SignIn.parse(["", ""]).run())) + == (MASError.notSupported, "", "") } } } diff --git a/Tests/masTests/Commands/SignOutSpec.swift b/Tests/masTests/Commands/SignOutSpec.swift index bc7cfcdf..d390d55c 100644 --- a/Tests/masTests/Commands/SignOutSpec.swift +++ b/Tests/masTests/Commands/SignOutSpec.swift @@ -18,10 +18,8 @@ public final class SignOutSpec: QuickSpec { } describe("signout command") { it("signs out") { - expect { - try MAS.SignOut.parse([]).run() - } - .toNot(throwError()) + expect(consequencesOf(try MAS.SignOut.parse([]).run())) + == (nil, "", "") } } } diff --git a/Tests/masTests/Commands/UninstallSpec.swift b/Tests/masTests/Commands/UninstallSpec.swift index 212c7d83..635e022c 100644 --- a/Tests/masTests/Commands/UninstallSpec.swift +++ b/Tests/masTests/Commands/UninstallSpec.swift @@ -31,46 +31,30 @@ public final class UninstallSpec: QuickSpec { let uninstall = try! MAS.Uninstall.parse(["--dry-run", String(appID)]) it("can't remove a missing app") { - expect { - try uninstall.run(appLibrary: MockAppLibrary()) - } - .to(throwError(MASError.notInstalled(appID: appID))) + expect(consequencesOf(try uninstall.run(appLibrary: MockAppLibrary()))) + == (MASError.notInstalled(appID: appID), "", "") } it("finds an app") { - expect { - try captureStream(stdout) { - try uninstall.run(appLibrary: MockAppLibrary(app)) - } - } - == "==> 'Some App' '/tmp/Some.app'\n==> (not removed, dry run)\n" + expect(consequencesOf(try uninstall.run(appLibrary: MockAppLibrary(app)))) + == (nil, "==> 'Some App' '/tmp/Some.app'\n==> (not removed, dry run)\n", "") } } context("wet run") { let uninstall = try! MAS.Uninstall.parse([String(appID)]) it("can't remove a missing app") { - expect { - try uninstall.run(appLibrary: MockAppLibrary()) - } - .to(throwError(MASError.notInstalled(appID: appID))) + expect(consequencesOf(try uninstall.run(appLibrary: MockAppLibrary()))) + == (MASError.notInstalled(appID: appID), "", "") } it("removes an app") { - expect { - try captureStream(stdout) { - try uninstall.run(appLibrary: MockAppLibrary(app)) - } - } - .toNot(throwError()) + expect(consequencesOf(try uninstall.run(appLibrary: MockAppLibrary(app)))) + == (nil, "", "") } it("fails if there is a problem with the trash command") { var brokenApp = app brokenApp.bundlePath = "/dev/null" - expect { - try captureStream(stdout) { - try uninstall.run(appLibrary: MockAppLibrary(brokenApp)) - } - } - .to(throwError(MASError.uninstallFailed(error: nil))) + expect(consequencesOf(try uninstall.run(appLibrary: MockAppLibrary(brokenApp)))) + == (MASError.uninstallFailed(error: nil), "", "") } } } diff --git a/Tests/masTests/Commands/UpgradeSpec.swift b/Tests/masTests/Commands/UpgradeSpec.swift index f1d4b844..7c99462e 100644 --- a/Tests/masTests/Commands/UpgradeSpec.swift +++ b/Tests/masTests/Commands/UpgradeSpec.swift @@ -6,7 +6,6 @@ // Copyright © 2018 mas-cli. All rights reserved. // -import Foundation import Nimble import Quick @@ -19,13 +18,13 @@ public final class UpgradeSpec: QuickSpec { } describe("upgrade command") { it("finds no upgrades") { - expect { - try captureStream(stderr) { + expect( + consequencesOf( try MAS.Upgrade.parse([]) .run(appLibrary: MockAppLibrary(), searcher: MockAppStoreSearcher()) - } - } - .toNot(throwError()) + ) + ) + == (nil, "", "") } } } diff --git a/Tests/masTests/Commands/VendorSpec.swift b/Tests/masTests/Commands/VendorSpec.swift index ffade499..30b7c1a3 100644 --- a/Tests/masTests/Commands/VendorSpec.swift +++ b/Tests/masTests/Commands/VendorSpec.swift @@ -18,10 +18,8 @@ public final class VendorSpec: QuickSpec { } describe("vendor command") { it("can't find app with unknown ID") { - expect { - try MAS.Vendor.parse(["999"]).run(searcher: MockAppStoreSearcher()) - } - .to(throwError(MASError.unknownAppID(999))) + expect(consequencesOf(try MAS.Vendor.parse(["999"]).run(searcher: MockAppStoreSearcher()))) + == (MASError.unknownAppID(999), "", "") } } } diff --git a/Tests/masTests/Commands/VersionSpec.swift b/Tests/masTests/Commands/VersionSpec.swift index fe456ed1..cef8f22d 100644 --- a/Tests/masTests/Commands/VersionSpec.swift +++ b/Tests/masTests/Commands/VersionSpec.swift @@ -6,7 +6,6 @@ // Copyright © 2018 mas-cli. All rights reserved. // -import Foundation import Nimble import Quick @@ -19,12 +18,8 @@ public final class VersionSpec: QuickSpec { } describe("version command") { it("displays the current version") { - expect { - try captureStream(stdout) { - try MAS.Version.parse([]).run() - } - } - == "\(Package.version)\n" + expect(consequencesOf(try MAS.Version.parse([]).run())) + == (nil, "\(Package.version)\n", "") } } } diff --git a/Tests/masTests/Controllers/ITunesSearchAppStoreSearcherSpec.swift b/Tests/masTests/Controllers/ITunesSearchAppStoreSearcherSpec.swift index 1537542c..f468eef9 100644 --- a/Tests/masTests/Controllers/ITunesSearchAppStoreSearcherSpec.swift +++ b/Tests/masTests/Controllers/ITunesSearchAppStoreSearcherSpec.swift @@ -18,26 +18,41 @@ public final class ITunesSearchAppStoreSearcherSpec: QuickSpec { } describe("url string") { it("contains the search term") { - expect { - ITunesSearchAppStoreSearcher() - .searchURL( - for: "myapp", - inRegion: findISORegion(forAlpha2Code: "US") - )? - .absoluteString - } - == "https://itunes.apple.com/search?media=software&entity=desktopSoftware&country=US&term=myapp" + expect( + consequencesOf( + ITunesSearchAppStoreSearcher() + .searchURL( + for: "myapp", + inRegion: findISORegion(forAlpha2Code: "US") + )? + .absoluteString + ) + ) + == ( + "https://itunes.apple.com/search?media=software&entity=desktopSoftware&country=US&term=myapp", + nil, + "", + "" + ) } it("contains the encoded search term") { - expect { - ITunesSearchAppStoreSearcher() - .searchURL( - for: "My App", - inRegion: findISORegion(forAlpha2Code: "US") - )? - .absoluteString - } - == "https://itunes.apple.com/search?media=software&entity=desktopSoftware&country=US&term=My%20App" + expect( + consequencesOf( + ITunesSearchAppStoreSearcher() + .searchURL( + for: "My App", + inRegion: findISORegion(forAlpha2Code: "US") + )? + .absoluteString + ) + ) + == ( + // swiftlint:disable:next line_length + "https://itunes.apple.com/search?media=software&entity=desktopSoftware&country=US&term=My%20App", + nil, + "", + "" + ) } } describe("store") { @@ -46,10 +61,11 @@ public final class ITunesSearchAppStoreSearcherSpec: QuickSpec { let networkSession = MockFromFileNetworkSession(responseFile: "search/slack.json") let searcher = ITunesSearchAppStoreSearcher(networkManager: NetworkManager(session: networkSession)) - expect { - try searcher.search(for: "slack").wait() - } - .to(haveCount(39)) + let consequences = consequencesOf(try searcher.search(for: "slack").wait()) + expect(consequences.value).to(haveCount(39)) + expect(consequences.error) == nil + expect(consequences.stdout).to(beEmpty()) + expect(consequences.stderr).to(beEmpty()) } } @@ -59,13 +75,12 @@ public final class ITunesSearchAppStoreSearcherSpec: QuickSpec { let networkSession = MockFromFileNetworkSession(responseFile: "lookup/slack.json") let searcher = ITunesSearchAppStoreSearcher(networkManager: NetworkManager(session: networkSession)) - var result: SearchResult? - expect { - result = try searcher.lookup(appID: appID).wait() - } - .toNot(throwError()) + let consequences = consequencesOf(try searcher.lookup(appID: appID).wait()) + expect(consequences.error) == nil + expect(consequences.stdout).to(beEmpty()) + expect(consequences.stderr).to(beEmpty()) - guard let result else { + guard let result = consequences.value else { fatalError("lookup result was nil") } diff --git a/Tests/masTests/Formatters/AppListFormatterSpec.swift b/Tests/masTests/Formatters/AppListFormatterSpec.swift index d68a5878..30072ce7 100644 --- a/Tests/masTests/Formatters/AppListFormatterSpec.swift +++ b/Tests/masTests/Formatters/AppListFormatterSpec.swift @@ -21,7 +21,7 @@ public final class AppListFormatterSpec: QuickSpec { } describe("app list formatter") { it("formats nothing as empty string") { - expect(format([])).to(beEmpty()) + expect(consequencesOf(format([]))) == ("", nil, "", "") } it("can format a single product") { let product = MockSoftwareProduct( @@ -31,30 +31,32 @@ public final class AppListFormatterSpec: QuickSpec { bundleVersion: "19.2.1", itemIdentifier: 12345 ) - expect(format([product])) == "12345 Awesome App (19.2.1)" + expect(consequencesOf(format([product]))) == ("12345 Awesome App (19.2.1)", nil, "", "") } it("can format two products") { expect( - format( - [ - MockSoftwareProduct( - appName: "Awesome App", - bundleIdentifier: "", - bundlePath: "", - bundleVersion: "19.2.1", - itemIdentifier: 12345 - ), - MockSoftwareProduct( - appName: "Even Better App", - bundleIdentifier: "", - bundlePath: "", - bundleVersion: "1.2.0", - itemIdentifier: 67890 - ), - ] + consequencesOf( + format( + [ + MockSoftwareProduct( + appName: "Awesome App", + bundleIdentifier: "", + bundlePath: "", + bundleVersion: "19.2.1", + itemIdentifier: 12345 + ), + MockSoftwareProduct( + appName: "Even Better App", + bundleIdentifier: "", + bundlePath: "", + bundleVersion: "1.2.0", + itemIdentifier: 67890 + ), + ] + ) ) ) - == "12345 Awesome App (19.2.1)\n67890 Even Better App (1.2.0)" + == ("12345 Awesome App (19.2.1)\n67890 Even Better App (1.2.0)", nil, "", "") } } } diff --git a/Tests/masTests/Formatters/SearchResultFormatterSpec.swift b/Tests/masTests/Formatters/SearchResultFormatterSpec.swift index 15d13e8e..8e4856de 100644 --- a/Tests/masTests/Formatters/SearchResultFormatterSpec.swift +++ b/Tests/masTests/Formatters/SearchResultFormatterSpec.swift @@ -21,7 +21,7 @@ public final class SearchResultFormatterSpec: QuickSpec { } describe("search results formatter") { it("formats nothing as empty string") { - expect(format([], false)).to(beEmpty()) + expect(consequencesOf(format([], false))) == ("", nil, "", "") } it("can format a single result") { let result = SearchResult( @@ -30,7 +30,7 @@ public final class SearchResultFormatterSpec: QuickSpec { trackName: "Awesome App", version: "19.2.1" ) - expect(format([result], false)) == " 12345 Awesome App (19.2.1)" + expect(consequencesOf(format([result], false))) == (" 12345 Awesome App (19.2.1)", nil, "", "") } it("can format a single result with price") { let result = SearchResult( @@ -39,51 +39,61 @@ public final class SearchResultFormatterSpec: QuickSpec { trackName: "Awesome App", version: "19.2.1" ) - expect(format([result], true)) == " 12345 Awesome App (19.2.1) $9.87" + expect(consequencesOf(format([result], true))) + == (" 12345 Awesome App (19.2.1) $9.87", nil, "", "") } it("can format a two results") { expect( - format( - [ - SearchResult( - formattedPrice: "$9.87", - trackId: 12345, - trackName: "Awesome App", - version: "19.2.1" - ), - SearchResult( - formattedPrice: "$0.01", - trackId: 67890, - trackName: "Even Better App", - version: "1.2.0" - ), - ], - false + consequencesOf( + format( + [ + SearchResult( + formattedPrice: "$9.87", + trackId: 12345, + trackName: "Awesome App", + version: "19.2.1" + ), + SearchResult( + formattedPrice: "$0.01", + trackId: 67890, + trackName: "Even Better App", + version: "1.2.0" + ), + ], + false + ) ) ) - == " 12345 Awesome App (19.2.1)\n 67890 Even Better App (1.2.0)" + == (" 12345 Awesome App (19.2.1)\n 67890 Even Better App (1.2.0)", nil, "", "") } it("can format a two results with prices") { expect( - format( - [ - SearchResult( - formattedPrice: "$9.87", - trackId: 12345, - trackName: "Awesome App", - version: "19.2.1" - ), - SearchResult( - formattedPrice: "$0.01", - trackId: 67890, - trackName: "Even Better App", - version: "1.2.0" - ), - ], - true + consequencesOf( + format( + [ + SearchResult( + formattedPrice: "$9.87", + trackId: 12345, + trackName: "Awesome App", + version: "19.2.1" + ), + SearchResult( + formattedPrice: "$0.01", + trackId: 67890, + trackName: "Even Better App", + version: "1.2.0" + ), + ], + true + ) ) ) - == " 12345 Awesome App (19.2.1) $9.87\n 67890 Even Better App (1.2.0) $0.01" + == ( + " 12345 Awesome App (19.2.1) $9.87\n 67890 Even Better App (1.2.0) $0.01", + nil, + "", + "" + ) } } } diff --git a/Tests/masTests/Models/SearchResultListSpec.swift b/Tests/masTests/Models/SearchResultListSpec.swift index ac6e3118..ec84c479 100644 --- a/Tests/masTests/Models/SearchResultListSpec.swift +++ b/Tests/masTests/Models/SearchResultListSpec.swift @@ -20,15 +20,23 @@ public final class SearchResultListSpec: QuickSpec { describe("search result list") { it("can parse bbedit") { expect( - try JSONDecoder().decode(SearchResultList.self, from: Data(from: "search/bbedit.json")).resultCount + consequencesOf( + try JSONDecoder() + .decode(SearchResultList.self, from: Data(from: "search/bbedit.json")) + .resultCount + ) ) - == 1 + == (1, nil, "", "") } it("can parse things") { expect( - try JSONDecoder().decode(SearchResultList.self, from: Data(from: "search/things.json")).resultCount + consequencesOf( + try JSONDecoder() + .decode(SearchResultList.self, from: Data(from: "search/things.json")) + .resultCount + ) ) - == 50 + == (50, nil, "", "") } } } diff --git a/Tests/masTests/Models/SearchResultSpec.swift b/Tests/masTests/Models/SearchResultSpec.swift index d800c748..3f1b6f97 100644 --- a/Tests/masTests/Models/SearchResultSpec.swift +++ b/Tests/masTests/Models/SearchResultSpec.swift @@ -20,11 +20,13 @@ public final class SearchResultSpec: QuickSpec { describe("search result") { it("can parse things") { expect( - try JSONDecoder() - .decode(SearchResult.self, from: Data(from: "search/things-that-go-bump.json")) - .trackId + consequencesOf( + try JSONDecoder() + .decode(SearchResult.self, from: Data(from: "search/things-that-go-bump.json")) + .trackId + ) ) - == 1_472_954_003 + == (1_472_954_003, nil, "", "") } } } diff --git a/Tests/masTests/Models/SoftwareProductSpec.swift b/Tests/masTests/Models/SoftwareProductSpec.swift index 44cd4838..c8bf23dc 100644 --- a/Tests/masTests/Models/SoftwareProductSpec.swift +++ b/Tests/masTests/Models/SoftwareProductSpec.swift @@ -27,16 +27,28 @@ public final class SoftwareProductSpec: QuickSpec { } describe("software product") { it("is not outdated when there is no new version available") { - expect(app.isOutdated(comparedTo: SearchResult(version: "1.0.0"))) == false + expect(consequencesOf(app.isOutdated(comparedTo: SearchResult(version: "1.0.0")))) + == (false, nil, "", "") } it("is outdated when there is a new version available") { - expect(app.isOutdated(comparedTo: SearchResult(version: "2.0.0"))) == true + expect(consequencesOf(app.isOutdated(comparedTo: SearchResult(version: "2.0.0")))) + == (true, nil, "", "") } it("is not outdated when the new version of mac-software requires a higher OS version") { - expect(app.isOutdated(comparedTo: SearchResult(minimumOsVersion: "99.0.0", version: "3.0.0"))) == false + expect( + consequencesOf( + app.isOutdated(comparedTo: SearchResult(minimumOsVersion: "99.0.0", version: "3.0.0")) + ) + ) + == (false, nil, "", "") } it("is not outdated when the new version of software requires a higher OS version") { - expect(app.isOutdated(comparedTo: SearchResult(minimumOsVersion: "99.0.0", version: "3.0.0"))) == false + expect( + consequencesOf( + app.isOutdated(comparedTo: SearchResult(minimumOsVersion: "99.0.0", version: "3.0.0")) + ) + ) + == (false, nil, "", "") } } } diff --git a/Tests/masTests/Utilities/Streams.swift b/Tests/masTests/Utilities/Streams.swift index 14899f26..bcec47ba 100644 --- a/Tests/masTests/Utilities/Streams.swift +++ b/Tests/masTests/Utilities/Streams.swift @@ -8,29 +8,86 @@ import Foundation -func captureStream( - _ stream: UnsafeMutablePointer, - encoding: String.Encoding = .utf8, - _ block: @escaping () throws -> Void -) rethrows -> String { - let originalFd = fileno(stream) - let duplicateFd = dup(originalFd) +@testable import mas + +func consequencesOf( + streamEncoding: String.Encoding = .utf8, + _ expression: @autoclosure @escaping () throws -> Void +) -> (error: MASError?, stdout: String, stderr: String) { + let consequences = consequences(streamEncoding: streamEncoding, expression) + return (consequences.error, consequences.stdout, consequences.stderr) +} + +func consequencesOf( + streamEncoding: String.Encoding = .utf8, + _ expression: @autoclosure @escaping () throws -> T +) -> (value: T?, error: MASError?, stdout: String, stderr: String) { + consequences(streamEncoding: streamEncoding, expression) +} + +// periphery:ignore +func consequencesOf( + streamEncoding: String.Encoding = .utf8, + _ body: @escaping () throws -> Void +) -> (error: MASError?, stdout: String, stderr: String) { + let consequences = consequences(streamEncoding: streamEncoding, body) + return (consequences.error, consequences.stdout, consequences.stderr) +} + +// periphery:ignore +func consequencesOf( + streamEncoding: String.Encoding = .utf8, + _ body: @escaping () throws -> T +) -> (value: T?, error: MASError?, stdout: String, stderr: String) { + consequences(streamEncoding: streamEncoding, body) +} + +private func consequences( + streamEncoding: String.Encoding = .utf8, + _ body: @escaping () throws -> T +) -> (value: T?, error: MASError?, stdout: String, stderr: String) { + let outOriginalFD = fileno(stdout) + let errOriginalFD = fileno(stderr) + + let outDuplicateFD = dup(outOriginalFD) defer { - close(duplicateFd) + close(outDuplicateFD) } - let pipe = Pipe() - dup2(pipe.fileHandleForWriting.fileDescriptor, originalFd) + let errDuplicateFD = dup(errOriginalFD) + defer { + close(errDuplicateFD) + } + + let outPipe = Pipe() + let errPipe = Pipe() + + dup2(outPipe.fileHandleForWriting.fileDescriptor, outOriginalFD) + dup2(errPipe.fileHandleForWriting.fileDescriptor, errOriginalFD) + var value: T? + var thrownError: MASError? do { defer { - fflush(stream) - dup2(duplicateFd, originalFd) - pipe.fileHandleForWriting.closeFile() + fflush(stdout) + fflush(stderr) + dup2(outDuplicateFD, outOriginalFD) + dup2(errDuplicateFD, errOriginalFD) + outPipe.fileHandleForWriting.closeFile() + errPipe.fileHandleForWriting.closeFile() } - try block() + value = try body() + } catch let error as MASError { + thrownError = error + } catch { + thrownError = MASError.failed(error: error as NSError) } - return String(data: pipe.fileHandleForReading.readDataToEndOfFile(), encoding: encoding) ?? "" + return ( + value, + thrownError, + String(data: outPipe.fileHandleForReading.readDataToEndOfFile(), encoding: streamEncoding) ?? "", + String(data: errPipe.fileHandleForReading.readDataToEndOfFile(), encoding: streamEncoding) ?? "" + ) } From ff4fce63971da709e69d2c786d99cff68dfe64e8 Mon Sep 17 00:00:00 2001 From: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> Date: Wed, 1 Jan 2025 19:44:07 -0500 Subject: [PATCH 9/9] Rename `Streams.swift` as `Consequences.swift`. Resolve #596 Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com> --- Tests/masTests/Utilities/{Streams.swift => Consequences.swift} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Tests/masTests/Utilities/{Streams.swift => Consequences.swift} (99%) diff --git a/Tests/masTests/Utilities/Streams.swift b/Tests/masTests/Utilities/Consequences.swift similarity index 99% rename from Tests/masTests/Utilities/Streams.swift rename to Tests/masTests/Utilities/Consequences.swift index bcec47ba..4b3e012f 100644 --- a/Tests/masTests/Utilities/Streams.swift +++ b/Tests/masTests/Utilities/Consequences.swift @@ -1,5 +1,5 @@ // -// Streams.swift +// Consequences.swift // masTests // // Created by Ross Goldberg on 2024-12-29.