diff options
author | 2023-02-14 17:54:50 -0600 | |
---|---|---|
committer | 2023-02-14 15:54:50 -0800 | |
commit | a80981c9662bc439871ca2197a908632c82491d9 (patch) | |
tree | 064202a6a68ec233b2226c1e6ef95abadd50a7bd /test/bun.js | |
parent | 6e1a52691a370058e97ddb84c8f7c49e5bbf1e7e (diff) | |
download | bun-a80981c9662bc439871ca2197a908632c82491d9.tar.gz bun-a80981c9662bc439871ca2197a908632c82491d9.tar.zst bun-a80981c9662bc439871ca2197a908632c82491d9.zip |
[WIP] fix(node:fs): export `fs.ReadStream` and `fs.WriteStream` (#1798)
* fix(node:fs): export fs.WriteStream and fs.ReadStream
* test(node:fs): add tests for fs.ReadStream and fs.WriteStream
* test(node:fs): prevent opening fd w/o closing
* fix(node:fs): hack ESM export for fs streams to keep lazy loading
* fix(node:fs): = -> ===, fix hasInstance comparison
* test(node:fs): add test that actually checks that re-exported streams work
* fix(fs): eagerly load our slow lazy fns (thanks esm)
* fix(fs): employ @alexlamsl 's constructor w/o new trick on Read/WriteStream
Diffstat (limited to '')
-rw-r--r-- | test/bun.js/fs.test.js | 184 |
1 files changed, 183 insertions, 1 deletions
diff --git a/test/bun.js/fs.test.js b/test/bun.js/fs.test.js index a203a47b4..086f19211 100644 --- a/test/bun.js/fs.test.js +++ b/test/bun.js/fs.test.js @@ -1,6 +1,6 @@ import { beforeEach, describe, expect, it } from "bun:test"; import { gc, gcTick } from "./gc"; -import { +import fs, { closeSync, existsSync, mkdirSync, @@ -26,8 +26,18 @@ import { Dirent, Stats, } from "node:fs"; +import { tmpdir } from "node:os"; import { join } from "node:path"; +import { + ReadStream as ReadStream_, + WriteStream as WriteStream_, +} from "../fixtures/export-lazy-fs-streams/export-from"; +import { + ReadStream as ReadStreamStar_, + WriteStream as WriteStreamStar_, +} from "../fixtures/export-lazy-fs-streams/export-*-from"; + const Buffer = globalThis.Buffer || Uint8Array; if (!import.meta.dir) { @@ -604,6 +614,178 @@ describe("createReadStream", () => { }); }); +describe("fs.WriteStream", () => { + it("should be exported", () => { + expect(fs.WriteStream).toBeDefined(); + }); + + it("should be constructable", () => { + const stream = new fs.WriteStream("test.txt"); + expect(stream instanceof fs.WriteStream).toBe(true); + }); + + it("should be able to write to a file", (done) => { + const pathToDir = `${tmpdir()}/${Date.now()}`; + mkdirSync(pathToDir); + const path = `${pathToDir}/fs-writestream-test.txt`; + + const stream = new fs.WriteStream(path, { flags: "w+" }); + stream.write("Test file written successfully"); + stream.end(); + + stream.on("error", (e) => { + done(e instanceof Error ? e : new Error(e)); + }); + + stream.on("finish", () => { + expect(readFileSync(path, "utf8")).toBe("Test file written successfully"); + done(); + }); + }); + + it("should work if re-exported by name", () => { + const stream = new WriteStream_("test.txt"); + expect(stream instanceof WriteStream_).toBe(true); + expect(stream instanceof WriteStreamStar_).toBe(true); + expect(stream instanceof fs.WriteStream).toBe(true); + }); + + it("should work if re-exported by name, called without new", () => { + const stream = WriteStream_("test.txt"); + expect(stream instanceof WriteStream_).toBe(true); + expect(stream instanceof WriteStreamStar_).toBe(true); + expect(stream instanceof fs.WriteStream).toBe(true); + }); + + it("should work if re-exported, as export * from ...", () => { + const stream = new WriteStreamStar_("test.txt"); + expect(stream instanceof WriteStream_).toBe(true); + expect(stream instanceof WriteStreamStar_).toBe(true); + expect(stream instanceof fs.WriteStream).toBe(true); + }); + + it("should work if re-exported, as export * from..., called without new", () => { + const stream = WriteStreamStar_("test.txt"); + expect(stream instanceof WriteStream_).toBe(true); + expect(stream instanceof WriteStreamStar_).toBe(true); + expect(stream instanceof fs.WriteStream).toBe(true); + }); + + it("should be able to write to a file with re-exported WriteStream", (done) => { + const pathToDir = `${tmpdir()}/${Date.now()}`; + mkdirSync(pathToDir); + const path = `${pathToDir}/fs-writestream-re-exported-test.txt`; + + const stream = new WriteStream_(path, { flags: "w+" }); + stream.write("Test file written successfully"); + stream.end(); + + stream.on("error", (e) => { + done(e instanceof Error ? e : new Error(e)); + }); + + stream.on("finish", () => { + expect(readFileSync(path, "utf8")).toBe("Test file written successfully"); + done(); + }); + }); +}); + +describe("fs.ReadStream", () => { + it("should be exported", () => { + expect(fs.ReadStream).toBeDefined(); + }); + + it("should be constructable", () => { + const stream = new fs.ReadStream("test.txt"); + expect(stream instanceof fs.ReadStream).toBe(true); + }); + + it("should be able to read from a file", (done) => { + const pathToDir = `${tmpdir()}/${Date.now()}`; + mkdirSync(pathToDir); + const path = `${pathToDir}fs-readstream-test.txt`; + + writeFileSync(path, "Test file written successfully", { + encoding: "utf8", + flag: "w+", + }); + + const stream = new fs.ReadStream(path); + stream.setEncoding("utf8"); + stream.on("error", (e) => { + done(e instanceof Error ? e : new Error(e)); + }); + + let data = ""; + + stream.on("data", (chunk) => { + data += chunk; + }); + + stream.on("end", () => { + expect(data).toBe("Test file written successfully"); + done(); + }); + }); + + it("should work if re-exported by name", () => { + const stream = new ReadStream_("test.txt"); + expect(stream instanceof ReadStream_).toBe(true); + expect(stream instanceof ReadStreamStar_).toBe(true); + expect(stream instanceof fs.ReadStream).toBe(true); + }); + + it("should work if re-exported by name, called without new", () => { + const stream = ReadStream_("test.txt"); + expect(stream instanceof ReadStream_).toBe(true); + expect(stream instanceof ReadStreamStar_).toBe(true); + expect(stream instanceof fs.ReadStream).toBe(true); + }); + + it("should work if re-exported as export * from ...", () => { + const stream = new ReadStreamStar_("test.txt"); + expect(stream instanceof ReadStreamStar_).toBe(true); + expect(stream instanceof ReadStream_).toBe(true); + expect(stream instanceof fs.ReadStream).toBe(true); + }); + + it("should work if re-exported as export * from ..., called without new", () => { + const stream = ReadStreamStar_("test.txt"); + expect(stream instanceof ReadStreamStar_).toBe(true); + expect(stream instanceof ReadStream_).toBe(true); + expect(stream instanceof fs.ReadStream).toBe(true); + }); + + it("should be able to read from a file, with re-exported ReadStream", (done) => { + const pathToDir = `${tmpdir()}/${Date.now()}`; + mkdirSync(pathToDir); + const path = `${pathToDir}fs-readstream-re-exported-test.txt`; + + writeFileSync(path, "Test file written successfully", { + encoding: "utf8", + flag: "w+", + }); + + const stream = new ReadStream_(path); + stream.setEncoding("utf8"); + stream.on("error", (e) => { + done(e instanceof Error ? e : new Error(e)); + }); + + let data = ""; + + stream.on("data", (chunk) => { + data += chunk; + }); + + stream.on("end", () => { + expect(data).toBe("Test file written successfully"); + done(); + }); + }); +}); + describe("createWriteStream", () => { it("simple write stream finishes", async () => { const path = `/tmp/fs.test.js/${Date.now()}.createWriteStream.txt`; |