input-shell 1.0.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/LICENSE +21 -0
- package/README.md +81 -0
- package/demos/demos.input.js +33 -0
- package/demos/demos.input.select.checkbox.js +30 -0
- package/demos/demos.input.select.multiple.questions.js +31 -0
- package/demos/demos.input.select.radio.js +31 -0
- package/index.js +240 -0
- package/package.json +32 -0
- package/test/test.input.js +52 -0
- package/test/test.input.multiple.js +157 -0
- package/test/test.input.select.js +101 -0
package/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Krishnamurthy G B
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# input-shell
|
2
|
+
python like `input` function using input-shell in nodejs
|
3
|
+
|
4
|
+
```
|
5
|
+
|
6
|
+
var { input } = require(input-select);
|
7
|
+
|
8
|
+
// Example usage:
|
9
|
+
input("Input Text: ")
|
10
|
+
.then((buffer) => {
|
11
|
+
console.log("Input (buffer):", buffer);
|
12
|
+
console.log("Input (text):", buffer.toString('utf8')); // Convert to text
|
13
|
+
process.exit(0);
|
14
|
+
})
|
15
|
+
.catch((error) => {
|
16
|
+
console.error("Error:", error);
|
17
|
+
process.exit(1);
|
18
|
+
});
|
19
|
+
|
20
|
+
```
|
21
|
+
|
22
|
+
|
23
|
+
```
|
24
|
+
|
25
|
+
var { inputSelect } = require(input-select);
|
26
|
+
|
27
|
+
// Example usage: checkboxes
|
28
|
+
inputSelect(
|
29
|
+
'Which fruits do you like? (Use space to select, enter to finish)',
|
30
|
+
['Apple', 'Banana', 'Orange', 'Grape'],
|
31
|
+
'checkbox',
|
32
|
+
(selections) => {
|
33
|
+
console.log('You selected:', selections);
|
34
|
+
}
|
35
|
+
);
|
36
|
+
|
37
|
+
```
|
38
|
+
|
39
|
+
```
|
40
|
+
|
41
|
+
var { inputSelect } = require(input-select);
|
42
|
+
|
43
|
+
// Example usage: radio button
|
44
|
+
inputSelect(
|
45
|
+
'What is your favorite color?',
|
46
|
+
['Red', 'Blue', 'Green', 'Yellow'],
|
47
|
+
'radio',
|
48
|
+
(selection) => {
|
49
|
+
console.log('You selected:', selection);
|
50
|
+
}
|
51
|
+
);
|
52
|
+
|
53
|
+
```
|
54
|
+
|
55
|
+
```
|
56
|
+
|
57
|
+
var { inputSelectMultiple } = require(input-select);
|
58
|
+
|
59
|
+
// Example usage: Multiple questions with Radio, Checkbox, and Text answers
|
60
|
+
const questions = [
|
61
|
+
{ text: 'What is your name?', type: 'text' },
|
62
|
+
{ text: 'What is your favorite color?', type: 'radio', options: ['Red', 'Blue', 'Green'] },
|
63
|
+
{ text: 'Which fruits do you like?', type: 'checkbox', options: ['Apple', 'Banana', 'Orange', 'Grape'] },
|
64
|
+
{ text: 'What is your age?', type: 'text' },
|
65
|
+
];
|
66
|
+
|
67
|
+
inputSelectMultiple(questions, (results) => {
|
68
|
+
console.log('Results:', results);
|
69
|
+
});
|
70
|
+
|
71
|
+
```
|
72
|
+
|
73
|
+
|
74
|
+
#### TESTS
|
75
|
+
|
76
|
+
* no tests written: use on your risk. But it works and should work for all use cases.
|
77
|
+
* the function written is just a sugar for process.stdin and/or its error.
|
78
|
+
* all the functions `input`, `inputSelect`, `inputSelectMultiple` do not work with each other in one file together.
|
79
|
+
* if you want multiple questions to be asked then use the `inputSelectMultiple` function.
|
80
|
+
|
81
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
/**
|
2
|
+
*
|
3
|
+
* Package:
|
4
|
+
* Author: Ganesh B
|
5
|
+
* Description:
|
6
|
+
* Install: npm i input --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
|
+
var { input } = require("../index");
|
20
|
+
|
21
|
+
// Example usage:
|
22
|
+
input("Input Text: ")
|
23
|
+
.then((buffer) => {
|
24
|
+
console.log("Input (buffer):", buffer);
|
25
|
+
console.log("Input (text):", buffer.toString('utf8')); // Convert to text
|
26
|
+
process.exit(0);
|
27
|
+
})
|
28
|
+
.catch((error) => {
|
29
|
+
console.error("Error:", error);
|
30
|
+
process.exit(1);
|
31
|
+
});
|
32
|
+
|
33
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
/**
|
2
|
+
*
|
3
|
+
* Package:
|
4
|
+
* Author: Ganesh B
|
5
|
+
* Description:
|
6
|
+
* Install: npm i input --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
|
+
var { inputSelect } = require("../index");
|
20
|
+
|
21
|
+
// Example usage: checkboxes
|
22
|
+
inputSelect(
|
23
|
+
'Which fruits do you like? (Use space to select, enter to finish)',
|
24
|
+
['Apple', 'Banana', 'Orange', 'Grape'],
|
25
|
+
'checkbox',
|
26
|
+
(selections) => {
|
27
|
+
console.log('You selected:', selections);
|
28
|
+
}
|
29
|
+
);
|
30
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
/**
|
2
|
+
*
|
3
|
+
* Package:
|
4
|
+
* Author: Ganesh B
|
5
|
+
* Description:
|
6
|
+
* Install: npm i input --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
|
+
var { inputSelectMultiple } = require("../index");
|
20
|
+
|
21
|
+
// Example usage:
|
22
|
+
const questions = [
|
23
|
+
{ text: 'What is your name?', type: 'text' },
|
24
|
+
{ text: 'What is your favorite color?', type: 'radio', options: ['Red', 'Blue', 'Green'] },
|
25
|
+
{ text: 'Which fruits do you like?', type: 'checkbox', options: ['Apple', 'Banana', 'Orange', 'Grape'] },
|
26
|
+
{ text: 'What is your age?', type: 'text' },
|
27
|
+
];
|
28
|
+
|
29
|
+
inputSelectMultiple(questions, (results) => {
|
30
|
+
console.log('Results:', results);
|
31
|
+
});
|
@@ -0,0 +1,31 @@
|
|
1
|
+
/**
|
2
|
+
*
|
3
|
+
* Package:
|
4
|
+
* Author: Ganesh B
|
5
|
+
* Description:
|
6
|
+
* Install: npm i input --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
|
+
var { inputSelect } = require("../index");
|
20
|
+
|
21
|
+
// Example usage: radio button
|
22
|
+
inputSelect(
|
23
|
+
'What is your favorite color?',
|
24
|
+
['Red', 'Blue', 'Green', 'Yellow'],
|
25
|
+
'radio',
|
26
|
+
(selection) => {
|
27
|
+
console.log('You selected:', selection);
|
28
|
+
}
|
29
|
+
);
|
30
|
+
|
31
|
+
|
package/index.js
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
/**
|
2
|
+
*
|
3
|
+
* Package:
|
4
|
+
* Author: Ganesh B
|
5
|
+
* Description:
|
6
|
+
* Install: npm i input --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 readline = require('readline');
|
20
|
+
|
21
|
+
function inputSelect(questionText, options, type, callback) {
|
22
|
+
const rl = readline.createInterface({
|
23
|
+
input: process.stdin,
|
24
|
+
output: process.stdout,
|
25
|
+
terminal: true,
|
26
|
+
});
|
27
|
+
|
28
|
+
let selectedIndex = 0;
|
29
|
+
let selectedOptionsArray = [];
|
30
|
+
|
31
|
+
function displayOptions() {
|
32
|
+
console.clear();
|
33
|
+
console.log(questionText);
|
34
|
+
options.forEach((option, index) => {
|
35
|
+
if (type === 'radio') {
|
36
|
+
if (index === selectedIndex) {
|
37
|
+
console.log(`> ${option}`);
|
38
|
+
} else {
|
39
|
+
console.log(` ${option}`);
|
40
|
+
}
|
41
|
+
} else if (type === 'checkbox') {
|
42
|
+
let selected = selectedOptionsArray.includes(index) ? '[x]' : '[ ]';
|
43
|
+
if (index === selectedIndex) {
|
44
|
+
console.log(`> ${selected} ${option}`);
|
45
|
+
} else {
|
46
|
+
console.log(` ${selected} ${option}`);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
});
|
50
|
+
}
|
51
|
+
|
52
|
+
displayOptions();
|
53
|
+
|
54
|
+
readline.emitKeypressEvents(process.stdin);
|
55
|
+
process.stdin.setRawMode(true);
|
56
|
+
|
57
|
+
process.stdin.on('keypress', (str, key) => {
|
58
|
+
if (key.name === 'up') {
|
59
|
+
selectedIndex = Math.max(0, selectedIndex - 1);
|
60
|
+
displayOptions();
|
61
|
+
} else if (key.name === 'down') {
|
62
|
+
selectedIndex = Math.min(options.length - 1, selectedIndex + 1);
|
63
|
+
displayOptions();
|
64
|
+
} else if (key.name === 'return') {
|
65
|
+
process.stdin.setRawMode(false);
|
66
|
+
process.stdin.pause();
|
67
|
+
rl.close();
|
68
|
+
if (type === 'radio') {
|
69
|
+
callback(options[selectedIndex]);
|
70
|
+
} else if (type === 'checkbox') {
|
71
|
+
const finalSelections = selectedOptionsArray.map((index) => options[index]);
|
72
|
+
callback(finalSelections);
|
73
|
+
}
|
74
|
+
} else if (key.ctrl && key.name === 'c') {
|
75
|
+
process.exit();
|
76
|
+
} else if (type === 'checkbox' && key.name === 'space') {
|
77
|
+
if (selectedOptionsArray.includes(selectedIndex)) {
|
78
|
+
selectedOptionsArray = selectedOptionsArray.filter(
|
79
|
+
(item) => item !== selectedIndex
|
80
|
+
);
|
81
|
+
} else {
|
82
|
+
selectedOptionsArray.push(selectedIndex);
|
83
|
+
}
|
84
|
+
displayOptions();
|
85
|
+
}
|
86
|
+
});
|
87
|
+
}
|
88
|
+
|
89
|
+
|
90
|
+
function input(text) {
|
91
|
+
console.log(text);
|
92
|
+
return new Promise((resolve, reject) => {
|
93
|
+
let buffer = Buffer.alloc(0); // Initialize an empty buffer
|
94
|
+
|
95
|
+
process.stdin.on('readable', () => {
|
96
|
+
let chunk;
|
97
|
+
while ((chunk = process.stdin.read()) !== null) {
|
98
|
+
// Find the index of the first newline character
|
99
|
+
const newlineIndex = chunk.indexOf('\n');
|
100
|
+
|
101
|
+
if (newlineIndex !== -1) {
|
102
|
+
// Newline found, extract the line up to the newline
|
103
|
+
const lineBuffer = Buffer.concat([buffer, chunk.slice(0, newlineIndex)]);
|
104
|
+
process.stdin.pause(); // Stop reading
|
105
|
+
resolve(lineBuffer);
|
106
|
+
return; // Exit the readable event
|
107
|
+
} else {
|
108
|
+
// No newline, append the chunk to the buffer
|
109
|
+
buffer = Buffer.concat([buffer, chunk]);
|
110
|
+
}
|
111
|
+
}
|
112
|
+
});
|
113
|
+
|
114
|
+
process.stdin.on('end', () => {
|
115
|
+
if (buffer.length > 0) {
|
116
|
+
resolve(buffer);
|
117
|
+
} else {
|
118
|
+
reject("No input received");
|
119
|
+
}
|
120
|
+
});
|
121
|
+
|
122
|
+
process.stdin.on('error', (err) => {
|
123
|
+
reject(err);
|
124
|
+
});
|
125
|
+
});
|
126
|
+
}
|
127
|
+
|
128
|
+
|
129
|
+
function inputSelectMultiple(questions, finalCallback) {
|
130
|
+
let results = [];
|
131
|
+
let questionIndex = 0;
|
132
|
+
|
133
|
+
function askQuestion() {
|
134
|
+
if (questionIndex >= questions.length) {
|
135
|
+
finalCallback(results);
|
136
|
+
return;
|
137
|
+
}
|
138
|
+
|
139
|
+
const question = questions[questionIndex];
|
140
|
+
const { text, type, options } = question;
|
141
|
+
|
142
|
+
if (type === 'text') {
|
143
|
+
const rl = readline.createInterface({
|
144
|
+
input: process.stdin,
|
145
|
+
output: process.stdout,
|
146
|
+
});
|
147
|
+
|
148
|
+
displayPreviousQuestions(); // Display previous questions
|
149
|
+
|
150
|
+
rl.question(`${text} `, (answer) => {
|
151
|
+
results.push({ text: text, answer: answer });
|
152
|
+
rl.close();
|
153
|
+
questionIndex++;
|
154
|
+
askQuestion();
|
155
|
+
});
|
156
|
+
} else if (type === 'radio' || type === 'checkbox') {
|
157
|
+
const rl = readline.createInterface({
|
158
|
+
input: process.stdin,
|
159
|
+
output: process.stdout,
|
160
|
+
terminal: true,
|
161
|
+
});
|
162
|
+
|
163
|
+
let selectedIndex = 0;
|
164
|
+
let selectedOptionsArray = [];
|
165
|
+
|
166
|
+
function displayOptions() {
|
167
|
+
console.clear();
|
168
|
+
displayPreviousQuestions(); // Display previous questions
|
169
|
+
console.log(text);
|
170
|
+
options.forEach((option, index) => {
|
171
|
+
if (type === 'radio') {
|
172
|
+
if (index === selectedIndex) {
|
173
|
+
console.log(`> ${option}`);
|
174
|
+
} else {
|
175
|
+
console.log(` ${option}`);
|
176
|
+
}
|
177
|
+
} else if (type === 'checkbox') {
|
178
|
+
let selected = selectedOptionsArray.includes(index) ? '[x]' : '[ ]';
|
179
|
+
if (index === selectedIndex) {
|
180
|
+
console.log(`> ${selected} ${option}`);
|
181
|
+
} else {
|
182
|
+
console.log(` ${selected} ${option}`);
|
183
|
+
}
|
184
|
+
}
|
185
|
+
});
|
186
|
+
}
|
187
|
+
|
188
|
+
displayOptions();
|
189
|
+
|
190
|
+
readline.emitKeypressEvents(process.stdin);
|
191
|
+
process.stdin.setRawMode(true);
|
192
|
+
|
193
|
+
process.stdin.on('keypress', (str, key) => {
|
194
|
+
if (key.name === 'up') {
|
195
|
+
selectedIndex = Math.max(0, selectedIndex - 1);
|
196
|
+
displayOptions();
|
197
|
+
} else if (key.name === 'down') {
|
198
|
+
selectedIndex = Math.min(options.length - 1, selectedIndex + 1);
|
199
|
+
displayOptions();
|
200
|
+
} else if (key.name === 'return') {
|
201
|
+
process.stdin.setRawMode(false);
|
202
|
+
process.stdin.pause();
|
203
|
+
rl.close();
|
204
|
+
let answer;
|
205
|
+
if (type === 'radio') {
|
206
|
+
answer = options[selectedIndex];
|
207
|
+
} else if (type === 'checkbox') {
|
208
|
+
answer = selectedOptionsArray.map((index) => options[index]);
|
209
|
+
}
|
210
|
+
results.push({ text: text, answer: answer });
|
211
|
+
questionIndex++;
|
212
|
+
askQuestion();
|
213
|
+
} else if (key.ctrl && key.name === 'c') {
|
214
|
+
process.exit();
|
215
|
+
} else if (type === 'checkbox' && key.name === 'space') {
|
216
|
+
if (selectedOptionsArray.includes(selectedIndex)) {
|
217
|
+
selectedOptionsArray = selectedOptionsArray.filter(
|
218
|
+
(item) => item !== selectedIndex
|
219
|
+
);
|
220
|
+
} else {
|
221
|
+
selectedOptionsArray.push(selectedIndex);
|
222
|
+
}
|
223
|
+
displayOptions();
|
224
|
+
}
|
225
|
+
});
|
226
|
+
}
|
227
|
+
}
|
228
|
+
|
229
|
+
function displayPreviousQuestions() {
|
230
|
+
results.forEach((result) => {
|
231
|
+
console.log(`${result.text} ${result.answer}`);
|
232
|
+
});
|
233
|
+
}
|
234
|
+
|
235
|
+
askQuestion();
|
236
|
+
}
|
237
|
+
|
238
|
+
|
239
|
+
module.exports = { input, inputSelect, inputSelectMultiple }
|
240
|
+
|
package/package.json
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
{
|
2
|
+
"name": "input-shell",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "python like input function using input-shell in nodejs",
|
5
|
+
"main": "index.js",
|
6
|
+
"directories": {
|
7
|
+
"test": "test"
|
8
|
+
},
|
9
|
+
"scripts": {
|
10
|
+
"test": "mocha --reporter spec --recursive --timeout 60000"
|
11
|
+
},
|
12
|
+
"devDependencies": {
|
13
|
+
"chai": "^5.1.2",
|
14
|
+
"mocha": "^11.1.0",
|
15
|
+
"package1": "^0.0.0",
|
16
|
+
"package2": "^1.0.0",
|
17
|
+
"sinon": "^19.0.2"
|
18
|
+
},
|
19
|
+
"keywords": [
|
20
|
+
"python input",
|
21
|
+
"shell",
|
22
|
+
"shell input",
|
23
|
+
"process input",
|
24
|
+
"process buffer input",
|
25
|
+
"process text input"
|
26
|
+
],
|
27
|
+
"author": "Ganesh Bhat <cgijs@gmail.com>",
|
28
|
+
"license": "MIT",
|
29
|
+
"dependencies": {
|
30
|
+
"input": "^1.0.1"
|
31
|
+
}
|
32
|
+
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
const assert = require('assert');
|
2
|
+
const { spawn } = require('child_process');
|
3
|
+
const process = require("process");
|
4
|
+
const fs = require('fs');
|
5
|
+
|
6
|
+
|
7
|
+
const scriptPath = './index.js';
|
8
|
+
|
9
|
+
// describe('readSingleLineBufferFromStdin', () => {
|
10
|
+
// var input, output;
|
11
|
+
// before(async () => {
|
12
|
+
// input = 'hello world\n';
|
13
|
+
// process.stdin.write(input);
|
14
|
+
// output = await scriptPath.input();
|
15
|
+
// output = output.toString('utf8');
|
16
|
+
// return output
|
17
|
+
// });
|
18
|
+
|
19
|
+
// it('should read a single line and return a buffer', async () => {
|
20
|
+
|
21
|
+
// assert(output.includes('Input (text): hello world'));
|
22
|
+
// assert(output.includes('Input (buffer): <Buffer'));
|
23
|
+
// });
|
24
|
+
|
25
|
+
// it('should handle empty input', async () => {
|
26
|
+
// const input = '';
|
27
|
+
// const output = await runScriptWithInput(scriptPath, input);
|
28
|
+
// assert(output.includes('Error: No input received'));
|
29
|
+
// });
|
30
|
+
|
31
|
+
// it('should handle input without a newline', async () => {
|
32
|
+
// const input = 'no newline';
|
33
|
+
// const output = await runScriptWithInput(scriptPath, input);
|
34
|
+
// assert(output.includes('Input (text): no newline'));
|
35
|
+
// assert(output.includes('Input (buffer): <Buffer'));
|
36
|
+
// });
|
37
|
+
|
38
|
+
// it('should handle a single character input', async () => {
|
39
|
+
// const input = 'a\n';
|
40
|
+
// const output = await runScriptWithInput(scriptPath, input);
|
41
|
+
// assert(output.includes('Input (text): a'));
|
42
|
+
// assert(output.includes('Input (buffer): <Buffer'));
|
43
|
+
// });
|
44
|
+
|
45
|
+
// it('should handle input with multiple newlines, only the first line is taken', async () => {
|
46
|
+
// const input = 'line1\nline2\nline3\n';
|
47
|
+
// const output = await runScriptWithInput(scriptPath, input);
|
48
|
+
// assert(output.includes('Input (text): line1'));
|
49
|
+
// assert(output.includes('Input (buffer): <Buffer'));
|
50
|
+
// });
|
51
|
+
// });
|
52
|
+
|
@@ -0,0 +1,157 @@
|
|
1
|
+
const assert = require('chai').assert;
|
2
|
+
const sinon = require('sinon');
|
3
|
+
const { inputSelectMultiple } = require('../index'); // Replace 'your-file-name'
|
4
|
+
|
5
|
+
// describe('inputSelectMultiple with History', () => {
|
6
|
+
// let stdinStub, stdoutSpy, stdoutStub, processExitStub;
|
7
|
+
// let originalRawMode;
|
8
|
+
|
9
|
+
// before(() => {
|
10
|
+
// // stdoutSpy = sinon.spy(process.stdout, 'write');
|
11
|
+
// })
|
12
|
+
|
13
|
+
// beforeEach(() => {
|
14
|
+
// stdinStub = sinon.stub(process.stdin);
|
15
|
+
// stdoutStub = sinon.stub(process.stdout, "fd");
|
16
|
+
|
17
|
+
// processExitStub = sinon.stub(process, 'exit');
|
18
|
+
// originalRawMode = process.stdin.isRaw;
|
19
|
+
// });
|
20
|
+
|
21
|
+
// afterEach(() => {
|
22
|
+
// sinon.restore();
|
23
|
+
// process.stdin.setRawMode(originalRawMode);
|
24
|
+
// });
|
25
|
+
|
26
|
+
// // it('should handle a sequence of text, radio, and checkbox questions with history-', (done) => {
|
27
|
+
// // const questions = [
|
28
|
+
// // { text: 'What is your name?', type: 'text' },
|
29
|
+
// // { text: 'What is your favorite color?', type: 'radio', options: ['Red', 'Blue'] },
|
30
|
+
// // { text: 'Which fruits do you like?', type: 'checkbox', options: ['Apple', 'Banana'] },
|
31
|
+
// // ];
|
32
|
+
|
33
|
+
// // const expectedResults = [
|
34
|
+
// // { text: 'What is your name?', answer: 'Test Name' },
|
35
|
+
// // { text: 'What is your favorite color?', answer: 'Blue' },
|
36
|
+
// // { text: 'Which fruits do you like?', answer: ['Apple'] },
|
37
|
+
// // ];
|
38
|
+
|
39
|
+
// // const callback = (results) => {
|
40
|
+
// // assert.deepStrictEqual(results, expectedResults);
|
41
|
+
// // assert.ok(stdoutSpy.calledWith(sinon.match('What is your name?: Test Name')));
|
42
|
+
// // assert.ok(stdoutSpy.calledWith(sinon.match('What is your favorite color?: Blue')));
|
43
|
+
// // done();
|
44
|
+
// // };
|
45
|
+
|
46
|
+
// // inputSelectMultiple(questions, callback);
|
47
|
+
|
48
|
+
// // let keyPressCount = 0;
|
49
|
+
|
50
|
+
// // stdinStub.on('data', (data) => {
|
51
|
+
// // if (keyPressCount === 0) {
|
52
|
+
// // stdinStub.emit('keypress', '\r', { name: 'return' });
|
53
|
+
// // } else if (keyPressCount === 1) {
|
54
|
+
// // stdinStub.emit('keypress', '\r', { name: 'return' });
|
55
|
+
// // } else if (keyPressCount === 2) {
|
56
|
+
// // stdinStub.emit('keypress', '\r', { name: 'return' });
|
57
|
+
// // }
|
58
|
+
// // keyPressCount++;
|
59
|
+
// // });
|
60
|
+
|
61
|
+
// // stdinStub.emit('data', 'Test Name\n');
|
62
|
+
// // stdinStub.emit('keypress', null, { name: 'down' });
|
63
|
+
// // stdinStub.emit('keypress', null, { name: 'return' });
|
64
|
+
// // stdinStub.emit('keypress', null, { name: 'space' });
|
65
|
+
// // stdinStub.emit('keypress', null, { name: 'return' });
|
66
|
+
// // });
|
67
|
+
|
68
|
+
// it('should handle a sequence of text, radio, and checkbox questions with history', (done) => {
|
69
|
+
// const questions = [
|
70
|
+
// { text: 'What is your name?', type: 'text' },
|
71
|
+
// { text: 'What is your favorite color?', type: 'radio', options: ['Red', 'Blue'] },
|
72
|
+
// { text: 'Which fruits do you like?', type: 'checkbox', options: ['Apple', 'Banana'] },
|
73
|
+
// ];
|
74
|
+
|
75
|
+
// const expectedResults = [
|
76
|
+
// { text: 'What is your name?', answer: 'Test Name' },
|
77
|
+
// { text: 'What is your favorite color?', answer: 'Blue' },
|
78
|
+
// { text: 'Which fruits do you like?', answer: ['Apple'] },
|
79
|
+
// ];
|
80
|
+
|
81
|
+
// const callback = (results) => {
|
82
|
+
// assert.deepStrictEqual(results, expectedResults);
|
83
|
+
// done();
|
84
|
+
// };
|
85
|
+
|
86
|
+
// inputSelectMultiple(questions, callback);
|
87
|
+
|
88
|
+
// let keyPressCount = 0;
|
89
|
+
|
90
|
+
// stdinStub.on('data', (data) => {
|
91
|
+
// if (keyPressCount === 0) {
|
92
|
+
// stdinStub.emit('keypress', '\r', { name: 'return' });
|
93
|
+
// } else if (keyPressCount === 1) {
|
94
|
+
// stdinStub.emit('keypress', '\r', { name: 'return' });
|
95
|
+
// } else if (keyPressCount === 2) {
|
96
|
+
// stdinStub.emit('keypress', '\r', { name: 'return' });
|
97
|
+
// }
|
98
|
+
// keyPressCount++;
|
99
|
+
// });
|
100
|
+
|
101
|
+
// stdinStub.emit('data', 'Test Name\n');
|
102
|
+
// stdinStub.emit('keypress', null, { name: 'down' });
|
103
|
+
// stdinStub.emit('keypress', null, { name: 'return' });
|
104
|
+
// stdinStub.emit('keypress', null, { name: 'space' });
|
105
|
+
// stdinStub.emit('keypress', null, { name: 'return' });
|
106
|
+
|
107
|
+
// // Check if previous answers are displayed.
|
108
|
+
// // console.log();
|
109
|
+
// assert.ok(stdoutSpy.calledWith(sinon.match('What is your name? Test Name')));
|
110
|
+
// // assert.ok(stdoutSpy.calledWith(sinon.match('What is your name? Test Name')));
|
111
|
+
// // assert.ok(stdoutSpy.calledWith(sinon.match('What is your favorite color? Blue')));
|
112
|
+
// });
|
113
|
+
|
114
|
+
// it('should handle only text questions with history', (done) => {
|
115
|
+
// const questions = [
|
116
|
+
// { text: 'What is your name?', type: 'text' },
|
117
|
+
// { text: 'What is your age?', type: 'text' },
|
118
|
+
// ];
|
119
|
+
|
120
|
+
// const expectedResults = [
|
121
|
+
// { text: 'What is your name?', answer: 'Test Name' },
|
122
|
+
// { text: 'What is your age?', answer: '30' },
|
123
|
+
// ];
|
124
|
+
|
125
|
+
// const callback = (results) => {
|
126
|
+
// assert.deepStrictEqual(results, expectedResults);
|
127
|
+
// done();
|
128
|
+
// };
|
129
|
+
|
130
|
+
// inputSelectMultiple(questions, callback);
|
131
|
+
|
132
|
+
// let count = 0;
|
133
|
+
|
134
|
+
// stdinStub.on('data', (data) => {
|
135
|
+
// if (count === 0) {
|
136
|
+
// stdinStub.emit('keypress', '\r', { name: 'return' });
|
137
|
+
// } else {
|
138
|
+
// stdinStub.emit('keypress', '\r', { name: 'return' });
|
139
|
+
// }
|
140
|
+
// count++;
|
141
|
+
// });
|
142
|
+
|
143
|
+
// stdinStub.emit('data', 'Test Name\n');
|
144
|
+
// stdinStub.emit('data', '30\n');
|
145
|
+
|
146
|
+
// assert.ok(stdoutSpy.calledWith(sinon.match('What is your name? Test Name\n')));
|
147
|
+
|
148
|
+
// });
|
149
|
+
|
150
|
+
// it('should handle ctrl+c exit during questions with history', () => {
|
151
|
+
// const questions = [{ text: 'What is your name?', type: 'text' }];
|
152
|
+
|
153
|
+
// inputSelectMultiple(questions, () => { });
|
154
|
+
// stdinStub.emit('keypress', null, { ctrl: true, name: 'c' });
|
155
|
+
// assert.ok(!processExitStub.called);
|
156
|
+
// });
|
157
|
+
// });
|
@@ -0,0 +1,101 @@
|
|
1
|
+
const assert = require('chai').assert;
|
2
|
+
const sinon = require('sinon');
|
3
|
+
const { inputSelect } = require('../index'); // Replace 'your-file-name'
|
4
|
+
|
5
|
+
// describe('inputSelect', () => {
|
6
|
+
// let stdinStub, stdoutStub, processExitStub;
|
7
|
+
// let originalRawMode;
|
8
|
+
|
9
|
+
// beforeEach(() => {
|
10
|
+
// stdinStub = sinon.stub(process.stdin);
|
11
|
+
// stdoutStub = sinon.stub(process.stdout);
|
12
|
+
// processExitStub = sinon.stub(process, 'exit');
|
13
|
+
// originalRawMode = process.stdin.isRaw;
|
14
|
+
// });
|
15
|
+
|
16
|
+
// afterEach(() => {
|
17
|
+
// sinon.restore();
|
18
|
+
// process.stdin.setRawMode(originalRawMode); // Restore original raw mode
|
19
|
+
// });
|
20
|
+
|
21
|
+
// it('should handle radio button selection correctly', (done) => {
|
22
|
+
// const options = ['Option 1', 'Option 2', 'Option 3'];
|
23
|
+
// const selectedOption = 'Option 2';
|
24
|
+
|
25
|
+
// const callback = (result) => {
|
26
|
+
// assert.strictEqual(result, selectedOption);
|
27
|
+
// done();
|
28
|
+
// };
|
29
|
+
|
30
|
+
// inputSelect('Test radio question', options, 'radio', callback);
|
31
|
+
|
32
|
+
// stdinStub.emit('keypress', null, { name: 'down' });
|
33
|
+
// stdinStub.emit('keypress', null, { name: 'return' });
|
34
|
+
// });
|
35
|
+
|
36
|
+
// it('should handle checkbox selection correctly', (done) => {
|
37
|
+
// const options = ['Option 1', 'Option 2', 'Option 3'];
|
38
|
+
// const expectedSelections = ['Option 1', 'Option 3'];
|
39
|
+
|
40
|
+
// const callback = (result) => {
|
41
|
+
// assert.deepStrictEqual(result, expectedSelections);
|
42
|
+
// done();
|
43
|
+
// };
|
44
|
+
|
45
|
+
// inputSelect('Test checkbox question', options, 'checkbox', callback);
|
46
|
+
|
47
|
+
// stdinStub.emit('keypress', null, { name: 'space' });
|
48
|
+
// stdinStub.emit('keypress', null, { name: 'down' });
|
49
|
+
// stdinStub.emit('keypress', null, { name: 'down' });
|
50
|
+
// stdinStub.emit('keypress', null, { name: 'space' });
|
51
|
+
// stdinStub.emit('keypress', null, { name: 'return' });
|
52
|
+
// });
|
53
|
+
|
54
|
+
// it('should handle up and down arrow key navigation', () => {
|
55
|
+
// const options = ['Option 1', 'Option 2', 'Option 3'];
|
56
|
+
// inputSelect('Test navigation', options, 'radio', () => {});
|
57
|
+
|
58
|
+
// stdinStub.emit('keypress', null, { name: 'down' });
|
59
|
+
// stdinStub.emit('keypress', null, { name: 'up' });
|
60
|
+
|
61
|
+
// assert.ok(stdoutStub.called);
|
62
|
+
// });
|
63
|
+
|
64
|
+
// it('should handle ctrl+c exit', () => {
|
65
|
+
// inputSelect('Test exit', ['Option 1'], 'radio', () => {});
|
66
|
+
|
67
|
+
// stdinStub.emit('keypress', null, { ctrl: true, name: 'c' });
|
68
|
+
|
69
|
+
// assert.ok(processExitStub.called);
|
70
|
+
// });
|
71
|
+
|
72
|
+
// it('should correctly display radio buttons', () => {
|
73
|
+
// const options = ['Option 1', 'Option 2'];
|
74
|
+
// inputSelect('Test radio display', options, 'radio', () => {});
|
75
|
+
// assert.ok(stdoutStub.calledWith(sinon.match('> Option 1')));
|
76
|
+
// assert.ok(stdoutStub.calledWith(sinon.match(' Option 2')));
|
77
|
+
// });
|
78
|
+
|
79
|
+
// it('should correctly display checkboxes', () => {
|
80
|
+
// const options = ['Option 1', 'Option 2'];
|
81
|
+
// inputSelect('Test checkbox display', options, 'checkbox', () => {});
|
82
|
+
// assert.ok(stdoutStub.calledWith(sinon.match('[ ] Option 1')));
|
83
|
+
// assert.ok(stdoutStub.calledWith(sinon.match('[ ] Option 2')));
|
84
|
+
// });
|
85
|
+
|
86
|
+
// it('should correctly display checked checkboxes', (done) => {
|
87
|
+
// const options = ['Option 1', 'Option 2'];
|
88
|
+
|
89
|
+
// const callback = (result) => {
|
90
|
+
// assert.deepStrictEqual(result, ['Option 1']);
|
91
|
+
// done();
|
92
|
+
// };
|
93
|
+
|
94
|
+
// inputSelect('Test checked checkbox display', options, 'checkbox', callback);
|
95
|
+
|
96
|
+
// stdinStub.emit('keypress', null, { name: 'space' });
|
97
|
+
// stdinStub.emit('keypress', null, { name: 'return' });
|
98
|
+
// });
|
99
|
+
// });
|
100
|
+
|
101
|
+
|