amplify-swift/AmplifyTests/CoreTests/InternalTaskTests.swift

251 lines
8.0 KiB
Swift

//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
import Foundation
import XCTest
@testable import Amplify
@testable import AmplifyTestCommon
@_implementationOnly import AmplifyAsyncTesting
class InternalTaskTests: XCTestCase {
override func setUp() async throws {
await Amplify.reset()
}
// MARK: - Magic Eight Ball (Non-Throwing) -
func testMagicEightBallTaskRunner() async throws {
let done = asyncExpectation(description: "done")
let delay = 0.01
let total = 10
let timeout = Double(total) * 2.0 * delay
let request = MagicEightBallRequest(total: total, delay: delay)
let runner = MagicEightBallTaskRunner(request: request)
let task = Task<[String], Never> {
let hubDone = asyncExpectation(description: "hub done")
var emojis = [String]()
var hubValues = [String]()
let token = runner.subscribe { emoji in
hubValues.append(emoji)
if hubValues.count == total {
Task {
await hubDone.fulfill()
}
}
}
await runner.sequence.forEach { emoji in
emojis.append(emoji)
}
await waitForExpectations([hubDone])
await done.fulfill()
XCTAssertEqual(total, hubValues.count)
XCTAssertEqual(total, emojis.count)
runner.unsubscribe(token)
return emojis
}
let output = await task.value
XCTAssertEqual(request.total, output.count)
await waitForExpectations([done], timeout: timeout)
}
func testMagicEightBallTaskRunnerWithRunnerCancellation() async throws {
let done = asyncExpectation(description: "done")
let delay = 0.01
let total = 10
let timeout = Double(total) * 2.0 * delay
let request = MagicEightBallRequest(total: total, delay: delay)
let runner = MagicEightBallTaskRunner(request: request)
// must retain sequence because it is the only strong reference
let sequence = runner.sequence
let task = Task<[String], Never> {
var emojis = [String]()
await sequence.forEach { emoji in
emojis.append(emoji)
}
await done.fulfill()
XCTAssertEqual(0, emojis.count)
return emojis
}
runner.cancel()
let output = await task.value
XCTAssertEqual(0, output.count)
await waitForExpectations([done], timeout: timeout)
}
func testMagicEightBallTaskRunnerWithSequenceCancellation() async throws {
let done = asyncExpectation(description: "done")
let delay = 0.01
let total = 10
let timeout = Double(total) * 2.0 * delay
let request = MagicEightBallRequest(total: total, delay: delay)
let runner = MagicEightBallTaskRunner(request: request)
let task = Task<[String], Never> {
var emojis = [String]()
let sequence = runner.sequence
sequence.cancel()
await sequence.forEach { emoji in
emojis.append(emoji)
}
await done.fulfill()
XCTAssertEqual(0, emojis.count)
return emojis
}
let output = await task.value
XCTAssertEqual(0, output.count)
await waitForExpectations([done], timeout: timeout)
}
func testMagicEightBallPluginAPI() async throws {
let done = asyncExpectation(description: "done")
let total = 10
let delay = 0.01
let timeout = Double(total) * 2.0 * delay
let plugin = MagicEightBallPlugin()
let task = Task<[String], Never> {
var answers = [String]()
await plugin.getAnswers(total: total, delay: delay).forEach { emoji in
answers.append(emoji)
}
await done.fulfill()
XCTAssertEqual(total, answers.count)
return answers
}
let answers = await task.value
XCTAssertEqual(answers.count, total)
await waitForExpectations([done], timeout: timeout)
}
// MARK: - Random Emoji (Throwing) -
func testRandomEmojiTaskRunner() async throws {
let done = asyncExpectation(description: "done")
let delay = 0.01
let total = 10
let timeout = Double(total) * 2.0 * delay
let request = RandomEmojiRequest(total: total, delay: delay)
let runner = RandomEmojiTaskRunner(request: request)
let task = Task<[String], Never> {
var emojis = [String]()
var thrown: Error?
do {
try await runner.sequence.forEach { emoji in
emojis.append(emoji)
}
await done.fulfill()
XCTAssertEqual(total, emojis.count)
} catch {
thrown = error
}
XCTAssertNil(thrown)
return emojis
}
let output = await task.value
XCTAssertEqual(request.total, output.count)
await waitForExpectations([done], timeout: timeout)
}
func testRandomEmojiTaskRunnerWithRunnerCancellation() async throws {
let done = asyncExpectation(description: "done")
let delay = 0.01
let total = 10
let timeout = Double(total) * 2.0 * delay
let request = RandomEmojiRequest(total: total, delay: delay)
let runner = RandomEmojiTaskRunner(request: request)
// must retain sequence because it is the only strong reference
let sequence = runner.sequence
let task = Task<[String], Never> {
var emojis = [String]()
var thrown: Error?
do {
try await sequence.forEach { emoji in
emojis.append(emoji)
}
await done.fulfill()
XCTAssertEqual(0, emojis.count)
} catch {
thrown = error
}
XCTAssertNil(thrown)
return emojis
}
runner.cancel()
let output = await task.value
XCTAssertEqual(0, output.count)
await waitForExpectations([done], timeout: timeout)
}
func testRandomEmojiTaskRunnerWithSequenceCancellation() async throws {
let done = asyncExpectation(description: "done")
let delay = 0.01
let total = 10
let timeout = Double(total) * 2.0 * delay
let request = RandomEmojiRequest(total: total, delay: delay)
let runner = RandomEmojiTaskRunner(request: request)
let task = Task<[String], Never> {
var emojis = [String]()
var thrown: Error?
do {
let sequence = runner.sequence
sequence.cancel()
try await sequence.forEach { emoji in
emojis.append(emoji)
}
await done.fulfill()
XCTAssertEqual(0, emojis.count)
} catch {
thrown = error
}
XCTAssertNil(thrown)
return emojis
}
let output = await task.value
XCTAssertEqual(0, output.count)
await waitForExpectations([done], timeout: timeout)
}
func testEmojisPluginAPI() async throws {
let done = asyncExpectation(description: "done")
let total = 10
let delay = 0.01
let timeout = Double(total) * 2.0 * delay
let plugin = EmojisPlugin()
let task = Task<[String], Error> {
var emojis = [String]()
try await plugin.getEmojis(total: total, delay: delay).forEach { emoji in
emojis.append(emoji)
}
await done.fulfill()
XCTAssertEqual(total, emojis.count)
return emojis
}
let emojis = try await task.value
XCTAssertEqual(emojis.count, total)
await waitForExpectations([done], timeout: timeout)
}
}