@inquirer/testing 3.1.1 → 3.2.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/dist/jest.d.ts +3 -1
- package/dist/jest.js +133 -56
- package/dist/vitest.d.ts +3 -1
- package/dist/vitest.js +133 -54
- package/package.json +5 -5
package/dist/jest.d.ts
CHANGED
|
@@ -15,5 +15,7 @@ export { screenInstance as screen };
|
|
|
15
15
|
* });
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
18
|
-
export declare function wrapPrompt<Value, Config>(prompt: Prompt<Value, Config>
|
|
18
|
+
export declare function wrapPrompt<Value, Config>(prompt: Prompt<Value, Config> | {
|
|
19
|
+
default: Prompt<Value, Config>;
|
|
20
|
+
}): Prompt<Value, Config>;
|
|
19
21
|
export { Screen, type KeypressEvent } from './screen.js';
|
package/dist/jest.js
CHANGED
|
@@ -22,9 +22,13 @@ beforeEach(() => {
|
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
24
|
export function wrapPrompt(prompt) {
|
|
25
|
+
// Unwrap SWC-style module namespace objects where barrel re-exports like
|
|
26
|
+
// `export { default as input } from '@inquirer/input'` get transformed into
|
|
27
|
+
// `{ default: fn }` instead of the function directly.
|
|
28
|
+
const fn = typeof prompt === 'function' ? prompt : prompt.default;
|
|
25
29
|
return (config, context) => {
|
|
26
30
|
const output = screenInstance.createOutput();
|
|
27
|
-
const promise =
|
|
31
|
+
const promise = fn(config, {
|
|
28
32
|
...context,
|
|
29
33
|
input: screenInstance.input,
|
|
30
34
|
output,
|
|
@@ -33,87 +37,160 @@ export function wrapPrompt(prompt) {
|
|
|
33
37
|
return promise;
|
|
34
38
|
};
|
|
35
39
|
}
|
|
36
|
-
//
|
|
40
|
+
// Prompt names used by the @inquirer/prompts barrel mock to wrap only prompt exports.
|
|
41
|
+
const promptNames = [
|
|
42
|
+
'input',
|
|
43
|
+
'select',
|
|
44
|
+
'confirm',
|
|
45
|
+
'checkbox',
|
|
46
|
+
'password',
|
|
47
|
+
'expand',
|
|
48
|
+
'rawlist',
|
|
49
|
+
'number',
|
|
50
|
+
'search',
|
|
51
|
+
'editor',
|
|
52
|
+
];
|
|
53
|
+
// Mock individual prompt packages (covers `import input from '@inquirer/input'` style).
|
|
54
|
+
// All prompt packages are optional peer dependencies, so factories silently skip
|
|
55
|
+
// packages that aren't installed in the consumer's project.
|
|
37
56
|
jest.mock('@inquirer/input', () => {
|
|
38
|
-
|
|
39
|
-
|
|
57
|
+
try {
|
|
58
|
+
const actual = jest.requireActual('@inquirer/input');
|
|
59
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return {};
|
|
63
|
+
}
|
|
40
64
|
});
|
|
41
65
|
jest.mock('@inquirer/select', () => {
|
|
42
|
-
|
|
43
|
-
|
|
66
|
+
try {
|
|
67
|
+
const actual = jest.requireActual('@inquirer/select');
|
|
68
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
44
73
|
});
|
|
45
74
|
jest.mock('@inquirer/confirm', () => {
|
|
46
|
-
|
|
47
|
-
|
|
75
|
+
try {
|
|
76
|
+
const actual = jest.requireActual('@inquirer/confirm');
|
|
77
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return {};
|
|
81
|
+
}
|
|
48
82
|
});
|
|
49
83
|
jest.mock('@inquirer/checkbox', () => {
|
|
50
|
-
|
|
51
|
-
|
|
84
|
+
try {
|
|
85
|
+
const actual = jest.requireActual('@inquirer/checkbox');
|
|
86
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return {};
|
|
90
|
+
}
|
|
52
91
|
});
|
|
53
92
|
jest.mock('@inquirer/password', () => {
|
|
54
|
-
|
|
55
|
-
|
|
93
|
+
try {
|
|
94
|
+
const actual = jest.requireActual('@inquirer/password');
|
|
95
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return {};
|
|
99
|
+
}
|
|
56
100
|
});
|
|
57
101
|
jest.mock('@inquirer/expand', () => {
|
|
58
|
-
|
|
59
|
-
|
|
102
|
+
try {
|
|
103
|
+
const actual = jest.requireActual('@inquirer/expand');
|
|
104
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return {};
|
|
108
|
+
}
|
|
60
109
|
});
|
|
61
110
|
jest.mock('@inquirer/rawlist', () => {
|
|
62
|
-
|
|
63
|
-
|
|
111
|
+
try {
|
|
112
|
+
const actual = jest.requireActual('@inquirer/rawlist');
|
|
113
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return {};
|
|
117
|
+
}
|
|
64
118
|
});
|
|
65
119
|
jest.mock('@inquirer/number', () => {
|
|
66
|
-
|
|
67
|
-
|
|
120
|
+
try {
|
|
121
|
+
const actual = jest.requireActual('@inquirer/number');
|
|
122
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return {};
|
|
126
|
+
}
|
|
68
127
|
});
|
|
69
128
|
jest.mock('@inquirer/search', () => {
|
|
70
|
-
|
|
71
|
-
|
|
129
|
+
try {
|
|
130
|
+
const actual = jest.requireActual('@inquirer/search');
|
|
131
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return {};
|
|
135
|
+
}
|
|
72
136
|
});
|
|
73
137
|
jest.mock('@inquirer/editor', () => {
|
|
74
|
-
|
|
75
|
-
|
|
138
|
+
try {
|
|
139
|
+
const actual = jest.requireActual('@inquirer/editor');
|
|
140
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return {};
|
|
144
|
+
}
|
|
76
145
|
});
|
|
77
146
|
// Mock @inquirer/prompts barrel re-exports (covers `import { input } from '@inquirer/prompts'` style).
|
|
78
147
|
// Jest's module mock for individual packages doesn't propagate through barrel re-exports.
|
|
148
|
+
// Only prompt functions are wrapped; other exports (like Separator) are passed through.
|
|
79
149
|
jest.mock('@inquirer/prompts', () => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
...actual
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
};
|
|
150
|
+
try {
|
|
151
|
+
const actual = jest.requireActual('@inquirer/prompts');
|
|
152
|
+
const wrapped = { ...actual };
|
|
153
|
+
for (const name of promptNames) {
|
|
154
|
+
if (name in actual) {
|
|
155
|
+
wrapped[name] = wrapPrompt(actual[name]);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return wrapped;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return {};
|
|
162
|
+
}
|
|
94
163
|
});
|
|
95
164
|
// Mock the external editor to capture typed input instead of spawning a real editor.
|
|
96
165
|
// Buffers all screen.type() calls and submits on screen.keypress('enter'), matching
|
|
97
166
|
// the interaction pattern of other prompts (type → enter).
|
|
98
|
-
jest.mock('@inquirer/external-editor', () =>
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
167
|
+
jest.mock('@inquirer/external-editor', () => {
|
|
168
|
+
try {
|
|
169
|
+
jest.requireActual('@inquirer/external-editor');
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
return {};
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
editAsync: (_text, callback) => {
|
|
176
|
+
let buffer = '';
|
|
177
|
+
const typeSpy = jest
|
|
178
|
+
.spyOn(screenInstance, 'type')
|
|
179
|
+
.mockImplementation((text) => {
|
|
180
|
+
buffer += text;
|
|
181
|
+
});
|
|
182
|
+
const keypressSpy = jest
|
|
183
|
+
.spyOn(screenInstance, 'keypress')
|
|
184
|
+
.mockImplementation((key) => {
|
|
185
|
+
const name = typeof key === 'string' ? key : key.name;
|
|
186
|
+
if (name === 'enter' || name === 'return') {
|
|
187
|
+
typeSpy.mockRestore();
|
|
188
|
+
keypressSpy.mockRestore();
|
|
189
|
+
process.nextTick(() => callback(undefined, buffer));
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
});
|
|
118
195
|
// Re-export Screen class and KeypressEvent type for advanced use cases
|
|
119
196
|
export { Screen } from './screen.js';
|
package/dist/vitest.d.ts
CHANGED
|
@@ -16,5 +16,7 @@ export { screenInstance as screen };
|
|
|
16
16
|
* });
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
-
export declare function wrapPrompt<Value, Config>(prompt: Prompt<Value, Config>
|
|
19
|
+
export declare function wrapPrompt<Value, Config>(prompt: Prompt<Value, Config> | {
|
|
20
|
+
default: Prompt<Value, Config>;
|
|
21
|
+
}): Prompt<Value, Config>;
|
|
20
22
|
export { Screen, type KeypressEvent } from './screen.js';
|
package/dist/vitest.js
CHANGED
|
@@ -22,9 +22,13 @@ beforeEach(() => {
|
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
24
|
export function wrapPrompt(prompt) {
|
|
25
|
+
// Unwrap SWC-style module namespace objects where barrel re-exports like
|
|
26
|
+
// `export { default as input } from '@inquirer/input'` get transformed into
|
|
27
|
+
// `{ default: fn }` instead of the function directly.
|
|
28
|
+
const fn = typeof prompt === 'function' ? prompt : prompt.default;
|
|
25
29
|
return (config, context) => {
|
|
26
30
|
const output = screenInstance.createOutput();
|
|
27
|
-
const promise =
|
|
31
|
+
const promise = fn(config, {
|
|
28
32
|
...context,
|
|
29
33
|
input: screenInstance.input,
|
|
30
34
|
output,
|
|
@@ -33,86 +37,161 @@ export function wrapPrompt(prompt) {
|
|
|
33
37
|
return promise;
|
|
34
38
|
};
|
|
35
39
|
}
|
|
36
|
-
//
|
|
40
|
+
// Prompt names used by the @inquirer/prompts barrel mock to wrap only prompt exports.
|
|
41
|
+
const promptNames = [
|
|
42
|
+
'input',
|
|
43
|
+
'select',
|
|
44
|
+
'confirm',
|
|
45
|
+
'checkbox',
|
|
46
|
+
'password',
|
|
47
|
+
'expand',
|
|
48
|
+
'rawlist',
|
|
49
|
+
'number',
|
|
50
|
+
'search',
|
|
51
|
+
'editor',
|
|
52
|
+
];
|
|
53
|
+
// Mock individual prompt packages (covers `import input from '@inquirer/input'` style).
|
|
54
|
+
// All prompt packages are optional peer dependencies, so factories silently skip
|
|
55
|
+
// packages that aren't installed in the consumer's project.
|
|
37
56
|
vi.mock('@inquirer/input', async (importOriginal) => {
|
|
38
|
-
|
|
39
|
-
|
|
57
|
+
try {
|
|
58
|
+
const actual = await importOriginal();
|
|
59
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return {};
|
|
63
|
+
}
|
|
40
64
|
});
|
|
41
65
|
vi.mock('@inquirer/select', async (importOriginal) => {
|
|
42
|
-
|
|
43
|
-
|
|
66
|
+
try {
|
|
67
|
+
const actual = await importOriginal();
|
|
68
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
44
73
|
});
|
|
45
74
|
vi.mock('@inquirer/confirm', async (importOriginal) => {
|
|
46
|
-
|
|
47
|
-
|
|
75
|
+
try {
|
|
76
|
+
const actual = await importOriginal();
|
|
77
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return {};
|
|
81
|
+
}
|
|
48
82
|
});
|
|
49
83
|
vi.mock('@inquirer/checkbox', async (importOriginal) => {
|
|
50
|
-
|
|
51
|
-
|
|
84
|
+
try {
|
|
85
|
+
const actual = await importOriginal();
|
|
86
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return {};
|
|
90
|
+
}
|
|
52
91
|
});
|
|
53
92
|
vi.mock('@inquirer/password', async (importOriginal) => {
|
|
54
|
-
|
|
55
|
-
|
|
93
|
+
try {
|
|
94
|
+
const actual = await importOriginal();
|
|
95
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return {};
|
|
99
|
+
}
|
|
56
100
|
});
|
|
57
101
|
vi.mock('@inquirer/expand', async (importOriginal) => {
|
|
58
|
-
|
|
59
|
-
|
|
102
|
+
try {
|
|
103
|
+
const actual = await importOriginal();
|
|
104
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return {};
|
|
108
|
+
}
|
|
60
109
|
});
|
|
61
110
|
vi.mock('@inquirer/rawlist', async (importOriginal) => {
|
|
62
|
-
|
|
63
|
-
|
|
111
|
+
try {
|
|
112
|
+
const actual = await importOriginal();
|
|
113
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return {};
|
|
117
|
+
}
|
|
64
118
|
});
|
|
65
119
|
vi.mock('@inquirer/number', async (importOriginal) => {
|
|
66
|
-
|
|
67
|
-
|
|
120
|
+
try {
|
|
121
|
+
const actual = await importOriginal();
|
|
122
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return {};
|
|
126
|
+
}
|
|
68
127
|
});
|
|
69
128
|
vi.mock('@inquirer/search', async (importOriginal) => {
|
|
70
|
-
|
|
71
|
-
|
|
129
|
+
try {
|
|
130
|
+
const actual = await importOriginal();
|
|
131
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return {};
|
|
135
|
+
}
|
|
72
136
|
});
|
|
73
137
|
vi.mock('@inquirer/editor', async (importOriginal) => {
|
|
74
|
-
|
|
75
|
-
|
|
138
|
+
try {
|
|
139
|
+
const actual = await importOriginal();
|
|
140
|
+
return { ...actual, default: wrapPrompt(actual.default) };
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return {};
|
|
144
|
+
}
|
|
76
145
|
});
|
|
77
146
|
// Mock @inquirer/prompts barrel re-exports (covers `import { input } from '@inquirer/prompts'` style).
|
|
78
147
|
// While Vitest's module interception often propagates through ESM re-exports, an explicit mock
|
|
79
148
|
// ensures consistent behavior across all environments and bundler configurations.
|
|
149
|
+
// Only prompt functions are wrapped; other exports (like Separator) are passed through.
|
|
80
150
|
vi.mock('@inquirer/prompts', async (importOriginal) => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
...actual
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
};
|
|
151
|
+
try {
|
|
152
|
+
const actual = await importOriginal();
|
|
153
|
+
const wrapped = { ...actual };
|
|
154
|
+
for (const name of promptNames) {
|
|
155
|
+
if (name in actual) {
|
|
156
|
+
wrapped[name] = wrapPrompt(actual[name]);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return wrapped;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return {};
|
|
163
|
+
}
|
|
95
164
|
});
|
|
96
165
|
// Mock the external editor to capture typed input instead of spawning a real editor.
|
|
97
166
|
// Buffers all screen.type() calls and submits on screen.keypress('enter'), matching
|
|
98
167
|
// the interaction pattern of other prompts (type → enter).
|
|
99
|
-
vi.mock('@inquirer/external-editor', () =>
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
168
|
+
vi.mock('@inquirer/external-editor', async (importOriginal) => {
|
|
169
|
+
try {
|
|
170
|
+
await importOriginal();
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return {};
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
editAsync: (_text, callback) => {
|
|
177
|
+
let buffer = '';
|
|
178
|
+
const typeSpy = vi
|
|
179
|
+
.spyOn(screenInstance, 'type')
|
|
180
|
+
.mockImplementation((text) => {
|
|
181
|
+
buffer += text;
|
|
182
|
+
});
|
|
183
|
+
const keypressSpy = vi
|
|
184
|
+
.spyOn(screenInstance, 'keypress')
|
|
185
|
+
.mockImplementation((key) => {
|
|
186
|
+
const name = typeof key === 'string' ? key : key.name;
|
|
187
|
+
if (name === 'enter' || name === 'return') {
|
|
188
|
+
typeSpy.mockRestore();
|
|
189
|
+
keypressSpy.mockRestore();
|
|
190
|
+
process.nextTick(() => callback(undefined, buffer));
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
});
|
|
117
196
|
// Re-export Screen class and KeypressEvent type for advanced use cases
|
|
118
197
|
export { Screen } from './screen.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inquirer/testing",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Inquirer testing utilities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"answer",
|
|
@@ -84,15 +84,15 @@
|
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
86
|
"@inquirer/type": "^4.0.3",
|
|
87
|
-
"@xterm/headless": "^
|
|
87
|
+
"@xterm/headless": "^6.0.0",
|
|
88
88
|
"mute-stream": "^3.0.0"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
|
-
"@types/jest": "^
|
|
91
|
+
"@types/jest": "^30.0.0",
|
|
92
92
|
"@types/mute-stream": "^0.0.4",
|
|
93
93
|
"@types/node": "^25.0.2",
|
|
94
94
|
"typescript": "^5.9.3",
|
|
95
|
-
"vitest": "^
|
|
95
|
+
"vitest": "^4.0.18"
|
|
96
96
|
},
|
|
97
97
|
"peerDependencies": {
|
|
98
98
|
"@inquirer/checkbox": ">=1.0.0",
|
|
@@ -167,5 +167,5 @@
|
|
|
167
167
|
},
|
|
168
168
|
"main": "./dist/index.js",
|
|
169
169
|
"types": "./dist/index.d.ts",
|
|
170
|
-
"gitHead": "
|
|
170
|
+
"gitHead": "fd001c191cfb287b430d5e90cb159cf8f6500dc5"
|
|
171
171
|
}
|