288 lines
9.9 KiB
Swift
288 lines
9.9 KiB
Swift
//
|
|
// Copyright Amazon.com Inc. or its affiliates.
|
|
// All Rights Reserved.
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
#if canImport(Combine)
|
|
import XCTest
|
|
import Combine
|
|
|
|
@testable import Amplify
|
|
@testable import AmplifyTestCommon
|
|
|
|
class AmplifyOperationCombineTests: XCTestCase {
|
|
|
|
func testResultPublisherSucceeds() {
|
|
let responder: MockPublisherOperation.Responder = { operation in
|
|
operation.dispatch(result: .success(1))
|
|
operation.finish()
|
|
}
|
|
|
|
let receivedValue = expectation(description: "Received value")
|
|
let receivedFinished = expectation(description: "Received finished")
|
|
let receivedFailure = expectation(description: "Received failure")
|
|
receivedFailure.isInverted = true
|
|
|
|
let operation = MockPublisherOperation(responder: responder)
|
|
let sink = operation
|
|
.internalResultPublisher
|
|
.sink(receiveCompletion: { completion in
|
|
switch completion {
|
|
case .failure:
|
|
receivedFailure.fulfill()
|
|
case .finished:
|
|
receivedFinished.fulfill()
|
|
}
|
|
}, receiveValue: { _ in
|
|
receivedValue.fulfill()
|
|
})
|
|
|
|
operation.main()
|
|
|
|
waitForExpectations(timeout: 0.05)
|
|
sink.cancel()
|
|
}
|
|
|
|
func testResultPublisherFails() {
|
|
let responder: MockPublisherOperation.Responder = { operation in
|
|
operation.dispatch(result: .failure(.unknown("Test", "Test")))
|
|
operation.finish()
|
|
}
|
|
|
|
let receivedValue = expectation(description: "Received value")
|
|
receivedValue.isInverted = true
|
|
let receivedFinished = expectation(description: "Received finished")
|
|
receivedFinished.isInverted = true
|
|
let receivedFailure = expectation(description: "Received failure")
|
|
|
|
let operation = MockPublisherOperation(responder: responder)
|
|
let sink = operation
|
|
.internalResultPublisher
|
|
.sink(receiveCompletion: { completion in
|
|
switch completion {
|
|
case .failure:
|
|
receivedFailure.fulfill()
|
|
case .finished:
|
|
receivedFinished.fulfill()
|
|
}
|
|
}, receiveValue: { _ in
|
|
receivedValue.fulfill()
|
|
})
|
|
|
|
operation.main()
|
|
|
|
waitForExpectations(timeout: 0.05)
|
|
sink.cancel()
|
|
}
|
|
|
|
func testResultPublisherCancels() {
|
|
let responder: MockPublisherOperation.Responder = { operation in
|
|
operation.dispatch(result: .success(1))
|
|
operation.finish()
|
|
}
|
|
|
|
let receivedValue = expectation(description: "Received value")
|
|
receivedValue.isInverted = true
|
|
let receivedFinished = expectation(description: "Received finished")
|
|
let receivedFailure = expectation(description: "Received failure")
|
|
receivedFailure.isInverted = true
|
|
|
|
let operation = MockPublisherOperation(responder: responder)
|
|
let sink = operation
|
|
.internalResultPublisher
|
|
.sink(receiveCompletion: { completion in
|
|
switch completion {
|
|
case .failure:
|
|
receivedFailure.fulfill()
|
|
case .finished:
|
|
receivedFinished.fulfill()
|
|
}
|
|
}, receiveValue: { _ in
|
|
receivedValue.fulfill()
|
|
})
|
|
|
|
operation.cancel()
|
|
|
|
waitForExpectations(timeout: 0.05)
|
|
sink.cancel()
|
|
}
|
|
|
|
func testChainedResultPublishersSucceed() {
|
|
let makeSuccessResponder: (Int) -> MockPublisherOperation.Responder = { value in
|
|
let successResponder: MockPublisherOperation.Responder = { operation in
|
|
operation.dispatch(result: .success(value))
|
|
operation.finish()
|
|
}
|
|
return successResponder
|
|
}
|
|
|
|
let receivedValue = expectation(description: "Received value")
|
|
let receivedFinished = expectation(description: "Received finished")
|
|
let receivedFailure = expectation(description: "Received failure")
|
|
receivedFailure.isInverted = true
|
|
|
|
let mockOp1 = MockPublisherOperation(responder: makeSuccessResponder(1))
|
|
let mockOp2 = MockPublisherOperation(responder: makeSuccessResponder(2))
|
|
|
|
let sink = Publishers.Zip(
|
|
mockOp1.internalResultPublisher,
|
|
mockOp2.internalResultPublisher
|
|
).flatMap { (value1: Int, value2: Int) -> AnyPublisher<Int, APIError> in
|
|
let mockOp = MockPublisherOperation(responder: makeSuccessResponder(value1 + value2))
|
|
mockOp.main()
|
|
return mockOp.internalResultPublisher
|
|
}.flatMap { (value: Int) -> AnyPublisher<Int, APIError> in
|
|
let mockOp = MockPublisherOperation(responder: makeSuccessResponder(value + 1))
|
|
mockOp.main()
|
|
return mockOp.internalResultPublisher
|
|
}.sink(receiveCompletion: { completion in
|
|
switch completion {
|
|
case .failure:
|
|
receivedFailure.fulfill()
|
|
case .finished:
|
|
receivedFinished.fulfill()
|
|
}
|
|
}, receiveValue: { _ in
|
|
receivedValue.fulfill()
|
|
})
|
|
|
|
mockOp1.main()
|
|
mockOp2.main()
|
|
|
|
waitForExpectations(timeout: 0.05)
|
|
sink.cancel()
|
|
}
|
|
|
|
func testChainedResultPublishersFail() {
|
|
let makeSuccessResponder: (Int) -> MockPublisherOperation.Responder = { value in
|
|
let successResponder: MockPublisherOperation.Responder = { operation in
|
|
operation.dispatch(result: .success(value))
|
|
operation.finish()
|
|
}
|
|
return successResponder
|
|
}
|
|
|
|
let failureResponder: MockPublisherOperation.Responder = { operation in
|
|
operation.dispatch(result: .failure(.unknown("Test", "Test")))
|
|
operation.finish()
|
|
}
|
|
|
|
let receivedValue = expectation(description: "Received value")
|
|
receivedValue.isInverted = true
|
|
let receivedFinished = expectation(description: "Received finished")
|
|
receivedFinished.isInverted = true
|
|
let receivedFailure = expectation(description: "Received failure")
|
|
|
|
let mockOp1 = MockPublisherOperation(responder: makeSuccessResponder(1))
|
|
let mockOp2 = MockPublisherOperation(responder: makeSuccessResponder(2))
|
|
|
|
let sink = Publishers.Zip(
|
|
mockOp1.internalResultPublisher,
|
|
mockOp2.internalResultPublisher
|
|
).flatMap { (_, _) -> AnyPublisher<Int, APIError> in
|
|
let mockOp = MockPublisherOperation(responder: failureResponder)
|
|
mockOp.main()
|
|
return mockOp.internalResultPublisher
|
|
}.flatMap { (value: Int) -> AnyPublisher<Int, APIError> in
|
|
let mockOp = MockPublisherOperation(responder: makeSuccessResponder(value + 1))
|
|
mockOp.main()
|
|
return mockOp.internalResultPublisher
|
|
}.sink(receiveCompletion: { completion in
|
|
switch completion {
|
|
case .failure:
|
|
receivedFailure.fulfill()
|
|
case .finished:
|
|
receivedFinished.fulfill()
|
|
}
|
|
}, receiveValue: { _ in
|
|
receivedValue.fulfill()
|
|
})
|
|
|
|
mockOp1.main()
|
|
mockOp2.main()
|
|
|
|
waitForExpectations(timeout: 0.05)
|
|
sink.cancel()
|
|
}
|
|
|
|
func testChainedResultPublishersCancel() {
|
|
let makeSuccessResponder: (Int) -> MockPublisherOperation.Responder = { value in
|
|
let successResponder: MockPublisherOperation.Responder = { operation in
|
|
operation.dispatch(result: .success(value))
|
|
operation.finish()
|
|
}
|
|
return successResponder
|
|
}
|
|
|
|
let receivedValue = expectation(description: "Received value")
|
|
receivedValue.isInverted = true
|
|
let receivedFinished = expectation(description: "Received finished")
|
|
let receivedFailure = expectation(description: "Received failure")
|
|
receivedFailure.isInverted = true
|
|
|
|
let mockOp1 = MockPublisherOperation(responder: makeSuccessResponder(1))
|
|
let mockOp2 = MockPublisherOperation(responder: makeSuccessResponder(2))
|
|
|
|
let sink = Publishers.Zip(
|
|
mockOp1.internalResultPublisher,
|
|
mockOp2.internalResultPublisher
|
|
).flatMap { (value1: Int, value2: Int) -> AnyPublisher<Int, APIError> in
|
|
let mockOp = MockPublisherOperation(responder: makeSuccessResponder(value1 + value2))
|
|
mockOp.cancel()
|
|
return mockOp.internalResultPublisher
|
|
}.flatMap { (value: Int) -> AnyPublisher<Int, APIError> in
|
|
let mockOp = MockPublisherOperation(responder: makeSuccessResponder(value + 1))
|
|
mockOp.main()
|
|
return mockOp.internalResultPublisher
|
|
}.sink(receiveCompletion: { completion in
|
|
switch completion {
|
|
case .failure:
|
|
receivedFailure.fulfill()
|
|
case .finished:
|
|
receivedFinished.fulfill()
|
|
}
|
|
}, receiveValue: { _ in
|
|
receivedValue.fulfill()
|
|
})
|
|
|
|
mockOp1.main()
|
|
mockOp2.main()
|
|
|
|
waitForExpectations(timeout: 0.05)
|
|
sink.cancel()
|
|
}
|
|
|
|
}
|
|
|
|
struct MockPublisherRequest: AmplifyOperationRequest {
|
|
struct Options { }
|
|
let options = Options()
|
|
}
|
|
|
|
extension HubPayloadEventName {
|
|
static var mockPublisherOperation = "MockPublisherOperation"
|
|
}
|
|
|
|
class MockPublisherOperation: AmplifyOperation<MockPublisherRequest, Int, APIError> {
|
|
typealias Responder = (MockPublisherOperation) -> Void
|
|
let responder: Responder
|
|
|
|
init(responder: @escaping Responder, resultListener: ResultListener? = nil) {
|
|
self.responder = responder
|
|
super.init(
|
|
categoryType: .api,
|
|
eventName: .mockPublisherOperation,
|
|
request: MockPublisherRequest(),
|
|
resultListener: resultListener
|
|
)
|
|
}
|
|
|
|
override func main() {
|
|
self.responder(self)
|
|
}
|
|
|
|
}
|
|
#endif
|