TeraClockTests.swift (1898B)
1 import Foundation 2 @testable import TeraApp 3 import XCTest 4 5 final class TeraClockTests: XCTestCase { 6 func testUnixClockUsesCheckedFlooringAtBothPrecisions() throws { 7 let clock = TeraClock(now: { Date(timeIntervalSince1970: 1_800_000_000.125) }) 8 9 XCTAssertEqual(try clock.unixSeconds(), 1_800_000_000) 10 XCTAssertEqual(try clock.unixMilliseconds(), 1_800_000_000_125) 11 XCTAssertEqual(try TeraClock.fixed(unixSeconds: 1).unixSeconds(requirePositive: true), 1) 12 } 13 14 func testUnixClockRejectsNonfinitePreEpochZeroAndOverflow() { 15 let vectors: [(TimeInterval, TeraClockError)] = [ 16 (.nan, .nonfinite), 17 (.infinity, .nonfinite), 18 (-0.001, .beforeUnixEpoch), 19 (TimeInterval.greatestFiniteMagnitude, .overflow), 20 ] 21 for (value, expected) in vectors { 22 XCTAssertThrowsError( 23 try TeraClock.unixMilliseconds(from: Date(timeIntervalSince1970: value)) 24 ) { error in 25 XCTAssertEqual(error as? TeraClockError, expected) 26 } 27 } 28 XCTAssertThrowsError( 29 try TeraClock.unixSeconds( 30 from: Date(timeIntervalSince1970: 0), 31 requirePositive: true 32 ) 33 ) { error in 34 XCTAssertEqual(error as? TeraClockError, .zeroNotAllowed) 35 } 36 XCTAssertThrowsError( 37 try TeraClock.signedUnixMilliseconds( 38 from: Date(timeIntervalSince1970: TimeInterval(Int64.max) / 1000 + 1) 39 ) 40 ) { error in 41 XCTAssertEqual(error as? TeraClockError, .overflow) 42 } 43 } 44 45 func testGenerationTransitionRejectsMaximumWithoutWrapping() throws { 46 XCTAssertEqual(try TeraCheckedStateTransition.nextGeneration(after: 0), 1) 47 XCTAssertEqual(try TeraCheckedStateTransition.nextGeneration(after: UInt64.max - 1), .max) 48 XCTAssertThrowsError(try TeraCheckedStateTransition.nextGeneration(after: .max)) { 49 error in 50 XCTAssertEqual(error as? TeraStateTransitionError, .generationOverflow) 51 } 52 } 53 }