feat: 搭建前后端可执行程序示例
This commit is contained in:
69
tests/server/app.test.ts
Normal file
69
tests/server/app.test.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { createFetchHandler, type StaticAssets } from "../../src/server/app";
|
||||
|
||||
const staticAssets: StaticAssets = {
|
||||
indexHtml: new Blob(["<!doctype html><title>Gateway Checker Demo</title><div id=\"root\"></div>"], {
|
||||
type: "text/html",
|
||||
}),
|
||||
files: {
|
||||
"/assets/app.js": new Blob(["console.log('demo');"], { type: "text/javascript" }),
|
||||
},
|
||||
};
|
||||
|
||||
describe("Bun fullstack runtime", () => {
|
||||
const fetchHandler = createFetchHandler({ mode: "test", staticAssets });
|
||||
|
||||
test("/api/demo 返回 JSON demo 响应", async () => {
|
||||
const response = await fetchHandler(new Request("http://localhost/api/demo"));
|
||||
const body = await response.json();
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers.get("content-type")).toContain("application/json");
|
||||
expect(body.message).toContain("/api/demo");
|
||||
expect(body.runtime.mode).toBe("test");
|
||||
});
|
||||
|
||||
test("/health 返回机器可读健康检查", async () => {
|
||||
const response = await fetchHandler(new Request("http://localhost/health"));
|
||||
const body = await response.json();
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(body.ok).toBe(true);
|
||||
expect(body.service).toBe("gateway-checker");
|
||||
});
|
||||
|
||||
test("未知 /api/* 路由返回 JSON 404", async () => {
|
||||
const response = await fetchHandler(new Request("http://localhost/api/missing"));
|
||||
const body = await response.json();
|
||||
|
||||
expect(response.status).toBe(404);
|
||||
expect(response.headers.get("content-type")).toContain("application/json");
|
||||
expect(body.status).toBe(404);
|
||||
});
|
||||
|
||||
test("生产根路径返回前端入口", async () => {
|
||||
const response = await fetchHandler(new Request("http://localhost/"));
|
||||
const body = await response.text();
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers.get("content-type")).toContain("text/html");
|
||||
expect(body).toContain("Gateway Checker Demo");
|
||||
});
|
||||
|
||||
test("生产静态资源返回正确内容类型", async () => {
|
||||
const response = await fetchHandler(new Request("http://localhost/assets/app.js"));
|
||||
const body = await response.text();
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers.get("content-type")).toContain("text/javascript");
|
||||
expect(body).toContain("demo");
|
||||
});
|
||||
|
||||
test("前端路由 fallback 到入口 HTML", async () => {
|
||||
const response = await fetchHandler(new Request("http://localhost/dashboard"));
|
||||
const body = await response.text();
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(body).toContain("Gateway Checker Demo");
|
||||
});
|
||||
});
|
||||
26
tests/server/config.test.ts
Normal file
26
tests/server/config.test.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { readRuntimeConfig } from "../../src/server/config";
|
||||
|
||||
describe("runtime config", () => {
|
||||
test("默认使用 127.0.0.1:3000", () => {
|
||||
expect(readRuntimeConfig([], {})).toEqual({ host: "127.0.0.1", port: 3000 });
|
||||
});
|
||||
|
||||
test("CLI 参数优先于环境变量", () => {
|
||||
expect(readRuntimeConfig(["--host", "0.0.0.0", "--port", "4001"], { HOST: "127.0.0.1", PORT: "3001" })).toEqual({
|
||||
host: "0.0.0.0",
|
||||
port: 4001,
|
||||
});
|
||||
});
|
||||
|
||||
test("支持 inline CLI 参数", () => {
|
||||
expect(readRuntimeConfig(["--host=localhost", "--port=4002"], {})).toEqual({
|
||||
host: "localhost",
|
||||
port: 4002,
|
||||
});
|
||||
});
|
||||
|
||||
test("拒绝无效端口", () => {
|
||||
expect(() => readRuntimeConfig(["--port", "invalid"], {})).toThrow("无效端口");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user