Skip to content

Commit

Permalink
fix(api): add collection type casting in swift 5.7 (#3602)
Browse files Browse the repository at this point in the history
* fix(api): add collection type casting in swift 5.7

* add unit test cases

* add descriptions to test cases
  • Loading branch information
5d authored Apr 10, 2024
1 parent 68c7eff commit 50e001f
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,31 @@ fileprivate func toAPIError<R: Decodable>(_ errors: [Error], type: R.Type) -> AP
(hasAuthorizationError ? ": \(APIError.UnauthorizedMessageString)" : "")
}

#if swift(<5.8)
if let errors = errors.cast(to: AppSyncRealTimeRequest.Error.self) {
let hasAuthorizationError = errors.contains(where: { $0 == .unauthorized})
return APIError.operationError(
errorDescription(hasAuthorizationError),
"",
errors.first
)
} else if let errors = errors.cast(to: GraphQLError.self) {
let hasAuthorizationError = errors.map(\.extensions)
.compactMap { $0.flatMap { $0["errorType"]?.stringValue } }
.contains(where: { AppSyncErrorType($0) == .unauthorized })
return APIError.operationError(
errorDescription(hasAuthorizationError),
"",
GraphQLResponseError<R>.error(errors)
)
} else {
return APIError.operationError(
errorDescription(),
"",
errors.first
)
}
#else
switch errors {
case let errors as [AppSyncRealTimeRequest.Error]:
let hasAuthorizationError = errors.contains(where: { $0 == .unauthorized})
Expand All @@ -402,5 +427,5 @@ fileprivate func toAPIError<R: Decodable>(_ errors: [Error], type: R.Type) -> AP
errors.first
)
}

#endif
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//


import Foundation

@_spi(AmplifyAPI)
extension Array where Element == Error {
func cast<T>(to type: T.Type) -> [T]? {
self.reduce([]) { partialResult, ele in
if let partialResult, let ele = ele as? T {
return partialResult + [ele]
}
return nil
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//


import XCTest
@testable @_spi(AmplifyAPI) import AWSAPIPlugin

class ArrayWithErrorElementExtensionTests: XCTestCase {

/**
Given: errors with generic protocol type
When: cast to the correct underlying concrete type
Then: successfully casted to underlying concrete type
*/
func testCast_toCorrectErrorType_returnCastedErrorType() {
let errors: [Error] = [
Error1(), Error1(), Error1()
]

let error1s = errors.cast(to: Error1.self)
XCTAssertNotNil(error1s)
XCTAssertTrue(!error1s!.isEmpty)
XCTAssertEqual(errors.count, error1s!.count)
}

/**
Given: errors with generic protocol type
When: cast to the wong underlying concrete type
Then: return nil
*/
func testCast_toWrongErrorType_returnNil() {
let errors: [Error] = [
Error1(), Error1(), Error1()
]

let error2s = errors.cast(to: Error2.self)
XCTAssertNil(error2s)
}

/**
Given: errors with generic protocol type
When: some of the elements failed to cast to the underlying concrete type
Then: return nil
*/

func testCast_partiallyToWrongErrorType_returnNil() {
let errors: [Error] = [
Error2(), Error2(), Error1()
]

let error2s = errors.cast(to: Error2.self)
XCTAssertNil(error2s)
}

struct Error1: Error { }

struct Error2: Error { }
}

0 comments on commit 50e001f

Please sign in to comment.