ouija board1
jeeboard docs testkit index.md
5.7 kB
Markdown
at main


title: Test utilities with @jeeboard/testkit description: Covers deterministic test helpers and the spatial benchmark from the @jeeboard/testkit package. #

@jeeboard/testkit #

The @jeeboard/testkit package gives you deterministic helpers for tests that use jeeboard. Deterministic means that each run gives the same result. The package also contains a benchmark that measures spatial index query speed.

Use this package in your test code. Do not use it in production code.

Key concepts #

  • Manual scheduler: a scheduler that queues tasks and runs them only when you flush a phase.
  • Phase: a named stage of work. The phases are presentation, compilation, raster, and background.
  • Manual clock: a clock that returns a fixed time until you advance it by hand.
  • Sequential ID generator: an identifier generator that returns predictable strings such as test-1 and test-2.
  • Fixture scene: a generated array of elements with a regular grid layout. A fixture is fixed test data.
  • Test editor: a bundle that contains an EditorCore and a ManualScheduler.

The types Clock, IdGenerator, EditorCore, and EditorElement come from core. The spatial index comes from scene.

Manual scheduler #

createManualScheduler creates a ManualScheduler. The scheduler stores tasks per phase. No task runs until you flush it.

import { createManualScheduler } from "@jeeboard/testkit";

const scheduler = createManualScheduler();
const events: string[] = [];

scheduler.request(() => events.push("background"), "background");
scheduler.request(() => events.push("presentation"), "presentation");
scheduler.request(() => events.push("raster"), "raster");

scheduler.flush("presentation");
// events is ["presentation"]
scheduler.pending("background"); // 1

scheduler.flushAll();
// events is ["presentation", "raster", "background"]

The ManualScheduler methods are:

  • request(task, phase?) queues a task. The default phase is background.
  • flush(phase) runs all queued tasks for one phase.
  • flushAll() runs all phases in the order presentation, compilation, raster, background.
  • pending(phase) returns the number of queued tasks for one phase.

Manual clock #

createManualClock creates a Clock with an extra advance method. The clock time does not change until you advance it.

import { createManualClock } from "@jeeboard/testkit";

const clock = createManualClock(100);

clock.advance(25);

clock.now(); // 125

The parameter of createManualClock is the start time. The default start time is 0. The parameter of advance is the number of milliseconds to add.

NOTE: advance throws an error if the value is negative or not finite.

Sequential ID generator #

createSequentialIdGenerator creates an IdGenerator that counts up from one.

import { createSequentialIdGenerator } from "@jeeboard/testkit";

const ids = createSequentialIdGenerator();

ids.next(); // "test-1"
ids.next(); // "test-2"

The optional parameter is the prefix. The default prefix is "test".

Test editor #

createTestEditor creates an EditorCore and a ManualScheduler together. Pass an array of initial elements to populate the core.

import { createTestEditor } from "@jeeboard/testkit";

const { core, scheduler } = createTestEditor();

The returned object has two read-only fields: core and scheduler. Use core for document state. Use scheduler to control when deferred work runs.

Fixture scenes #

createShapeBenchmarkScene creates count shape elements in a grid layout. Each element is 100 units wide and 80 units high. The columns have a spacing of 120 units. The rows have a spacing of 100 units. Each element has the identifier benchmark-shape-<index> and the properties { shape: "rectangle" }.

import { createShapeBenchmarkScene } from "@jeeboard/testkit";

const elements = createShapeBenchmarkScene(100);

The function is deterministic. Two calls with the same count return the same identifiers.

NOTE: createShapeBenchmarkScene throws an error if the count is not a non-negative integer.

Spatial benchmark #

benchmarkSpatialIndex builds a fixture scene, inserts it into a uniform grid index, and runs rectangle queries. It returns a SpatialBenchmarkResult:

  • elementCount: the requested number of elements.
  • queryCount: the requested number of queries.
  • indexedElements: the number of elements inserted into the index.
  • queriedElements: the total number of elements returned by all queries.
  • elapsedMs: the total query time in milliseconds.
  • averageQueryMs: the query time divided by the query count.
import { benchmarkSpatialIndex } from "@jeeboard/testkit";

const result = benchmarkSpatialIndex(100, 3);
// result.elementCount is 100
// result.indexedElements is 100

The defaults are 100,000 elements and 100 queries. The index cell size is 3,000 units. Each query rectangle is 1,920 by 1,080 units.

NOTE: benchmarkSpatialIndex throws an error if the element count is not a non-negative integer. It also throws if the query count is not a positive integer.

Benchmark script #

The package contains a benchmark script at test/benchmark.mjs. The script prints the result as JSON. Run it from the repository with pnpm:

  1. Open a terminal in the repository root.
  2. Run pnpm --filter @jeeboard/testkit bench.
  3. Read the JSON result on the standard output.

NOTE: The script imports the compiled dist output. The bench script builds the package before it runs the benchmark.

API reference #

See the generated TypeDoc page for @jeeboard/testkit.