2022-11-07 16:46:32 -06:00
|
|
|
|
//
|
|
|
|
|
|
// AltTests.swift
|
|
|
|
|
|
// AltTests
|
|
|
|
|
|
//
|
|
|
|
|
|
// Created by Riley Testut on 10/6/22.
|
|
|
|
|
|
// Copyright © 2022 Riley Testut. All rights reserved.
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
import XCTest
|
2022-11-07 16:47:23 -06:00
|
|
|
|
@testable import AltStore
|
|
|
|
|
|
@testable import AltStoreCore
|
|
|
|
|
|
|
|
|
|
|
|
import AltSign
|
|
|
|
|
|
|
|
|
|
|
|
extension String
|
|
|
|
|
|
{
|
|
|
|
|
|
static let testDomain = "TestErrorDomain"
|
|
|
|
|
|
|
|
|
|
|
|
static let testLocalizedTitle = "AltTest Failed"
|
|
|
|
|
|
static let testLocalizedFailure = "The AltTest failed to pass."
|
|
|
|
|
|
|
|
|
|
|
|
static let testOriginalLocalizedFailure = "The AltServer operation could not be completed."
|
|
|
|
|
|
|
|
|
|
|
|
static let testUnrecognizedFailureReason = "The alien invasion has begun."
|
|
|
|
|
|
static let testUnrecognizedRecoverySuggestion = "Find your loved ones and pray the aliens are merciful."
|
|
|
|
|
|
|
2022-12-15 15:59:39 -06:00
|
|
|
|
static let testDescription = "The operation could not be completed because an error occured."
|
2022-11-07 16:47:23 -06:00
|
|
|
|
static let testDebugDescription = "The very specific operation could not be completed because a detailed error occured. Code=101."
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension [String: String]
|
|
|
|
|
|
{
|
|
|
|
|
|
static let unrecognizedProvider: Self = [
|
|
|
|
|
|
NSLocalizedFailureReasonErrorKey: .testUnrecognizedFailureReason,
|
|
|
|
|
|
NSLocalizedRecoverySuggestionErrorKey: .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension Error
|
|
|
|
|
|
{
|
|
|
|
|
|
func serialized(provider: [String: String]?) -> NSError
|
|
|
|
|
|
{
|
|
|
|
|
|
AltTests.mockUserInfoValueProvider(for: self, values: provider) {
|
|
|
|
|
|
return (self as NSError).sanitizedForSerialization()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension URL
|
|
|
|
|
|
{
|
2023-03-01 14:07:04 -06:00
|
|
|
|
static let testFileURL = URL(fileURLWithPath: "~/Desktop/TestApp.ipa")
|
2022-11-07 16:47:23 -06:00
|
|
|
|
}
|
2022-11-07 16:46:32 -06:00
|
|
|
|
|
|
|
|
|
|
final class AltTests: XCTestCase
|
|
|
|
|
|
{
|
|
|
|
|
|
override func setUpWithError() throws
|
|
|
|
|
|
{
|
|
|
|
|
|
// Put setup code here. This method is called before the invocation of each test method in the class.
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
override func tearDownWithError() throws
|
|
|
|
|
|
{
|
|
|
|
|
|
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-11-07 16:47:23 -06:00
|
|
|
|
|
|
|
|
|
|
// Helper Methods
|
|
|
|
|
|
extension AltTests
|
|
|
|
|
|
{
|
|
|
|
|
|
func unbridge<T: ALTLocalizedError>(_ error: NSError, to errorType: T) throws -> Error
|
|
|
|
|
|
{
|
|
|
|
|
|
let unbridgedError = try XCTUnwrap(error as? T)
|
|
|
|
|
|
return unbridgedError
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func send(_ error: Error, serverProvider: [String: String]? = nil, clientProvider: [String: String]? = nil) throws -> NSError
|
|
|
|
|
|
{
|
|
|
|
|
|
let altserverError = ALTServerError(error)
|
|
|
|
|
|
|
|
|
|
|
|
let codableError = CodableError(error: altserverError)
|
|
|
|
|
|
|
|
|
|
|
|
let jsonData: Data
|
|
|
|
|
|
if let serverProvider
|
|
|
|
|
|
{
|
|
|
|
|
|
jsonData = try AltTests.mockUserInfoValueProvider(for: error, values: serverProvider) {
|
|
|
|
|
|
return try JSONEncoder().encode(codableError)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
jsonData = try JSONEncoder().encode(codableError)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let decodedError: CodableError
|
|
|
|
|
|
if let clientProvider
|
|
|
|
|
|
{
|
|
|
|
|
|
decodedError = try AltTests.mockUserInfoValueProvider(for: error, values: clientProvider) {
|
|
|
|
|
|
return try Foundation.JSONDecoder().decode(CodableError.self, from: jsonData)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
decodedError = try Foundation.JSONDecoder().decode(CodableError.self, from: jsonData)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = decodedError.error
|
|
|
|
|
|
return receivedError as NSError
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static func mockUserInfoValueProvider<T, Error: Swift.Error>(for error: Error, values: [String: String]?, closure: () throws -> T) rethrows -> T
|
|
|
|
|
|
{
|
|
|
|
|
|
let provider = NSError.userInfoValueProvider(forDomain: error._domain)
|
|
|
|
|
|
NSError.setUserInfoValueProvider(forDomain: error._domain) { (error, key) -> Any? in
|
|
|
|
|
|
let nsError = error as NSError
|
|
|
|
|
|
guard nsError.code == error._code else { return provider?(nsError, key) }
|
|
|
|
|
|
|
|
|
|
|
|
switch key
|
|
|
|
|
|
{
|
|
|
|
|
|
case NSLocalizedDescriptionKey:
|
|
|
|
|
|
guard nsError.localizedFailure == nil else {
|
|
|
|
|
|
// Error has localizedFailure, so return nil to construct localizedDescription from it + localizedFailureReason.
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Otherwise, return failureReason for localizedDescription to avoid system prepending "Operation Failed" message.
|
|
|
|
|
|
return values?[NSLocalizedFailureReasonErrorKey]
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
return values?[key]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
defer {
|
|
|
|
|
|
NSError.setUserInfoValueProvider(forDomain: error._domain) { (error, key) in
|
|
|
|
|
|
provider?(error, key)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let value = try closure()
|
|
|
|
|
|
return value
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func ALTAssertErrorsEqual(_ error1: Error, _ error2: Error, ignoring ignoredValues: Set<String> = [], ignoreExtraUserInfoValues: Bool = false, file: StaticString = #file, line: UInt = #line)
|
|
|
|
|
|
{
|
|
|
|
|
|
if !ignoredValues.contains(ALTUnderlyingErrorDomainErrorKey)
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTAssertEqual(error1._domain, error2._domain, file: file, line: line)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if !ignoredValues.contains(ALTUnderlyingErrorCodeErrorKey)
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTAssertEqual(error1._code, error2._code, file: file, line: line)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if !ignoredValues.contains(NSLocalizedDescriptionKey)
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTAssertEqual(error1.localizedDescription, error2.localizedDescription, "Localized Descriptions don't match.", file: file, line: line)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let nsError1 = error1 as NSError
|
|
|
|
|
|
let nsError2 = error2 as NSError
|
|
|
|
|
|
|
|
|
|
|
|
if !ignoredValues.contains(ALTLocalizedTitleErrorKey)
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTAssertEqual(nsError1.localizedTitle, nsError2.localizedTitle, "Titles don't match.", file: file, line: line)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if !ignoredValues.contains(NSLocalizedFailureErrorKey)
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTAssertEqual(nsError1.localizedFailure, nsError2.localizedFailure, "Failures don't match.", file: file, line: line)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if !ignoredValues.contains(NSLocalizedFailureReasonErrorKey)
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTAssertEqual(nsError1.localizedFailureReason, nsError2.localizedFailureReason, "Failure reasons don't match.", file: file, line: line)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if !ignoredValues.contains(NSLocalizedRecoverySuggestionErrorKey)
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTAssertEqual(nsError1.localizedRecoverySuggestion, nsError2.localizedRecoverySuggestion, file: file, line: line)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if !ignoredValues.contains(NSDebugDescriptionErrorKey)
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTAssertEqual(nsError1.localizedDebugDescription, nsError2.localizedDebugDescription, file: file, line: line)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if !ignoreExtraUserInfoValues
|
|
|
|
|
|
{
|
|
|
|
|
|
// Ensure remaining user info values match.
|
|
|
|
|
|
let standardKeys: Set<String> = [NSLocalizedDescriptionKey, ALTLocalizedTitleErrorKey, NSLocalizedFailureErrorKey, NSLocalizedFailureReasonErrorKey, NSLocalizedRecoverySuggestionErrorKey, NSUnderlyingErrorKey, NSDebugDescriptionErrorKey]
|
|
|
|
|
|
let filteredUserInfo1 = nsError1.userInfo.filter { !standardKeys.contains($0.key) }
|
|
|
|
|
|
let filteredUserInfo2 = nsError2.userInfo.filter { !standardKeys.contains($0.key) }
|
|
|
|
|
|
XCTAssertEqual(filteredUserInfo1 as NSDictionary, filteredUserInfo2 as NSDictionary, file: file, line: line)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@discardableResult
|
|
|
|
|
|
func ALTAssertUnderlyingErrorEqualsError(_ receivedError: Error, _ error: Error, ignoring ignoredValues: Set<String> = [], ignoreExtraUserInfoValues: Bool = false, file: StaticString = #file, line: UInt = #line) throws -> NSError
|
|
|
|
|
|
{
|
|
|
|
|
|
// Test receivedError == ALTServerError.underlyingError
|
|
|
|
|
|
XCTAssertEqual(receivedError._domain, ALTServerError.errorDomain, file: file, line: line)
|
|
|
|
|
|
|
|
|
|
|
|
if !ignoredValues.contains(ALTUnderlyingErrorCodeErrorKey)
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTAssertEqual(receivedError._code, ALTServerError.underlyingError.rawValue, file: file, line: line)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Test underlyingError == error
|
|
|
|
|
|
let underlyingError = try XCTUnwrap(receivedError.underlyingError)
|
|
|
|
|
|
ALTAssertErrorsEqual(underlyingError, error, ignoring: ignoredValues, ignoreExtraUserInfoValues: ignoreExtraUserInfoValues, file: file, line: line)
|
|
|
|
|
|
|
|
|
|
|
|
// Test receivedError forwards all properties to underlyingError.
|
|
|
|
|
|
var ignoredValues = ignoredValues
|
|
|
|
|
|
ignoredValues.formUnion([ALTUnderlyingErrorDomainErrorKey, ALTUnderlyingErrorCodeErrorKey])
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedError, underlyingError, ignoring: ignoredValues, ignoreExtraUserInfoValues: true, file: file, line: line) // Always ignore extra user info values.
|
|
|
|
|
|
|
|
|
|
|
|
return underlyingError as NSError
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func ALTAssertErrorFailureAndDescription(_ error: Error, failure: String?, baseDescription: String, file: StaticString = #file, line: UInt = #line)
|
|
|
|
|
|
{
|
|
|
|
|
|
let localizedDescription: String
|
|
|
|
|
|
if let failure
|
|
|
|
|
|
{
|
|
|
|
|
|
localizedDescription = failure + " " + baseDescription
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
localizedDescription = baseDescription
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(error.localizedDescription, localizedDescription, file: file, line: line)
|
|
|
|
|
|
XCTAssertEqual((error as NSError).localizedFailure, failure, file: file, line: line)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Local Errors
|
|
|
|
|
|
extension AltTests
|
|
|
|
|
|
{
|
|
|
|
|
|
func testToNSErrorBridging() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in AltTests.allLocalErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let nsError = (error as NSError)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedDescription, error.localizedDescription)
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedFailure, error.errorFailure)
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedFailureReason, error.errorFailureReason)
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedRecoverySuggestion, error.recoverySuggestion)
|
|
|
|
|
|
|
|
|
|
|
|
if let provider = NSError.userInfoValueProvider(forDomain: OperationError.errorDomain),
|
|
|
|
|
|
let debugDescription = provider(error, NSDebugDescriptionErrorKey) as? String
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTAssertEqual(debugDescription, nsError.debugDescription)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testToNSErrorAndBackBridging() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in AltTests.allLocalErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let nsError = (error as NSError)
|
|
|
|
|
|
let unbridgedError = try XCTUnwrap(nsError as? any ALTLocalizedError)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(unbridgedError.localizedDescription, error.localizedDescription)
|
|
|
|
|
|
XCTAssertEqual(unbridgedError.errorFailure, error.errorFailure)
|
|
|
|
|
|
XCTAssertEqual(unbridgedError.failureReason, error.errorFailureReason)
|
|
|
|
|
|
XCTAssertEqual(unbridgedError.recoverySuggestion, error.recoverySuggestion)
|
|
|
|
|
|
|
|
|
|
|
|
if let provider = NSError.userInfoValueProvider(forDomain: OperationError.errorDomain),
|
|
|
|
|
|
let debugDescription = provider(error, NSDebugDescriptionErrorKey) as? String
|
|
|
|
|
|
{
|
|
|
|
|
|
let unbridgedDebugDescription = provider(unbridgedError, NSDebugDescriptionErrorKey) as? String
|
|
|
|
|
|
XCTAssertEqual(debugDescription, unbridgedDebugDescription)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testDefaultErrorDomain()
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in VerificationError.testErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let expectedErrorDomain = "AltStore.VerificationError"
|
|
|
|
|
|
XCTAssertEqual(error._domain, expectedErrorDomain)
|
|
|
|
|
|
|
|
|
|
|
|
let nsError = (error as NSError)
|
|
|
|
|
|
XCTAssertEqual(nsError.domain, expectedErrorDomain)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testCustomErrorDomain() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in allTestErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTAssertEqual(error._domain, TestError.errorDomain)
|
|
|
|
|
|
|
|
|
|
|
|
let nsError = (error as NSError)
|
|
|
|
|
|
XCTAssertEqual(nsError.domain, TestError.errorDomain)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testLocalizedDescriptionProvider() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in AltTests.allRealErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
let expectedFailureReason = try XCTUnwrap((error as NSError).localizedFailureReason)
|
|
|
|
|
|
|
|
|
|
|
|
if let localizedFailure = (error as NSError).localizedFailure
|
|
|
|
|
|
{
|
|
|
|
|
|
// Test localizedDescription == original localizedFailure + localizedFailureReason
|
|
|
|
|
|
let expectedLocalizedDescription = localizedFailure + " " + expectedFailureReason
|
|
|
|
|
|
XCTAssertEqual(error.localizedDescription, expectedLocalizedDescription)
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// Test localizedDescription does not start with "The operation couldn't be completed."
|
|
|
|
|
|
XCTAssert(!error.localizedDescription.starts(with: "The operation couldn’t be completed."), error.localizedDescription)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let expectedLocalizedDescription = String.testLocalizedFailure + " " + expectedFailureReason
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedDescription, expectedLocalizedDescription)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testWithLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in AltTests.allRealErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let expectedFailureReason = try XCTUnwrap((error as NSError).localizedFailureReason)
|
|
|
|
|
|
let expectedLocalizedDescription = String.testLocalizedFailure + " " + expectedFailureReason
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedDescription, expectedLocalizedDescription)
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedFailure, .testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
ALTAssertErrorsEqual(nsError, error, ignoring: [NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testWithInitialLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in OperationError.testErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
var localizedError = OperationError(error, localizedFailure: .testLocalizedFailure)
|
|
|
|
|
|
localizedError.sourceFile = error.sourceFile
|
|
|
|
|
|
localizedError.sourceLine = error.sourceLine
|
|
|
|
|
|
|
|
|
|
|
|
let nsError = localizedError as NSError
|
|
|
|
|
|
|
|
|
|
|
|
let expectedLocalizedDescription = String.testLocalizedFailure + " " + error.errorFailureReason
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedDescription, expectedLocalizedDescription)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(localizedError.errorFailure, .testLocalizedFailure)
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedFailure, .testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
// Test remainder
|
|
|
|
|
|
ALTAssertErrorsEqual(nsError, error, ignoring: [NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testWithInitialLocalizedTitle() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in OperationError.testErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
var localizedError = OperationError(error, localizedTitle: .testLocalizedTitle)
|
|
|
|
|
|
localizedError.sourceFile = error.sourceFile
|
|
|
|
|
|
localizedError.sourceLine = error.sourceLine
|
|
|
|
|
|
|
|
|
|
|
|
let nsError = localizedError as NSError
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedDescription, error.localizedDescription)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(localizedError.errorTitle, .testLocalizedTitle)
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedTitle, .testLocalizedTitle)
|
|
|
|
|
|
|
|
|
|
|
|
// Test remainder
|
|
|
|
|
|
ALTAssertErrorsEqual(nsError, error, ignoring: [NSLocalizedDescriptionKey, ALTLocalizedTitleErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testWithLocalizedFailureAndBack() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in AltTests.allLocalErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
func test(_ unbridgedError: Error, against nsError: NSError)
|
|
|
|
|
|
{
|
|
|
|
|
|
let unbridgedNSError = (unbridgedError as NSError)
|
|
|
|
|
|
|
|
|
|
|
|
let expectedLocalizedDescription = String.testLocalizedFailure + " " + error.errorFailureReason
|
|
|
|
|
|
XCTAssertEqual(unbridgedError.localizedDescription, expectedLocalizedDescription)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(unbridgedNSError.localizedFailure, .testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
// Test dynamic type matches original error type
|
|
|
|
|
|
XCTAssert(type(of: unbridgedError) == type(of: error))
|
|
|
|
|
|
|
|
|
|
|
|
// Test remainder
|
|
|
|
|
|
ALTAssertErrorsEqual(unbridgedNSError, error, ignoring: [NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
|
{
|
|
|
|
|
|
throw nsError as NSError
|
|
|
|
|
|
}
|
|
|
|
|
|
catch let error as VerificationError
|
|
|
|
|
|
{
|
|
|
|
|
|
test(error, against: nsError)
|
|
|
|
|
|
}
|
|
|
|
|
|
catch let error as OperationError
|
|
|
|
|
|
{
|
|
|
|
|
|
test(error, against: nsError)
|
|
|
|
|
|
}
|
|
|
|
|
|
catch let error as ALTLocalizedError
|
|
|
|
|
|
{
|
|
|
|
|
|
// Make sure VerificationError and OperationError were caught by above handlers.
|
|
|
|
|
|
XCTAssertNotEqual(error._domain, VerificationError.errorDomain)
|
|
|
|
|
|
XCTAssertNotEqual(error._domain, OperationError.errorDomain)
|
|
|
|
|
|
|
|
|
|
|
|
let unbridgedError = try self.unbridge(error as NSError, to: error)
|
|
|
|
|
|
test(unbridgedError, against: nsError)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-12-20 14:01:54 -06:00
|
|
|
|
func testPatternMatchingErrorCode() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
do
|
|
|
|
|
|
{
|
|
|
|
|
|
// ALTLocalizedError
|
|
|
|
|
|
throw OperationError.serverNotFound
|
|
|
|
|
|
}
|
|
|
|
|
|
catch ~OperationError.Code.serverNotFound
|
|
|
|
|
|
{
|
|
|
|
|
|
// Success
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTFail("Failed to catch error as OperationError.Code.serverNotFound: \(error)")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
|
{
|
|
|
|
|
|
// ALTErrorEnum
|
|
|
|
|
|
throw AuthenticationError(.noTeam)
|
|
|
|
|
|
}
|
|
|
|
|
|
catch ~AuthenticationErrorCode.noTeam
|
|
|
|
|
|
{
|
|
|
|
|
|
// Success
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTFail("Failed to catch error as AuthenticationErrorCode.noTeam: \(error)")
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-11-07 16:47:23 -06:00
|
|
|
|
func testWithLocalizedTitle() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let localizedTitle = "AltTest Failed"
|
|
|
|
|
|
|
|
|
|
|
|
for error in AltTests.allLocalErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedTitle(localizedTitle)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedTitle, localizedTitle)
|
|
|
|
|
|
|
|
|
|
|
|
ALTAssertErrorsEqual(nsError, error, ignoring: [ALTLocalizedTitleErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testWithLocalizedTitleAndBack() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in AltTests.allLocalErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedTitle(.testLocalizedTitle)
|
|
|
|
|
|
|
|
|
|
|
|
let unbridgedError = try self.unbridge(nsError, to: error)
|
|
|
|
|
|
let unbridgedNSError = (unbridgedError as NSError)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(unbridgedNSError.localizedTitle, .testLocalizedTitle)
|
|
|
|
|
|
|
|
|
|
|
|
ALTAssertErrorsEqual(unbridgedNSError, error, ignoring: [ALTLocalizedTitleErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testWithLocalizedTitleAndFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in AltTests.allRealErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
var nsError = (error as NSError).withLocalizedTitle(.testLocalizedTitle)
|
|
|
|
|
|
nsError = nsError.withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedTitle, .testLocalizedTitle)
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedFailure, .testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let expectedLocalizedDescription = try String.testLocalizedFailure + " " + XCTUnwrap((error as NSError).localizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedDescription, expectedLocalizedDescription)
|
|
|
|
|
|
|
|
|
|
|
|
// Test remainder
|
|
|
|
|
|
ALTAssertErrorsEqual(nsError, error, ignoring: [NSLocalizedDescriptionKey, ALTLocalizedTitleErrorKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-12-15 15:59:39 -06:00
|
|
|
|
func testSwiftErrorWithLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
enum MyError: Int, LocalizedError, CaseIterable
|
|
|
|
|
|
{
|
|
|
|
|
|
case strange
|
|
|
|
|
|
case nothing
|
|
|
|
|
|
|
|
|
|
|
|
var errorDescription: String? {
|
|
|
|
|
|
switch self
|
|
|
|
|
|
{
|
|
|
|
|
|
case .strange: return "A strange error occured."
|
|
|
|
|
|
case .nothing: return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var recoverySuggestion: String? {
|
|
|
|
|
|
return "Have you tried turning it off and on again?"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for error in MyError.allCases
|
|
|
|
|
|
{
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
ALTAssertErrorsEqual(nsError, error, ignoring: [NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(nsError, failure: .testLocalizedFailure, baseDescription: error.localizedDescription)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testNSErrorWithLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = NSError(domain: .testDomain, code: 14, userInfo: [NSLocalizedDescriptionKey: String.testDescription])
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
ALTAssertErrorsEqual(nsError, error, ignoring: [NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(nsError, failure: .testLocalizedFailure, baseDescription: .testDescription)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-11-07 16:47:23 -06:00
|
|
|
|
func testReceivingAltServerError() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in ALTServerError.testErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let codableError = CodableError(error: error)
|
|
|
|
|
|
let jsonData = try JSONEncoder().encode(codableError)
|
|
|
|
|
|
|
|
|
|
|
|
let decodedError = try Foundation.JSONDecoder().decode(CodableError.self, from: jsonData)
|
|
|
|
|
|
let receivedError = decodedError.error
|
|
|
|
|
|
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedError, error)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingAltServerErrorWithLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in ALTServerError.testErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
let altserverError = ALTServerError(nsError)
|
|
|
|
|
|
|
|
|
|
|
|
let codableError = CodableError(error: altserverError)
|
|
|
|
|
|
let jsonData = try JSONEncoder().encode(codableError)
|
|
|
|
|
|
|
|
|
|
|
|
let decodedError = try Foundation.JSONDecoder().decode(CodableError.self, from: jsonData)
|
|
|
|
|
|
let receivedError = decodedError.error
|
|
|
|
|
|
let receivedNSError = receivedError as NSError
|
|
|
|
|
|
|
|
|
|
|
|
let expectedLocalizedDescription = try String.testLocalizedFailure + " " + XCTUnwrap((error as NSError).localizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(nsError.localizedDescription, expectedLocalizedDescription)
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedFailure, .testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedError, error, ignoring: [NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingAltServerErrorWithLocalizedTitle() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in ALTServerError.testErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedTitle(.testLocalizedTitle)
|
|
|
|
|
|
let receivedError = try self.send(nsError)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedTitle, .testLocalizedTitle)
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedError, error, ignoring: [ALTLocalizedTitleErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingAltServerErrorThenAddingLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in ALTServerError.testErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let receivedError = try self.send(error)
|
|
|
|
|
|
let receivedNSError = (receivedError as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let expectedLocalizedDescription = try String.testLocalizedFailure + " " + XCTUnwrap((error as NSError).localizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedDescription, expectedLocalizedDescription)
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedFailure, .testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedNSError, error, ignoring: [NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingAltServerErrorThenAddingLocalizedTitle() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in ALTServerError.testErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let receivedError = try self.send(error)
|
|
|
|
|
|
let receivedNSError = (receivedError as NSError).withLocalizedTitle(.testLocalizedTitle)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedTitle, .testLocalizedTitle)
|
|
|
|
|
|
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedNSError, error, ignoring: [ALTLocalizedTitleErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingAltServerErrorWithLocalizedFailureThenChangingLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in ALTServerError.testErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testOriginalLocalizedFailure)
|
|
|
|
|
|
let receivedError = try self.send(nsError)
|
|
|
|
|
|
let receivedNSError = (receivedError as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let expectedLocalizedDescription = try String.testLocalizedFailure + " " + XCTUnwrap(nsError.localizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedDescription, expectedLocalizedDescription)
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedFailure, .testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
// Test that decoded error retains original localized failure.
|
|
|
|
|
|
XCTAssertEqual((receivedError as NSError).localizedFailure, .testOriginalLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedNSError, error, ignoring: [NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingAltServerErrorWithLocalizedFailureThenAddingLocalizedTitle() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in ALTServerError.testErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
let receivedError = try self.send(nsError)
|
|
|
|
|
|
let receivedNSError = (receivedError as NSError).withLocalizedTitle(.testLocalizedTitle)
|
|
|
|
|
|
|
|
|
|
|
|
let expectedLocalizedDescription = try String.testLocalizedFailure + " " + XCTUnwrap(nsError.localizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedDescription, expectedLocalizedDescription)
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedFailure, .testLocalizedFailure)
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedTitle, .testLocalizedTitle)
|
|
|
|
|
|
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedNSError, error, ignoring: [NSLocalizedDescriptionKey, ALTLocalizedTitleErrorKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingNonAltServerSwiftError() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in allTestErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let receivedError = try self.send(error)
|
|
|
|
|
|
try ALTAssertUnderlyingErrorEqualsError(receivedError, error)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingNonAltServerSwiftErrorWithSourceLocation() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let file = #fileID
|
|
|
|
|
|
let line = #line as UInt
|
|
|
|
|
|
|
|
|
|
|
|
let error = OperationError.unknown(file: file, line: line)
|
|
|
|
|
|
let receivedError = try self.send(error)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(receivedError.userInfo[ALTSourceFileErrorKey] as? String, file)
|
|
|
|
|
|
|
|
|
|
|
|
if let uint = receivedError.userInfo[ALTSourceLineErrorKey] as? UInt
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTAssertEqual(uint, line)
|
|
|
|
|
|
}
|
|
|
|
|
|
else if let int = receivedError.userInfo[ALTSourceLineErrorKey] as? Int
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTAssertEqual(int, Int(line))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try ALTAssertUnderlyingErrorEqualsError(receivedError, error)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingNonAltServerSwiftErrorWithLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in allTestErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
let receivedError = try self.send(nsError)
|
|
|
|
|
|
|
|
|
|
|
|
let expectedLocalizedDescription = try String.testLocalizedFailure + " " + XCTUnwrap(nsError.localizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedDescription, expectedLocalizedDescription)
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedFailure, .testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedUnderlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedError, error, ignoring: [NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
XCTAssertEqual(receivedUnderlyingError.localizedDescription, expectedLocalizedDescription)
|
|
|
|
|
|
XCTAssertEqual(receivedUnderlyingError.localizedFailure, .testLocalizedFailure)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingNonAltServerSwiftErrorThenAddingLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in allTestErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let receivedError = try self.send(error)
|
|
|
|
|
|
let receivedNSError = (receivedError as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedUnderlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedNSError, error, ignoring: [NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
XCTAssertEqual(receivedUnderlyingError.localizedDescription, error.errorFailureReason)
|
|
|
|
|
|
XCTAssertNil(receivedUnderlyingError.localizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let expectedLocalizedDescription = try String.testLocalizedFailure + " " + XCTUnwrap((error as NSError).localizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedDescription, expectedLocalizedDescription)
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedFailure, .testLocalizedFailure)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingNonAltServerSwiftErrorThenAddingLocalizedTitle() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
for error in allTestErrors
|
|
|
|
|
|
{
|
|
|
|
|
|
let receivedError = try self.send(error)
|
|
|
|
|
|
let receivedNSError = (receivedError as NSError).withLocalizedTitle(.testLocalizedTitle)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertNil(error.errorTitle)
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedTitle, .testLocalizedTitle)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedUnderlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedNSError, error, ignoring: [ALTLocalizedTitleErrorKey])
|
|
|
|
|
|
XCTAssertNil(receivedUnderlyingError.localizedTitle)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingUnrecognizedNonAltServerSwiftError() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
enum MyError: Int, LocalizedError, CaseIterable
|
|
|
|
|
|
{
|
|
|
|
|
|
case strange
|
|
|
|
|
|
case nothing
|
|
|
|
|
|
|
|
|
|
|
|
var errorDescription: String? {
|
|
|
|
|
|
switch self
|
|
|
|
|
|
{
|
|
|
|
|
|
case .strange: return "A strange error occured."
|
|
|
|
|
|
case .nothing: return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var recoverySuggestion: String? {
|
|
|
|
|
|
return "Have you tried turning it off and on again?"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for error in MyError.allCases
|
|
|
|
|
|
{
|
|
|
|
|
|
let receivedError = try self.send(error, clientProvider: [:])
|
|
|
|
|
|
try ALTAssertUnderlyingErrorEqualsError(receivedError, error)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingUnrecognizedNonAltServerSwiftErrorThenAddingLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
enum MyError: Int, LocalizedError, CaseIterable
|
|
|
|
|
|
{
|
|
|
|
|
|
case strange
|
|
|
|
|
|
case nothing
|
|
|
|
|
|
|
|
|
|
|
|
var errorDescription: String? {
|
|
|
|
|
|
switch self
|
|
|
|
|
|
{
|
|
|
|
|
|
case .strange: return "A strange error occured."
|
|
|
|
|
|
case .nothing: return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var recoverySuggestion: String? {
|
|
|
|
|
|
return "Have you tried turning it off and on again?"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for error in MyError.allCases
|
|
|
|
|
|
{
|
|
|
|
|
|
let receivedError = try self.send(error, clientProvider: [:])
|
|
|
|
|
|
let receivedNSError = receivedError.withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedUnderlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedNSError, error, ignoring: [NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedNSError, failure: .testLocalizedFailure, baseDescription: error.localizedDescription)
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedUnderlyingError, failure: nil, baseDescription: error.localizedDescription)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingNonAltServerCocoaError() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = CocoaError(.fileReadNoSuchFile, userInfo: [NSFilePathErrorKey: "~/Desktop/TestFile"])
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(error)
|
|
|
|
|
|
try ALTAssertUnderlyingErrorEqualsError(receivedError, error)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingNonAltServerCocoaErrorWithLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = CocoaError(.fileReadNoSuchFile, userInfo: [NSFilePathErrorKey: "~/Desktop/TestFile"])
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(nsError)
|
|
|
|
|
|
try ALTAssertUnderlyingErrorEqualsError(receivedError, nsError)
|
|
|
|
|
|
|
|
|
|
|
|
// Description == .testLocalizedFailure + failureReason ?? description
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedError, failure: .testLocalizedFailure, baseDescription: nsError.localizedFailureReason ?? error.localizedDescription)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingAltServerConnectionError() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTServerConnectionError(.deviceLocked, userInfo: [ALTDeviceNameErrorKey: "Riley's iPhone"])
|
|
|
|
|
|
let nsError = error as NSError
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(nsError)
|
|
|
|
|
|
let receivedUnderlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedError, nsError, ignoring: [ALTUnderlyingErrorCodeErrorKey, NSLocalizedFailureErrorKey, NSLocalizedDescriptionKey])
|
|
|
|
|
|
|
|
|
|
|
|
// Code == ALTServerError.connectionFailed
|
|
|
|
|
|
XCTAssertEqual(receivedError.code, ALTServerError.connectionFailed.rawValue)
|
|
|
|
|
|
|
|
|
|
|
|
// Underlying Code == ALTServerConnectionError.deviceLocked
|
|
|
|
|
|
XCTAssertEqual(receivedUnderlyingError.code, ALTServerConnectionError.deviceLocked.rawValue)
|
|
|
|
|
|
|
|
|
|
|
|
// Description == defaultFailure + error.localizedDescription
|
|
|
|
|
|
let defaultFailure = try XCTUnwrap((ALTServerError(.connectionFailed) as NSError).localizedFailureReason)
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedError, failure: defaultFailure, baseDescription: error.localizedDescription)
|
|
|
|
|
|
|
|
|
|
|
|
// Underlying Description = error.localizedDescription
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedUnderlyingError, failure: nil, baseDescription: error.localizedDescription)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingAppleAPIError() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTAppleAPIError(.incorrectCredentials)
|
|
|
|
|
|
let nsError = error as NSError
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(nsError, serverProvider: [NSDebugDescriptionErrorKey: .testDebugDescription])
|
|
|
|
|
|
|
|
|
|
|
|
// Debug Description == .testDebugDescription
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedDebugDescription, .testDebugDescription)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedUnderlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedError, error, ignoring: [NSDebugDescriptionErrorKey])
|
|
|
|
|
|
|
|
|
|
|
|
// Debug Description == .testDebugDescription
|
|
|
|
|
|
XCTAssertEqual(receivedUnderlyingError.localizedDebugDescription, .testDebugDescription)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingCodableError() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let json = "{'name2': 'riley'}"
|
|
|
|
|
|
|
|
|
|
|
|
struct Test: Decodable
|
|
|
|
|
|
{
|
|
|
|
|
|
var name: String
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let rawData = json.data(using: .utf8)!
|
|
|
|
|
|
let error: DecodingError
|
|
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
|
{
|
|
|
|
|
|
_ = try Foundation.JSONDecoder().decode(Test.self, from: rawData)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
catch let decodingError as DecodingError
|
|
|
|
|
|
{
|
|
|
|
|
|
error = decodingError
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
XCTFail("Only DecodingErrors should be thrown.")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let nsError = error as NSError
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(nsError)
|
|
|
|
|
|
|
|
|
|
|
|
// Code == ALTServerError.invalidRequest
|
|
|
|
|
|
// Description == CocoaError.coderReadCorrupt.localizedDescription
|
|
|
|
|
|
XCTAssertEqual(receivedError.code, ALTServerError.invalidRequest.rawValue)
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedDescription, CocoaError(.coderReadCorrupt).localizedDescription)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedUnderlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedError, nsError, ignoring: [ALTUnderlyingErrorCodeErrorKey, NSLocalizedDescriptionKey])
|
|
|
|
|
|
|
|
|
|
|
|
// Underlying Code == CocoaError.coderReadCorrupt
|
|
|
|
|
|
// Underlying Description == CocoaError.coderReadCorrupt.localizedDescription
|
|
|
|
|
|
XCTAssertEqual(receivedUnderlyingError.code, CocoaError.coderReadCorrupt.rawValue)
|
|
|
|
|
|
XCTAssertEqual(receivedUnderlyingError.localizedDescription, CocoaError(.coderReadCorrupt).localizedDescription)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingUnrecognizedAppleAPIError() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTAppleAPIError(.init(rawValue: -27)!) /* Alien Invasion */
|
|
|
|
|
|
let cachedError = error.serialized(provider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(error, serverProvider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
// Description == .testUnrecognizedFailureReason
|
|
|
|
|
|
// Recovery Suggestion == .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedError, failure: nil, baseDescription: .testUnrecognizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedRecoverySuggestion, .testUnrecognizedRecoverySuggestion)
|
|
|
|
|
|
|
|
|
|
|
|
let underlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedError, cachedError)
|
|
|
|
|
|
|
|
|
|
|
|
// Underlying Description == .testUnrecognizedFailureReason
|
|
|
|
|
|
// Underlying Recovery Suggestion == .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(underlyingError, failure: nil, baseDescription: .testUnrecognizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(underlyingError.localizedRecoverySuggestion, .testUnrecognizedRecoverySuggestion)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingUnrecognizedAppleAPIErrorWithLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTAppleAPIError(.init(rawValue: -27)!) /* Alien Invasion */
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(nsError, serverProvider: [
|
|
|
|
|
|
NSLocalizedFailureReasonErrorKey: .testUnrecognizedFailureReason,
|
|
|
|
|
|
NSLocalizedRecoverySuggestionErrorKey: .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == .testLocalizedFailure
|
|
|
|
|
|
// Description == Failure + .testUnrecognizedFailureReason
|
|
|
|
|
|
// Recovery Suggestion == .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedError, failure: .testLocalizedFailure, baseDescription: .testUnrecognizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedRecoverySuggestion, .testUnrecognizedRecoverySuggestion)
|
|
|
|
|
|
|
|
|
|
|
|
let underlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedError, nsError, ignoring: [NSLocalizedFailureReasonErrorKey, NSLocalizedRecoverySuggestionErrorKey, NSLocalizedDescriptionKey])
|
|
|
|
|
|
|
|
|
|
|
|
// Underlying Failure == .testLocalizedFailure
|
|
|
|
|
|
// Underlying Description == Failure + .testUnrecognizedFailureReason
|
|
|
|
|
|
// Underlying Recovery Suggestion == .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(underlyingError, failure: .testLocalizedFailure, baseDescription: .testUnrecognizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(underlyingError.localizedRecoverySuggestion, .testUnrecognizedRecoverySuggestion)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingUnrecognizedAppleAPIErrorThenAddingLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTAppleAPIError(.init(rawValue: -27)!) /* Alien Invasion */
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(error, serverProvider: [
|
|
|
|
|
|
NSLocalizedFailureReasonErrorKey: .testUnrecognizedFailureReason,
|
|
|
|
|
|
NSLocalizedRecoverySuggestionErrorKey: .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
])
|
|
|
|
|
|
let receivedNSError = (receivedError as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == .testLocalizedFailure
|
|
|
|
|
|
// Description == Failure + .testUnrecognizedFailureReason
|
|
|
|
|
|
// Recovery Suggestion == .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedNSError, failure: .testLocalizedFailure, baseDescription: .testUnrecognizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedRecoverySuggestion, .testUnrecognizedRecoverySuggestion)
|
|
|
|
|
|
|
|
|
|
|
|
let underlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedNSError, error, ignoring: [NSLocalizedFailureReasonErrorKey, NSLocalizedRecoverySuggestionErrorKey, NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
|
|
|
|
|
|
// Underlying Failure == nil
|
|
|
|
|
|
// Underlying Description == .testUnrecognizedFailureReason
|
|
|
|
|
|
// Underlying Recovery Suggestion == .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(underlyingError, failure: nil, baseDescription: .testUnrecognizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(underlyingError.localizedRecoverySuggestion, .testUnrecognizedRecoverySuggestion)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingUnrecognizedAppleAPIErrorWithLocalizedFailureThenChangingLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTAppleAPIError(.init(rawValue: -27)!) /* Alien Invasion */
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testOriginalLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(nsError, serverProvider: [
|
|
|
|
|
|
NSLocalizedFailureReasonErrorKey: .testUnrecognizedFailureReason,
|
|
|
|
|
|
NSLocalizedRecoverySuggestionErrorKey: .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == .testOriginalLocalizedFailure
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedFailure, .testOriginalLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedNSError = (receivedError as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == .testLocalizedFailure
|
|
|
|
|
|
// Description == Failure + .testUnrecognizedFailureReason
|
|
|
|
|
|
// Recovery Suggestion == .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedNSError, failure: .testLocalizedFailure, baseDescription: .testUnrecognizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedNSError.localizedRecoverySuggestion, .testUnrecognizedRecoverySuggestion)
|
|
|
|
|
|
|
|
|
|
|
|
let underlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedNSError, nsError, ignoring: [NSLocalizedFailureReasonErrorKey, NSLocalizedRecoverySuggestionErrorKey, NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
|
|
|
|
|
|
// Underlying Failure == .testOriginalLocalizedFailure
|
|
|
|
|
|
// Underlying Description == Underlying Failure + .testUnrecognizedFailureReason
|
|
|
|
|
|
// Underlying Recovery Suggestion == .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(underlyingError, failure: .testOriginalLocalizedFailure, baseDescription: .testUnrecognizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(underlyingError.localizedRecoverySuggestion, .testUnrecognizedRecoverySuggestion)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingUnrecognizedObjCErrorsWithLocalizedFailureThenChangingLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
// User Info = nil
|
|
|
|
|
|
var nsErrorWithNoUserInfo = NSError(domain: .testDomain, code: 14)
|
|
|
|
|
|
nsErrorWithNoUserInfo = nsErrorWithNoUserInfo.withLocalizedFailure(.testOriginalLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
// User Info = Failure Reason
|
|
|
|
|
|
var nsErrorWithUserInfoFailureReason = NSError(domain: .testDomain, code: 14, userInfo: [
|
|
|
|
|
|
NSLocalizedFailureReasonErrorKey: String.testUnrecognizedFailureReason
|
|
|
|
|
|
])
|
|
|
|
|
|
nsErrorWithUserInfoFailureReason = nsErrorWithUserInfoFailureReason.withLocalizedFailure(.testOriginalLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
// User Info = Description
|
|
|
|
|
|
var nsErrorWithUserInfoDescription = NSError(domain: .testDomain, code: 14, userInfo: [
|
|
|
|
|
|
NSLocalizedDescriptionKey: String.testDebugDescription
|
|
|
|
|
|
])
|
|
|
|
|
|
nsErrorWithUserInfoDescription = nsErrorWithUserInfoDescription.withLocalizedFailure(.testOriginalLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
// User Info = Failure
|
|
|
|
|
|
let nsErrorWithUserInfoFailure = NSError(domain: .testDomain, code: 14, userInfo: [
|
|
|
|
|
|
NSLocalizedFailureErrorKey: String.testOriginalLocalizedFailure
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
// User Info = Failure, Failure Reason
|
|
|
|
|
|
let nsErrorWithUserInfoFailureAndFailureReason = NSError(domain: .testDomain, code: 14, userInfo: [
|
|
|
|
|
|
NSLocalizedFailureErrorKey: String.testOriginalLocalizedFailure,
|
|
|
|
|
|
NSLocalizedFailureReasonErrorKey: String.testUnrecognizedFailureReason
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
// User Info = Failure, Description
|
|
|
|
|
|
let nsErrorWithUserInfoFailureAndDescription = NSError(domain: .testDomain, code: 14, userInfo: [
|
|
|
|
|
|
NSLocalizedFailureErrorKey: String.testOriginalLocalizedFailure,
|
|
|
|
|
|
NSLocalizedDescriptionKey: String.testDebugDescription
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
let errors = [nsErrorWithNoUserInfo, nsErrorWithUserInfoFailureReason, nsErrorWithUserInfoDescription, nsErrorWithUserInfoFailure, nsErrorWithUserInfoFailureAndFailureReason, nsErrorWithUserInfoFailureAndDescription]
|
|
|
|
|
|
for nsError in [errors[0]]
|
|
|
|
|
|
{
|
|
|
|
|
|
let provider = [NSLocalizedFailureReasonErrorKey: String.testUnrecognizedFailureReason]
|
|
|
|
|
|
|
|
|
|
|
|
// Use provider only if user info doesn't contain failure reason or localized description.
|
|
|
|
|
|
let serverProvider = (nsError.userInfo.keys.contains(NSLocalizedFailureReasonErrorKey) || nsError.userInfo.keys.contains(NSLocalizedDescriptionKey)) ? nil : provider
|
|
|
|
|
|
let baseDescription = serverProvider?[NSLocalizedFailureReasonErrorKey] ?? nsError.localizedFailureReason ?? .testDebugDescription
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(nsError, serverProvider: serverProvider)
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == .testOriginalLocalizedFailure
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedFailure, .testOriginalLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedNSError = (receivedError as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == .testLocalizedFailure
|
|
|
|
|
|
// Description == Failure + baseDescription
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedNSError, failure: .testLocalizedFailure, baseDescription: baseDescription)
|
|
|
|
|
|
|
|
|
|
|
|
let underlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedNSError, nsError, ignoring: [NSLocalizedFailureReasonErrorKey, NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey])
|
|
|
|
|
|
|
|
|
|
|
|
// Underlying Failure == .testOriginalLocalizedFailure
|
|
|
|
|
|
// Underlying Description == Underlying Failure + baseDescription
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(underlyingError, failure: .testOriginalLocalizedFailure, baseDescription: serverProvider?[NSLocalizedFailureReasonErrorKey] ?? nsError.localizedFailureReason ?? .testDebugDescription)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension AltTests
|
|
|
|
|
|
{
|
|
|
|
|
|
func testReceivingUnrecognizedAltServerError() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTServerError(.init(rawValue: -27)!) /* Alien Invasion */
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(error, serverProvider: [
|
|
|
|
|
|
NSLocalizedFailureReasonErrorKey: .testUnrecognizedFailureReason,
|
|
|
|
|
|
NSLocalizedRecoverySuggestionErrorKey: .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
// Description == .testUnrecognizedFailureReason
|
|
|
|
|
|
// Failure Reason == .testUnrecognizedFailureReason
|
|
|
|
|
|
// Recovery Suggestion == .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedFailureReason, .testUnrecognizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedRecoverySuggestion, .testUnrecognizedRecoverySuggestion)
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedError, failure: nil, baseDescription: .testUnrecognizedFailureReason)
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedError, error, ignoring: [NSLocalizedFailureReasonErrorKey, NSLocalizedRecoverySuggestionErrorKey, NSLocalizedDescriptionKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingUnrecognizedAltServerErrorWithLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTServerError(.init(rawValue: -27)!) /* Alien Invasion */
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(nsError, serverProvider: [
|
|
|
|
|
|
NSLocalizedFailureReasonErrorKey: .testUnrecognizedFailureReason,
|
|
|
|
|
|
NSLocalizedRecoverySuggestionErrorKey: .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == .testLocalizedFailure
|
|
|
|
|
|
// Description == Failure + .testUnrecognizedFailureReason
|
|
|
|
|
|
// Failure Reason == .testUnrecognizedFailureReason
|
|
|
|
|
|
// Recovery Suggestion == .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedError, failure: .testLocalizedFailure, baseDescription: .testUnrecognizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedFailureReason, .testUnrecognizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedRecoverySuggestion, .testUnrecognizedRecoverySuggestion)
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedError, nsError, ignoring: [NSLocalizedFailureReasonErrorKey, NSLocalizedRecoverySuggestionErrorKey, NSLocalizedDescriptionKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingUnrecognizedAltServerErrorWithLocalizedTitle() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTServerError(.init(rawValue: -27)!) /* Alien Invasion */
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedTitle(.testLocalizedTitle)
|
|
|
|
|
|
let referenceError = nsError.serialized(provider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(nsError, serverProvider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
// Title == .testLocalizedTitle
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedTitle, .testLocalizedTitle)
|
|
|
|
|
|
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedError, referenceError)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingUnrecognizedAltServerErrorThenAddingLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTServerError(.init(rawValue: -27)!) /* Alien Invasion */
|
|
|
|
|
|
let serializedError = (error as NSError).serialized(provider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(error, serverProvider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == nil
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedFailure, nil)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedNSError = receivedError.withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == .testLocalizedFailure
|
|
|
|
|
|
// Description == Failure + .testUnrecognizedFailureReason
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedNSError, failure: .testLocalizedFailure, baseDescription: .testUnrecognizedFailureReason)
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedNSError, serializedError, ignoring: [NSLocalizedFailureErrorKey, NSLocalizedDescriptionKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingUnrecognizedAltServerErrorThenAddingLocalizedTitle() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTServerError(.init(rawValue: -27)!) /* Alien Invasion */
|
|
|
|
|
|
let serializedError = error.serialized(provider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(error, serverProvider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
// Title == nil
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedTitle, nil)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedNSError = receivedError.withLocalizedTitle(.testLocalizedTitle)
|
|
|
|
|
|
|
|
|
|
|
|
// Title == .testLocalizedTitle
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedNSError, serializedError, ignoring: [ALTLocalizedTitleErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingUnrecognizedAltServerErrorWithLocalizedFailureThenChangingLocalizedFailure() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTServerError(.init(rawValue: -27)!) /* Alien Invasion */
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testOriginalLocalizedFailure)
|
|
|
|
|
|
let serializedError = nsError.serialized(provider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(nsError, serverProvider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == .testOriginalLocalizedFailure
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedFailure, .testOriginalLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedNSError = receivedError.withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == .testLocalizedFailure
|
|
|
|
|
|
// Description == Failure + .testUnrecognizedFailureReason
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedNSError, failure: .testLocalizedFailure, baseDescription: .testUnrecognizedFailureReason)
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedNSError, serializedError, ignoring: [NSLocalizedFailureErrorKey, NSLocalizedDescriptionKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension AltTests
|
|
|
|
|
|
{
|
|
|
|
|
|
func testReceivingAltServerErrorWithDifferentErrorMessages() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTServerError(.pluginNotFound)
|
|
|
|
|
|
let serializedError = error.serialized(provider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(error, serverProvider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
// Description == error.localizedDescription (not .testUnrecognizedFailureReason)
|
|
|
|
|
|
// Failure Reason == error.localizedFailureReason (not .testUnrecognizedFailureReason)
|
|
|
|
|
|
// Recovery Suggestion == error.recoverySuggestion (not .testUnrecognizedRecoverySuggestion)
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedDescription, error.localizedDescription)
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedFailureReason, (error as NSError).localizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedRecoverySuggestion, (error as NSError).localizedRecoverySuggestion)
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedError, serializedError, ignoring: [NSLocalizedDescriptionKey, NSLocalizedFailureReasonErrorKey, NSLocalizedRecoverySuggestionErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testReceivingAltServerErrorWithLocalizedFailureAndDifferentErrorMessages() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTServerError(.pluginNotFound)
|
|
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
let serializedError = nsError.serialized(provider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(nsError, serverProvider: .unrecognizedProvider)
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == .testLocalizedFailure
|
|
|
|
|
|
// Description == Failure + error.localizedFailureReason (not .testUnrecognizedFailureReason)
|
|
|
|
|
|
// Failure Reason == error.localizedFailureReason (not .testUnrecognizedFailureReason)
|
|
|
|
|
|
// Recovery Suggestion == error.recoverySuggestion (not .testUnrecognizedRecoverySuggestion)
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(receivedError, failure: .testLocalizedFailure, baseDescription: try XCTUnwrap(nsError.localizedFailureReason))
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedFailureReason, (error as NSError).localizedFailureReason)
|
|
|
|
|
|
XCTAssertEqual(receivedError.localizedRecoverySuggestion, (error as NSError).localizedRecoverySuggestion)
|
|
|
|
|
|
ALTAssertErrorsEqual(receivedError, serializedError, ignoring: [NSLocalizedDescriptionKey, NSLocalizedFailureErrorKey, NSLocalizedFailureReasonErrorKey, NSLocalizedRecoverySuggestionErrorKey])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension AltTests
|
|
|
|
|
|
{
|
|
|
|
|
|
func testReceivingUnrecognizedAltServerErrorThenAddingLocalizedFailureBeforeSerializing() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let error = ALTServerError(.init(rawValue: -27)!) /* Alien Invasion */
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(error, serverProvider: .unrecognizedProvider)
|
|
|
|
|
|
let receivedNSError = receivedError.withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let serializedError = receivedNSError.sanitizedForSerialization()
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == .testLocalizedFailure
|
|
|
|
|
|
// Description == Failure + .testUnrecognizedFailureReason
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(serializedError, failure: .testLocalizedFailure, baseDescription: .testUnrecognizedFailureReason)
|
|
|
|
|
|
|
|
|
|
|
|
// Failure Reason == .testUnrecognizedFailureReason
|
|
|
|
|
|
// Recovery Suggestion == .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
ALTAssertErrorsEqual(serializedError, receivedNSError, ignoring: [])
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testAddingLocalizedFailureThenSerializing() async throws
|
|
|
|
|
|
{
|
2023-03-01 14:07:04 -06:00
|
|
|
|
let error = CocoaError(.fileReadNoSuchFile, userInfo: [NSURLErrorKey: URL(fileURLWithPath: "~/Users/rileytestut/delta")])
|
2022-11-07 16:47:23 -06:00
|
|
|
|
let nsError = (error as NSError).withLocalizedFailure(.testOriginalLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(nsError)
|
|
|
|
|
|
let receivedNSError = receivedError.withLocalizedFailure(.testLocalizedFailure)
|
|
|
|
|
|
|
|
|
|
|
|
let serializedError = receivedNSError.sanitizedForSerialization()
|
|
|
|
|
|
|
|
|
|
|
|
// Failure == .testLocalizedFailure
|
|
|
|
|
|
// Description == Failure + .testUnrecognizedFailureReason
|
|
|
|
|
|
ALTAssertErrorFailureAndDescription(serializedError, failure: .testLocalizedFailure, baseDescription: try XCTUnwrap(nsError.localizedFailureReason))
|
|
|
|
|
|
|
|
|
|
|
|
// Failure Reason == .testUnrecognizedFailureReason
|
|
|
|
|
|
// Recovery Suggestion == .testUnrecognizedRecoverySuggestion
|
|
|
|
|
|
ALTAssertErrorsEqual(serializedError, receivedNSError, ignoring: [])
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testSerializingUserInfoValues() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
let userInfo = [
|
|
|
|
|
|
"RSTString": "test",
|
|
|
|
|
|
"RSTNumber": -1 as Int,
|
|
|
|
|
|
"RSTUnsignedNumber": 2 as UInt,
|
|
|
|
|
|
// "RSTURL": URL(string: "https://rileytestut.com")!, // URLs get converted to Strings
|
|
|
|
|
|
"RSTArray": [1, "test"],
|
|
|
|
|
|
"RSTDictionary": ["key1": 11, "key2": "string"]
|
|
|
|
|
|
] as [String: Any]
|
|
|
|
|
|
|
|
|
|
|
|
let error = NSError(domain: .testDomain, code: 17, userInfo: userInfo)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(error)
|
|
|
|
|
|
let receivedUnderlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedError, error)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedUserInfo = receivedUnderlyingError.userInfo.filter { $0.key != NSLocalizedDescriptionKey } // Remove added NSLocalizedDescription value for unrecognized error.
|
|
|
|
|
|
|
|
|
|
|
|
// let receivedURLString = try XCTUnwrap(receivedUserInfo["RSTURL"] as? String)
|
|
|
|
|
|
// receivedUserInfo["RSTURL"] = URL(string: receivedURLString)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertEqual(receivedUserInfo as NSDictionary, userInfo as NSDictionary)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func testSerializingNonCodableUserInfoValues() async throws
|
|
|
|
|
|
{
|
|
|
|
|
|
struct MyStruct
|
|
|
|
|
|
{
|
|
|
|
|
|
var property = 1
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let userInfo = [
|
|
|
|
|
|
"MyStruct": MyStruct(),
|
|
|
|
|
|
"RSTDictionary": ["key": MyStruct()],
|
|
|
|
|
|
"RSTArray": [MyStruct()],
|
|
|
|
|
|
] as [String : Any]
|
|
|
|
|
|
|
|
|
|
|
|
let error = NSError(domain: .testDomain, code: 17, userInfo: userInfo)
|
|
|
|
|
|
|
|
|
|
|
|
let receivedError = try self.send(error)
|
|
|
|
|
|
let receivedUnderlyingError = try ALTAssertUnderlyingErrorEqualsError(receivedError, error, ignoreExtraUserInfoValues: true)
|
|
|
|
|
|
|
|
|
|
|
|
XCTAssertNil(receivedUnderlyingError.userInfo["MyStruct"])
|
|
|
|
|
|
XCTAssertFalse(receivedUnderlyingError.userInfo.keys.contains("MyStruct"))
|
|
|
|
|
|
|
|
|
|
|
|
let dictionary = try XCTUnwrap(receivedUnderlyingError.userInfo["RSTDictionary"] as? [String: Any])
|
|
|
|
|
|
XCTAssertNil(dictionary["key"])
|
|
|
|
|
|
XCTAssertFalse(dictionary.keys.contains("key"))
|
|
|
|
|
|
|
|
|
|
|
|
let array = try XCTUnwrap(receivedUnderlyingError.userInfo["RSTArray"] as? [Any])
|
|
|
|
|
|
XCTAssert(array.isEmpty)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|