Add an HTTP server for development purposes that replies to requests with both the static resources and on the fly generated pages. This serves the following needs. - Modern module scripts requires an origin supporting CORS policies, which is not supported when pages are read from disk by the browser. - Provide a way for implemting automatic reloading of pages when changes are made to the source files. - Act as the starting point for making interactive features such as comments and analytics.
97 lines
3.4 KiB
TypeScript
97 lines
3.4 KiB
TypeScript
import * as assert from "node:assert/strict";
|
|
import { after, before, suite, test } from "node:test";
|
|
import * as http from "node:http";
|
|
import { createServer } from "./http-server.js";
|
|
import { once } from "node:events";
|
|
import type { AddressInfo } from "node:net";
|
|
|
|
suite("function createServer", () => {
|
|
let server: ReturnType<typeof createServer>;
|
|
let baseUrl: URL;
|
|
|
|
before(async () => {
|
|
server = createServer(
|
|
ref => {
|
|
if (ref === "/test.html") return Buffer.from("<p>Test!</p>");
|
|
if (ref === "/style.css") return Buffer.from("p { font-weight: bold; }");
|
|
if (ref === "/script.js") return Buffer.from("alert('Hello world!');");
|
|
return undefined;
|
|
}
|
|
);
|
|
server.listen(0, "localhost");
|
|
await once(server, "listening");
|
|
baseUrl = new URL(`http://localhost:${(server.address() as AddressInfo).port}`)
|
|
});
|
|
after(() => {
|
|
server.close();
|
|
})
|
|
|
|
async function makeRequest(method: string, ref: string) {
|
|
const url = new URL(ref, baseUrl);
|
|
const request = http.request(url, {
|
|
method,
|
|
timeout: 1000,
|
|
});
|
|
request.end();
|
|
const response: http.IncomingMessage & { body: Buffer } = (await once(request, "response"))[0];
|
|
response.body = Buffer.concat(await response.toArray());
|
|
return { request, response };
|
|
}
|
|
|
|
async function getTest(ref: string, statusCode: number, content: Buffer, mediaType: string) {
|
|
const { response } = await makeRequest("GET", ref);
|
|
assert.equal(response.statusCode, statusCode);
|
|
assert.equal(response.headers["content-type"], mediaType);
|
|
assert.equal(Number.parseInt(response.headers["content-length"]!), content.length);
|
|
assert.deepEqual(response.body, content);
|
|
}
|
|
|
|
async function headTest(ref: string, statusCode: number, content: Buffer, mediaType: string) {
|
|
const { response } = await makeRequest("HEAD", ref);
|
|
assert.equal(response.statusCode, statusCode);
|
|
assert.equal(response.headers["content-type"], mediaType);
|
|
assert.equal(Number.parseInt(response.headers["content-length"]!), content.length);
|
|
assert.deepEqual(response.body, Buffer.alloc(0));
|
|
}
|
|
|
|
test("GET /test.html", async () => {
|
|
await getTest("/test.html", 200, Buffer.from("<p>Test!</p>"), "text/html")
|
|
});
|
|
|
|
test("GET /style.css", async () => {
|
|
await getTest("/style.css", 200, Buffer.from("p { font-weight: bold; }"), "text/css")
|
|
});
|
|
|
|
test("GET /script.js", async () => {
|
|
await getTest("/script.js", 200, Buffer.from("alert('Hello world!');"), "text/javascript")
|
|
});
|
|
|
|
test("GET /does-not-exist", async () => {
|
|
await getTest("/does-not-exist", 404, Buffer.from("404 Not Found"), "text/plain")
|
|
});
|
|
|
|
test("HEAD /test.html", async () => {
|
|
await headTest("/test.html", 200, Buffer.from("<p>Test!</p>"), "text/html")
|
|
});
|
|
|
|
test("HEAD /style.css", async () => {
|
|
await headTest("/style.css", 200, Buffer.from("p { font-weight: bold; }"), "text/css")
|
|
});
|
|
|
|
test("HEAD /script.js", async () => {
|
|
await headTest("/script.js", 200, Buffer.from("alert('Hello world!');"), "text/javascript")
|
|
});
|
|
|
|
test("HEAD /does-not-exist", async () => {
|
|
await headTest("/does-not-exist", 404, Buffer.from("404 Not Found"), "text/plain")
|
|
});
|
|
|
|
test("POST /test.html", async () => {
|
|
const { response } = await makeRequest("POST", "/test.html");
|
|
const content = Buffer.from("400 Bad Request");
|
|
assert.equal(response.statusCode, 400);
|
|
assert.equal(response.headers["content-type"], "text/plain");
|
|
assert.equal(Number.parseInt(response.headers["content-length"]!), content.length);
|
|
assert.deepEqual(response.body, content);
|
|
});
|
|
});
|