aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/js/node/stream/node-stream.test.js124
1 files changed, 123 insertions, 1 deletions
diff --git a/test/js/node/stream/node-stream.test.js b/test/js/node/stream/node-stream.test.js
index 5f5b9d67a..44f3f4ff8 100644
--- a/test/js/node/stream/node-stream.test.js
+++ b/test/js/node/stream/node-stream.test.js
@@ -1,8 +1,10 @@
import { expect, describe, it } from "bun:test";
import { Readable, Writable, Duplex, Transform, PassThrough } from "node:stream";
import { createReadStream } from "node:fs";
+import { join } from "path";
+import { bunExe, bunEnv } from "harness";
import { tmpdir } from "node:os";
-import { writeFileSync } from "node:fs";
+import { writeFileSync, mkdirSync } from "node:fs";
describe("Readable", () => {
it("should be able to be created without _construct method defined", done => {
@@ -192,3 +194,123 @@ describe("PassThrough", () => {
expect(subclass instanceof PassThrough).toBe(true);
});
});
+
+const ttyStreamsTest = `
+import tty from "tty";
+
+import { dlopen } from "bun:ffi";
+
+const suffix = process.platform === "darwin" ? "dylib" : "so.6";
+
+var lazyOpenpty;
+export function openpty() {
+ if (!lazyOpenpty) {
+ lazyOpenpty = dlopen(\`libc.\${suffix}\`, {
+ openpty: {
+ args: ["ptr", "ptr", "ptr", "ptr", "ptr"],
+ returns: "int",
+ },
+ }).symbols.openpty;
+ }
+
+ const parent_fd = new Int32Array(1).fill(0);
+ const child_fd = new Int32Array(1).fill(0);
+ const name_buf = new Int8Array(1000).fill(0);
+ const term_buf = new Uint8Array(1000).fill(0);
+ const win_buf = new Uint8Array(1000).fill(0);
+
+ lazyOpenpty(parent_fd, child_fd, name_buf, term_buf, win_buf);
+
+ return {
+ parent_fd: parent_fd[0],
+ child_fd: child_fd[0],
+ };
+}
+
+var lazyClose;
+export function close(fd) {
+ if (!lazyClose) {
+ lazyClose = dlopen(\`libc.\${suffix}\`, {
+ close: {
+ args: ["int"],
+ returns: "int",
+ },
+ }).symbols.close;
+ }
+
+ lazyClose(fd);
+}
+
+describe("TTY", () => {
+ it("ReadStream stdin", () => {
+ const { parent_fd, child_fd } = openpty();
+ const rs = new tty.ReadStream(parent_fd);
+ const rs1 = tty.ReadStream(child_fd);
+ expect(rs1 instanceof tty.ReadStream).toBe(true);
+ expect(rs instanceof tty.ReadStream).toBe(true);
+ expect(tty.isatty(rs.fd)).toBe(true);
+ expect(tty.isatty(rs1.fd)).toBe(true);
+ expect(rs.isRaw).toBe(false);
+ expect(rs.isTTY).toBe(true);
+ expect(rs.setRawMode).toBeInstanceOf(Function);
+ expect(rs.setRawMode(true)).toBe(rs);
+ expect(rs.isRaw).toBe(true);
+ expect(rs.setRawMode(false)).toBe(rs);
+ expect(rs.isRaw).toBe(false);
+ close(parent_fd);
+ close(child_fd);
+ });
+ it("WriteStream stdout", () => {
+ const { child_fd, parent_fd } = openpty();
+ const ws = new tty.WriteStream(child_fd);
+ const ws1 = tty.WriteStream(parent_fd);
+ expect(ws1 instanceof tty.WriteStream).toBe(true);
+ expect(ws instanceof tty.WriteStream).toBe(true);
+ expect(tty.isatty(ws.fd)).toBe(true);
+ expect(ws.isTTY).toBe(true);
+
+ // pseudo terminal, not the best test because cols and rows can be 0
+ expect(ws.columns).toBeGreaterThanOrEqual(0);
+ expect(ws.rows).toBeGreaterThanOrEqual(0);
+ expect(ws.getColorDepth()).toBeGreaterThanOrEqual(0);
+ expect(ws.hasColors(2)).toBe(true);
+ close(parent_fd);
+ close(child_fd);
+ });
+ it("process.stdio tty", () => {
+ expect(process.stdin instanceof tty.ReadStream).toBe(true);
+ expect(process.stdout instanceof tty.WriteStream).toBe(true);
+ expect(process.stderr instanceof tty.WriteStream).toBe(true);
+ expect(process.stdin.isTTY).toBeDefined();
+ expect(process.stdout.isTTY).toBeDefined();
+ expect(process.stderr.isTTY).toBeDefined();
+ });
+ it("read and write stream prototypes", () => {
+ expect(tty.ReadStream.prototype.setRawMode).toBeInstanceOf(Function);
+ expect(tty.WriteStream.prototype.clearLine).toBeInstanceOf(Function);
+ expect(tty.WriteStream.prototype.clearScreenDown).toBeInstanceOf(Function);
+ expect(tty.WriteStream.prototype.cursorTo).toBeInstanceOf(Function);
+ expect(tty.WriteStream.prototype.getColorDepth).toBeInstanceOf(Function);
+ expect(tty.WriteStream.prototype.getWindowSize).toBeInstanceOf(Function);
+ expect(tty.WriteStream.prototype.hasColors).toBeInstanceOf(Function);
+ expect(tty.WriteStream.prototype.hasColors).toBeInstanceOf(Function);
+ expect(tty.WriteStream.prototype.moveCursor).toBeInstanceOf(Function);
+ });
+});
+`;
+
+it("TTY streams", () => {
+ mkdirSync(join(tmpdir(), "tty-test"), { recursive: true });
+ writeFileSync(join(tmpdir(), "tty-test/tty-streams.test.js"), ttyStreamsTest, {});
+
+ const { stdout, stderr, exitCode } = Bun.spawnSync({
+ cmd: [bunExe(), "test", "tty-streams.test.js"],
+ env: bunEnv,
+ stdio: ["ignore", "pipe", "pipe"],
+ cwd: join(tmpdir(), "tty-test"),
+ });
+
+ expect(stdout.toString()).toBe("");
+ expect(stderr.toString()).toContain("0 fail");
+ expect(exitCode).toBe(0);
+});