11import { cursor } from 'sisteransi' ;
2- import { afterEach , beforeEach , describe , expect , test , vi } from 'vitest' ;
3- import { default as AutocompletePrompt } from '../../src/prompts/autocomplete.js' ;
4- import { MockReadable } from '../mock-readable.js' ;
5- import { MockWritable } from '../mock-writable.js' ;
2+ import { beforeEach , describe , expect , test } from 'vitest' ;
3+ import { default as AutocompletePrompt } from './autocomplete.js' ;
4+ import { createMocks , type Mocks } from '@bomb.sh/tools/test-utils' ;
65
76describe ( 'AutocompletePrompt' , ( ) => {
8- let input : MockReadable ;
9- let output : MockWritable ;
7+ let mocks : Mocks < { input : true ; output : true } > ;
108 const testOptions = [
119 { value : 'apple' , label : 'Apple' } ,
1210 { value : 'banana' , label : 'Banana' } ,
@@ -16,29 +14,24 @@ describe('AutocompletePrompt', () => {
1614 ] ;
1715
1816 beforeEach ( ( ) => {
19- input = new MockReadable ( ) ;
20- output = new MockWritable ( ) ;
21- } ) ;
22-
23- afterEach ( ( ) => {
24- vi . restoreAllMocks ( ) ;
17+ mocks = createMocks ( { input : true , output : true } ) ;
2518 } ) ;
2619
2720 test ( 'renders render() result' , ( ) => {
2821 const instance = new AutocompletePrompt ( {
29- input,
30- output,
22+ input : mocks . input ,
23+ output : mocks . output ,
3124 render : ( ) => 'foo' ,
3225 options : testOptions ,
3326 } ) ;
3427 instance . prompt ( ) ;
35- expect ( output . buffer ) . to . deep . equal ( [ cursor . hide , 'foo' ] ) ;
28+ expect ( mocks . output . buffer ) . to . deep . equal ( [ cursor . hide , 'foo' ] ) ;
3629 } ) ;
3730
3831 test ( 'initial options match provided options' , ( ) => {
3932 const instance = new AutocompletePrompt ( {
40- input,
41- output,
33+ input : mocks . input ,
34+ output : mocks . output ,
4235 render : ( ) => 'foo' ,
4336 options : testOptions ,
4437 } ) ;
@@ -52,8 +45,8 @@ describe('AutocompletePrompt', () => {
5245
5346 test ( 'cursor navigation with event emitter' , ( ) => {
5447 const instance = new AutocompletePrompt ( {
55- input,
56- output,
48+ input : mocks . input ,
49+ output : mocks . output ,
5750 render : ( ) => 'foo' ,
5851 options : testOptions ,
5952 } ) ;
@@ -78,8 +71,8 @@ describe('AutocompletePrompt', () => {
7871
7972 test ( 'initialValue selects correct option' , ( ) => {
8073 const instance = new AutocompletePrompt ( {
81- input,
82- output,
74+ input : mocks . input ,
75+ output : mocks . output ,
8376 render : ( ) => 'foo' ,
8477 options : testOptions ,
8578 initialValue : [ 'cherry' ] ,
@@ -95,8 +88,8 @@ describe('AutocompletePrompt', () => {
9588
9689 test ( 'initialValue defaults to first option when non-multiple' , ( ) => {
9790 const instance = new AutocompletePrompt ( {
98- input,
99- output,
91+ input : mocks . input ,
92+ output : mocks . output ,
10093 render : ( ) => 'foo' ,
10194 options : testOptions ,
10295 } ) ;
@@ -107,8 +100,8 @@ describe('AutocompletePrompt', () => {
107100
108101 test ( 'initialValue is empty when multiple' , ( ) => {
109102 const instance = new AutocompletePrompt ( {
110- input,
111- output,
103+ input : mocks . input ,
104+ output : mocks . output ,
112105 render : ( ) => 'foo' ,
113106 options : testOptions ,
114107 multiple : true ,
@@ -120,8 +113,8 @@ describe('AutocompletePrompt', () => {
120113
121114 test ( 'filtering through user input' , ( ) => {
122115 const instance = new AutocompletePrompt ( {
123- input,
124- output,
116+ input : mocks . input ,
117+ output : mocks . output ,
125118 render : ( ) => 'foo' ,
126119 options : testOptions ,
127120 } ) ;
@@ -132,7 +125,7 @@ describe('AutocompletePrompt', () => {
132125 expect ( instance . filteredOptions . length ) . to . equal ( testOptions . length ) ;
133126
134127 // Simulate typing 'a' by emitting keypress event
135- input . emit ( 'keypress' , 'a' , { name : 'a' } ) ;
128+ mocks . input . emit ( 'keypress' , 'a' , { name : 'a' } ) ;
136129
137130 // Check that filtered options are updated to include options with 'a'
138131 expect ( instance . filteredOptions . length ) . to . be . lessThan ( testOptions . length ) ;
@@ -144,37 +137,37 @@ describe('AutocompletePrompt', () => {
144137
145138 test ( 'default filter function works correctly' , ( ) => {
146139 const instance = new AutocompletePrompt ( {
147- input,
148- output,
140+ input : mocks . input ,
141+ output : mocks . output ,
149142 render : ( ) => 'foo' ,
150143 options : testOptions ,
151144 } ) ;
152145
153146 instance . prompt ( ) ;
154147
155- input . emit ( 'keypress' , 'a' , { name : 'a' } ) ;
156- input . emit ( 'keypress' , 'p' , { name : 'p' } ) ;
148+ mocks . input . emit ( 'keypress' , 'a' , { name : 'a' } ) ;
149+ mocks . input . emit ( 'keypress' , 'p' , { name : 'p' } ) ;
157150
158151 expect ( instance . filteredOptions ) . toEqual ( [
159152 { value : 'apple' , label : 'Apple' } ,
160153 { value : 'grape' , label : 'Grape' } ,
161154 ] ) ;
162155
163- input . emit ( 'keypress' , 'z' , { name : 'z' } ) ;
156+ mocks . input . emit ( 'keypress' , 'z' , { name : 'z' } ) ;
164157
165158 expect ( instance . filteredOptions ) . toEqual ( [ ] ) ;
166159 } ) ;
167160
168161 test ( 'submit without nav resolves to first option in non-multiple' , async ( ) => {
169162 const instance = new AutocompletePrompt ( {
170- input,
171- output,
163+ input : mocks . input ,
164+ output : mocks . output ,
172165 render : ( ) => 'foo' ,
173166 options : testOptions ,
174167 } ) ;
175168
176169 const promise = instance . prompt ( ) ;
177- input . emit ( 'keypress' , '' , { name : 'return' } ) ;
170+ mocks . input . emit ( 'keypress' , '' , { name : 'return' } ) ;
178171 const result = await promise ;
179172
180173 expect ( instance . selectedValues ) . to . deep . equal ( [ 'apple' ] ) ;
@@ -183,15 +176,15 @@ describe('AutocompletePrompt', () => {
183176
184177 test ( 'submit without nav resolves to [] in multiple' , async ( ) => {
185178 const instance = new AutocompletePrompt ( {
186- input,
187- output,
179+ input : mocks . input ,
180+ output : mocks . output ,
188181 render : ( ) => 'foo' ,
189182 options : testOptions ,
190183 multiple : true ,
191184 } ) ;
192185
193186 const promise = instance . prompt ( ) ;
194- input . emit ( 'keypress' , '' , { name : 'return' } ) ;
187+ mocks . input . emit ( 'keypress' , '' , { name : 'return' } ) ;
195188 const result = await promise ;
196189
197190 expect ( instance . selectedValues ) . to . deep . equal ( [ ] ) ;
@@ -200,16 +193,16 @@ describe('AutocompletePrompt', () => {
200193
201194 test ( 'Tab with empty input and placeholder fills input and submit returns matching option' , async ( ) => {
202195 const instance = new AutocompletePrompt ( {
203- input,
204- output,
196+ input : mocks . input ,
197+ output : mocks . output ,
205198 render : ( ) => 'foo' ,
206199 options : testOptions ,
207200 placeholder : 'apple' ,
208201 } ) ;
209202
210203 const promise = instance . prompt ( ) ;
211- input . emit ( 'keypress' , '\t' , { name : 'tab' } ) ;
212- input . emit ( 'keypress' , '' , { name : 'return' } ) ;
204+ mocks . input . emit ( 'keypress' , '\t' , { name : 'tab' } ) ;
205+ mocks . input . emit ( 'keypress' , '' , { name : 'return' } ) ;
213206 const result = await promise ;
214207
215208 expect ( instance . userInput ) . to . equal ( 'apple' ) ;
@@ -222,15 +215,15 @@ describe('AutocompletePrompt', () => {
222215 { value : 'banana' , label : 'Banana' } ,
223216 ] ;
224217 const instance = new AutocompletePrompt ( {
225- input,
226- output,
218+ input : mocks . input ,
219+ output : mocks . output ,
227220 render : ( ) => 'foo' ,
228221 options : ( ) => dynamicOptions ,
229222 } ) ;
230223
231224 instance . prompt ( ) ;
232225
233- input . emit ( 'keypress' , 'z' , { name : 'z' } ) ;
226+ mocks . input . emit ( 'keypress' , 'z' , { name : 'z' } ) ;
234227
235228 expect ( instance . filteredOptions ) . toEqual ( dynamicOptions ) ;
236229 } ) ;
@@ -242,32 +235,32 @@ describe('AutocompletePrompt', () => {
242235 { value : 'cherry' , label : 'Cherry' } ,
243236 ] ;
244237 const instance = new AutocompletePrompt ( {
245- input,
246- output,
238+ input : mocks . input ,
239+ output : mocks . output ,
247240 render : ( ) => 'foo' ,
248241 options : ( ) => dynamicOptions ,
249242 filter : ( search , opt ) => ( opt . label ?? '' ) . toLowerCase ( ) . endsWith ( search . toLowerCase ( ) ) ,
250243 } ) ;
251244
252245 instance . prompt ( ) ;
253246
254- input . emit ( 'keypress' , 'a' , { name : 'a' } ) ;
247+ mocks . input . emit ( 'keypress' , 'a' , { name : 'a' } ) ;
255248
256249 // 'endsWith' matches Banana but not Apple or Cherry
257250 expect ( instance . filteredOptions ) . toEqual ( [ { value : 'banana' , label : 'Banana' } ] ) ;
258251 } ) ;
259252
260253 test ( 'Tab with non-matching placeholder does not fill input' , async ( ) => {
261254 const instance = new AutocompletePrompt ( {
262- input,
263- output,
255+ input : mocks . input ,
256+ output : mocks . output ,
264257 render : ( ) => 'foo' ,
265258 options : testOptions ,
266259 placeholder : 'Type to search...' ,
267260 } ) ;
268261
269262 instance . prompt ( ) ;
270- input . emit ( 'keypress' , '\t' , { name : 'tab' } ) ;
263+ mocks . input . emit ( 'keypress' , '\t' , { name : 'tab' } ) ;
271264
272265 // Placeholder does not match any option, so input must not be filled with placeholder
273266 expect ( instance . userInput ) . not . to . equal ( 'Type to search...' ) ;
0 commit comments