| 1 | import { assert, describe, it, vi } from "@effect/vitest" |
| 2 | import { Clock, Effect } from "effect" |
| 3 | |
| 4 | describe("Clock", { concurrent: false }, () => { |
| 5 | it.live("keeps wall time aligned while exposing the monotonic source", () => { |
| 6 | let wallMillis = 1_000_000 |
| 7 | let monotonicNanos = 5_000_000_000n |
| 8 | const dateNow = vi.spyOn(Date, "now").mockImplementation(() => wallMillis) |
| 9 | const hrtime = vi.spyOn(process.hrtime, "bigint").mockImplementation(() => monotonicNanos) |
| 10 | return Effect.gen(function*() { |
| 11 | const clock = yield* Clock.Clock |
| 12 | const nanosPerMilli = 1_000_000n |
| 13 | |
| 14 | assert.strictEqual(clock.currentTimeNanosUnsafe(), BigInt(wallMillis) * nanosPerMilli) |
| 15 | assert.strictEqual(clock.monotonicTimeNanosUnsafe(), monotonicNanos) |
| 16 | |
| 17 | wallMillis += 250 |
| 18 | monotonicNanos += 250_000_000n |
| 19 | assert.strictEqual(clock.currentTimeNanosUnsafe(), BigInt(wallMillis) * nanosPerMilli) |
| 20 | |
| 21 | wallMillis += 5_000 |
| 22 | const beforeSuspend = clock.monotonicTimeNanosUnsafe() |
| 23 | assert.strictEqual(clock.currentTimeNanosUnsafe(), BigInt(wallMillis) * nanosPerMilli) |
| 24 | assert.strictEqual(clock.monotonicTimeNanosUnsafe(), beforeSuspend) |
| 25 | |
| 26 | wallMillis -= 3_000 |
| 27 | monotonicNanos += 100_000_000n |
| 28 | assert.strictEqual(clock.currentTimeNanosUnsafe(), BigInt(wallMillis) * nanosPerMilli) |
| 29 | assert.isTrue(clock.monotonicTimeNanosUnsafe() > beforeSuspend) |
| 30 | }).pipe( |
| 31 | Effect.ensuring(Effect.sync(() => { |
| 32 | dateNow.mockRestore() |
| 33 | hrtime.mockRestore() |
| 34 | })) |
| 35 | ) |
| 36 | }) |
| 37 | }) |