@hegeldev/hegel
v0.4.0
Published
Property-based testing for TypeScript
Maintainers
Readme
[!IMPORTANT] We're excited you're checking out Hegel! Hegel is in beta, and we'd love for you to try it and report any feedback.
As part of our beta, we may make breaking changes if it makes Hegel a better property-based testing library. If that instability bothers you, please check back in a few months for a stable release!
See https://hegel.dev/compatibility for more details.
Hegel for TypeScript
Hegel is a property-based testing library for TypeScript. Hegel is based on Hypothesis, using the Hegel protocol.
Installation
To install: npm install --save-dev @hegeldev/hegel.
Hegel requires Node 20.11+. Bun and Deno are not currently supported.
Hegel drives libhegel — the native Rust
engine — directly via FFI. The prebuilt libhegel shared library for every
supported platform is bundled inside the npm package (under native/), so there
is nothing to download or compile at install time — npm install just works
offline. Set HEGEL_LIBHEGEL_PATH to point at a local build to override the
bundled library.
Supported platforms (those with a bundled libhegel artifact): Linux amd64/arm64, macOS arm64 (Apple Silicon), and Windows amd64/arm64.
Quickstart
Here's a quick example of how to write a Hegel test:
import { test } from "vitest";
import * as hegel from "@hegeldev/hegel";
import * as gs from "@hegeldev/hegel/generators";
function mySort(ls: number[]): number[] {
const result = [...ls].sort((a, b) => a - b);
return [...new Set(result)];
}
test("my_sort matches builtin", () =>
hegel.test((tc) => {
const vec1 = tc.draw(gs.arrays(gs.integers()));
const vec2 = mySort(vec1);
const sorted = [...vec1].sort((a, b) => a - b);
if (JSON.stringify(sorted) !== JSON.stringify(vec2)) {
throw new Error(`sort mismatch: ${JSON.stringify(sorted)} != ${JSON.stringify(vec2)}`);
}
}));This test will fail when run with vitest! Hegel will produce a minimal failing test case for us:
Draw 1: [0, 0]
Error: sort mismatch: [0,0] != [0]Hegel reports the minimal example showing that our sort is incorrectly dropping duplicates. If we remove the new Set(...) deduplication from mySort(), this test will then pass (because it's just comparing the standard sort against itself).
Async tests
For async tests, use hegel.testAsync:
import { test } from "vitest";
import * as hegel from "@hegeldev/hegel";
import * as gs from "@hegeldev/hegel/generators";
test("fetch returns a value matching its input", () =>
hegel.testAsync(async (tc) => {
const id = tc.draw(gs.integers({ minValue: 1, maxValue: 1000 }));
const result = await fetchUser(id);
if (result.id !== id) {
throw new Error(`Expected id=${id}, got ${result.id}`);
}
}));