T-iOS-1: ios/ XcodeGen project (iOS 17, Swift 6 strict concurrency, ATS per PLAN §5.2), 5 SPM package shells, CI skeleton T-iOS-2: Origin spike vs real server — URLSessionWebSocketTask custom Origin CONFIRMED (no Starscream); 16MiB replay + EMSGSIZE(40) errno correction written back to plan T-iOS-3: WireProtocol frozen contract, 59 tests, 100% line coverage, cross-impl vectors vs src/protocol.ts via tsx T-iOS-4: FakeTransport/FakeClock/FakeHTTPTransport doubles Verify: independent agent re-ran all acceptance — 6/6 PASS
33 lines
1.2 KiB
Swift
33 lines
1.2 KiB
Swift
import Testing
|
|
@testable import TestSupport
|
|
|
|
@Suite("FakeClock")
|
|
struct FakeClockTests {
|
|
private static let sleepDuration: Duration = .seconds(25)
|
|
private static let partialAdvance: Duration = .seconds(10)
|
|
private static let remainingAdvance: Duration = .seconds(15)
|
|
|
|
@Test("sleeper wakes only after the clock is manually advanced past its deadline")
|
|
func sleeperWakesOnlyAfterAdvancePastDeadline() async throws {
|
|
// Arrange
|
|
let clock = FakeClock()
|
|
let deadline = clock.now.advanced(by: Self.sleepDuration)
|
|
let sleeper = Task {
|
|
try await clock.sleep(until: deadline, tolerance: nil)
|
|
}
|
|
await clock.waitForSleepers(count: 1)
|
|
|
|
// Act: advance short of the deadline — the sleeper must stay asleep.
|
|
clock.advance(by: Self.partialAdvance)
|
|
#expect(clock.pendingSleeperCount == 1)
|
|
|
|
// Act: advance up to the deadline — the sleeper must wake.
|
|
clock.advance(by: Self.remainingAdvance)
|
|
try await sleeper.value
|
|
|
|
// Assert: zero real-time waiting, purely manual time.
|
|
#expect(clock.pendingSleeperCount == 0)
|
|
#expect(clock.now == FakeClock.Instant(offset: Self.sleepDuration))
|
|
}
|
|
}
|