amplify-swift/AmplifyTests/CoreTests/AmplifyTaskTests.swift

190 lines
5.4 KiB
Swift

//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
import XCTest
#if canImport(Combine)
import Combine
#endif
@testable import Amplify
@testable import AmplifyTestCommon
class AmplifyTaskTests: XCTestCase {
let queue = OperationQueue()
func testFastOperation() async throws {
let input = [1, 2, 3]
var output: Int = 0
var thrown: Error? = nil
do {
let request = FastOperationRequest(numbers: input)
let result = try await runFastOperation(request: request)
output = result.value
} catch {
thrown = error
}
XCTAssertEqual(input.sum(), output)
XCTAssertNil(thrown)
}
#if canImport(Combine)
func testFastOperationWithPublisher() throws {
let exp1 = expectation(description: "\(#function)-1")
let exp2 = expectation(description: "\(#function)-2")
let input = [1, 2, 3]
var output: Int = 0
var thrown: Error? = nil
let request = FastOperationRequest(numbers: input)
let publisher = runFastOperationWithPublisher(request: request)
let sink = publisher.sink { completion in
switch completion {
case .failure(let error):
thrown = error
case .finished:
exp1.fulfill()
}
} receiveValue: { result in
output = result.value
exp2.fulfill()
}
defer {
sink.cancel()
}
wait(for: [exp1, exp2], timeout: 5.0)
XCTAssertEqual(input.sum(), output)
XCTAssertNil(thrown)
}
#endif
func testLongOperation() async throws {
var success = false
var output: String? = nil
var thrown: Error? = nil
let request = LongOperationRequest(steps: 10, delay: 0.01)
let longTask = await runLongOperation(request: request)
Task {
var progressCount = 0
var lastProgress: Double = 0
await longTask.progress.forEach { progress in
lastProgress = progress.fractionCompleted
progressCount += 1
}
XCTAssertEqual(progressCount, 11)
XCTAssertEqual(lastProgress, 100)
}
do {
let value = try await longTask.value
output = value.id
success = true
} catch {
thrown = error
}
XCTAssertTrue(success)
XCTAssertNotNil(output)
XCTAssertFalse(output.isEmpty)
XCTAssertNil(thrown)
}
#if canImport(Combine)
func testLongOperationWithPublishers() async throws {
let exp1 = expectation(description: "\(#function)-1")
let exp2 = expectation(description: "\(#function)-2")
var success = false
var output: String? = nil
var thrown: Error? = nil
var requestID: String? = nil
var progressCount = 0
var lastProgress: Double = 0
let request = LongOperationRequest(steps: 10, delay: 0.01)
let longTask = await runLongOperation(request: request)
let progressPublisher = longTask.inProcessPublisher
let resultPublisher = longTask.resultPublisher
let progressSink = progressPublisher.sink { completion in
switch completion {
case .failure:
break
case .finished:
exp1.fulfill()
}
} receiveValue: { progress in
lastProgress = progress.fractionCompleted
progressCount += 1
}
defer {
progressSink.cancel()
}
let resultSink = resultPublisher.sink { completion in
switch completion {
case .failure(let error):
thrown = error
case .finished:
success = true
}
} receiveValue: { result in
output = result.id
requestID = longTask.requestID
exp2.fulfill()
}
defer {
resultSink.cancel()
}
wait(for: [exp1, exp2], timeout: 10.0)
XCTAssertGreaterThanOrEqual(progressCount, 10)
XCTAssertEqual(lastProgress, 1)
XCTAssertTrue(success)
XCTAssertNotNil(output)
XCTAssertFalse(output.isEmpty)
XCTAssertNil(thrown)
XCTAssertFalse(requestID.isEmpty)
XCTAssertEqual(request.requestID, requestID)
}
#endif
private func runFastOperation(request: FastOperationRequest) async throws -> FastTask.Success {
let operation = FastOperation(request: request)
let taskAdapter = AmplifyOperationTaskAdapter(operation: operation)
queue.addOperation(operation)
return try await taskAdapter.value
}
private func runLongOperation(request: LongOperationRequest) async -> LongTask {
let operation = LongOperation(request: request)
let taskAdapter = AmplifyInProcessReportingOperationTaskAdapter(operation: operation)
queue.addOperation(operation)
return taskAdapter
}
private func runFastOperationWithPublisher(request: FastOperationRequest) -> FastResultPublisher {
let operation = FastOperation(request: request)
let taskAdapter = AmplifyOperationTaskAdapter(operation: operation)
let resultPublisher = taskAdapter.resultPublisher
queue.addOperation(operation)
return resultPublisher
}
}