diff options
author | 2022-12-28 02:34:33 +0200 | |
---|---|---|
committer | 2022-12-27 16:34:33 -0800 | |
commit | f78f423d0b3e225c5e7e5c3028e33823b9147f45 (patch) | |
tree | 6e2b1058965c4dee86ae54269e38361fded6e606 /test | |
parent | c4ca4c70d194f63cc6598c8452656d97c3f7a5e6 (diff) | |
download | bun-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.ts | 738 |
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; - } - } + }); }); } }); |