Lox Nexus

Class: TestClock

A clock that only moves when the test says so, so a plugin that polls every few seconds or acts at a time of day can be tested without waiting. Give it to PluginTestHost ({ clock }): the plugin's every() and after() run on it, and this.clock.now() reads it.

Unlike mock.timers.tick(), which sets the time to the end of the tick before running the due timers, advance() runs each timer at its own due time, so a callback that asks for the time or sets the next timer sees the time it was due at.

Example

Start at a known moment, let five polls pass, then jump to a time of day:

const clock = new TestClock("2026-10-28T08:00:00Z")
const host = await PluginTestHost.start(SmartPlugPlugin, { clock, config: { address } })
await clock.advance(5 * 5000)
await clock.advanceTo("2026-10-28T09:30:00Z")

Implements

Constructors

Constructor

new TestClock(start?): TestClock

Parameters

start?

string | number | Date = 0

the initial time: epoch milliseconds, an ISO string or a Date; default 0

Returns

TestClock

Accessors

pending

Get Signature

get pending(): number

timers that haven't fired yet (intervals count until cleared)

Returns

number

Methods

now()

now(): number

milliseconds since the epoch, like Date.now()

Returns

number

Implementation of

Clock.now


setTimeout()

setTimeout(fn, ms): number

like the global setTimeout; the handle is only meant for clearTimeout

Parameters

fn

() => void

ms

number

Returns

number

Implementation of

Clock.setTimeout


clearTimeout()

clearTimeout(handle): void

Parameters

handle

unknown

Returns

void

Implementation of

Clock.clearTimeout


setInterval()

setInterval(fn, ms): number

like the global setInterval; the handle is only meant for clearInterval

Parameters

fn

() => void

ms

number

Returns

number

Implementation of

Clock.setInterval


clearInterval()

clearInterval(handle): void

Parameters

handle

unknown

Returns

void

Implementation of

Clock.clearInterval


advance()

advance(ms): Promise<void>

Moves the time forward by ms, running every timer that comes due on the way at its due time, in order, including timers those callbacks set. After each callback it lets pending promise callbacks and I/O events run once, so async work started by a timer can continue at that time.

A callback that throws ends the advance: it rejects with that error, the time stays at that timer's due time and later timers don't run (in production it would be an uncaught exception).

Parameters

ms

number

Returns

Promise<void>

Throws

RangeError for a negative or non-finite ms; Error while another advance() runs


jump()

jump(ms): void

Steps the time by ms (negative goes back) without running anything, like an NTP correction: timers keep their remaining delay, because real timers count elapsed time, not wall time.

Parameters

ms

number

Returns

void


advanceTo()

advanceTo(time): Promise<void>

advance() up to a time: epoch milliseconds, an ISO string or a Date; never moves backwards

Parameters

time

string | number | Date

Returns

Promise<void>