input-shell 1.0.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -9
- package/demos/demos.input.async.js +28 -0
- package/demos/demos.input.js +1 -1
- package/demos/demos.input.select.checkbox.async.js +30 -0
- package/demos/demos.input.select.checkbox.js +5 -9
- package/demos/demos.input.select.multiple.questions.async.js +42 -0
- package/demos/demos.input.select.multiple.questions.js +27 -3
- package/demos/demos.input.select.radio.async.js +29 -0
- package/demos/demos.input.select.radio.js +6 -9
- package/index.js +389 -36
- package/package.json +1 -4
- package/test/test.input.js +18 -0
- package/test/test.input.multiple.async.js +175 -0
- package/test/test.input.multiple.js +93 -74
- package/test/test.input.select.js +18 -0
- package/test/test.input.select.multiple.js +84 -0
package/index.js
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
* Package:
|
4
4
|
* Author: Ganesh B
|
5
5
|
* Description:
|
6
|
-
* Install: npm i input --save
|
6
|
+
* Install: npm i input-shell --save
|
7
7
|
* Github: https://github.com/ganeshkbhat/
|
8
8
|
* npmjs Link: https://www.npmjs.com/package/
|
9
9
|
* File: index.js
|
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
const readline = require('readline');
|
20
20
|
|
21
|
-
function
|
21
|
+
function inputSelectAsync(questionText, options, type, callback) {
|
22
22
|
const rl = readline.createInterface({
|
23
23
|
input: process.stdin,
|
24
24
|
output: process.stdout,
|
@@ -86,47 +86,161 @@ function inputSelect(questionText, options, type, callback) {
|
|
86
86
|
});
|
87
87
|
}
|
88
88
|
|
89
|
+
function inputSelect(questionText, options, type) {
|
90
|
+
return new Promise((resolve) => {
|
91
|
+
const rl = readline.createInterface({
|
92
|
+
input: process.stdin,
|
93
|
+
output: process.stdout,
|
94
|
+
terminal: true,
|
95
|
+
});
|
96
|
+
|
97
|
+
let selectedIndex = 0;
|
98
|
+
let selectedOptionsArray = [];
|
99
|
+
|
100
|
+
function displayOptions() {
|
101
|
+
console.clear();
|
102
|
+
console.log(questionText);
|
103
|
+
options.forEach((option, index) => {
|
104
|
+
if (type === 'radio') {
|
105
|
+
if (index === selectedIndex) {
|
106
|
+
console.log(`> ${option}`);
|
107
|
+
} else {
|
108
|
+
console.log(` ${option}`);
|
109
|
+
}
|
110
|
+
} else if (type === 'checkbox') {
|
111
|
+
let selected = selectedOptionsArray.includes(index) ? '[x]' : '[ ]';
|
112
|
+
if (index === selectedIndex) {
|
113
|
+
console.log(`> ${selected} ${option}`);
|
114
|
+
} else {
|
115
|
+
console.log(` ${selected} ${option}`);
|
116
|
+
}
|
117
|
+
}
|
118
|
+
});
|
119
|
+
}
|
120
|
+
|
121
|
+
displayOptions();
|
122
|
+
|
123
|
+
readline.emitKeypressEvents(process.stdin);
|
124
|
+
process.stdin.setRawMode(true);
|
125
|
+
|
126
|
+
process.stdin.on('keypress', (str, key) => {
|
127
|
+
if (key.name === 'up') {
|
128
|
+
selectedIndex = Math.max(0, selectedIndex - 1);
|
129
|
+
displayOptions();
|
130
|
+
} else if (key.name === 'down') {
|
131
|
+
selectedIndex = Math.min(options.length - 1, selectedIndex + 1);
|
132
|
+
displayOptions();
|
133
|
+
} else if (key.name === 'return') {
|
134
|
+
process.stdin.setRawMode(false);
|
135
|
+
process.stdin.pause();
|
136
|
+
rl.close();
|
137
|
+
if (type === 'radio') {
|
138
|
+
resolve(options[selectedIndex]);
|
139
|
+
} else if (type === 'checkbox') {
|
140
|
+
const finalSelections = selectedOptionsArray.map((index) => options[index]);
|
141
|
+
resolve(finalSelections);
|
142
|
+
}
|
143
|
+
} else if (key.ctrl && key.name === 'c') {
|
144
|
+
process.exit();
|
145
|
+
} else if (type === 'checkbox' && key.name === 'space') {
|
146
|
+
if (selectedOptionsArray.includes(selectedIndex)) {
|
147
|
+
selectedOptionsArray = selectedOptionsArray.filter(
|
148
|
+
(item) => item !== selectedIndex
|
149
|
+
);
|
150
|
+
} else {
|
151
|
+
selectedOptionsArray.push(selectedIndex);
|
152
|
+
}
|
153
|
+
displayOptions();
|
154
|
+
}
|
155
|
+
});
|
156
|
+
});
|
157
|
+
}
|
89
158
|
|
90
159
|
function input(text) {
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
160
|
+
console.log(text);
|
161
|
+
return new Promise((resolve, reject) => {
|
162
|
+
let buffer = Buffer.alloc(0); // Initialize an empty buffer
|
163
|
+
|
164
|
+
process.stdin.on('readable', () => {
|
165
|
+
let chunk;
|
166
|
+
while ((chunk = process.stdin.read()) !== null) {
|
167
|
+
// Find the index of the first newline character
|
168
|
+
const newlineIndex = chunk.indexOf('\n');
|
169
|
+
|
170
|
+
if (newlineIndex !== -1) {
|
171
|
+
// Newline found, extract the line up to the newline
|
172
|
+
const lineBuffer = Buffer.concat([buffer, chunk.slice(0, newlineIndex)]);
|
173
|
+
process.stdin.pause(); // Stop reading
|
174
|
+
resolve(lineBuffer);
|
175
|
+
return; // Exit the readable event
|
176
|
+
} else {
|
177
|
+
// No newline, append the chunk to the buffer
|
178
|
+
buffer = Buffer.concat([buffer, chunk]);
|
179
|
+
}
|
180
|
+
}
|
181
|
+
});
|
113
182
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
183
|
+
process.stdin.on('end', () => {
|
184
|
+
if (buffer.length > 0) {
|
185
|
+
resolve(buffer);
|
186
|
+
} else {
|
187
|
+
reject("No input received");
|
188
|
+
}
|
189
|
+
});
|
121
190
|
|
122
|
-
|
123
|
-
|
124
|
-
});
|
191
|
+
process.stdin.on('error', (err) => {
|
192
|
+
reject(err);
|
125
193
|
});
|
194
|
+
});
|
126
195
|
}
|
127
196
|
|
197
|
+
function inputAsync(text, callback) {
|
198
|
+
console.log(text);
|
199
|
+
let buffer = Buffer.alloc(0); // Initialize an empty buffer
|
200
|
+
|
201
|
+
const readableHandler = () => {
|
202
|
+
let chunk;
|
203
|
+
while ((chunk = process.stdin.read()) !== null) {
|
204
|
+
const newlineIndex = chunk.indexOf('\n');
|
205
|
+
|
206
|
+
if (newlineIndex !== -1) {
|
207
|
+
const lineBuffer = Buffer.concat([buffer, chunk.slice(0, newlineIndex)]);
|
208
|
+
process.stdin.pause(); // Stop reading
|
209
|
+
process.stdin.off('readable', readableHandler); // Remove the event listener
|
210
|
+
process.stdin.off('end', endHandler); // Remove the event listener
|
211
|
+
process.stdin.off('error', errorHandler); // Remove the event listener
|
212
|
+
callback(null, lineBuffer);
|
213
|
+
return;
|
214
|
+
} else {
|
215
|
+
buffer = Buffer.concat([buffer, chunk]);
|
216
|
+
}
|
217
|
+
}
|
218
|
+
};
|
219
|
+
|
220
|
+
const endHandler = () => {
|
221
|
+
process.stdin.off('readable', readableHandler); // Remove the event listener
|
222
|
+
process.stdin.off('end', endHandler); // Remove the event listener
|
223
|
+
process.stdin.off('error', errorHandler); // Remove the event listener
|
224
|
+
if (buffer.length > 0) {
|
225
|
+
callback(null, buffer);
|
226
|
+
} else {
|
227
|
+
callback("No input received", null);
|
228
|
+
}
|
229
|
+
};
|
230
|
+
|
231
|
+
const errorHandler = (err) => {
|
232
|
+
process.stdin.off('readable', readableHandler); // Remove the event listener
|
233
|
+
process.stdin.off('end', endHandler); // Remove the event listener
|
234
|
+
process.stdin.off('error', errorHandler); // Remove the event listener
|
235
|
+
callback(err, null);
|
236
|
+
};
|
237
|
+
|
238
|
+
process.stdin.on('readable', readableHandler);
|
239
|
+
process.stdin.on('end', endHandler);
|
240
|
+
process.stdin.on('error', errorHandler);
|
241
|
+
}
|
128
242
|
|
129
|
-
function
|
243
|
+
function inputSelectMultipleAsync(questions, finalCallback) {
|
130
244
|
let results = [];
|
131
245
|
let questionIndex = 0;
|
132
246
|
|
@@ -235,6 +349,245 @@ function inputSelectMultiple(questions, finalCallback) {
|
|
235
349
|
askQuestion();
|
236
350
|
}
|
237
351
|
|
352
|
+
// function inputSelectMultiple(questions) {
|
353
|
+
// return new Promise((resolve, reject) => {
|
354
|
+
// let results = [];
|
355
|
+
// let questionIndex = 0;
|
356
|
+
|
357
|
+
// function askQuestion() {
|
358
|
+
// if (questionIndex >= questions.length) {
|
359
|
+
// resolve(results);
|
360
|
+
// return;
|
361
|
+
// }
|
362
|
+
|
363
|
+
// const question = questions[questionIndex];
|
364
|
+
// const { text, type, options } = question;
|
365
|
+
|
366
|
+
// if (type === 'text') {
|
367
|
+
// const rl = readline.createInterface({
|
368
|
+
// input: process.stdin,
|
369
|
+
// output: process.stdout,
|
370
|
+
// });
|
371
|
+
|
372
|
+
// rl.question(`${text} `, (answer) => {
|
373
|
+
// results.push({ text: text, answer: answer });
|
374
|
+
// rl.close();
|
375
|
+
// questionIndex++;
|
376
|
+
// askQuestion();
|
377
|
+
// });
|
378
|
+
// } else if (type === 'radio' || type === 'checkbox') {
|
379
|
+
// const rl = readline.createInterface({
|
380
|
+
// input: process.stdin,
|
381
|
+
// output: process.stdout,
|
382
|
+
// terminal: true,
|
383
|
+
// });
|
384
|
+
|
385
|
+
// let selectedIndex = 0;
|
386
|
+
// let selectedOptionsArray = [];
|
387
|
+
|
388
|
+
// function displayOptions() {
|
389
|
+
// console.clear();
|
390
|
+
// console.log(text);
|
391
|
+
// options.forEach((option, index) => {
|
392
|
+
// if (type === 'radio') {
|
393
|
+
// if (index === selectedIndex) {
|
394
|
+
// console.log(`> ${option}`);
|
395
|
+
// } else {
|
396
|
+
// console.log(` ${option}`);
|
397
|
+
// }
|
398
|
+
// } else if (type === 'checkbox') {
|
399
|
+
// let selected = selectedOptionsArray.includes(index) ? '[x]' : '[ ]';
|
400
|
+
// if (index === selectedIndex) {
|
401
|
+
// console.log(`> ${selected} ${option}`);
|
402
|
+
// } else {
|
403
|
+
// console.log(` ${selected} ${option}`);
|
404
|
+
// }
|
405
|
+
// }
|
406
|
+
// });
|
407
|
+
// }
|
408
|
+
|
409
|
+
// displayOptions();
|
410
|
+
|
411
|
+
// readline.emitKeypressEvents(process.stdin);
|
412
|
+
// process.stdin.setRawMode(true);
|
413
|
+
|
414
|
+
// process.stdin.on('keypress', (str, key) => {
|
415
|
+
// if (key.name === 'up') {
|
416
|
+
// selectedIndex = Math.max(0, selectedIndex - 1);
|
417
|
+
// displayOptions();
|
418
|
+
// } else if (key.name === 'down') {
|
419
|
+
// selectedIndex = Math.min(options.length - 1, selectedIndex + 1);
|
420
|
+
// displayOptions();
|
421
|
+
// } else if (key.name === 'return') {
|
422
|
+
// process.stdin.setRawMode(false);
|
423
|
+
// process.stdin.pause();
|
424
|
+
// rl.close();
|
425
|
+
// let answer;
|
426
|
+
// if (type === 'radio') {
|
427
|
+
// answer = options[selectedIndex];
|
428
|
+
// } else if (type === 'checkbox') {
|
429
|
+
// answer = selectedOptionsArray.map((index) => options[index]);
|
430
|
+
// }
|
431
|
+
// results.push({ text: text, answer: answer });
|
432
|
+
// questionIndex++;
|
433
|
+
// askQuestion();
|
434
|
+
// } else if (key.ctrl && key.name === 'c') {
|
435
|
+
// process.exit();
|
436
|
+
// } else if (type === 'checkbox' && key.name === 'space') {
|
437
|
+
// if (selectedOptionsArray.includes(selectedIndex)) {
|
438
|
+
// selectedOptionsArray = selectedOptionsArray.filter(
|
439
|
+
// (item) => item !== selectedIndex
|
440
|
+
// );
|
441
|
+
// } else {
|
442
|
+
// selectedOptionsArray.push(selectedIndex);
|
443
|
+
// }
|
444
|
+
// displayOptions();
|
445
|
+
// }
|
446
|
+
// });
|
447
|
+
// }
|
448
|
+
// }
|
449
|
+
|
450
|
+
// askQuestion();
|
451
|
+
// });
|
452
|
+
// }
|
453
|
+
|
454
|
+
|
455
|
+
async function recursiveQuestion(questions, answers = [], currentIndex = 0) {
|
456
|
+
if (currentIndex >= questions.length) {
|
457
|
+
return answers;
|
458
|
+
}
|
459
|
+
|
460
|
+
const currentQuestion = questions[currentIndex];
|
461
|
+
|
462
|
+
for (let i = 0; i < answers.length; i++) {
|
463
|
+
console.log(`${questions[i].text}: ${Array.isArray(answers[i].answer) ? answers[i].answer.join(', ') : answers[i].answer}`);
|
464
|
+
}
|
465
|
+
|
466
|
+
console.log(`${currentQuestion.text}`);
|
467
|
+
|
468
|
+
let answer;
|
469
|
+
|
470
|
+
if (currentQuestion.type === 'text') {
|
471
|
+
answer = await questionAsync('> ');
|
472
|
+
} else if (currentQuestion.type === 'checkbox') {
|
473
|
+
answer = await checkboxMenu(currentQuestion.options, answers);
|
474
|
+
} else if (currentQuestion.type === 'radio') {
|
475
|
+
answer = await radioMenu(currentQuestion.options, answers);
|
476
|
+
} else {
|
477
|
+
throw new Error(`Unknown question type: ${currentQuestion.type}`);
|
478
|
+
}
|
479
|
+
|
480
|
+
answers.push({ question: currentQuestion.text, answer: answer });
|
481
|
+
return recursiveQuestion(questions, answers, currentIndex + 1);
|
482
|
+
}
|
483
|
+
|
484
|
+
function questionAsync(prompt) {
|
485
|
+
const rl = readline.createInterface({
|
486
|
+
input: process.stdin,
|
487
|
+
output: process.stdout,
|
488
|
+
});
|
489
|
+
|
490
|
+
return new Promise((resolve) => {
|
491
|
+
rl.question(prompt, (answer) => {
|
492
|
+
rl.close();
|
493
|
+
resolve(answer);
|
494
|
+
});
|
495
|
+
});
|
496
|
+
}
|
497
|
+
|
498
|
+
async function checkboxMenu(choices, previousAnswers) {
|
499
|
+
const selected = new Array(choices.length).fill(false);
|
500
|
+
let currentIndex = 0;
|
501
|
+
|
502
|
+
while (true) {
|
503
|
+
console.clear();
|
504
|
+
for (let i = 0; i < previousAnswers.length; i++) {
|
505
|
+
console.log(`${previousAnswers[i].question}: ${Array.isArray(previousAnswers[i].answer) ? previousAnswers[i].answer.join(', ') : previousAnswers[i].answer}`);
|
506
|
+
}
|
507
|
+
|
508
|
+
console.log("Select with space, confirm with enter, navigate with arrows:");
|
509
|
+
for (let i = 0; i < choices.length; i++) {
|
510
|
+
const prefix = i === currentIndex ? '>' : ' ';
|
511
|
+
const check = selected[i] ? '[x]' : '[ ]';
|
512
|
+
console.log(`${prefix} ${check} ${choices[i]}`);
|
513
|
+
}
|
514
|
+
|
515
|
+
const key = await readKey();
|
516
|
+
|
517
|
+
if (key === '\r') {
|
518
|
+
return choices.filter((_, i) => selected[i]);
|
519
|
+
} else if (key === '\u001b[A') {
|
520
|
+
currentIndex = (currentIndex - 1 + choices.length) % choices.length;
|
521
|
+
} else if (key === '\u001b[B') {
|
522
|
+
currentIndex = (currentIndex + 1) % choices.length;
|
523
|
+
} else if (key === ' ') {
|
524
|
+
selected[currentIndex] = !selected[currentIndex];
|
525
|
+
}
|
526
|
+
}
|
527
|
+
}
|
528
|
+
|
529
|
+
async function radioMenu(choices, previousAnswers) {
|
530
|
+
let currentIndex = 0;
|
531
|
+
|
532
|
+
while (true) {
|
533
|
+
console.clear();
|
534
|
+
for (let i = 0; i < previousAnswers.length; i++) {
|
535
|
+
console.log(`${previousAnswers[i].question}: ${Array.isArray(previousAnswers[i].answer) ? previousAnswers[i].answer.join(', ') : previousAnswers[i].answer}`);
|
536
|
+
}
|
537
|
+
console.log("Select with enter, navigate with arrows:");
|
538
|
+
|
539
|
+
for (let i = 0; i < choices.length; i++) {
|
540
|
+
const prefix = i === currentIndex ? '>' : ' ';
|
541
|
+
const radio = i === currentIndex ? '(o)' : '( )';
|
542
|
+
console.log(`${prefix} ${radio} ${choices[i]}`);
|
543
|
+
}
|
544
|
+
|
545
|
+
const key = await readKey();
|
546
|
+
|
547
|
+
if (key === '\r') {
|
548
|
+
return choices[currentIndex];
|
549
|
+
} else if (key === '\u001b[A') {
|
550
|
+
currentIndex = (currentIndex - 1 + choices.length) % choices.length;
|
551
|
+
} else if (key === '\u001b[B') {
|
552
|
+
currentIndex = (currentIndex + 1) % choices.length;
|
553
|
+
}
|
554
|
+
}
|
555
|
+
}
|
556
|
+
|
557
|
+
function readKey() {
|
558
|
+
return new Promise((resolve) => {
|
559
|
+
process.stdin.setRawMode(true);
|
560
|
+
process.stdin.resume();
|
561
|
+
process.stdin.once('data', (data) => {
|
562
|
+
process.stdin.setRawMode(false);
|
563
|
+
process.stdin.pause();
|
564
|
+
resolve(data.toString());
|
565
|
+
});
|
566
|
+
});
|
567
|
+
}
|
568
|
+
|
569
|
+
function inputSelectMultiple(questions) {
|
570
|
+
return new Promise(async (resolve, reject) => {
|
571
|
+
try {
|
572
|
+
const results = await recursiveQuestion(questions);
|
573
|
+
resolve(results);
|
574
|
+
} catch (error) {
|
575
|
+
reject(error);
|
576
|
+
}
|
577
|
+
});
|
578
|
+
}
|
579
|
+
|
580
|
+
|
581
|
+
function inputSelectMultipleAsync(questions, callback) {
|
582
|
+
recursiveQuestion(questions)
|
583
|
+
.then((results) => {
|
584
|
+
callback(null, results); // Pass null for error, results for success
|
585
|
+
})
|
586
|
+
.catch((error) => {
|
587
|
+
callback(error, null); // Pass error, null for results
|
588
|
+
});
|
589
|
+
}
|
590
|
+
|
238
591
|
|
239
|
-
module.exports = { input, inputSelect, inputSelectMultiple }
|
592
|
+
module.exports = { input, inputAsync, inputSelect, inputSelectAsync, inputSelectMultipleAsync, inputSelectMultiple }
|
240
593
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "input-shell",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.3.0",
|
4
4
|
"description": "python like input function using input-shell in nodejs",
|
5
5
|
"main": "index.js",
|
6
6
|
"directories": {
|
@@ -12,8 +12,6 @@
|
|
12
12
|
"devDependencies": {
|
13
13
|
"chai": "^5.1.2",
|
14
14
|
"mocha": "^11.1.0",
|
15
|
-
"package1": "^0.0.0",
|
16
|
-
"package2": "^1.0.0",
|
17
15
|
"sinon": "^19.0.2"
|
18
16
|
},
|
19
17
|
"keywords": [
|
@@ -27,6 +25,5 @@
|
|
27
25
|
"author": "Ganesh Bhat <cgijs@gmail.com>",
|
28
26
|
"license": "MIT",
|
29
27
|
"dependencies": {
|
30
|
-
"input": "^1.0.1"
|
31
28
|
}
|
32
29
|
}
|
package/test/test.input.js
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
/**
|
2
|
+
*
|
3
|
+
* Package:
|
4
|
+
* Author: Ganesh B
|
5
|
+
* Description:
|
6
|
+
* Install: npm i input-shell --save
|
7
|
+
* Github: https://github.com/ganeshkbhat/
|
8
|
+
* npmjs Link: https://www.npmjs.com/package/
|
9
|
+
* File: index.js
|
10
|
+
* File Description:
|
11
|
+
*
|
12
|
+
*
|
13
|
+
*/
|
14
|
+
|
15
|
+
/* eslint no-console: 0 */
|
16
|
+
|
17
|
+
'use strict';
|
18
|
+
|
1
19
|
const assert = require('assert');
|
2
20
|
const { spawn } = require('child_process');
|
3
21
|
const process = require("process");
|
@@ -0,0 +1,175 @@
|
|
1
|
+
/**
|
2
|
+
*
|
3
|
+
* Package:
|
4
|
+
* Author: Ganesh B
|
5
|
+
* Description:
|
6
|
+
* Install: npm i input-shell --save
|
7
|
+
* Github: https://github.com/ganeshkbhat/
|
8
|
+
* npmjs Link: https://www.npmjs.com/package/
|
9
|
+
* File: index.js
|
10
|
+
* File Description:
|
11
|
+
*
|
12
|
+
*
|
13
|
+
*/
|
14
|
+
|
15
|
+
/* eslint no-console: 0 */
|
16
|
+
|
17
|
+
'use strict';
|
18
|
+
|
19
|
+
const assert = require('chai').assert;
|
20
|
+
const sinon = require('sinon');
|
21
|
+
const { inputSelectMultipleAsync } = require('../index'); // Replace 'your-file-name'
|
22
|
+
|
23
|
+
// describe('inputSelectMultipleAsync with History', () => {
|
24
|
+
// let stdinStub, stdoutSpy, stdoutStub, processExitStub;
|
25
|
+
// let originalRawMode;
|
26
|
+
|
27
|
+
// before(() => {
|
28
|
+
// // stdoutSpy = sinon.spy(process.stdout, 'write');
|
29
|
+
// })
|
30
|
+
|
31
|
+
// beforeEach(() => {
|
32
|
+
// stdinStub = sinon.stub(process.stdin);
|
33
|
+
// stdoutStub = sinon.stub(process.stdout, "fd");
|
34
|
+
|
35
|
+
// processExitStub = sinon.stub(process, 'exit');
|
36
|
+
// originalRawMode = process.stdin.isRaw;
|
37
|
+
// });
|
38
|
+
|
39
|
+
// afterEach(() => {
|
40
|
+
// sinon.restore();
|
41
|
+
// process.stdin.setRawMode(originalRawMode);
|
42
|
+
// });
|
43
|
+
|
44
|
+
// // it('should handle a sequence of text, radio, and checkbox questions with history-', (done) => {
|
45
|
+
// // const questions = [
|
46
|
+
// // { text: 'What is your name?', type: 'text' },
|
47
|
+
// // { text: 'What is your favorite color?', type: 'radio', options: ['Red', 'Blue'] },
|
48
|
+
// // { text: 'Which fruits do you like?', type: 'checkbox', options: ['Apple', 'Banana'] },
|
49
|
+
// // ];
|
50
|
+
|
51
|
+
// // const expectedResults = [
|
52
|
+
// // { text: 'What is your name?', answer: 'Test Name' },
|
53
|
+
// // { text: 'What is your favorite color?', answer: 'Blue' },
|
54
|
+
// // { text: 'Which fruits do you like?', answer: ['Apple'] },
|
55
|
+
// // ];
|
56
|
+
|
57
|
+
// // const callback = (results) => {
|
58
|
+
// // assert.deepStrictEqual(results, expectedResults);
|
59
|
+
// // assert.ok(stdoutSpy.calledWith(sinon.match('What is your name?: Test Name')));
|
60
|
+
// // assert.ok(stdoutSpy.calledWith(sinon.match('What is your favorite color?: Blue')));
|
61
|
+
// // done();
|
62
|
+
// // };
|
63
|
+
|
64
|
+
// // inputSelectMultipleAsync(questions, callback);
|
65
|
+
|
66
|
+
// // let keyPressCount = 0;
|
67
|
+
|
68
|
+
// // stdinStub.on('data', (data) => {
|
69
|
+
// // if (keyPressCount === 0) {
|
70
|
+
// // stdinStub.emit('keypress', '\r', { name: 'return' });
|
71
|
+
// // } else if (keyPressCount === 1) {
|
72
|
+
// // stdinStub.emit('keypress', '\r', { name: 'return' });
|
73
|
+
// // } else if (keyPressCount === 2) {
|
74
|
+
// // stdinStub.emit('keypress', '\r', { name: 'return' });
|
75
|
+
// // }
|
76
|
+
// // keyPressCount++;
|
77
|
+
// // });
|
78
|
+
|
79
|
+
// // stdinStub.emit('data', 'Test Name\n');
|
80
|
+
// // stdinStub.emit('keypress', null, { name: 'down' });
|
81
|
+
// // stdinStub.emit('keypress', null, { name: 'return' });
|
82
|
+
// // stdinStub.emit('keypress', null, { name: 'space' });
|
83
|
+
// // stdinStub.emit('keypress', null, { name: 'return' });
|
84
|
+
// // });
|
85
|
+
|
86
|
+
// it('should handle a sequence of text, radio, and checkbox questions with history', (done) => {
|
87
|
+
// const questions = [
|
88
|
+
// { text: 'What is your name?', type: 'text' },
|
89
|
+
// { text: 'What is your favorite color?', type: 'radio', options: ['Red', 'Blue'] },
|
90
|
+
// { text: 'Which fruits do you like?', type: 'checkbox', options: ['Apple', 'Banana'] },
|
91
|
+
// ];
|
92
|
+
|
93
|
+
// const expectedResults = [
|
94
|
+
// { text: 'What is your name?', answer: 'Test Name' },
|
95
|
+
// { text: 'What is your favorite color?', answer: 'Blue' },
|
96
|
+
// { text: 'Which fruits do you like?', answer: ['Apple'] },
|
97
|
+
// ];
|
98
|
+
|
99
|
+
// const callback = (results) => {
|
100
|
+
// assert.deepStrictEqual(results, expectedResults);
|
101
|
+
// done();
|
102
|
+
// };
|
103
|
+
|
104
|
+
// inputSelectMultipleAsync(questions, callback);
|
105
|
+
|
106
|
+
// let keyPressCount = 0;
|
107
|
+
|
108
|
+
// stdinStub.on('data', (data) => {
|
109
|
+
// if (keyPressCount === 0) {
|
110
|
+
// stdinStub.emit('keypress', '\r', { name: 'return' });
|
111
|
+
// } else if (keyPressCount === 1) {
|
112
|
+
// stdinStub.emit('keypress', '\r', { name: 'return' });
|
113
|
+
// } else if (keyPressCount === 2) {
|
114
|
+
// stdinStub.emit('keypress', '\r', { name: 'return' });
|
115
|
+
// }
|
116
|
+
// keyPressCount++;
|
117
|
+
// });
|
118
|
+
|
119
|
+
// stdinStub.emit('data', 'Test Name\n');
|
120
|
+
// stdinStub.emit('keypress', null, { name: 'down' });
|
121
|
+
// stdinStub.emit('keypress', null, { name: 'return' });
|
122
|
+
// stdinStub.emit('keypress', null, { name: 'space' });
|
123
|
+
// stdinStub.emit('keypress', null, { name: 'return' });
|
124
|
+
|
125
|
+
// // Check if previous answers are displayed.
|
126
|
+
// // console.log();
|
127
|
+
// assert.ok(stdoutSpy.calledWith(sinon.match('What is your name? Test Name')));
|
128
|
+
// // assert.ok(stdoutSpy.calledWith(sinon.match('What is your name? Test Name')));
|
129
|
+
// // assert.ok(stdoutSpy.calledWith(sinon.match('What is your favorite color? Blue')));
|
130
|
+
// });
|
131
|
+
|
132
|
+
// it('should handle only text questions with history', (done) => {
|
133
|
+
// const questions = [
|
134
|
+
// { text: 'What is your name?', type: 'text' },
|
135
|
+
// { text: 'What is your age?', type: 'text' },
|
136
|
+
// ];
|
137
|
+
|
138
|
+
// const expectedResults = [
|
139
|
+
// { text: 'What is your name?', answer: 'Test Name' },
|
140
|
+
// { text: 'What is your age?', answer: '30' },
|
141
|
+
// ];
|
142
|
+
|
143
|
+
// const callback = (results) => {
|
144
|
+
// assert.deepStrictEqual(results, expectedResults);
|
145
|
+
// done();
|
146
|
+
// };
|
147
|
+
|
148
|
+
// inputSelectMultipleAsync(questions, callback);
|
149
|
+
|
150
|
+
// let count = 0;
|
151
|
+
|
152
|
+
// stdinStub.on('data', (data) => {
|
153
|
+
// if (count === 0) {
|
154
|
+
// stdinStub.emit('keypress', '\r', { name: 'return' });
|
155
|
+
// } else {
|
156
|
+
// stdinStub.emit('keypress', '\r', { name: 'return' });
|
157
|
+
// }
|
158
|
+
// count++;
|
159
|
+
// });
|
160
|
+
|
161
|
+
// stdinStub.emit('data', 'Test Name\n');
|
162
|
+
// stdinStub.emit('data', '30\n');
|
163
|
+
|
164
|
+
// assert.ok(stdoutSpy.calledWith(sinon.match('What is your name? Test Name\n')));
|
165
|
+
|
166
|
+
// });
|
167
|
+
|
168
|
+
// it('should handle ctrl+c exit during questions with history', () => {
|
169
|
+
// const questions = [{ text: 'What is your name?', type: 'text' }];
|
170
|
+
|
171
|
+
// inputSelectMultipleAsync(questions, () => { });
|
172
|
+
// stdinStub.emit('keypress', null, { ctrl: true, name: 'c' });
|
173
|
+
// assert.ok(!processExitStub.called);
|
174
|
+
// });
|
175
|
+
// });
|