From 88e24fb80c13a6c1bdd47ff47956348a370576c0 Mon Sep 17 00:00:00 2001 From: Philippe Hausler Date: Wed, 15 Jun 2022 09:29:39 -0700 Subject: [PATCH 1/7] Remove the disable of availability and mark methods as available to clock/instant/duration --- Package.swift | 14 ++------ .../ValidationTest.swift | 4 +++ Tests/AsyncAlgorithmsTests/TestBuffer.swift | 6 ++++ Tests/AsyncAlgorithmsTests/TestChunk.swift | 33 ++++++++++++++++++- Tests/AsyncAlgorithmsTests/TestDebounce.swift | 1 + Tests/AsyncAlgorithmsTests/TestMerge.swift | 2 ++ .../AsyncAlgorithmsTests/TestTaskSelect.swift | 4 +++ Tests/AsyncAlgorithmsTests/TestThrottle.swift | 1 + Tests/AsyncAlgorithmsTests/TestTimer.swift | 1 + .../TestValidationTests.swift | 2 ++ 10 files changed, 55 insertions(+), 13 deletions(-) diff --git a/Package.swift b/Package.swift index afc2378f..c43747c0 100644 --- a/Package.swift +++ b/Package.swift @@ -25,20 +25,10 @@ let package = Package( .systemLibrary(name: "_CAsyncSequenceValidationSupport"), .target( name: "AsyncAlgorithms_XCTest", - dependencies: ["AsyncAlgorithms", "AsyncSequenceValidation"], - swiftSettings: [ - .unsafeFlags([ - "-Xfrontend", "-disable-availability-checking" - ]) - ]), + dependencies: ["AsyncAlgorithms", "AsyncSequenceValidation"]), .testTarget( name: "AsyncAlgorithmsTests", - dependencies: ["AsyncAlgorithms", "AsyncSequenceValidation", "AsyncAlgorithms_XCTest"], - swiftSettings: [ - .unsafeFlags([ - "-Xfrontend", "-disable-availability-checking" - ]) - ]), + dependencies: ["AsyncAlgorithms", "AsyncSequenceValidation", "AsyncAlgorithms_XCTest"]), ] ) diff --git a/Sources/AsyncAlgorithms_XCTest/ValidationTest.swift b/Sources/AsyncAlgorithms_XCTest/ValidationTest.swift index 2a7f5667..70dd514b 100644 --- a/Sources/AsyncAlgorithms_XCTest/ValidationTest.swift +++ b/Sources/AsyncAlgorithms_XCTest/ValidationTest.swift @@ -24,6 +24,7 @@ extension XCTestCase { #endif } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func validate(theme: Theme, expectedFailures: Set, @AsyncSequenceValidationDiagram _ build: (AsyncSequenceValidationDiagram) -> Test, file: StaticString = #file, line: UInt = #line) { var expectations = expectedFailures var result: AsyncSequenceValidationDiagram.ExpectationResult? @@ -62,14 +63,17 @@ extension XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func validate(expectedFailures: Set, @AsyncSequenceValidationDiagram _ build: (AsyncSequenceValidationDiagram) -> Test, file: StaticString = #file, line: UInt = #line) { validate(theme: .ascii, expectedFailures: expectedFailures, build, file: file, line: line) } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) public func validate(theme: Theme, @AsyncSequenceValidationDiagram _ build: (AsyncSequenceValidationDiagram) -> Test, file: StaticString = #file, line: UInt = #line) { validate(theme: theme, expectedFailures: [], build, file: file, line: line) } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) public func validate(@AsyncSequenceValidationDiagram _ build: (AsyncSequenceValidationDiagram) -> Test, file: StaticString = #file, line: UInt = #line) { validate(theme: .ascii, expectedFailures: [], build, file: file, line: line) } diff --git a/Tests/AsyncAlgorithmsTests/TestBuffer.swift b/Tests/AsyncAlgorithmsTests/TestBuffer.swift index d6838203..a488ded3 100644 --- a/Tests/AsyncAlgorithmsTests/TestBuffer.swift +++ b/Tests/AsyncAlgorithmsTests/TestBuffer.swift @@ -431,6 +431,7 @@ final class TestBuffer: XCTestCase { XCTAssertEqual(1, [task1Results, task2Results].compactMap{ $0.1 }.count) } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_bufferingOldest() async { validate { "X-12- 34- 5 |" @@ -439,6 +440,7 @@ final class TestBuffer: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_bufferingOldest_noDrops() async { validate { "X-12 3 4 5 |" @@ -447,6 +449,7 @@ final class TestBuffer: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_bufferingOldest_error() async { validate { "X-12345^" @@ -455,6 +458,7 @@ final class TestBuffer: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_bufferingNewest() async { validate { "X-12- 34 -5|" @@ -463,6 +467,7 @@ final class TestBuffer: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_bufferingNewest_noDrops() async { validate { "X-12 3 4 5 |" @@ -471,6 +476,7 @@ final class TestBuffer: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_bufferingNewest_error() async { validate { "X-12345^" diff --git a/Tests/AsyncAlgorithmsTests/TestChunk.swift b/Tests/AsyncAlgorithmsTests/TestChunk.swift index ba340a80..e785768f 100644 --- a/Tests/AsyncAlgorithmsTests/TestChunk.swift +++ b/Tests/AsyncAlgorithmsTests/TestChunk.swift @@ -22,7 +22,7 @@ func concatCharacters(_ array: [String]) -> String { } final class TestChunk: XCTestCase { - + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signal_equalChunks() { validate { "ABC- DEF- GHI- |" @@ -32,6 +32,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signal_unequalChunks() { validate { "AB- A-ABCDEFGH- |" @@ -41,6 +42,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signal_emptyChunks() { validate { "--1--|" @@ -50,6 +52,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signal_error() { validate { "AB^" @@ -59,6 +62,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signal_unsignaledTrailingChunk() { validate { "111-111|" @@ -68,6 +72,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signalAndCount_signalAlwaysPrevails() { validate { "AB- A-ABCDEFGH- |" @@ -77,6 +82,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signalAndCount_countAlwaysPrevails() { validate { "AB --A-B -|" @@ -86,6 +92,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signalAndCount_countResetsAfterCount() { validate { "ABCDE -ABCDE |" @@ -95,6 +102,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signalAndCount_countResetsAfterSignal() { validate { "AB- ABCDE |" @@ -104,6 +112,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signalAndCount_error() { validate { "ABC^" @@ -113,6 +122,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_time_equalChunks() { validate { "ABC- DEF- GHI- |" @@ -121,6 +131,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_time_unequalChunks() { validate { "AB------ A------- ABCDEFG- |" @@ -129,6 +140,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_time_emptyChunks() { validate { "-- 1- --|" @@ -137,6 +149,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_time_error() { validate { "AB^" @@ -145,6 +158,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_time_unsignaledTrailingChunk() { validate { "111-111|" @@ -153,6 +167,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_timeAndCount_timeAlwaysPrevails() { validate { "AB------ A------- ABCDEFG- |" @@ -161,6 +176,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_timeAndCount_countAlwaysPrevails() { validate { "AB --A-B -|" @@ -169,6 +185,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_timeAndCount_countResetsAfterCount() { validate { "ABCDE --- ABCDE |" @@ -177,6 +194,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_timeAndCount_countResetsAfterSignal() { validate { "AB------ ABCDE |" @@ -185,6 +203,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_timeAndCount_error() { validate { "ABC^" @@ -193,6 +212,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_count() { validate { "ABC DEF |" @@ -201,6 +221,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_count_nonuniformTiming() { validate { "A--B-C --DE-F |" @@ -209,6 +230,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_count_trailingChunk() { validate { "11111|" @@ -217,6 +239,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_count_error() { validate { "AB^" @@ -225,6 +248,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_group() { validate { "ABC def GH ij Kl|" @@ -233,6 +257,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_group_singleValue() { validate { "A----|" @@ -241,6 +266,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_group_singleGroup() { validate { "ABCDE|" @@ -249,6 +275,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_group_error() { validate { "AB^" @@ -257,6 +284,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_projection() { validate { "A'Aa''ab' b'BB''bb' 'cc''CC' |" @@ -265,6 +293,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_projection_singleValue() { validate { "A----|" @@ -273,6 +302,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_projection_singleGroup() { validate { "ABCDE|" @@ -281,6 +311,7 @@ final class TestChunk: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_projection_error() { validate { "Aa^" diff --git a/Tests/AsyncAlgorithmsTests/TestDebounce.swift b/Tests/AsyncAlgorithmsTests/TestDebounce.swift index 27643dfb..49b42507 100644 --- a/Tests/AsyncAlgorithmsTests/TestDebounce.swift +++ b/Tests/AsyncAlgorithmsTests/TestDebounce.swift @@ -12,6 +12,7 @@ import XCTest import AsyncAlgorithms +@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) final class TestDebounce: XCTestCase { func test_delayingValues() { validate { diff --git a/Tests/AsyncAlgorithmsTests/TestMerge.swift b/Tests/AsyncAlgorithmsTests/TestMerge.swift index fe8ae8d8..01571d08 100644 --- a/Tests/AsyncAlgorithmsTests/TestMerge.swift +++ b/Tests/AsyncAlgorithmsTests/TestMerge.swift @@ -123,6 +123,7 @@ final class TestMerge2: XCTestCase { XCTAssertNil(pastEnd) } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_diagram() { validate { "a-c-e-g-|" @@ -310,6 +311,7 @@ final class TestMerge3: XCTestCase { XCTAssertNil(pastEnd) } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_diagram() { validate { "a---e---|" diff --git a/Tests/AsyncAlgorithmsTests/TestTaskSelect.swift b/Tests/AsyncAlgorithmsTests/TestTaskSelect.swift index d054257b..ea0f9657 100644 --- a/Tests/AsyncAlgorithmsTests/TestTaskSelect.swift +++ b/Tests/AsyncAlgorithmsTests/TestTaskSelect.swift @@ -14,6 +14,7 @@ import Dispatch import AsyncAlgorithms final class TestTaskSelect: XCTestCase { + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_first() async { let firstValue = await Task.select(Task { return 1 @@ -24,6 +25,7 @@ final class TestTaskSelect: XCTestCase { XCTAssertEqual(firstValue, 1) } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_second() async { let firstValue = await Task.select(Task { try! await Task.sleep(until: .now + .seconds(2), clock: .continuous) @@ -34,6 +36,7 @@ final class TestTaskSelect: XCTestCase { XCTAssertEqual(firstValue, 2) } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_throwing() async { do { _ = try await Task.select(Task { () async throws -> Int in @@ -48,6 +51,7 @@ final class TestTaskSelect: XCTestCase { } } + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_cancellation() async { let firstReady = expectation(description: "first ready") let secondReady = expectation(description: "second ready") diff --git a/Tests/AsyncAlgorithmsTests/TestThrottle.swift b/Tests/AsyncAlgorithmsTests/TestThrottle.swift index 972f04c1..f2aa9f77 100644 --- a/Tests/AsyncAlgorithmsTests/TestThrottle.swift +++ b/Tests/AsyncAlgorithmsTests/TestThrottle.swift @@ -12,6 +12,7 @@ import XCTest import AsyncAlgorithms +@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) final class TestThrottle: XCTestCase { func test_rate_0() { validate { diff --git a/Tests/AsyncAlgorithmsTests/TestTimer.swift b/Tests/AsyncAlgorithmsTests/TestTimer.swift index 823e7701..398be567 100644 --- a/Tests/AsyncAlgorithmsTests/TestTimer.swift +++ b/Tests/AsyncAlgorithmsTests/TestTimer.swift @@ -13,6 +13,7 @@ import XCTest import AsyncAlgorithms import AsyncSequenceValidation +@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) final class TestTimer: XCTestCase { func test_tick1() { validate { diff --git a/Tests/AsyncAlgorithmsTests/TestValidationTests.swift b/Tests/AsyncAlgorithmsTests/TestValidationTests.swift index f60259c1..442fdeba 100644 --- a/Tests/AsyncAlgorithmsTests/TestValidationTests.swift +++ b/Tests/AsyncAlgorithmsTests/TestValidationTests.swift @@ -14,6 +14,7 @@ import AsyncAlgorithms import AsyncSequenceValidation @testable import AsyncAlgorithms_XCTest +@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) final class TestValidationDiagram: XCTestCase { func test_diagram() { validate { @@ -309,6 +310,7 @@ final class TestValidationDiagram: XCTestCase { } } +@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) struct LaggingAsyncSequence : AsyncSequence { typealias Element = Base.Element From c9465fb197f79e2b6656e75dbb9d990588ad04f0 Mon Sep 17 00:00:00 2001 From: Philippe Hausler Date: Wed, 15 Jun 2022 15:03:07 -0700 Subject: [PATCH 2/7] Rework availability to be more permissive for tests --- .../ValidationTest.swift | 4 -- .../AsyncSequenceValidationDiagram.swift | 1 - Sources/AsyncSequenceValidation/Clock.swift | 24 +++++-- Sources/AsyncSequenceValidation/Event.swift | 1 - .../AsyncSequenceValidation/Expectation.swift | 1 - Sources/AsyncSequenceValidation/Input.swift | 1 - Sources/AsyncSequenceValidation/Job.swift | 1 - .../AsyncSequenceValidation/TaskDriver.swift | 2 - Sources/AsyncSequenceValidation/Test.swift | 6 +- Sources/AsyncSequenceValidation/Theme.swift | 3 - .../AsyncSequenceValidation/WorkQueue.swift | 1 - Tests/AsyncAlgorithmsTests/TestBuffer.swift | 6 -- Tests/AsyncAlgorithmsTests/TestChunk.swift | 62 ++++++------------- Tests/AsyncAlgorithmsTests/TestMerge.swift | 2 - .../AsyncAlgorithmsTests/TestTaskSelect.swift | 34 +++++++--- 15 files changed, 67 insertions(+), 82 deletions(-) diff --git a/Sources/AsyncAlgorithms_XCTest/ValidationTest.swift b/Sources/AsyncAlgorithms_XCTest/ValidationTest.swift index 70dd514b..2a7f5667 100644 --- a/Sources/AsyncAlgorithms_XCTest/ValidationTest.swift +++ b/Sources/AsyncAlgorithms_XCTest/ValidationTest.swift @@ -24,7 +24,6 @@ extension XCTestCase { #endif } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func validate(theme: Theme, expectedFailures: Set, @AsyncSequenceValidationDiagram _ build: (AsyncSequenceValidationDiagram) -> Test, file: StaticString = #file, line: UInt = #line) { var expectations = expectedFailures var result: AsyncSequenceValidationDiagram.ExpectationResult? @@ -63,17 +62,14 @@ extension XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func validate(expectedFailures: Set, @AsyncSequenceValidationDiagram _ build: (AsyncSequenceValidationDiagram) -> Test, file: StaticString = #file, line: UInt = #line) { validate(theme: .ascii, expectedFailures: expectedFailures, build, file: file, line: line) } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) public func validate(theme: Theme, @AsyncSequenceValidationDiagram _ build: (AsyncSequenceValidationDiagram) -> Test, file: StaticString = #file, line: UInt = #line) { validate(theme: theme, expectedFailures: [], build, file: file, line: line) } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) public func validate(@AsyncSequenceValidationDiagram _ build: (AsyncSequenceValidationDiagram) -> Test, file: StaticString = #file, line: UInt = #line) { validate(theme: .ascii, expectedFailures: [], build, file: file, line: line) } diff --git a/Sources/AsyncSequenceValidation/AsyncSequenceValidationDiagram.swift b/Sources/AsyncSequenceValidation/AsyncSequenceValidationDiagram.swift index 63c59ad0..40afd11d 100644 --- a/Sources/AsyncSequenceValidation/AsyncSequenceValidationDiagram.swift +++ b/Sources/AsyncSequenceValidation/AsyncSequenceValidationDiagram.swift @@ -11,7 +11,6 @@ import _CAsyncSequenceValidationSupport -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) @resultBuilder public struct AsyncSequenceValidationDiagram : Sendable { public struct Component { diff --git a/Sources/AsyncSequenceValidation/Clock.swift b/Sources/AsyncSequenceValidation/Clock.swift index 66f8a532..772cc4c9 100644 --- a/Sources/AsyncSequenceValidation/Clock.swift +++ b/Sources/AsyncSequenceValidation/Clock.swift @@ -11,7 +11,6 @@ import AsyncAlgorithms -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) extension AsyncSequenceValidationDiagram { public struct Clock { let queue: WorkQueue @@ -22,8 +21,20 @@ extension AsyncSequenceValidationDiagram { } } -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) -extension AsyncSequenceValidationDiagram.Clock: Clock { + +public protocol TestClock: Sendable { + associatedtype Instant: TestInstant + + var now: Instant { get } + + func sleep(until deadline: Self.Instant, tolerance: Self.Instant.Duration?) async throws +} + +public protocol TestInstant: Equatable { + associatedtype Duration +} + +extension AsyncSequenceValidationDiagram.Clock { public struct Step: DurationProtocol, Hashable, CustomStringConvertible { internal var rawValue: Int @@ -66,7 +77,7 @@ extension AsyncSequenceValidationDiagram.Clock: Clock { } } - public struct Instant: InstantProtocol, CustomStringConvertible { + public struct Instant: CustomStringConvertible { public typealias Duration = Step let when: Step @@ -111,3 +122,8 @@ extension AsyncSequenceValidationDiagram.Clock: Clock { } } } + +extension AsyncSequenceValidationDiagram.Clock.Instant: TestInstant { } +extension AsyncSequenceValidationDiagram.Clock.Instant: InstantProtocol { } +extension AsyncSequenceValidationDiagram.Clock: TestClock { } +extension AsyncSequenceValidationDiagram.Clock: Clock { } diff --git a/Sources/AsyncSequenceValidation/Event.swift b/Sources/AsyncSequenceValidation/Event.swift index 0ee11fe5..70101475 100644 --- a/Sources/AsyncSequenceValidation/Event.swift +++ b/Sources/AsyncSequenceValidation/Event.swift @@ -9,7 +9,6 @@ // //===----------------------------------------------------------------------===// -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) extension AsyncSequenceValidationDiagram { struct Failure: Error, Equatable { } diff --git a/Sources/AsyncSequenceValidation/Expectation.swift b/Sources/AsyncSequenceValidation/Expectation.swift index 1cc1a439..63121d66 100644 --- a/Sources/AsyncSequenceValidation/Expectation.swift +++ b/Sources/AsyncSequenceValidation/Expectation.swift @@ -9,7 +9,6 @@ // //===----------------------------------------------------------------------===// -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) extension AsyncSequenceValidationDiagram { public struct ExpectationResult: Sendable { public struct Event: Sendable { diff --git a/Sources/AsyncSequenceValidation/Input.swift b/Sources/AsyncSequenceValidation/Input.swift index 7cd31e0c..35ede268 100644 --- a/Sources/AsyncSequenceValidation/Input.swift +++ b/Sources/AsyncSequenceValidation/Input.swift @@ -9,7 +9,6 @@ // //===----------------------------------------------------------------------===// -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) extension AsyncSequenceValidationDiagram { public struct Specification: Sendable { public let specification: String diff --git a/Sources/AsyncSequenceValidation/Job.swift b/Sources/AsyncSequenceValidation/Job.swift index 87ccd44e..44dedbc8 100644 --- a/Sources/AsyncSequenceValidation/Job.swift +++ b/Sources/AsyncSequenceValidation/Job.swift @@ -11,7 +11,6 @@ import _CAsyncSequenceValidationSupport -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) struct Job: Hashable, @unchecked Sendable { let job: JobRef diff --git a/Sources/AsyncSequenceValidation/TaskDriver.swift b/Sources/AsyncSequenceValidation/TaskDriver.swift index 28140ebb..9f45c1f6 100644 --- a/Sources/AsyncSequenceValidation/TaskDriver.swift +++ b/Sources/AsyncSequenceValidation/TaskDriver.swift @@ -20,7 +20,6 @@ import _CAsyncSequenceValidationSupport #endif #if canImport(Darwin) -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func start_thread(_ raw: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? { Unmanaged.fromOpaque(raw).takeRetainedValue().run() return nil @@ -34,7 +33,6 @@ func start_thread(_ raw: UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? { #error("TODO: Port TaskDriver threading to windows") #endif -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) final class TaskDriver { let work: (TaskDriver) -> Void let queue: WorkQueue diff --git a/Sources/AsyncSequenceValidation/Test.swift b/Sources/AsyncSequenceValidation/Test.swift index 981dd4d7..98944e59 100644 --- a/Sources/AsyncSequenceValidation/Test.swift +++ b/Sources/AsyncSequenceValidation/Test.swift @@ -19,22 +19,20 @@ internal func _swiftJobRun( _ executor: UnownedSerialExecutor ) -> () -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) public protocol AsyncSequenceValidationTest: Sendable { var inputs: [AsyncSequenceValidationDiagram.Specification] { get } var output: AsyncSequenceValidationDiagram.Specification { get } - func test(with clock: C, activeTicks: [C.Instant], output: AsyncSequenceValidationDiagram.Specification, _ event: (String) -> Void) async throws + func test(with clock: C, activeTicks: [C.Instant], output: AsyncSequenceValidationDiagram.Specification, _ event: (String) -> Void) async throws } -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) extension AsyncSequenceValidationDiagram { struct Test: AsyncSequenceValidationTest, @unchecked Sendable where Operation.Element == String { let inputs: [Specification] let sequence: Operation let output: Specification - func test(with clock: C, activeTicks: [C.Instant], output: Specification, _ event: (String) -> Void) async throws { + func test(with clock: C, activeTicks: [C.Instant], output: Specification, _ event: (String) -> Void) async throws { var iterator = sequence.makeAsyncIterator() do { for tick in activeTicks { diff --git a/Sources/AsyncSequenceValidation/Theme.swift b/Sources/AsyncSequenceValidation/Theme.swift index 5d627292..19e80419 100644 --- a/Sources/AsyncSequenceValidation/Theme.swift +++ b/Sources/AsyncSequenceValidation/Theme.swift @@ -9,21 +9,18 @@ // //===----------------------------------------------------------------------===// -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) public protocol AsyncSequenceValidationTheme { func token(_ character: Character, inValue: Bool) -> AsyncSequenceValidationDiagram.Token func description(for token: AsyncSequenceValidationDiagram.Token) -> String } -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) extension AsyncSequenceValidationTheme where Self == AsyncSequenceValidationDiagram.ASCIITheme { public static var ascii: AsyncSequenceValidationDiagram.ASCIITheme { return AsyncSequenceValidationDiagram.ASCIITheme() } } -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) extension AsyncSequenceValidationDiagram { public enum Token: Sendable { case step diff --git a/Sources/AsyncSequenceValidation/WorkQueue.swift b/Sources/AsyncSequenceValidation/WorkQueue.swift index 769ea6f8..784e5e82 100644 --- a/Sources/AsyncSequenceValidation/WorkQueue.swift +++ b/Sources/AsyncSequenceValidation/WorkQueue.swift @@ -9,7 +9,6 @@ // //===----------------------------------------------------------------------===// -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) struct WorkQueue: Sendable { enum Item: CustomStringConvertible, Comparable { case blocked(Token, AsyncSequenceValidationDiagram.Clock.Instant, UnsafeContinuation) diff --git a/Tests/AsyncAlgorithmsTests/TestBuffer.swift b/Tests/AsyncAlgorithmsTests/TestBuffer.swift index a488ded3..d6838203 100644 --- a/Tests/AsyncAlgorithmsTests/TestBuffer.swift +++ b/Tests/AsyncAlgorithmsTests/TestBuffer.swift @@ -431,7 +431,6 @@ final class TestBuffer: XCTestCase { XCTAssertEqual(1, [task1Results, task2Results].compactMap{ $0.1 }.count) } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_bufferingOldest() async { validate { "X-12- 34- 5 |" @@ -440,7 +439,6 @@ final class TestBuffer: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_bufferingOldest_noDrops() async { validate { "X-12 3 4 5 |" @@ -449,7 +447,6 @@ final class TestBuffer: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_bufferingOldest_error() async { validate { "X-12345^" @@ -458,7 +455,6 @@ final class TestBuffer: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_bufferingNewest() async { validate { "X-12- 34 -5|" @@ -467,7 +463,6 @@ final class TestBuffer: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_bufferingNewest_noDrops() async { validate { "X-12 3 4 5 |" @@ -476,7 +471,6 @@ final class TestBuffer: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_bufferingNewest_error() async { validate { "X-12345^" diff --git a/Tests/AsyncAlgorithmsTests/TestChunk.swift b/Tests/AsyncAlgorithmsTests/TestChunk.swift index e785768f..4970cdc0 100644 --- a/Tests/AsyncAlgorithmsTests/TestChunk.swift +++ b/Tests/AsyncAlgorithmsTests/TestChunk.swift @@ -22,7 +22,6 @@ func concatCharacters(_ array: [String]) -> String { } final class TestChunk: XCTestCase { - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signal_equalChunks() { validate { "ABC- DEF- GHI- |" @@ -32,7 +31,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signal_unequalChunks() { validate { "AB- A-ABCDEFGH- |" @@ -42,7 +40,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signal_emptyChunks() { validate { "--1--|" @@ -52,7 +49,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signal_error() { validate { "AB^" @@ -62,7 +58,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signal_unsignaledTrailingChunk() { validate { "111-111|" @@ -72,7 +67,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signalAndCount_signalAlwaysPrevails() { validate { "AB- A-ABCDEFGH- |" @@ -82,7 +76,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signalAndCount_countAlwaysPrevails() { validate { "AB --A-B -|" @@ -92,7 +85,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signalAndCount_countResetsAfterCount() { validate { "ABCDE -ABCDE |" @@ -102,7 +94,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signalAndCount_countResetsAfterSignal() { validate { "AB- ABCDE |" @@ -112,7 +103,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_signalAndCount_error() { validate { "ABC^" @@ -122,8 +112,8 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) - func test_time_equalChunks() { + func test_time_equalChunks() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "ABC- DEF- GHI- |" $0.inputs[0].chunked(by: .repeating(every: .steps(4), clock: $0.clock)).map(concatCharacters) @@ -131,8 +121,8 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) - func test_time_unequalChunks() { + func test_time_unequalChunks() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "AB------ A------- ABCDEFG- |" $0.inputs[0].chunked(by: .repeating(every: .steps(8), clock: $0.clock)).map(concatCharacters) @@ -140,8 +130,8 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) - func test_time_emptyChunks() { + func test_time_emptyChunks() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "-- 1- --|" $0.inputs[0].chunked(by: .repeating(every: .steps(2), clock: $0.clock)).map(concatCharacters) @@ -149,8 +139,8 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) - func test_time_error() { + func test_time_error() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "AB^" $0.inputs[0].chunked(by: .repeating(every: .steps(5), clock: $0.clock)).map(concatCharacters) @@ -158,8 +148,8 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) - func test_time_unsignaledTrailingChunk() { + func test_time_unsignaledTrailingChunk() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "111-111|" $0.inputs[0].chunked(by: .repeating(every: .steps(4), clock: $0.clock)).map(sumCharacters) @@ -167,8 +157,8 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) - func test_timeAndCount_timeAlwaysPrevails() { + func test_timeAndCount_timeAlwaysPrevails() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "AB------ A------- ABCDEFG- |" $0.inputs[0].chunks(ofCount: 42, or: .repeating(every: .steps(8), clock: $0.clock)).map(concatCharacters) @@ -176,8 +166,8 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) - func test_timeAndCount_countAlwaysPrevails() { + func test_timeAndCount_countAlwaysPrevails() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "AB --A-B -|" $0.inputs[0].chunks(ofCount: 2, or: .repeating(every: .steps(8), clock: $0.clock)).map(concatCharacters) @@ -185,8 +175,8 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) - func test_timeAndCount_countResetsAfterCount() { + func test_timeAndCount_countResetsAfterCount() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "ABCDE --- ABCDE |" $0.inputs[0].chunks(ofCount: 5, or: .repeating(every: .steps(8), clock: $0.clock)).map(concatCharacters) @@ -194,8 +184,8 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) - func test_timeAndCount_countResetsAfterSignal() { + func test_timeAndCount_countResetsAfterSignal() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "AB------ ABCDE |" $0.inputs[0].chunks(ofCount: 5, or: .repeating(every: .steps(8), clock: $0.clock)).map(concatCharacters) @@ -203,8 +193,8 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) - func test_timeAndCount_error() { + func test_timeAndCount_error() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "ABC^" $0.inputs[0].chunks(ofCount: 5, or: .repeating(every: .steps(8), clock: $0.clock)).map(concatCharacters) @@ -212,7 +202,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_count() { validate { "ABC DEF |" @@ -221,7 +210,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_count_nonuniformTiming() { validate { "A--B-C --DE-F |" @@ -230,7 +218,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_count_trailingChunk() { validate { "11111|" @@ -239,7 +226,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_count_error() { validate { "AB^" @@ -248,7 +234,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_group() { validate { "ABC def GH ij Kl|" @@ -257,7 +242,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_group_singleValue() { validate { "A----|" @@ -266,7 +250,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_group_singleGroup() { validate { "ABCDE|" @@ -275,7 +258,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_group_error() { validate { "AB^" @@ -284,7 +266,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_projection() { validate { "A'Aa''ab' b'BB''bb' 'cc''CC' |" @@ -293,7 +274,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_projection_singleValue() { validate { "A----|" @@ -302,7 +282,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_projection_singleGroup() { validate { "ABCDE|" @@ -311,7 +290,6 @@ final class TestChunk: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_projection_error() { validate { "Aa^" diff --git a/Tests/AsyncAlgorithmsTests/TestMerge.swift b/Tests/AsyncAlgorithmsTests/TestMerge.swift index 01571d08..fe8ae8d8 100644 --- a/Tests/AsyncAlgorithmsTests/TestMerge.swift +++ b/Tests/AsyncAlgorithmsTests/TestMerge.swift @@ -123,7 +123,6 @@ final class TestMerge2: XCTestCase { XCTAssertNil(pastEnd) } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_diagram() { validate { "a-c-e-g-|" @@ -311,7 +310,6 @@ final class TestMerge3: XCTestCase { XCTAssertNil(pastEnd) } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_diagram() { validate { "a---e---|" diff --git a/Tests/AsyncAlgorithmsTests/TestTaskSelect.swift b/Tests/AsyncAlgorithmsTests/TestTaskSelect.swift index ea0f9657..ea0910e2 100644 --- a/Tests/AsyncAlgorithmsTests/TestTaskSelect.swift +++ b/Tests/AsyncAlgorithmsTests/TestTaskSelect.swift @@ -14,21 +14,27 @@ import Dispatch import AsyncAlgorithms final class TestTaskSelect: XCTestCase { - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_first() async { let firstValue = await Task.select(Task { return 1 }, Task { - try! await Task.sleep(until: .now + .seconds(2), clock: .continuous) + if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { + try! await Task.sleep(until: .now + .seconds(2), clock: .continuous) + } else { + try! await Task.sleep(nanoseconds: NSEC_PER_SEC * 2) + } return 2 }).value XCTAssertEqual(firstValue, 1) } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_second() async { let firstValue = await Task.select(Task { - try! await Task.sleep(until: .now + .seconds(2), clock: .continuous) + if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { + try! await Task.sleep(until: .now + .seconds(2), clock: .continuous) + } else { + try! await Task.sleep(nanoseconds: NSEC_PER_SEC * 2) + } return 1 }, Task { return 2 @@ -36,11 +42,14 @@ final class TestTaskSelect: XCTestCase { XCTAssertEqual(firstValue, 2) } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_throwing() async { do { _ = try await Task.select(Task { () async throws -> Int in - try await Task.sleep(until: .now + .seconds(2), clock: .continuous) + if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { + try await Task.sleep(until: .now + .seconds(2), clock: .continuous) + } else { + try await Task.sleep(nanoseconds: NSEC_PER_SEC * 2) + } return 1 }, Task { () async throws -> Int in throw NSError(domain: NSCocoaErrorDomain, code: -1, userInfo: nil) @@ -51,7 +60,6 @@ final class TestTaskSelect: XCTestCase { } } - @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) func test_cancellation() async { let firstReady = expectation(description: "first ready") let secondReady = expectation(description: "second ready") @@ -63,7 +71,11 @@ final class TestTaskSelect: XCTestCase { firstCancelled.fulfill() } operation: { () -> Int in firstReady.fulfill() - try? await Task.sleep(until: .now + .seconds(2), clock: .continuous) + if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { + try? await Task.sleep(until: .now + .seconds(2), clock: .continuous) + } else { + try? await Task.sleep(nanoseconds: NSEC_PER_SEC * 2) + } return 1 } }, Task { @@ -71,7 +83,11 @@ final class TestTaskSelect: XCTestCase { secondCancelled.fulfill() } operation: { () -> Int in secondReady.fulfill() - try? await Task.sleep(until: .now + .seconds(2), clock: .continuous) + if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { + try? await Task.sleep(until: .now + .seconds(2), clock: .continuous) + } else { + try? await Task.sleep(nanoseconds: NSEC_PER_SEC * 2) + } return 1 } }) From 0dc362871882db9ef556d699fbdada23f797eceb Mon Sep 17 00:00:00 2001 From: Philippe Hausler Date: Wed, 15 Jun 2022 15:09:47 -0700 Subject: [PATCH 3/7] Use hand coded values instead of defines (only available via Darwin versions of Dispatch) --- Tests/AsyncAlgorithmsTests/TestTaskSelect.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Tests/AsyncAlgorithmsTests/TestTaskSelect.swift b/Tests/AsyncAlgorithmsTests/TestTaskSelect.swift index ea0910e2..e70b3adf 100644 --- a/Tests/AsyncAlgorithmsTests/TestTaskSelect.swift +++ b/Tests/AsyncAlgorithmsTests/TestTaskSelect.swift @@ -21,7 +21,7 @@ final class TestTaskSelect: XCTestCase { if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { try! await Task.sleep(until: .now + .seconds(2), clock: .continuous) } else { - try! await Task.sleep(nanoseconds: NSEC_PER_SEC * 2) + try! await Task.sleep(nanoseconds: 2_000_000_000) } return 2 }).value @@ -33,7 +33,7 @@ final class TestTaskSelect: XCTestCase { if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { try! await Task.sleep(until: .now + .seconds(2), clock: .continuous) } else { - try! await Task.sleep(nanoseconds: NSEC_PER_SEC * 2) + try! await Task.sleep(nanoseconds: 2_000_000_000) } return 1 }, Task { @@ -48,7 +48,7 @@ final class TestTaskSelect: XCTestCase { if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { try await Task.sleep(until: .now + .seconds(2), clock: .continuous) } else { - try await Task.sleep(nanoseconds: NSEC_PER_SEC * 2) + try await Task.sleep(nanoseconds: 2_000_000_000) } return 1 }, Task { () async throws -> Int in @@ -74,7 +74,7 @@ final class TestTaskSelect: XCTestCase { if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { try? await Task.sleep(until: .now + .seconds(2), clock: .continuous) } else { - try? await Task.sleep(nanoseconds: NSEC_PER_SEC * 2) + try? await Task.sleep(nanoseconds: 2_000_000_000) } return 1 } @@ -86,7 +86,7 @@ final class TestTaskSelect: XCTestCase { if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { try? await Task.sleep(until: .now + .seconds(2), clock: .continuous) } else { - try? await Task.sleep(nanoseconds: NSEC_PER_SEC * 2) + try? await Task.sleep(nanoseconds: 2_000_000_000) } return 1 } From 0f57b77f476240f303e4391a7b9fda2b5e2b317e Mon Sep 17 00:00:00 2001 From: Philippe Hausler Date: Wed, 15 Jun 2022 22:20:48 -0700 Subject: [PATCH 4/7] Adjust additional test availability --- Sources/AsyncSequenceValidation/Clock.swift | 5 +++ Tests/AsyncAlgorithmsTests/TestDebounce.swift | 15 ++++--- Tests/AsyncAlgorithmsTests/TestThrottle.swift | 43 ++++++++++++------- Tests/AsyncAlgorithmsTests/TestTimer.swift | 13 +++--- .../TestValidationTests.swift | 4 +- 5 files changed, 52 insertions(+), 28 deletions(-) diff --git a/Sources/AsyncSequenceValidation/Clock.swift b/Sources/AsyncSequenceValidation/Clock.swift index 772cc4c9..5eeb7360 100644 --- a/Sources/AsyncSequenceValidation/Clock.swift +++ b/Sources/AsyncSequenceValidation/Clock.swift @@ -124,6 +124,11 @@ extension AsyncSequenceValidationDiagram.Clock { } extension AsyncSequenceValidationDiagram.Clock.Instant: TestInstant { } + +@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) extension AsyncSequenceValidationDiagram.Clock.Instant: InstantProtocol { } + extension AsyncSequenceValidationDiagram.Clock: TestClock { } + +@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) extension AsyncSequenceValidationDiagram.Clock: Clock { } diff --git a/Tests/AsyncAlgorithmsTests/TestDebounce.swift b/Tests/AsyncAlgorithmsTests/TestDebounce.swift index 49b42507..cd0a73a4 100644 --- a/Tests/AsyncAlgorithmsTests/TestDebounce.swift +++ b/Tests/AsyncAlgorithmsTests/TestDebounce.swift @@ -12,9 +12,8 @@ import XCTest import AsyncAlgorithms -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) final class TestDebounce: XCTestCase { - func test_delayingValues() { + func test_delayingValues() throws { validate { "abcd----e---f-g----|" $0.inputs[0].debounce(for: .steps(3), clock: $0.clock) @@ -22,7 +21,8 @@ final class TestDebounce: XCTestCase { } } - func test_delayingValues_dangling_last() { + func test_delayingValues_dangling_last() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "abcd----e---f-g-|" $0.inputs[0].debounce(for: .steps(3), clock: $0.clock) @@ -31,7 +31,8 @@ final class TestDebounce: XCTestCase { } - func test_finishDoesntDebounce() { + func test_finishDoesntDebounce() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "a|" $0.inputs[0].debounce(for: .steps(3), clock: $0.clock) @@ -39,7 +40,8 @@ final class TestDebounce: XCTestCase { } } - func test_throwDoesntDebounce() { + func test_throwDoesntDebounce() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "a^" $0.inputs[0].debounce(for: .steps(3), clock: $0.clock) @@ -47,7 +49,8 @@ final class TestDebounce: XCTestCase { } } - func test_noValues() { + func test_noValues() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "----|" $0.inputs[0].debounce(for: .steps(3), clock: $0.clock) diff --git a/Tests/AsyncAlgorithmsTests/TestThrottle.swift b/Tests/AsyncAlgorithmsTests/TestThrottle.swift index f2aa9f77..72c90f65 100644 --- a/Tests/AsyncAlgorithmsTests/TestThrottle.swift +++ b/Tests/AsyncAlgorithmsTests/TestThrottle.swift @@ -12,9 +12,9 @@ import XCTest import AsyncAlgorithms -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) final class TestThrottle: XCTestCase { - func test_rate_0() { + func test_rate_0() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "abcdefghijk|" $0.inputs[0].throttle(for: .steps(0), clock: $0.clock) @@ -22,7 +22,8 @@ final class TestThrottle: XCTestCase { } } - func test_rate_0_leading_edge() { + func test_rate_0_leading_edge() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "abcdefghijk|" $0.inputs[0].throttle(for: .steps(0), clock: $0.clock, latest: false) @@ -30,7 +31,8 @@ final class TestThrottle: XCTestCase { } } - func test_rate_1() { + func test_rate_1() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "abcdefghijk|" $0.inputs[0].throttle(for: .steps(1), clock: $0.clock) @@ -38,7 +40,8 @@ final class TestThrottle: XCTestCase { } } - func test_rate_1_leading_edge() { + func test_rate_1_leading_edge() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "abcdefghijk|" $0.inputs[0].throttle(for: .steps(1), clock: $0.clock, latest: false) @@ -46,7 +49,8 @@ final class TestThrottle: XCTestCase { } } - func test_rate_2() { + func test_rate_2() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "abcdefghijk|" $0.inputs[0].throttle(for: .steps(2), clock: $0.clock) @@ -54,7 +58,8 @@ final class TestThrottle: XCTestCase { } } - func test_rate_2_leading_edge() { + func test_rate_2_leading_edge() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "abcdefghijk|" $0.inputs[0].throttle(for: .steps(2), clock: $0.clock, latest: false) @@ -62,7 +67,8 @@ final class TestThrottle: XCTestCase { } } - func test_rate_3() { + func test_rate_3() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "abcdefghijk|" $0.inputs[0].throttle(for: .steps(3), clock: $0.clock) @@ -70,7 +76,8 @@ final class TestThrottle: XCTestCase { } } - func test_rate_3_leading_edge() { + func test_rate_3_leading_edge() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "abcdefghijk|" $0.inputs[0].throttle(for: .steps(3), clock: $0.clock, latest: false) @@ -78,7 +85,8 @@ final class TestThrottle: XCTestCase { } } - func test_throwing() { + func test_throwing() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "abcdef^hijk|" $0.inputs[0].throttle(for: .steps(2), clock: $0.clock) @@ -86,7 +94,8 @@ final class TestThrottle: XCTestCase { } } - func test_throwing_leading_edge() { + func test_throwing_leading_edge() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "abcdef^hijk|" $0.inputs[0].throttle(for: .steps(2), clock: $0.clock, latest: false) @@ -94,7 +103,8 @@ final class TestThrottle: XCTestCase { } } - func test_emission_2_rate_1() { + func test_emission_2_rate_1() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "-a-b-c-d-e-f-g-h-i-j-k-|" $0.inputs[0].throttle(for: .steps(1), clock: $0.clock) @@ -102,7 +112,8 @@ final class TestThrottle: XCTestCase { } } - func test_emission_2_rate_2() { + func test_emission_2_rate_2() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "-a-b-c-d-e-f-g-h-i-j-k-|" $0.inputs[0].throttle(for: .steps(2), clock: $0.clock) @@ -110,7 +121,8 @@ final class TestThrottle: XCTestCase { } } - func test_emission_3_rate_2() { + func test_emission_3_rate_2() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "--a--b--c--d--e--f--g|" $0.inputs[0].throttle(for: .steps(2), clock: $0.clock) @@ -118,7 +130,8 @@ final class TestThrottle: XCTestCase { } } - func test_emission_2_rate_3() { + func test_emission_2_rate_3() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "-a-b-c-d-e-f-g-h-i-j-k-|" $0.inputs[0].throttle(for: .steps(3), clock: $0.clock) diff --git a/Tests/AsyncAlgorithmsTests/TestTimer.swift b/Tests/AsyncAlgorithmsTests/TestTimer.swift index 398be567..65db910e 100644 --- a/Tests/AsyncAlgorithmsTests/TestTimer.swift +++ b/Tests/AsyncAlgorithmsTests/TestTimer.swift @@ -13,30 +13,33 @@ import XCTest import AsyncAlgorithms import AsyncSequenceValidation -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) final class TestTimer: XCTestCase { - func test_tick1() { + func test_tick1() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { AsyncTimerSequence(interval: .steps(1), clock: $0.clock).map { _ in "x" } "xxxxxxx[;|]" } } - func test_tick2() { + func test_tick2() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { AsyncTimerSequence(interval: .steps(2), clock: $0.clock).map { _ in "x" } "-x-x-x-[;|]" } } - func test_tick3() { + func test_tick3() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { AsyncTimerSequence(interval: .steps(3), clock: $0.clock).map { _ in "x" } "--x--x-[;|]" } } - func test_tick2_event_skew3() { + func test_tick2_event_skew3() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { diagram in AsyncTimerSequence(interval: .steps(2), clock: diagram.clock).map { [diagram] (_) -> String in try? await diagram.clock.sleep(until: diagram.clock.now.advanced(by: .steps(3))) diff --git a/Tests/AsyncAlgorithmsTests/TestValidationTests.swift b/Tests/AsyncAlgorithmsTests/TestValidationTests.swift index 442fdeba..c002d64a 100644 --- a/Tests/AsyncAlgorithmsTests/TestValidationTests.swift +++ b/Tests/AsyncAlgorithmsTests/TestValidationTests.swift @@ -14,7 +14,6 @@ import AsyncAlgorithms import AsyncSequenceValidation @testable import AsyncAlgorithms_XCTest -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) final class TestValidationDiagram: XCTestCase { func test_diagram() { validate { @@ -293,7 +292,8 @@ final class TestValidationDiagram: XCTestCase { } } - func test_delayNext_into_emptyTick() { + func test_delayNext_into_emptyTick() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "xx|" LaggingAsyncSequence($0.inputs[0], delayBy: .steps(3), using: $0.clock) From 38012e77caee744af6c97fae1ec8c8cfd6d2894b Mon Sep 17 00:00:00 2001 From: Philippe Hausler Date: Wed, 15 Jun 2022 22:22:23 -0700 Subject: [PATCH 5/7] Correct debounce test availability guard --- Tests/AsyncAlgorithmsTests/TestDebounce.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/AsyncAlgorithmsTests/TestDebounce.swift b/Tests/AsyncAlgorithmsTests/TestDebounce.swift index cd0a73a4..2005c134 100644 --- a/Tests/AsyncAlgorithmsTests/TestDebounce.swift +++ b/Tests/AsyncAlgorithmsTests/TestDebounce.swift @@ -14,6 +14,7 @@ import AsyncAlgorithms final class TestDebounce: XCTestCase { func test_delayingValues() throws { + guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) else { throw XCTSkip("Skipped due to Clock/Instant/Duration availability") } validate { "abcd----e---f-g----|" $0.inputs[0].debounce(for: .steps(3), clock: $0.clock) From 587cf86a0c24f580efe525aa5e1467c606922acd Mon Sep 17 00:00:00 2001 From: Philippe Hausler Date: Thu, 16 Jun 2022 08:58:52 -0700 Subject: [PATCH 6/7] Update build instructions to indicate Xcode requirements --- README.md | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index e3c957a9..cde1208f 100644 --- a/README.md +++ b/README.md @@ -87,28 +87,17 @@ Finally, add `import AsyncAlgorithms` to your source code. ## Getting Started -⚠️ Please note that this package currently requires a recent [Swift Trunk Development toolchain](https://www.swift.org/download/#trunk-development-main). More information on how to use custom toolchains with Xcode can be viewed [here](https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/AlternativeToolchains.html). +⚠️ Please note that this package requires Xcode 14 on macOS hosts. Previous versions of Xcode do not contain the required Swift version. ### Building/Testing Using Xcode on macOS - 1. Download the most recent development Xcode toolchain. - 2. Install the package - 4. Select the development toolchain in Xcode - 4. Open the `swift-async-algorithms` package directory in Xcode - 5. Build or Test in Xcode as normal - -⚠️ Note: `swift test` does not currently work properly with custom toolchains for this package. + 1. In the `swift-async-algorithms` directory run `swift build` or `swift test` accordingly ### Building/Testing on Linux 1. Download the most recent development toolchain for your Linux distribution 2. Decompress the archive to a path in which the `swift` executable is in the binary search path environment variable (`$PATH`) 3. In the `swift-async-algorithms` directory run `swift build` or `swift test` accordingly - -### Building with Swift 5.6 - - 1. `git checkout swift-5.6` - 2. run `swift build` or `swift test` accordingly ## Source Stability From e109cb59f845938e4891fc0d13706c28773f7686 Mon Sep 17 00:00:00 2001 From: Philippe Hausler Date: Thu, 16 Jun 2022 09:03:11 -0700 Subject: [PATCH 7/7] Ensure the clock property of the validation diagram is only available for targets that can support it --- .../AsyncSequenceValidationDiagram.swift | 9 +++++++-- Sources/AsyncSequenceValidation/Test.swift | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Sources/AsyncSequenceValidation/AsyncSequenceValidationDiagram.swift b/Sources/AsyncSequenceValidation/AsyncSequenceValidationDiagram.swift index 40afd11d..b7ee6547 100644 --- a/Sources/AsyncSequenceValidation/AsyncSequenceValidationDiagram.swift +++ b/Sources/AsyncSequenceValidation/AsyncSequenceValidationDiagram.swift @@ -96,15 +96,20 @@ public struct AsyncSequenceValidationDiagram : Sendable { } let queue: WorkQueue + let _clock: Clock public var inputs: InputList - public let clock: Clock + + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) + public var clock: Clock { + _clock + } internal init() { let queue = WorkQueue() self.queue = queue self.inputs = InputList(queue: queue) - self.clock = Clock(queue: queue) + self._clock = Clock(queue: queue) } } diff --git a/Sources/AsyncSequenceValidation/Test.swift b/Sources/AsyncSequenceValidation/Test.swift index 98944e59..35177cf2 100644 --- a/Sources/AsyncSequenceValidation/Test.swift +++ b/Sources/AsyncSequenceValidation/Test.swift @@ -263,7 +263,7 @@ extension AsyncSequenceValidationDiagram { @AsyncSequenceValidationDiagram _ build: (AsyncSequenceValidationDiagram) -> Test ) throws -> (ExpectationResult, [ExpectationFailure]) { let diagram = AsyncSequenceValidationDiagram() - let clock = diagram.clock + let clock = diagram._clock let test = build(diagram) for index in 0..