KloradDocs

Test with a manual clock

Deterministic tests of staleness and ordering, with node:test and createManualClock.

Time-dependent behaviour is the easiest to get wrong and the hardest to test with real time. Give the scene a manual clock and you decide exactly when "now" is.

stale.test.ts
import assert from "node:assert/strict";
import { test } from "node:test";
import { createManualClock, createScene } from "@klorad/api/world";

test("a quiet sensor turns stale after its window", () => {
  const clock = createManualClock(Date.parse("2026-10-09T10:00:00Z"));
  const scene = createScene({ coordinateSystem: { origin: { lat: 40.62637, lon: 22.94838 } }, clock, staleAfterMs: 60_000 });
  scene.add({ id: "t1", name: "Probe", position: { east: 0, north: 0 }, correspondence: "shadow", binding: { source: "bms", entity: "t1" } });

  scene.observe({ objectId: "t1", quantity: "temperature", value: 21.5, observedAt: clock.now(), source: "bms" });
  assert.equal(scene.isStale("t1", "temperature"), false);

  clock.advance(61_000);
  assert.equal(scene.isStale("t1", "temperature"), true);
});

Run it with Node's built in test runner (node --test, through tsx for TypeScript). The same clock can be passed to fixtureSource and fixtureDevice, so the readings they produce are stamped with time you control (their intervals still run on real timers).

What to test this way

  • A reading observed earlier than the current one is late and does not change latest.
  • A sensor turns stale exactly after its window, and fresh again with the next reading.
  • A rule in @klorad/notify fires once on the edge, not on every reading above a limit.
  • A Behaviour stamps now from the scene's clock, so its output is predictable.

Something wrong or unclear? Tell your contact at Prieston Technologies.