Ende.EndeTest

interface

interface Ende.EndeTest

Call signatures

Call signature

(t: TestDefinition): void

Register a test which will be run when ende test is used on the command line and the containing module looks like a test module.

fn can be async if required.

import { assertEquals } from "jsr:@ende/assert";

Ende.test({
  name: "example test",
  fn() {
    assertEquals("world", "world");
  },
});

Ende.test({
  name: "example ignored test",
  ignore: Ende.build.os === "windows",
  fn() {
    // This test is ignored only on Windows machines
  },
});

Ende.test({
  name: "example async test",
  async fn() {
    const decoder = new TextDecoder("utf-8");
    const data = await Ende.readFile("hello_world.txt");
    assertEquals(decoder.decode(data), "Hello world");
  }
});
(name: string, fn: (t: TestContext) => void | Promise<void>): void

Register a test which will be run when ende test is used on the command line and the containing module looks like a test module.

fn can be async if required.

import { assertEquals } from "jsr:@ende/assert";

Ende.test("My test description", () => {
  assertEquals("hello", "hello");
});

Ende.test("My async test description", async () => {
  const decoder = new TextDecoder("utf-8");
  const data = await Ende.readFile("hello_world.txt");
  assertEquals(decoder.decode(data), "Hello world");
});
(fn: (t: TestContext) => void | Promise<void>): void

Register a test which will be run when ende test is used on the command line and the containing module looks like a test module.

fn can be async if required. Declared function must have a name.

import { assertEquals } from "jsr:@ende/assert";

Ende.test(function myTestName() {
  assertEquals("hello", "hello");
});

Ende.test(async function myOtherTestName() {
  const decoder = new TextDecoder("utf-8");
  const data = await Ende.readFile("hello_world.txt");
  assertEquals(decoder.decode(data), "Hello world");
});
(name: string, options: Omit<TestDefinition, "fn" | "name">, fn: (t: TestContext) => void | Promise<void>): void

Register a test which will be run when ende test is used on the command line and the containing module looks like a test module.

fn can be async if required.

import { assert, fail, assertEquals } from "jsr:@ende/assert";

Ende.test("My test description", { permissions: { read: true } }, (): void => {
  assertEquals("hello", "hello");
});

Ende.test("My async test description", { permissions: { read: false } }, async (): Promise<void> => {
  const decoder = new TextDecoder("utf-8");
  const data = await Ende.readFile("hello_world.txt");
  assertEquals(decoder.decode(data), "Hello world");
});
(options: Omit<TestDefinition, "fn" | "name">, fn: (t: TestContext) => void | Promise<void>): void

Register a test which will be run when ende test is used on the command line and the containing module looks like a test module.

fn can be async if required.

import { assertEquals } from "jsr:@ende/assert";

Ende.test(
  {
    name: "My test description",
    permissions: { read: true },
  },
  () => {
    assertEquals("hello", "hello");
  },
);

Ende.test(
  {
    name: "My async test description",
    permissions: { read: false },
  },
  async () => {
    const decoder = new TextDecoder("utf-8");
    const data = await Ende.readFile("hello_world.txt");
    assertEquals(decoder.decode(data), "Hello world");
  },
);
(options: Omit<TestDefinition, "fn">, fn: (t: TestContext) => void | Promise<void>): void

Register a test which will be run when ende test is used on the command line and the containing module looks like a test module.

fn can be async if required. Declared function must have a name.

import { assertEquals } from "jsr:@ende/assert";

Ende.test(
  { permissions: { read: true } },
  function myTestName() {
    assertEquals("hello", "hello");
  },
);

Ende.test(
  { permissions: { read: false } },
  async function myOtherTestName() {
    const decoder = new TextDecoder("utf-8");
    const data = await Ende.readFile("hello_world.txt");
    assertEquals(decoder.decode(data), "Hello world");
  },
);

Properties

each

each: TestEach

Register a parameterized group of tests, one per case in cases.

Returns a function that takes a name template and a test function. For each case the name template is interpolated and the test function is called with the case's value(s) followed by the TestContext.

Array cases are spread as positional arguments; object (or primitive) cases are passed as a single argument.

The name template supports printf-style tokens that consume the case's values in order (%s, %d/%i, %f, %j, %o/%O), %# for the zero-based case index, and %% for a literal %. For object cases, $key (and $key.nested) interpolates the corresponding property.

import { assertEquals } from "jsr:@ende/assert";

Ende.test.each([
  [1, 1, 2],
  [1, 2, 3],
  [2, 1, 3],
])("add(%i, %i) = %i", (a, b, expected) => {
  assertEquals(a + b, expected);
});

Ende.test.each([
  { a: 1, b: 1, sum: 2 },
  { a: 1, b: 2, sum: 3 },
])("$a + $b = $sum", ({ a, b, sum }) => {
  assertEquals(a + b, sum);
});

ignore

ignore: TestIgnore

Shorthand property for ignoring a particular test case.

only

only: TestOnly

Shorthand property for focusing a particular test case.

Methods

beforeAll

beforeAll(fn: () => void | Promise<void>): void

Register a function to be called before all tests in the current scope.

These functions are run in FIFO order (first in, first out).

If an exception is raised during execution of this hook, the remaining beforeAll hooks will not be run.

Ende.test.beforeAll(() => {
  // Setup code that runs once before all tests
  console.log("Setting up test suite");
});

beforeEach

beforeEach(fn: () => void | Promise<void>): void

Register a function to be called before each test in the current scope.

These functions are run in FIFO order (first in, first out).

If an exception is raised during execution of this hook, the remaining hooks will not be run and the currently running test case will be marked as failed.

Ende.test.beforeEach(() => {
  // Setup code that runs before each test
  console.log("Setting up test");
});

afterEach

afterEach(fn: () => void | Promise<void>): void

Register a function to be called after each test in the current scope.

These functions are run in LIFO order (last in, first out).

If an exception is raised during execution of this hook, the remaining hooks will not be run and the currently running test case will be marked as failed.

Ende.test.afterEach(() => {
  // Cleanup code that runs after each test
  console.log("Cleaning up test");
});

afterAll

afterAll(fn: () => void | Promise<void>): void

Register a function to be called after all tests in the current scope have finished running.

These functions are run in the LIFO order (last in, first out).

If an exception is raised during execution of this hook, the remaining afterAll hooks will not be run.

Ende.test.afterAll(() => {
  // Cleanup code that runs once after all tests
  console.log("Cleaning up test suite");
});

sanitizer

sanitizer(options: { ops?: boolean; resources?: boolean }): void

Configure sanitizers at the module level. This overrides CLI flags and config file settings, but can still be overridden per-test via sanitizeOps / sanitizeResources in test options.

Should be called at the top of the module, before any Ende.test() registrations — each call sets the defaults that subsequently registered tests inherit, so tests registered before the call use the previous defaults.

// Enable both sanitizers for all tests in this file
Ende.test.sanitizer({ ops: true, resources: true });

Ende.test("my test", () => {
  // This test will have ops and resources sanitizers enabled
});

Ende.test({
  name: "override per-test",
  sanitizeOps: false,
  fn() {
    // This test opts out of ops sanitizer
  },
});