1import { assert, describe, it, vi } from "@effect/vitest"
2import { Clock, Effect } from "effect"
3
4describe("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})