import fetch2, { fetch, Response, Request, Headers } from "node-fetch"; import * as iso from "isomorphic-fetch"; import * as vercelFetch from "@vercel/fetch"; import * as stream from "stream"; import { test, expect } from "bun:test"; test("node-fetch", () => { expect(Response.prototype).toBeInstanceOf(globalThis.Response); expect(Request).toBe(globalThis.Request); expect(Headers).toBe(globalThis.Headers); expect(fetch2.default).toBe(fetch2); expect(fetch2.Response).toBe(Response); }); for (const [impl, name] of [ [fetch, "node-fetch.fetch"], [fetch2, "node-fetch.default"], [fetch2.default, "node-fetch.default.default"], [iso.fetch, "isomorphic-fetch.fetch"], [iso.default.fetch, "isomorphic-fetch.default.fetch"], [iso.default, "isomorphic-fetch.default"], [vercelFetch.default(fetch), "@vercel/fetch.default"], ]) { test(name + " fetches", async () => { const server = Bun.serve({ port: 0, fetch(req, server) { server.stop(); return new Response("it works"); }, }); expect(await impl("http://" + server.hostname + ":" + server.port)).toBeInstanceOf(globalThis.Response); server.stop(true); }); } test("node-fetch uses node streams instead of web streams", async () => { const server = Bun.serve({ port: 0, async fetch(req, server) { const body = await req.text(); expect(body).toBe("the input text"); return new Response("hello world"); }, }); try { const result = await fetch2("http://" + server.hostname + ":" + server.port, { body: new stream.Readable({ read() { this.push("the input text"); this.push(null); }, }), method: "POST", }); expect(result.body).toBeInstanceOf(stream.Readable); expect(result.body === result.body).toBe(true); // cached lazy getter const chunks = []; for await (const chunk of result.body) { chunks.push(chunk); } expect(Buffer.concat(chunks).toString()).toBe("hello world"); } finally { server.stop(true); } });