Skip to content
File

Blob: src/workerd/api/node/tests/readline-nodejs-test.js

javascript279 lines
1// Copyright (c) 2025 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4import readline from 'node:readline';
5import assert from 'node:assert';
6import { EventEmitter } from 'node:events';
7import promises from 'node:readline/promises';
8 
9export const readlineClearLine = {
10 test() {
11 assert.strictEqual(readline.clearLine(), false);
12 assert.strictEqual(typeof readline.clearLine, 'function');
13 },
14};
15 
16export const readlineClearScreenDown = {
17 test() {
18 assert.strictEqual(readline.clearScreenDown(), false);
19 assert.strictEqual(typeof readline.clearScreenDown, 'function');
20 },
21};
22 
23export const readlineCursorTo = {
24 test() {
25 assert.strictEqual(readline.cursorTo(), false);
26 assert.strictEqual(typeof readline.cursorTo, 'function');
27 },
28};
29 
30export const readlineMoveCursor = {
31 test() {
32 assert.strictEqual(readline.moveCursor(), false);
33 assert.strictEqual(typeof readline.moveCursor, 'function');
34 },
35};
36 
37export const readlineEmitKeypressEvents = {
38 test() {
39 assert.doesNotThrow(() => readline.emitKeypressEvents());
40 assert.strictEqual(readline.emitKeypressEvents(), undefined);
41 assert.strictEqual(typeof readline.emitKeypressEvents, 'function');
42 },
43};
44 
45export const readlineCreateInterface = {
46 test() {
47 // createInterface returns a no-op stub that matches unenv behavior
48 const rl = readline.createInterface();
49 assert.ok(rl instanceof readline.Interface);
50 assert.strictEqual(rl.terminal, false);
51 assert.strictEqual(rl.line, '');
52 assert.strictEqual(rl.cursor, 0);
53 assert.strictEqual(typeof readline.createInterface, 'function');
54 },
55};
56 
57export const readlineInterface = {
58 test() {
59 // Interface constructor returns a no-op stub that matches unenv behavior
60 const rl = new readline.Interface();
61 assert.ok(rl instanceof readline.Interface);
62 assert.strictEqual(rl.terminal, false);
63 assert.strictEqual(rl.line, '');
64 assert.strictEqual(rl.cursor, 0);
65 
66 // Test methods return sensible defaults instead of throwing
67 assert.strictEqual(rl.getPrompt(), '');
68 rl.setPrompt('test'); // Should not throw
69 rl.prompt(); // Should not throw
70 rl.close(); // Should not throw
71 rl.write('test'); // Should not throw
72 assert.deepStrictEqual(rl.getCursorPos(), { rows: 0, cols: 0 });
73 assert.strictEqual(rl.pause(), rl);
74 assert.strictEqual(rl.resume(), rl);
75 
76 // question calls callback with empty string
77 let questionAnswer = null;
78 rl.question('test?', (answer) => {
79 questionAnswer = answer;
80 });
81 assert.strictEqual(questionAnswer, '');
82 
83 // question with options also works
84 let questionAnswer2 = null;
85 rl.question('test?', {}, (answer) => {
86 questionAnswer2 = answer;
87 });
88 assert.strictEqual(questionAnswer2, '');
89 
90 assert.strictEqual(typeof readline.Interface, 'function');
91 },
92};
93 
94export const readlineInterfaceMethods = {
95 test() {
96 const InterfaceProto = readline.Interface.prototype;
97 
98 assert.strictEqual(typeof InterfaceProto.getPrompt, 'function');
99 assert.strictEqual(typeof InterfaceProto.setPrompt, 'function');
100 assert.strictEqual(typeof InterfaceProto.prompt, 'function');
101 assert.strictEqual(typeof InterfaceProto.question, 'function');
102 assert.strictEqual(typeof InterfaceProto.pause, 'function');
103 assert.strictEqual(typeof InterfaceProto.resume, 'function');
104 assert.strictEqual(typeof InterfaceProto.close, 'function');
105 assert.strictEqual(typeof InterfaceProto.write, 'function');
106 assert.strictEqual(typeof InterfaceProto.getCursorPos, 'function');
107 
108 assert.strictEqual(typeof InterfaceProto.on, 'function');
109 assert.strictEqual(typeof InterfaceProto.emit, 'function');
110 assert.strictEqual(typeof InterfaceProto.once, 'function');
111 assert.strictEqual(typeof InterfaceProto.removeListener, 'function');
112 },
113};
114 
115export const readlineInterfaceInheritance = {
116 test() {
117 assert.strictEqual(
118 readline.Interface.prototype instanceof EventEmitter,
119 true
120 );
121 },
122};
123 
124export const readlinePromises = {
125 test() {
126 assert.strictEqual(typeof readline.promises, 'object');
127 assert.strictEqual(typeof readline.promises.Interface, 'function');
128 assert.strictEqual(typeof readline.promises.Readline, 'function');
129 assert.strictEqual(typeof readline.promises.createInterface, 'function');
130 },
131};
132 
133export const readlinePromisesInterface = {
134 async test() {
135 // promises.Interface constructor returns a no-op stub that matches unenv behavior
136 const rl = new readline.promises.Interface();
137 assert.ok(rl instanceof readline.promises.Interface);
138 assert.strictEqual(rl.terminal, false);
139 assert.strictEqual(rl.line, '');
140 assert.strictEqual(rl.cursor, 0);
141 
142 // Test methods return sensible defaults instead of throwing
143 assert.strictEqual(rl.getPrompt(), '');
144 rl.setPrompt('test'); // Should not throw
145 rl.prompt(); // Should not throw
146 rl.close(); // Should not throw
147 rl.write('test'); // Should not throw
148 assert.deepStrictEqual(rl.getCursorPos(), { rows: 0, cols: 0 });
149 assert.strictEqual(rl.pause(), rl);
150 assert.strictEqual(rl.resume(), rl);
151 
152 // question returns a promise that resolves to empty string
153 const answer = await rl.question('test?');
154 assert.strictEqual(answer, '');
155 },
156};
157 
158export const readlinePromisesCreateInterface = {
159 test() {
160 // promises.createInterface returns a no-op stub that matches unenv behavior
161 const rl = readline.promises.createInterface();
162 assert.ok(rl instanceof readline.promises.Interface);
163 assert.strictEqual(rl.terminal, false);
164 assert.strictEqual(rl.line, '');
165 assert.strictEqual(rl.cursor, 0);
166 },
167};
168 
169export const readlinePromisesReadline = {
170 async test() {
171 // Readline constructor returns a no-op stub that matches unenv behavior
172 const rl = new readline.promises.Readline(process.stdout);
173 assert.ok(rl instanceof readline.promises.Readline);
174 
175 // Test methods return sensible defaults instead of throwing
176 assert.strictEqual(rl.clearLine(0), rl);
177 assert.strictEqual(rl.clearScreenDown(), rl);
178 assert.strictEqual(rl.cursorTo(0), rl);
179 assert.strictEqual(rl.cursorTo(0, 0), rl);
180 assert.strictEqual(rl.moveCursor(1, 1), rl);
181 assert.strictEqual(rl.rollback(), rl);
182 
183 // commit returns a promise that resolves to undefined
184 const result = await rl.commit();
185 assert.strictEqual(result, undefined);
186 },
187};
188 
189export const readlineDefaultExport = {
190 test() {
191 assert.strictEqual(typeof readline, 'object');
192 assert.strictEqual(typeof readline.clearLine, 'function');
193 assert.strictEqual(typeof readline.clearScreenDown, 'function');
194 assert.strictEqual(typeof readline.createInterface, 'function');
195 assert.strictEqual(typeof readline.cursorTo, 'function');
196 assert.strictEqual(typeof readline.emitKeypressEvents, 'function');
197 assert.strictEqual(typeof readline.moveCursor, 'function');
198 assert.strictEqual(typeof readline.Interface, 'function');
199 assert.strictEqual(typeof readline.promises, 'object');
200 },
201};
202 
203export const readlineModuleExports = {
204 async test() {
205 const readlineModule = await import('node:readline');
206 
207 assert.strictEqual(typeof readlineModule.default, 'object');
208 assert.strictEqual(typeof readlineModule.clearLine, 'function');
209 assert.strictEqual(typeof readlineModule.clearScreenDown, 'function');
210 assert.strictEqual(typeof readlineModule.createInterface, 'function');
211 assert.strictEqual(typeof readlineModule.cursorTo, 'function');
212 assert.strictEqual(typeof readlineModule.emitKeypressEvents, 'function');
213 assert.strictEqual(typeof readlineModule.moveCursor, 'function');
214 assert.strictEqual(typeof readlineModule.Interface, 'function');
215 assert.strictEqual(typeof readlineModule.promises, 'object');
216 
217 assert.strictEqual(
218 readlineModule.default.clearLine,
219 readlineModule.clearLine
220 );
221 assert.strictEqual(
222 readlineModule.default.clearScreenDown,
223 readlineModule.clearScreenDown
224 );
225 assert.strictEqual(
226 readlineModule.default.createInterface,
227 readlineModule.createInterface
228 );
229 assert.strictEqual(
230 readlineModule.default.cursorTo,
231 readlineModule.cursorTo
232 );
233 assert.strictEqual(
234 readlineModule.default.emitKeypressEvents,
235 readlineModule.emitKeypressEvents
236 );
237 assert.strictEqual(
238 readlineModule.default.moveCursor,
239 readlineModule.moveCursor
240 );
241 assert.strictEqual(
242 readlineModule.default.Interface,
243 readlineModule.Interface
244 );
245 assert.strictEqual(
246 readlineModule.default.promises,
247 readlineModule.promises
248 );
249 },
250};
251 
252export const readlineFunctionReturnValues = {
253 test() {
254 const testArgs = [
255 [],
256 [null],
257 [undefined],
258 [1, 2],
259 ['test', 123],
260 [{}, [], () => {}],
261 ];
262 
263 for (const args of testArgs) {
264 assert.strictEqual(readline.clearLine(...args), false);
265 assert.strictEqual(readline.clearScreenDown(...args), false);
266 assert.strictEqual(readline.cursorTo(...args), false);
267 assert.strictEqual(readline.moveCursor(...args), false);
268 assert.strictEqual(readline.emitKeypressEvents(...args), undefined);
269 }
270 },
271};
272 
273export const readlineImportedPromisesModule = {
274 test() {
275 assert.strictEqual(typeof promises, 'object');
276 assert.strictEqual(typeof promises.createInterface, 'function');
277 },
278};