Files
WRNexusJS/packages/dev-server/test/plugin-config-lifecycle.test.ts
2026-07-29 12:51:10 +05:30

83 lines
2.5 KiB
TypeScript

import { afterAll, expect, test } from "bun:test";
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import { get } from "node:http";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { definePlugin } from "@wrnexus/plugin";
import { startServer } from "../src/index.ts";
const root = mkdtempSync(join(tmpdir(), "wrnexus-plugin-config-"));
const appDir = join(root, "app");
const routeFile = join(root, "config-probe.ts");
const runtimeKey = `@wrnexus/dev-server:test:plugin-config:${crypto.randomUUID()}`;
mkdirSync(appDir, { recursive: true });
writeFileSync(join(root, "package.json"), JSON.stringify({ name: "plugin-config-lifecycle-test" }));
writeFileSync(
routeFile,
`
export function GET() {
return Response.json({
value: globalThis[Symbol.for(${JSON.stringify(runtimeKey)})],
});
}
`,
);
afterAll(() => {
delete (globalThis as Record<PropertyKey, unknown>)[Symbol.for(runtimeKey)];
rmSync(root, { recursive: true, force: true });
});
function getJson(url: string): Promise<{ status: number | undefined; body: unknown }> {
return new Promise((resolve, reject) => {
const request = get(url, (response) => {
const chunks: Buffer[] = [];
response.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
response.on("end", () => {
try {
resolve({
status: response.statusCode,
body: JSON.parse(Buffer.concat(chunks).toString("utf8")),
});
} catch (error) {
reject(error);
}
});
});
request.on("error", reject);
});
}
test("startServer configures plugins once with the complete application config", async () => {
let configureCalls = 0;
const plugin = definePlugin({
name: "plugin-config-lifecycle-test",
configure(config) {
configureCalls += 1;
(globalThis as Record<PropertyKey, unknown>)[Symbol.for(runtimeKey)] =
config.lifecycleSentinel;
},
routeEntries: [{ kind: "api", path: "/api/config-probe", entry: routeFile }],
});
const server = await startServer({
appDir,
appConfig: { lifecycleSentinel: "configured" },
plugins: plugin,
hostname: "127.0.0.1",
port: 0,
mode: "development",
hmr: false,
});
try {
const response = await getJson(`${server.url}/api/config-probe`);
expect(response.status).toBe(200);
expect(response.body).toEqual({ value: "configured" });
expect(configureCalls).toBe(1);
} finally {
server.stop();
}
});