Skip to content

Commit

Permalink
ci: disable OperationQueue tests on non-macos platforms (#5)
Browse files Browse the repository at this point in the history
* ci: fix test failure

* ci: fix rounding off errors for tests

* ci: cancel underlying task on deinit of operation

* ci: disable `OperationQueue` tests on non-macos platform
  • Loading branch information
soumyamahunt authored Aug 25, 2022
1 parent 9a852d9 commit 81c2c9c
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 15 deletions.
1 change: 1 addition & 0 deletions Sources/AsyncObjects/CancellationSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ public actor CancellationSource {
/// and propagate cancellation to linked cancellation sources.
///
/// - Parameter nanoseconds: The delay after which cancellation event triggered.
/// - Throws: `CancellationError` if cancelled.
@Sendable
public func cancel(afterNanoseconds nanoseconds: UInt64) async throws {
try await Task.sleep(nanoseconds: nanoseconds)
Expand Down
2 changes: 2 additions & 0 deletions Sources/AsyncObjects/Future.swift
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ extension Future where Failure == Error {
/// Immediately returns if `Future` is fulfilled otherwise waits asynchronously
/// for `Future` to be fulfilled. If the Future terminates with an error,
/// the awaiting caller receives the error instead.
///
/// - Throws: If future rejected with error or `CancellationError` if cancelled.
public var value: Output {
get async throws {
if let result = result { return try result.get() }
Expand Down
1 change: 1 addition & 0 deletions Sources/AsyncObjects/Locker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public final class Locker: Equatable, Hashable, Sendable {
///
/// - Parameter critical: The critical task to perform.
/// - Returns: The result from the critical task.
/// - Throws: Error occurred running critical task.
@discardableResult
public func perform<R>(_ critical: () throws -> R) rethrows -> R {
lock()
Expand Down
7 changes: 1 addition & 6 deletions Sources/AsyncObjects/TaskOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,6 @@ public final class TaskOperation<R: Sendable>: Operation, AsyncObject,
/// - operation: The asynchronous operation to execute.
///
/// - Returns: The newly created asynchronous operation.
///
/// - Important: When specifying to track child tasks to true,
/// be sure that you aren't keeping strong reference
/// to ``TaskTracker/current`` inside your asynchronous operation.
/// Otherwise, operation won't complete as soon asynchronous operation
/// and their child tasks complete.
public init(
trackChildTasks shouldTrackChildTasks: Bool = false,
synchronizedWith locker: Locker = .init(),
Expand All @@ -134,6 +128,7 @@ public final class TaskOperation<R: Sendable>: Operation, AsyncObject,
}

deinit {
execTask?.cancel()
locker.perform { self.continuations.forEach { $0.value.cancel() } }
}

Expand Down
6 changes: 3 additions & 3 deletions Sources/AsyncObjects/TaskTracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/// Do not keep strong reference of this object, as then object won't
/// deallocate as soon asynchronous operations and their child tasks
/// complete.
public final class TaskTracker: Sendable {
final class TaskTracker: Sendable {
/// The tracker associated with current task.
///
/// Use the `withValue` method to assign a tracker to asynchronous operation.
Expand All @@ -21,7 +21,7 @@ public final class TaskTracker: Sendable {
/// deallocate as soon asynchronous operations and their child tasks
/// complete.
@TaskLocal
public static var current: TaskTracker?
static var current: TaskTracker?

/// The action to complete when task and all its child tasks complete.
private let fire: @Sendable () -> Void
Expand All @@ -39,7 +39,7 @@ public final class TaskTracker: Sendable {
/// Do not keep strong reference of this object, as then object won't
/// deallocate as soon asynchronous operations and their child tasks
/// complete.
public init(onComplete fire: @Sendable @escaping () -> Void) {
init(onComplete fire: @Sendable @escaping () -> Void) {
self.fire = fire
}

Expand Down
3 changes: 2 additions & 1 deletion Tests/AsyncObjectsTests/TaskOperationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Dispatch
@testable import AsyncObjects

class TaskOperationTests: XCTestCase {

#if canImport(Darwin)
func testTaskOperation() async throws {
let queue = OperationQueue()
let operation = TaskOperation {
Expand Down Expand Up @@ -120,6 +120,7 @@ class TaskOperationTests: XCTestCase {
XCTAssertFalse(operation.isExecuting)
XCTAssertTrue(operation.isCancelled)
}
#endif

func testTaskOperationAsyncWait() async throws {
let operation = TaskOperation {
Expand Down
14 changes: 9 additions & 5 deletions Tests/AsyncObjectsTests/XCTestCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ extension XCTestCase {
XCTAssertEqual(
seconds,
Int(
DispatchTime.now().uptimeNanoseconds - time.uptimeNanoseconds
) / Int(1E9)
(Double(
DispatchTime.now().uptimeNanoseconds
- time.uptimeNanoseconds
) / 1E9).rounded(.toNearestOrAwayFromZero)
)
)
}

Expand Down Expand Up @@ -41,10 +44,11 @@ extension XCTestCase {
) async rethrows where R.Bound == Int {
let time = DispatchTime.now()
try await task()
let duration =
Int(
let duration = Int(
(Double(
DispatchTime.now().uptimeNanoseconds - time.uptimeNanoseconds
) / Int(1E9)
) / 1E9).rounded(.toNearestOrAwayFromZero)
)
XCTAssertTrue(
range.contains(duration),
"\(duration) not present in \(range)"
Expand Down

0 comments on commit 81c2c9c

Please sign in to comment.