aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorGravatar Alex Lam S.L <alexlamsl@gmail.com> 2022-12-28 02:34:33 +0200
committerGravatar GitHub <noreply@github.com> 2022-12-27 16:34:33 -0800
commitf78f423d0b3e225c5e7e5c3028e33823b9147f45 (patch)
tree6e2b1058965c4dee86ae54269e38361fded6e606 /test
parentc4ca4c70d194f63cc6598c8452656d97c3f7a5e6 (diff)
downloadbun-f78f423d0b3e225c5e7e5c3028e33823b9147f45.tar.gz
bun-f78f423d0b3e225c5e7e5c3028e33823b9147f45.tar.zst
bun-f78f423d0b3e225c5e7e5c3028e33823b9147f45.zip
emit `206 Partial Content` only for partial response (#1670)
fixes #1668
Diffstat (limited to 'test')
-rw-r--r--test/bun.js/serve.test.ts738
1 files changed, 297 insertions, 441 deletions
diff --git a/test/bun.js/serve.test.ts b/test/bun.js/serve.test.ts
index e8825d94f..becddc678 100644
--- a/test/bun.js/serve.test.ts
+++ b/test/bun.js/serve.test.ts
@@ -5,161 +5,145 @@ import { resolve } from "path";
afterEach(() => Bun.gc(true));
-var port = 40001;
+var port = 10000;
+var count = 200;
-class TestPass extends Error {
- constructor(message) {
- super(message);
- this.name = "TestPass";
+async function runTest(serverOptions, test) {
+ var server;
+ while (true) {
+ try {
+ serverOptions.port = port++;
+ server = serve(serverOptions);
+ break;
+ } catch (e: any) {
+ if (e?.message !== `Failed to start server. Is port ${serverOptions.port} in use?`) {
+ throw e;
+ }
+ }
+ }
+ try {
+ await test(server);
+ } finally {
+ server?.stop();
+ server = null;
}
}
-var count = 200;
it("should work for a file", async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
const textToExpect = readFileSync(fixture, "utf-8");
-
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(file(fixture));
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response.text()).toBe(textToExpect);
});
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response.text()).toBe(textToExpect);
- server.stop();
});
it("request.url should log successfully", async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
const textToExpect = readFileSync(fixture, "utf-8");
var expected;
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
expect(Bun.inspect(req).includes(expected)).toBe(true);
return new Response(file(fixture));
},
+ }, async (server) => {
+ expected = `http://localhost:${server.port}/helloooo`;
+ const response = await fetch(expected);
+ expect(response.url).toBe(expected);
+ expect(await response.text()).toBe(textToExpect);
});
- expected = `http://localhost:${server.port}/helloooo`;
- const response = await fetch(expected);
- expect(response.url).toBe(expected);
- expect(await response.text()).toBe(textToExpect);
- server.stop();
});
it("request.url should be based on the Host header", async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
const textToExpect = readFileSync(fixture, "utf-8");
- var expected;
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
expect(req.url).toBe("http://example.com/helloooo");
return new Response(file(fixture));
},
+ }, async (server) => {
+ const expected = `http://${server.hostname}:${server.port}/helloooo`;
+ const response = await fetch(expected, {
+ headers: {
+ Host: "example.com",
+ },
+ });
+ expect(response.url).toBe(expected);
+ expect(await response.text()).toBe(textToExpect);
});
- expected = `http://${server.hostname}:${server.port}/helloooo`;
- const response = await fetch(expected, {
- headers: {
- Host: "example.com",
- },
- });
- expect(response.url).toBe(expected);
- expect(await response.text()).toBe(textToExpect);
- server.stop();
});
describe("streaming", () => {
describe("error handler", () => {
it("throw on pull reports an error and close the connection", async () => {
- var server;
- try {
- var pass = false;
- server = serve({
- port: port++,
- development: false,
- error(e) {
- pass = true;
- return new Response("fail", { status: 500 });
- },
-
- fetch(req) {
- return new Response(
- new ReadableStream({
- pull(controller) {
- throw new Error("error");
- },
- }),
- );
- },
- });
-
+ var pass = false;
+ await runTest({
+ development: false,
+ error(e) {
+ pass = true;
+ return new Response("PASS", { status: 555 });
+ },
+ fetch(req) {
+ return new Response(
+ new ReadableStream({
+ pull(controller) {
+ throw new Error("FAIL");
+ },
+ }),
+ );
+ },
+ }, async (server) => {
const response = await fetch(
`http://${server.hostname}:${server.port}`,
);
if (response.status > 0) {
- expect(response.status).toBe(500);
- expect(await response.text()).toBe("fail");
+ expect(response.status).toBe(555);
+ expect(await response.text()).toBe("PASS");
}
-
expect(pass).toBe(true);
- } catch (e) {
- throw e;
- } finally {
- server?.stop();
- }
+ });
});
it("throw on pull after writing should not call the error handler", async () => {
- var server;
- try {
- var pass = true;
- server = serve({
- port: port++,
- development: false,
- error(e) {
- pass = false;
- server?.stop();
- server = null;
- return new Response("fail", { status: 500 });
- },
-
- fetch(req) {
- return new Response(
- new ReadableStream({
- pull(controller) {
- controller.enqueue("such fail");
- throw new Error("error");
- },
- }),
- );
- },
- });
-
+ var pass = true;
+ await runTest({
+ development: false,
+ error(e) {
+ pass = true;
+ return new Response("FAIL", { status: 555 });
+ },
+ fetch(req) {
+ return new Response(
+ new ReadableStream({
+ pull(controller) {
+ controller.enqueue("PASS");
+ throw new Error("error");
+ },
+ }),
+ );
+ },
+ }, async (server) => {
const response = await fetch(
`http://${server.hostname}:${server.port}`,
);
// connection terminated
- if (response.status > 0) {
- expect(response.status).toBe(200);
- expect(await response.text()).toBe("such fail");
- }
+ expect(response.status).toBe(500);
+ expect(await response.text()).toBe("PASS");
expect(pass).toBe(true);
- } catch (e) {
- throw e;
- } finally {
- server?.stop();
- }
+ });
});
});
it("text from JS, one chunk", async () => {
const relative = new URL("./fetch.js.txt", import.meta.url);
const textToExpect = readFileSync(relative, "utf-8");
-
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(
new ReadableStream({
@@ -170,20 +154,17 @@ describe("streaming", () => {
}),
);
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ const text = await response.text();
+ expect(text.length).toBe(textToExpect.length);
+ expect(text).toBe(textToExpect);
});
-
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- const text = await response.text();
- expect(text.length).toBe(textToExpect.length);
- expect(text).toBe(textToExpect);
- server.stop();
});
it("text from JS, two chunks", async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
- const textToExpect = readFileSync(fixture, "utf-8");
-
- const server = serve({
- port: port++,
+ const textToExpect = readFileSync(fixture, "utf-8")
+ await runTest({
fetch(req) {
return new Response(
new ReadableStream({
@@ -195,95 +176,64 @@ describe("streaming", () => {
}),
);
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response.text()).toBe(textToExpect);
});
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response.text()).toBe(textToExpect);
- server.stop();
});
it("text from JS throws on start no error handler", async () => {
- var server;
- try {
- var pass = false;
- server = serve({
- port: port++,
- development: false,
- fetch(req) {
- return new Response(
- new ReadableStream({
- start(controller) {
- throw new TestPass("Test Passed");
- },
- }),
- );
- },
- });
-
- var response;
- try {
- response = await fetch(`http://${server.hostname}:${server.port}`);
- } catch (e: any) {
- if (e.name !== "ConnectionClosed") {
- throw e;
- }
- }
-
- if (response) {
- expect(response.status).toBe(500);
- }
- } catch (e) {
- if (!e || !(e instanceof TestPass)) {
- throw e;
- }
- } finally {
- server?.stop();
- }
- gc(true);
+ await runTest({
+ port: port++,
+ development: false,
+ fetch(req) {
+ return new Response(
+ new ReadableStream({
+ start(controller) {
+ throw new Error("Test Passed");
+ },
+ }),
+ );
+ },
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(response.status).toBe(500);
+ });
});
it("text from JS throws on start has error handler", async () => {
- var server;
- try {
- var pass = false;
- var err = { name: "", message: "" };
- server = serve({
- port: port++,
- development: false,
- error(e) {
- pass = true;
- err = e;
- return new Response("Fail", { status: 500 });
- },
- fetch(req) {
- return new Response(
- new ReadableStream({
- start(controller) {
- throw new TypeError("error");
- },
- }),
- );
- },
- });
-
+ var pass = false;
+ var err;
+ await runTest({
+ development: false,
+ error(e) {
+ pass = true;
+ err = e;
+ return new Response("Fail", { status: 500 });
+ },
+ fetch(req) {
+ return new Response(
+ new ReadableStream({
+ start(controller) {
+ throw new TypeError("error");
+ },
+ }),
+ );
+ },
+ }, async (server) => {
const response = await fetch(`http://${server.hostname}:${server.port}`);
expect(response.status).toBe(500);
expect(await response.text()).toBe("Fail");
expect(pass).toBe(true);
- expect(err.name).toBe("TypeError");
- expect(err.message).toBe("error");
- } catch (e) {
- throw e;
- } finally {
- server?.stop();
- }
+ expect(err?.name).toBe("TypeError");
+ expect(err?.message).toBe("error");
+ });
});
it("text from JS, 2 chunks, with delay", async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
const textToExpect = readFileSync(fixture, "utf-8");
-
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(
new ReadableStream({
@@ -297,18 +247,16 @@ describe("streaming", () => {
}),
);
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response.text()).toBe(textToExpect);
});
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response.text()).toBe(textToExpect);
- server.stop();
});
it("text from JS, 1 chunk via pull()", async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
const textToExpect = readFileSync(fixture, "utf-8");
-
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(
new ReadableStream({
@@ -319,19 +267,17 @@ describe("streaming", () => {
}),
);
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ const text = await response.text();
+ expect(text).toBe(textToExpect);
});
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- const text = await response.text();
- expect(text).toBe(textToExpect);
- server.stop();
});
it("text from JS, 2 chunks, with delay in pull", async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
const textToExpect = readFileSync(fixture, "utf-8");
-
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(
new ReadableStream({
@@ -345,18 +291,16 @@ describe("streaming", () => {
}),
);
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response.text()).toBe(textToExpect);
});
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response.text()).toBe(textToExpect);
- server.stop();
});
it("text from JS, 2 chunks, with async pull", async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
const textToExpect = readFileSync(fixture, "utf-8");
-
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(
new ReadableStream({
@@ -370,18 +314,16 @@ describe("streaming", () => {
}),
);
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response.text()).toBe(textToExpect);
});
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response.text()).toBe(textToExpect);
- server.stop();
});
it("text from JS, 10 chunks, with async pull", async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
const textToExpect = readFileSync(fixture, "utf-8");
-
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(
new ReadableStream({
@@ -399,75 +341,66 @@ describe("streaming", () => {
}),
);
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response.text()).toBe(textToExpect);
});
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response.text()).toBe(textToExpect);
- server.stop();
});
});
it("should work for a hello world", async () => {
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(`Hello, world!`);
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response.text()).toBe("Hello, world!");
});
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response.text()).toBe("Hello, world!");
- server.stop();
});
it("should work for a blob", async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
const textToExpect = readFileSync(fixture, "utf-8");
-
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(new Blob([textToExpect]));
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response.text()).toBe(textToExpect);
});
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response.text()).toBe(textToExpect);
- server.stop();
});
it("should work for a blob stream", async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
const textToExpect = readFileSync(fixture, "utf-8");
-
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(new Blob([textToExpect]).stream());
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response.text()).toBe(textToExpect);
});
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response.text()).toBe(textToExpect);
- server.stop();
});
it("should work for a file stream", async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
const textToExpect = readFileSync(fixture, "utf-8");
-
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(file(fixture).stream());
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response.text()).toBe(textToExpect);
});
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response.text()).toBe(textToExpect);
- server.stop();
});
it("fetch should work with headers", async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
-
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
if (req.headers.get("X-Foo") !== "bar") {
return new Response("X-Foo header not set", { status: 500 });
@@ -476,127 +409,107 @@ it("fetch should work with headers", async () => {
headers: { "X-Both-Ways": "1" },
});
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`, {
+ headers: {
+ "X-Foo": "bar",
+ },
+ });
+ expect(response.status).toBe(200);
+ expect(response.headers.get("X-Both-Ways")).toBe("1");
});
- const response = await fetch(`http://${server.hostname}:${server.port}`, {
- headers: {
- "X-Foo": "bar",
- },
- });
-
- expect(response.status).toBe(200);
- expect(response.headers.get("X-Both-Ways")).toBe("1");
- server.stop();
});
it(`should work for a file ${count} times serial`, async () => {
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
const textToExpect = readFileSync(fixture, "utf-8");
- var ran = 0;
- const server = serve({
- port: port++,
+ await runTest({
async fetch(req) {
return new Response(file(fixture));
},
+ }, async (server) => {
+ for (let i = 0; i < count; i++) {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response.text()).toBe(textToExpect);
+ }
});
-
- for (let i = 0; i < count; i++) {
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response.text()).toBe(textToExpect);
- }
-
- server.stop();
});
it(`should work for ArrayBuffer ${count} times serial`, async () => {
const textToExpect = "hello";
- var ran = 0;
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(new TextEncoder().encode(textToExpect));
},
+ }, async (server) => {
+ for (let i = 0; i < count; i++) {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response.text()).toBe(textToExpect);
+ }
});
-
- for (let i = 0; i < count; i++) {
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response.text()).toBe(textToExpect);
- }
-
- server.stop();
});
-describe("parallell", () => {
+describe("parallel", () => {
it(`should work for text ${count} times in batches of 5`, async () => {
const textToExpect = "hello";
- var ran = 0;
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(textToExpect);
},
- });
-
- for (let i = 0; i < count; ) {
- let responses = await Promise.all([
- fetch(`http://${server.hostname}:${server.port}`),
- fetch(`http://${server.hostname}:${server.port}`),
- fetch(`http://${server.hostname}:${server.port}`),
- fetch(`http://${server.hostname}:${server.port}`),
- fetch(`http://${server.hostname}:${server.port}`),
- ]);
-
- for (let response of responses) {
- expect(await response.text()).toBe(textToExpect);
+ }, async (server) => {
+ for (let i = 0; i < count; ) {
+ let responses = await Promise.all([
+ fetch(`http://${server.hostname}:${server.port}`),
+ fetch(`http://${server.hostname}:${server.port}`),
+ fetch(`http://${server.hostname}:${server.port}`),
+ fetch(`http://${server.hostname}:${server.port}`),
+ fetch(`http://${server.hostname}:${server.port}`),
+ ]);
+
+ for (let response of responses) {
+ expect(await response.text()).toBe(textToExpect);
+ }
+ i += responses.length;
}
- i += responses.length;
- }
-
- server.stop();
+ });
});
it(`should work for Uint8Array ${count} times in batches of 5`, async () => {
const textToExpect = "hello";
- var ran = 0;
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response(new TextEncoder().encode(textToExpect));
},
- });
-
- for (let i = 0; i < count; ) {
- let responses = await Promise.all([
- fetch(`http://${server.hostname}:${server.port}`),
- fetch(`http://${server.hostname}:${server.port}`),
- fetch(`http://${server.hostname}:${server.port}`),
- fetch(`http://${server.hostname}:${server.port}`),
- fetch(`http://${server.hostname}:${server.port}`),
- ]);
-
- for (let response of responses) {
- expect(await response.text()).toBe(textToExpect);
+ }, async (server) => {
+ for (let i = 0; i < count; ) {
+ let responses = await Promise.all([
+ fetch(`http://${server.hostname}:${server.port}`),
+ fetch(`http://${server.hostname}:${server.port}`),
+ fetch(`http://${server.hostname}:${server.port}`),
+ fetch(`http://${server.hostname}:${server.port}`),
+ fetch(`http://${server.hostname}:${server.port}`),
+ ]);
+
+ for (let response of responses) {
+ expect(await response.text()).toBe(textToExpect);
+ }
+ i += responses.length;
}
- i += responses.length;
- }
-
- server.stop();
+ });
});
});
it("should support reloading", async () => {
const first = (req) => new Response("first");
const second = (req) => new Response("second");
-
- const server = serve({
- port: port++,
+ await runTest({
fetch: first,
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response.text()).toBe("first");
+ server.reload({ fetch: second });
+ const response2 = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(await response2.text()).toBe("second");
});
-
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response.text()).toBe("first");
- server.reload({ fetch: second });
- const response2 = await fetch(`http://${server.hostname}:${server.port}`);
- expect(await response2.text()).toBe("second");
- server.stop();
});
describe("status code text", () => {
@@ -664,24 +577,21 @@ describe("status code text", () => {
for (let code in fixture) {
it(`should return ${code} ${fixture[code]}`, async () => {
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response("hey", { status: +code });
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(response.status).toBe(parseInt(code));
+ expect(response.statusText).toBe(fixture[code]);
});
-
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- expect(response.status).toBe(parseInt(code));
- expect(response.statusText).toBe(fixture[code]);
- server.stop();
});
}
});
it("should support multiple Set-Cookie headers", async () => {
- const server = serve({
- port: port++,
+ await runTest({
fetch(req) {
return new Response("hello", {
headers: [
@@ -691,38 +601,30 @@ it("should support multiple Set-Cookie headers", async () => {
],
});
},
+ }, async (server) => {
+ const response = await fetch(`http://${server.hostname}:${server.port}`);
+ expect(response.headers.getAll("Set-Cookie")).toEqual(["foo=bar", "baz=qux"]);
+ expect(response.headers.get("Set-Cookie")).toEqual("foo=bar, baz=qux");
+
+ const cloned = response.clone().headers;
+ expect(response.headers.getAll("Set-Cookie")).toEqual(["foo=bar", "baz=qux"]);
+
+ response.headers.delete("Set-Cookie");
+ expect(response.headers.getAll("Set-Cookie")).toEqual([]);
+ response.headers.delete("Set-Cookie");
+ expect(cloned.getAll("Set-Cookie")).toEqual(["foo=bar", "baz=qux"]);
+ expect(new Headers(cloned).getAll("Set-Cookie")).toEqual([
+ "foo=bar",
+ "baz=qux",
+ ]);
});
-
- const response = await fetch(`http://${server.hostname}:${server.port}`);
- server.stop();
-
- expect(response.headers.getAll("Set-Cookie")).toEqual(["foo=bar", "baz=qux"]);
- expect(response.headers.get("Set-Cookie")).toEqual("foo=bar, baz=qux");
-
- const cloned = response.clone().headers;
- expect(response.headers.getAll("Set-Cookie")).toEqual(["foo=bar", "baz=qux"]);
-
- response.headers.delete("Set-Cookie");
- expect(response.headers.getAll("Set-Cookie")).toEqual([]);
- response.headers.delete("Set-Cookie");
- expect(cloned.getAll("Set-Cookie")).toEqual(["foo=bar", "baz=qux"]);
- expect(new Headers(cloned).getAll("Set-Cookie")).toEqual([
- "foo=bar",
- "baz=qux",
- ]);
});
describe("should support Content-Range with Bun.file()", () => {
var server;
- var full;
-
- const fixture = resolve(import.meta.dir + "/fetch.js.txt") + ".big";
-
// this must be a big file so we can test potentially multiple chunks
// more than 65 KB
- function getFull() {
- if (full) return full;
- console.log("here");
+ const full = function() {
const fixture = resolve(import.meta.dir + "/fetch.js.txt");
const chunk = readFileSync(fixture);
var whole = new Uint8Array(chunk.byteLength * 128);
@@ -730,69 +632,50 @@ describe("should support Content-Range with Bun.file()", () => {
whole.set(chunk, i * chunk.byteLength);
}
writeFileSync(fixture + ".big", whole);
- return (full = whole);
- }
+ return whole;
+ }();
+ const fixture = resolve(import.meta.dir + "/fetch.js.txt") + ".big";
+ const getServer = runTest.bind(null, {
+ fetch(req) {
+ const { searchParams } = new URL(req.url);
+ const start = Number(searchParams.get("start"));
+ const end = Number(searchParams.get("end"));
+ return new Response(Bun.file(fixture).slice(start, end));
+ },
+ });
- function getServer() {
- server ||= serve({
- port: port++,
- fetch(req) {
- const { searchParams } = new URL(req.url);
- const start = Number(searchParams.get("start"));
- const end = Number(searchParams.get("end"));
- return new Response(Bun.file(fixture).slice(start, end));
- },
+ const good = [
+ [0, 1],
+ [1, 2],
+ [0, 10],
+ [10, 20],
+ [0, Infinity],
+ [10, Infinity],
+ [NaN, Infinity],
+ [full.byteLength - 10, full.byteLength],
+ [full.byteLength - 10, full.byteLength - 1],
+ [full.byteLength - 1, full.byteLength],
+ [0, full.byteLength],
+ ] as const;
+
+ for (const [start, end] of good) {
+ it(`good range: ${start} - ${end}`, async () => {
+ await getServer(async (server) => {
+ const response = await fetch(
+ `http://${server.hostname}:${server.port}/?start=${start}&end=${end}`,
+ {},
+ { verbose: true },
+ );
+ expect(await response.arrayBuffer()).toEqual(
+ full.buffer.slice(start, end),
+ );
+ expect(response.status).toBe(
+ start > 0 || end < full.byteLength ? 206 : 200,
+ );
+ });
});
}
- describe("good range", () => {
- getFull();
-
- const good = [
- [0, 1],
- [1, 2],
- [0, 10],
- [10, 20],
- [0, Infinity],
- [NaN, Infinity],
- [full.byteLength - 10, full.byteLength],
- [full.byteLength - 10, full.byteLength - 1],
- [full.byteLength - 1, full.byteLength],
- [0, full.byteLength],
- ] as const;
-
- for (let [start, end] of good) {
- const last = start === good.at(-1)![0] && end === good.at(-1)![1];
-
- it(`range: ${start} - ${end}`, async () => {
- try {
- getFull();
- getServer();
-
- await 1;
- const response = await fetch(
- `http://${server.hostname}:${server.port}/?start=${start}&end=${end}`,
- {},
- { verbose: true },
- );
- expect(await response.arrayBuffer()).toEqual(
- full.buffer.slice(start, end),
- );
- expect(response.status).toBe(
- end - start === full.byteLength ? 200 : 206,
- );
- } catch (e) {
- throw e;
- } finally {
- if (last) {
- server.stop();
- server = null;
- }
- }
- });
- }
- });
-
const emptyRanges = [
[0, 0],
[1, 1],
@@ -805,34 +688,19 @@ describe("should support Content-Range with Bun.file()", () => {
[full.byteLength - 1, full.byteLength - 1],
];
- for (let [start, end] of emptyRanges) {
+ for (const [start, end] of emptyRanges) {
it(`empty range: ${start} - ${end}`, async () => {
- const last =
- start === emptyRanges.at(-1)[0] && end === emptyRanges.at(-1)[1];
-
- try {
- getFull();
- getServer();
-
+ await getServer(async (server) => {
const response = await fetch(
`http://${server.hostname}:${server.port}/?start=${start}&end=${end}`,
);
const out = await response.arrayBuffer();
expect(out).toEqual(new ArrayBuffer(0));
expect(response.status).toBe(206);
- } catch (e) {
- throw e;
- } finally {
- if (last) {
- server.stop();
- server = null;
- }
- }
+ });
});
}
- getFull();
-
const badRanges = [
[10, NaN],
[10, -Infinity],
@@ -844,28 +712,16 @@ describe("should support Content-Range with Bun.file()", () => {
[full.byteLength + 100, -full.byteLength],
];
- for (let [start, end] of badRanges) {
+ for (const [start, end] of badRanges) {
it(`bad range: ${start} - ${end}`, async () => {
- const last = start === badRanges.at(-1)[0] && end === badRanges.at(-1)[1];
-
- try {
- getFull();
- getServer();
-
+ await getServer(async (server) => {
const response = await fetch(
`http://${server.hostname}:${server.port}/?start=${start}&end=${end}`,
);
const out = await response.arrayBuffer();
expect(out).toEqual(new ArrayBuffer(0));
expect(response.status).toBe(206);
- } catch (e) {
- throw e;
- } finally {
- if (last) {
- server.stop();
- server = null;
- }
- }
+ });
});
}
});