- Bump every @wrnexus/* dependency to its latest release (ui 0.8.88, styles 0.8.26, cli 0.8.72, core 0.8.16, i18n 0.8.12, ...) and refresh bun.lock and package-lock.json. graphql/native 0.8.8 were republished, so their stale lockfile integrity entries were re-resolved. - wrnexus.config.ts: drop `functions` and `compatibility`, both removed from the framework. - Regenerate package, portal and discovery docs from the installed packages, including the new 0.8.72 release page. - Package pages now install each package's own released version (ui 0.8.88, core 0.8.16) instead of stamping the CLI version on all. - llms.txt / llms-full.txt: the generator kept every earlier run's CLI reference and appended another; it now replaces it, so the guide holds one current reference and no longer advertises the removed `wrnexus compatibility` command. - docs.test.ts: compileWireFile was renamed compileWrnFile; tests follow the per-package install versions and the removed command. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
320 lines
24 KiB
Plaintext
320 lines
24 KiB
Plaintext
page wrnexustest {
|
|
seo {
|
|
title = "@wrnexus/test"
|
|
description = "WRNexusJS-aware component, route, and browser testing utilities."
|
|
}
|
|
|
|
view {
|
|
<div class="docs-shell">
|
|
<a href="#main" class="skip-link">Skip to content</a>
|
|
<header class="topbar">
|
|
<a class="brand" href="/"><span>W</span> WRNexusJS</a>
|
|
<nav aria-label="Primary"><a href="/getting-started">Get started</a><a href="/packages">Packages</a><a href="https://component.wrnexusjs.dev/">Components</a><a href="/language">Language</a><a href="/architecture">Architecture</a></nav>
|
|
<div class="topbar-actions"><a class="preview-pill" href="/access">Private preview · v0.8.72</a><button data-wire-theme-toggle class="theme-button" aria-label="Toggle color theme" title="Toggle color theme">◐</button></div>
|
|
</header>
|
|
<div class="mobile-doc-nav"><details><summary>Browse documentation</summary><nav><a href="/getting-started">Get started</a><a href="/packages">Packages</a><a href="https://component.wrnexusjs.dev/">Components</a><a href="/language">Language</a><a href="/architecture">Architecture</a><a href="/tutorial">Tutorial</a><a href="/guides/project-structure">Guides</a><a href="/examples">Examples</a><a href="/search">Search</a></nav></details></div>
|
|
<main id="main" class="portal-main docs-layout docs-layout--navigation"><aside class="docs-section-menu" aria-label="Documentation sections"><nav>
|
|
<section><strong>Get started</strong><a href="/getting-started">Quick start</a><a href="/tutorial">Tutorial</a><a href="/guides/full-stack-auth-demo">Auth dashboard demo</a><a href="/guides/configuration-and-profiles">Configuration</a></section>
|
|
<section><strong>Build</strong><a href="/guides/pages-and-components">Pages and components</a><a href="/guides/routing">Routing</a><a href="/guides/server-data">Server data</a><a href="/guides/forms-and-validation">Forms and validation</a><a href="/guides/database">Database</a></section>
|
|
<section><strong>Auth and security</strong><a href="/guides/authentication">Authentication</a><a href="/guides/authorization">Authorization</a><a href="/guides/security">Application security</a><a href="/security">Security policy</a></section>
|
|
<section><strong>Reference</strong><a href="/packages">Packages overview</a><a href="/packages/cli">CLI</a><a href="/language">.wrn language</a><a href="https://component.wrnexusjs.dev/">Components</a><a href="/examples">Examples</a></section>
|
|
<section class="package-menu"><strong>Packages</strong><a href="/packages/ai">@wrnexus/ai</a><a href="/packages/auth">@wrnexus/auth</a><a href="/packages/authz">@wrnexus/authz</a><a href="/packages/benchmark">@wrnexus/benchmark</a><a href="/packages/cache">@wrnexus/cache</a><a href="/packages/captcha">@wrnexus/captcha</a><a href="/packages/cli">@wrnexus/cli</a><a href="/packages/compiler">@wrnexus/compiler</a><a href="/packages/content">@wrnexus/content</a><a href="/packages/core">@wrnexus/core</a><a href="/packages/csr">@wrnexus/csr</a><a href="/packages/db">@wrnexus/db</a><a href="/packages/dev-server">@wrnexus/dev-server</a><a href="/packages/dev-toolbar">@wrnexus/dev-toolbar</a><a href="/packages/encryption">@wrnexus/encryption</a><a href="/packages/graphql">@wrnexus/graphql</a><a href="/packages/helpers">@wrnexus/helpers</a><a href="/packages/i18n">@wrnexus/i18n</a><a href="/packages/identity">@wrnexus/identity</a><a href="/packages/image">@wrnexus/image</a><a href="/packages/jwt">@wrnexus/jwt</a><a href="/packages/language-server">@wrnexus/language-server</a><a href="/packages/mcp">@wrnexus/mcp</a><a href="/packages/mobile">@wrnexus/mobile</a><a href="/packages/native">@wrnexus/native</a><a href="/packages/oauth">@wrnexus/oauth</a><a href="/packages/observability">@wrnexus/observability</a><a href="/packages/playground">@wrnexus/playground</a><a href="/packages/plugin">@wrnexus/plugin</a><a href="/packages/pubsub">@wrnexus/pubsub</a><a href="/packages/pwa">@wrnexus/pwa</a><a href="/packages/queue">@wrnexus/queue</a><a href="/packages/reactive">@wrnexus/reactive</a><a href="/packages/realtime">@wrnexus/realtime</a><a href="/packages/router">@wrnexus/router</a><a href="/packages/security">@wrnexus/security</a><a href="/packages/ssr">@wrnexus/ssr</a><a href="/packages/store">@wrnexus/store</a><a href="/packages/styles">@wrnexus/styles</a><a href="/packages/syntax">@wrnexus/syntax</a><a href="/packages/test">@wrnexus/test</a><a href="/packages/tracking">@wrnexus/tracking</a><a href="/packages/typecheck">@wrnexus/typecheck</a><a href="/packages/ui">@wrnexus/ui</a><a href="/packages/uploader">@wrnexus/uploader</a><a href="/packages/validation">@wrnexus/validation</a></section>
|
|
</nav></aside><div class="docs-reading-column">
|
|
<article class="documentation prose standalone package-document"><nav class="breadcrumbs" aria-label="Breadcrumb"><a href="/">Home</a><span>/</span><a href="/packages">Packages</a><span>/</span><span aria-current="page">@wrnexus/test</span></nav><section class="doc-intro"><span class="eyebrow">Tooling · Package reference</span><h1>@wrnexus/test</h1><p>WRNexusJS-aware component, route, and browser testing utilities.</p><div class="doc-meta"><span>v0.8.16</span><span>Private registry</span><span>Tooling</span></div><section id="access" class="access-callout"><h2>Install the package</h2><p>After WorkRoot approves private registry access, install the package:</p><pre><code>bun add @wrnexus/test@0.8.16</code><button type="button" class="copy-button" aria-label="Copy installation command">Copy</button></pre><p><a href="/access">Request preview access</a>. Never put registry tokens in source control.</p></section></section><section id="guide"><blockquote>Testing utilities for WRNexusJS apps — component rendering, reactive-DOM mounting, route handler calls, and a full in-process app harness, plus a one-import re-export of <code>bun:test</code>.</blockquote>
|
|
<p>Part of the <strong>WRNexusJS</strong> framework — an SSR-first, Bun-native full-stack web framework.</p>
|
|
<h3 id="overview">Overview</h3>
|
|
<p><code>@wrnexus/test</code> is the server-side test toolkit you reach for when writing tests for a WRNexusJS app. It runs under <code>bun test</code> (invoked via <code>wrnexus test</code>) and gives you a single import surface: the <code>bun:test</code> primitives (<code>test</code>, <code>expect</code>, <code>mock</code>, …) re-exported alongside WRNexusJS-aware helpers that compile <code>.wrn</code> components, hydrate server HTML in a DOM, invoke API route handlers, and boot the real app on an ephemeral port for integration tests.</p>
|
|
<pre data-language="bash"><code>bun add @wrnexus/test</code></pre>
|
|
<blockquote>Private package — the machine must be authenticated to the <code>wrnexus</code> npm org</blockquote>
|
|
<blockquote>(a read token in <code>~/.npmrc</code>). Requires <strong>Bun</strong> (Node is not supported).</blockquote>
|
|
<h3 id="api">API</h3>
|
|
<h4 id="re-exported-test-primitives">Re-exported test primitives</h4>
|
|
<p>For one-import DX, the following are re-exported straight from <code>bun:test</code>:</p>
|
|
<p><code>test</code>, <code>expect</code>, <code>describe</code>, <code>it</code>, <code>beforeEach</code>, <code>afterEach</code>, <code>beforeAll</code>, <code>afterAll</code>, <code>mock</code>, <code>spyOn</code>.</p>
|
|
<p><code>createContext</code> is also re-exported from <code>@wrnexus/core</code>.</p>
|
|
<h4 id="rendercomponent-source-props"><code>renderComponent(source, props?)</code></h4>
|
|
<pre data-language="ts"><code>function renderComponent(source: string, props?: Record<string, unknown>): Promise<string>;</code></pre>
|
|
<p>Compiles a <code>.wrn</code> component <code>source</code> string (via <code>@wrnexus/compiler</code>) and renders it to an HTML string with the given <code>props</code>. Throws if the compiled module has no <code>render</code> export.</p>
|
|
<h4 id="mounthtml-html"><code>mountHtml(html)</code></h4>
|
|
<pre data-language="ts"><code>function mountHtml(html: string): {
|
|
document: Document;
|
|
window: unknown;
|
|
querySelector: (sel: string) => Element | null;
|
|
querySelectorAll: (sel: string) => Element[];
|
|
};</code></pre>
|
|
<p>Mounts server-rendered <code>html</code> in a <code>happy-dom</code> window with the reactive runtime hydrated, so you can test <code>data-scope</code> / <code>data-text</code> / <code>data-for</code> / <code>data-show</code> behaviour. Returns the window plus <code>document</code> and query helpers; assert on those.</p>
|
|
<blockquote><code>happy-dom</code> is loaded lazily (via <code>require</code>), so importing this package never</blockquote>
|
|
<blockquote>requires it unless you actually call <code>mountHtml</code>.</blockquote>
|
|
<h4 id="callroute-handler-request"><code>callRoute(handler, request)</code></h4>
|
|
<pre data-language="ts"><code>function callRoute(
|
|
handler: (ctx: Context) => Response | Promise<Response>,
|
|
request: Request,
|
|
): Promise<Response>;</code></pre>
|
|
<p>Calls an API route <code>handler</code> with a <code>Context</code> built from a <code>Request</code> (using <code>createContext</code>). Returns the handler's <code>Response</code>.</p>
|
|
<h4 id="createharness-projectroot-options"><code>createHarness(projectRoot, options?)</code></h4>
|
|
<pre data-language="ts"><code>function createHarness(projectRoot: string, options?: HarnessOptions): Promise<Harness>;
|
|
|
|
interface HarnessOptions {
|
|
/** Config/env profile. Default "test". */
|
|
profile?: string;
|
|
}
|
|
|
|
interface Harness {
|
|
/** Base URL of the ephemeral test server. */
|
|
url: string;
|
|
/** Fetch a path on the app (relative to `url`). */
|
|
fetch(path: string, init?: RequestInit): Promise<Response>;
|
|
/** The scanned router (pages/api/realtime/components). */
|
|
router: unknown;
|
|
/** Stop the server. */
|
|
close(): void;
|
|
}</code></pre>
|
|
<p>Boots the app at <code>projectRoot</code> on an ephemeral port (<code>port: 0</code>) for integration tests covering pages, API routes, middleware, and the full request pipeline. Loads env and app config for the given <code>profile</code> (default <code>"test"</code>) so it picks up your test database/env. The server runs in <code>development</code> mode with HMR disabled. Remember to <code>await app.close()</code> when done.</p>
|
|
<h3 id="usage">Usage</h3>
|
|
<p>The CLI supports focused suites by file or directory convention:</p>
|
|
<pre data-language="bash"><code>wrnexus test unit # *.unit.test.ts or test/unit/**
|
|
wrnexus test component # *.component.test.ts or test/component/**
|
|
wrnexus test api # *.api.test.ts or test/api/**
|
|
wrnexus test accessibility # *.a11y.test.ts / *.accessibility.test.ts
|
|
wrnexus test performance # *.performance.test.ts / *.benchmark.test.ts
|
|
wrnexus test browser # Playwright project when configured
|
|
wrnexus test visual # Playwright tests tagged @visual</code></pre>
|
|
<p>Pass the application directory after the level, for example <code>wrnexus test component examples/basic-app</code>. A focused command fails clearly when no matching suite exists instead of silently running unrelated tests.</p>
|
|
<pre data-language="ts"><code>import { test, expect, renderComponent, mountHtml, createHarness } from "@wrnexus/test";
|
|
|
|
test("counter renders its label", async () => {
|
|
const html = await renderComponent(SRC, { start: 3, label: "Hits" });
|
|
expect(html).toContain("Hits");
|
|
});
|
|
|
|
test("reactive scope hydrates", () => {
|
|
const { querySelector } = mountHtml(serverHtml);
|
|
expect(querySelector("[data-text]")?.textContent).toBe("3");
|
|
});
|
|
|
|
test("home page responds", async () => {
|
|
const app = await createHarness("examples/basic-app");
|
|
const res = await app.fetch("/");
|
|
expect(res.status).toBe(200);
|
|
await app.close();
|
|
});</code></pre>
|
|
<p>Calling an API route handler directly:</p>
|
|
<pre data-language="ts"><code>import { test, expect, callRoute } from "@wrnexus/test";
|
|
import { GET } from "../app/api/health.ts";
|
|
|
|
test("health endpoint", async () => {
|
|
const res = await callRoute(GET, new Request("http://test/api/health"));
|
|
expect(res.status).toBe(200);
|
|
});</code></pre>
|
|
<h3 id="requirements-notes">Requirements / Notes</h3>
|
|
<ul>
|
|
<li><strong>Bun-only.</strong> Runs under <code>bun test</code> (via <code>wrnexus test</code>); uses Bun's module</li>
|
|
<p>loading and the <code>bun:test</code> runtime.</p>
|
|
<li><code>mountHtml</code> requires <strong><code>happy-dom</code></strong> to be available in the workspace (loaded</li>
|
|
<p>lazily; it's a dev dependency, not a runtime dependency of this package).</p>
|
|
<li>Works with the rest of the WRNexusJS toolchain:</li>
|
|
<p>[<code>@wrnexus/compiler</code>](../compiler) (compiles <code>.wrn</code> sources), [<code>@wrnexus/core</code>](../core) (<code>Context</code> / <code>createContext</code>), [<code>@wrnexus/csr</code>](../csr) (reactive runtime for <code>mountHtml</code>), [<code>@wrnexus/dev-server</code>](../dev-server) (<code>startServer</code> behind <code>createHarness</code>), and [<code>@wrnexus/styles</code>](../styles) (config/env/profile loading for the harness).</p>
|
|
</ul></section><section id="api" class="api"><h2>Complete TypeScript API</h2><p>Generated from the exact installed package declarations.</p><pre data-language="typescript"><code>import { Context, ProblemDetails } from '@wrnexus/core';
|
|
export { createContext } from '@wrnexus/core';
|
|
export { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, mock, spyOn, test } from 'bun:test';
|
|
|
|
interface TestRequestOptions extends Omit<RequestInit, "body"> {
|
|
body?: BodyInit | Record<string, unknown> | URLSearchParams | FormData | null;
|
|
baseUrl?: string;
|
|
params?: Record<string, string>;
|
|
user?: unknown;
|
|
locals?: Record<string, unknown>;
|
|
}
|
|
/** Build a web-standard Request with convenient JSON/FormData handling. */
|
|
declare function testRequest(path?: string, options?: TestRequestOptions): Request;
|
|
/** Create a complete Context suitable for middleware and route unit tests. */
|
|
declare function testContext(path?: string, options?: TestRequestOptions): Context;
|
|
/** Preferred descriptive alias for testContext(). */
|
|
declare const createTestContext: typeof testContext;
|
|
/** Fluent, Bun-compatible fetch mock (including Bun.fetch.preconnect). */
|
|
type FetchMock = typeof fetch & {
|
|
readonly calls: ReadonlyArray<{
|
|
input: string | URL | Request;
|
|
init?: RequestInit;
|
|
}>;
|
|
respondOnce(response: Response | (() => Response | Promise<Response>)): FetchMock;
|
|
reset(): void;
|
|
};
|
|
declare function createFetchMock(): FetchMock;
|
|
interface JsonResponse<T> {
|
|
response: Response;
|
|
body: T;
|
|
}
|
|
declare function readJsonResponse<T = unknown>(response: Response): Promise<JsonResponse<T>>;
|
|
declare function expectProblem(response: Response, status?: number): Promise<ProblemDetails>;
|
|
interface Deferred<T> {
|
|
promise: Promise<T>;
|
|
resolve(value: T | PromiseLike<T>): void;
|
|
reject(reason?: unknown): void;
|
|
}
|
|
declare function deferred<T>(): Deferred<T>;
|
|
interface WaitForOptions {
|
|
timeoutMs?: number;
|
|
intervalMs?: number;
|
|
signal?: AbortSignal;
|
|
}
|
|
/** Poll a condition without depending on fake timers or a browser runtime. */
|
|
declare function waitFor(condition: () => boolean | Promise<boolean>, options?: WaitForOptions): Promise<void>;
|
|
declare class MemoryCookieJar {
|
|
#private;
|
|
apply(response: Response): void;
|
|
header(): string;
|
|
request(path: string, options?: TestRequestOptions): Request;
|
|
clear(): void;
|
|
}
|
|
|
|
interface TransactionalDatabase {
|
|
tx<T>(callback: (transaction: TransactionalDatabase) => Promise<T>): Promise<T>;
|
|
}
|
|
/** Run test work in a real transaction and always force rollback. */
|
|
declare function withDatabaseRollback<T>(db: TransactionalDatabase, run: (transaction: TransactionalDatabase) => T | Promise<T>): Promise<T>;
|
|
declare function createFactory<T extends Record<string, unknown>>(build: (sequence: number) => T): {
|
|
build(overrides?: Partial<T>): T;
|
|
buildMany(count: number, overrides?: Partial<T>): T[];
|
|
reset(): void;
|
|
};
|
|
interface BrowserArtifactPage {
|
|
screenshot(options: {
|
|
path: string;
|
|
fullPage?: boolean;
|
|
}): Promise<unknown>;
|
|
context(): {
|
|
tracing?: {
|
|
stop(options: {
|
|
path: string;
|
|
}): Promise<unknown>;
|
|
};
|
|
};
|
|
}
|
|
declare function captureBrowserArtifacts(page: BrowserArtifactPage, testName: string, options?: {
|
|
root?: string;
|
|
screenshot?: boolean;
|
|
trace?: boolean;
|
|
}): Promise<{
|
|
screenshot?: string;
|
|
trace?: string;
|
|
}>;
|
|
|
|
interface MutationCase<T> {
|
|
name: string;
|
|
value: T;
|
|
}
|
|
interface MutationReport<O> {
|
|
baseline: O;
|
|
killed: string[];
|
|
survived: string[];
|
|
}
|
|
interface DetectMutationsOptions<T, O> {
|
|
baseline: T;
|
|
mutations: Array<MutationCase<T>>;
|
|
exercise(value: T): O | Promise<O>;
|
|
equivalent?(left: O, right: O): boolean;
|
|
}
|
|
/**
|
|
* Run the same behavioural probe against a baseline and explicit mutations.
|
|
* A mutation survives when the observable result is unchanged. The helper
|
|
* throws with every survivor by default, making it suitable for an ordinary
|
|
* Bun test and CI without a second runner or source-rewriting process.
|
|
*/
|
|
declare function detectMutations<T, O>(options: DetectMutationsOptions<T, O>): Promise<MutationReport<O>>;
|
|
|
|
/**
|
|
* @wrnexus/test — testing utilities for WRNexusJS apps. Runs on `bun test` (via
|
|
* `wrnexus test`). Import everything from one place:
|
|
*
|
|
* import { test, expect, renderComponent, mountHtml, createHarness } from "@wrnexus/test";
|
|
*
|
|
* test("counter renders its label", async () => {
|
|
* const html = await renderComponent(SRC, { start: 3, label: "Hits" });
|
|
* expect(html).toContain("Hits");
|
|
* });
|
|
*
|
|
* test("home page responds", async () => {
|
|
* const app = await createHarness("examples/basic-app");
|
|
* const res = await app.fetch("/");
|
|
* expect(res.status).toBe(200);
|
|
* await app.close();
|
|
* });
|
|
*/
|
|
|
|
/** Compile a `.wrn` component source + render it to HTML with the given props. */
|
|
declare function renderComponent(source: string, props?: Record<string, unknown>): Promise<string>;
|
|
/**
|
|
* Mount server-rendered HTML in a happy-dom window with the reactive runtime
|
|
* hydrated, so you can test `data-scope`/`data-text`/`data-for`/`data-show`
|
|
* behaviour. Returns the window; assert on `win.document`.
|
|
*/
|
|
declare function mountHtml(html: string): {
|
|
document: Document;
|
|
window: unknown;
|
|
querySelector: (sel: string) => Element | null;
|
|
querySelectorAll: (sel: string) => Element[];
|
|
};
|
|
/** Call an API route handler with a `Context` built from a Request. */
|
|
declare function callRoute(handler: (ctx: Context) => Response | Promise<Response>, request: Request): Promise<Response>;
|
|
interface Harness {
|
|
/** Base URL of the ephemeral test server. */
|
|
url: string;
|
|
/** Fetch a path on the app (relative to `url`). */
|
|
fetch(path: string, init?: RequestInit): Promise<Response>;
|
|
/** The scanned router (pages/api/realtime/components). */
|
|
router: unknown;
|
|
/** Stop the server. */
|
|
close(): void;
|
|
}
|
|
interface HarnessOptions {
|
|
/** Config/env profile. Default "test". */
|
|
profile?: string;
|
|
}
|
|
/**
|
|
* Boot the app on an ephemeral port for integration tests (pages, API routes,
|
|
* middleware, the full pipeline). Uses the "test" profile by default so it picks
|
|
* up your test database/env. Remember to `await app.close()`.
|
|
*/
|
|
declare function createHarness(projectRoot: string, options?: HarnessOptions): Promise<Harness>;
|
|
/** Preferred full-stack name; retained alongside createHarness for compatibility. */
|
|
declare const createTestApp: typeof createHarness;
|
|
|
|
export { type BrowserArtifactPage, type Deferred, type DetectMutationsOptions, type FetchMock, type Harness, type HarnessOptions, type JsonResponse, MemoryCookieJar, type MutationCase, type MutationReport, type TestRequestOptions, type TransactionalDatabase, type WaitForOptions, callRoute, captureBrowserArtifacts, createFactory, createFetchMock, createHarness, createTestApp, createTestContext, deferred, detectMutations, expectProblem, mountHtml, readJsonResponse, renderComponent, testContext, testRequest, waitFor, withDatabaseRollback };
|
|
</code></pre></section><section id="examples" class="examples"><h2>Examples</h2><p>Copy-ready examples from the installed package documentation.</p><div class="example-grid"><article class="example-card"><h3>The CLI supports focused suites by file or directory convention</h3><pre data-language="bash"><code>wrnexus test unit # *.unit.test.ts or test/unit/**
|
|
wrnexus test component # *.component.test.ts or test/component/**
|
|
wrnexus test api # *.api.test.ts or test/api/**
|
|
wrnexus test accessibility # *.a11y.test.ts / *.accessibility.test.ts
|
|
wrnexus test performance # *.performance.test.ts / *.benchmark.test.ts
|
|
wrnexus test browser # Playwright project when configured
|
|
wrnexus test visual # Playwright tests tagged @visual</code></pre></article><article class="example-card"><h3>suite exists instead of silently running unrelated tests.</h3><pre data-language="ts"><code>import { test, expect, renderComponent, mountHtml, createHarness } from "@wrnexus/test";
|
|
|
|
test("counter renders its label", async () => {
|
|
const html = await renderComponent(SRC, { start: 3, label: "Hits" });
|
|
expect(html).toContain("Hits");
|
|
});
|
|
|
|
test("reactive scope hydrates", () => {
|
|
const { querySelector } = mountHtml(serverHtml);
|
|
expect(querySelector("[data-text]")?.textContent).toBe("3");
|
|
});
|
|
|
|
test("home page responds", async () => {
|
|
const app = await createHarness("examples/basic-app");
|
|
const res = await app.fetch("/");
|
|
expect(res.status).toBe(200);
|
|
await app.close();
|
|
});</code></pre></article><article class="example-card"><h3>Calling an API route handler directly</h3><pre data-language="ts"><code>import { test, expect, callRoute } from "@wrnexus/test";
|
|
import { GET } from "../app/api/health.ts";
|
|
|
|
test("health endpoint", async () => {
|
|
const res = await callRoute(GET, new Request("http://test/api/health"));
|
|
expect(res.status).toBe(200);
|
|
});</code></pre></article></div></section></article></div>
|
|
<aside class="on-this-page"><h2>On this page</h2><nav><a class="toc-level-2" href="#guide">Guide</a><a class="toc-level-3" href="#overview">Overview</a><a class="toc-level-3" href="#api">API</a><a class="toc-level-4" href="#re-exported-test-primitives">Re-exported test primitives</a><a class="toc-level-4" href="#rendercomponent-source-props">renderComponent(source, props?)</a><a class="toc-level-4" href="#mounthtml-html">mountHtml(html)</a><a class="toc-level-4" href="#callroute-handler-request">callRoute(handler, request)</a><a class="toc-level-4" href="#createharness-projectroot-options">createHarness(projectRoot, options?)</a><a class="toc-level-3" href="#usage">Usage</a><a class="toc-level-3" href="#requirements-notes">Requirements / Notes</a><a class="toc-level-2" href="#api">Complete API</a><a class="toc-level-2" href="#examples">Examples</a></nav></aside>
|
|
</main>
|
|
<footer><div class="footer-brand"><span class="footer-mark" aria-hidden="true">W</span><p><strong>WRNexusJS 0.8.72</strong><span>Complete API documentation generated from installed package declarations.</span></p></div><nav aria-label="Footer"><a href="/packages">All packages</a><a href="/getting-started">Get started</a><a href="/security">Security</a><a href="/support">Support</a><a href="/llms.txt">AI guide</a></nav><p class="footer-meta">Private Developer Preview · Bun-native</p></footer>
|
|
</div>
|
|
}
|
|
}
|