Files
bun.sh/test/js/node/stream/node-stream.test.js
Ai Hoshino 9b91e3c1a2 fix the chunk boundary (node:stream:createReadStream) (#3853)
* fix the slice boundary.
Close: #3668

* Add more boundary test case.

* fix end is 0.
2023-07-28 15:44:33 -07:00

169 lines
4.5 KiB
JavaScript

import { expect, describe, it } from "bun:test";
import { Readable, Writable, Duplex, Transform, PassThrough } from "node:stream";
import { createReadStream } from "node:fs";
import { tmpdir } from "node:os";
import { writeFileSync } from "node:fs";
describe("Readable", () => {
it("should be able to be created without _construct method defined", done => {
const readable = new Readable({
read() {
this.push("Hello World!\n");
this.push(null);
},
});
expect(readable instanceof Readable).toBe(true);
let data = "";
readable.on("data", chunk => {
data += chunk.toString();
});
readable.on("end", () => {
expect(data).toBe("Hello World!\n");
done();
});
});
it("should be able to be piped via .pipe", done => {
const readable = new Readable({
read() {
this.push("Hello World!");
this.push(null);
},
});
const writable = new Writable({
write(chunk, encoding, callback) {
expect(chunk.toString()).toBe("Hello World!");
callback();
done();
},
});
readable.pipe(writable);
});
it("should be able to be piped via .pipe, issue #3668", done => {
const path = `${tmpdir()}/${Date.now()}.testReadStream.txt`;
writeFileSync(path, "12345");
const stream = createReadStream(path, { start: 0, end: 4 });
const writable = new Writable({
write(chunk, encoding, callback) {
try {
expect(chunk.toString()).toBe("12345");
} catch (err) {
done(err);
return;
}
callback();
done();
},
});
stream.on("error", err => {
done(err);
});
stream.pipe(writable);
});
it("should be able to be piped via .pipe, both start and end are 0", done => {
const path = `${tmpdir()}/${Date.now()}.testReadStream2.txt`;
writeFileSync(path, "12345");
const stream = createReadStream(path, { start: 0, end: 0 });
const writable = new Writable({
write(chunk, encoding, callback) {
try {
// Both start and end are inclusive and start counting at 0.
expect(chunk.toString()).toBe("1");
} catch (err) {
done(err);
return;
}
callback();
done();
},
});
stream.on("error", err => {
done(err);
});
stream.pipe(writable);
});
it("should be able to be piped via .pipe with a large file", done => {
const length = 128 * 1024;
const data = "B".repeat(length);
const path = `${tmpdir()}/${Date.now()}.testReadStreamLargeFile.txt`;
writeFileSync(path, data);
const stream = createReadStream(path, { start: 0, end: length - 1 });
let res = "";
let count = 0;
const writable = new Writable({
write(chunk, encoding, callback) {
count += 1;
res += chunk;
callback();
},
});
writable.on("finish", () => {
try {
expect(res).toEqual(data);
expect(count).toBeGreaterThan(1);
} catch (err) {
return done(err);
}
done();
});
stream.on("error", err => {
done(err);
});
stream.pipe(writable);
});
});
describe("Duplex", () => {
it("should allow subclasses to be derived via .call() on class", () => {
function Subclass(opts) {
if (!(this instanceof Subclass)) return new Subclass(opts);
Duplex.call(this, opts);
}
Object.setPrototypeOf(Subclass.prototype, Duplex.prototype);
Object.setPrototypeOf(Subclass, Duplex);
const subclass = new Subclass();
expect(subclass instanceof Duplex).toBe(true);
});
});
describe("Transform", () => {
it("should allow subclasses to be derived via .call() on class", () => {
function Subclass(opts) {
if (!(this instanceof Subclass)) return new Subclass(opts);
Transform.call(this, opts);
}
Object.setPrototypeOf(Subclass.prototype, Transform.prototype);
Object.setPrototypeOf(Subclass, Transform);
const subclass = new Subclass();
expect(subclass instanceof Transform).toBe(true);
});
});
describe("PassThrough", () => {
it("should allow subclasses to be derived via .call() on class", () => {
function Subclass(opts) {
if (!(this instanceof Subclass)) return new Subclass(opts);
PassThrough.call(this, opts);
}
Object.setPrototypeOf(Subclass.prototype, PassThrough.prototype);
Object.setPrototypeOf(Subclass, PassThrough);
const subclass = new Subclass();
expect(subclass instanceof PassThrough).toBe(true);
});
});