11import { randomUUID } from 'crypto' ;
2+ import { cursor } from 'sisteransi' ;
23import { mockPrompt , setGlobalAliases } from '../../src' ;
34import Prompt , { PromptOptions } from '../../src/prompts/prompt' ;
5+ import { MockReadable , MockWritable } from '../mocks' ;
46
57const outputSpy = jest . spyOn ( process . stdout , 'write' ) . mockImplementation ( ) ;
68
@@ -17,8 +19,15 @@ const makeSut = (opts?: Omit<PromptOptions<Prompt>, 'render'>, trackValue?: bool
1719} ;
1820
1921describe ( 'Prompt' , ( ) => {
22+ let input : MockReadable ;
23+ let output : MockWritable ;
2024 const mock = mockPrompt ( ) ;
2125
26+ beforeEach ( ( ) => {
27+ input = new MockReadable ( ) ;
28+ output = new MockWritable ( ) ;
29+ } ) ;
30+
2231 afterEach ( ( ) => {
2332 mock . close ( ) ;
2433 } ) ;
@@ -139,15 +148,22 @@ describe('Prompt', () => {
139148 } ) ;
140149
141150 it ( 'should allow tab completion for placeholders' , ( ) => {
142- const placeholder = randomUUID ( ) ;
143- makeSut ( { initialValue : '' , placeholder } ) ;
151+ makeSut ( { initialValue : '' , placeholder : 'bar' } ) ;
152+
153+ mock . pressKey ( '\t' , { name : 'tab' } ) ;
154+
155+ expect ( mock . value ) . toBe ( 'bar' ) ;
156+ } ) ;
157+
158+ it ( 'should not allow tab completion if value is set' , ( ) => {
159+ makeSut ( { initialValue : 'foo' , placeholder : 'bar' } ) ;
144160
145161 mock . pressKey ( '\t' , { name : 'tab' } ) ;
146162
147- expect ( mock . value ) . toBe ( placeholder ) ;
163+ expect ( mock . value ) . toBe ( 'foo' ) ;
148164 } ) ;
149165
150- it ( 'should render prompt' , ( ) => {
166+ it ( 'should render prompt on default output ' , ( ) => {
151167 mock . setIsTestMode ( false ) ;
152168 const value = randomUUID ( ) ;
153169
@@ -158,6 +174,31 @@ describe('Prompt', () => {
158174 expect ( outputSpy ) . toHaveBeenCalledWith ( value ) ;
159175 } ) ;
160176
177+ test ( 'should render prompt on custom output' , ( ) => {
178+ mock . setIsTestMode ( false ) ;
179+ const value = 'foo' ;
180+
181+ makeSut ( { input, output, initialValue : value } ) ;
182+
183+ expect ( output . buffer ) . toStrictEqual ( [ cursor . hide , 'foo' ] ) ;
184+ } ) ;
185+
186+ it ( 'should re-render prompt on resize' , ( ) => {
187+ const renderFn = jest . fn ( ) . mockImplementation ( ( ) => 'foo' ) ;
188+ const instance = new Prompt ( {
189+ input,
190+ output,
191+ render : renderFn ,
192+ } ) ;
193+ instance . prompt ( ) ;
194+
195+ expect ( renderFn ) . toHaveBeenCalledTimes ( 1 ) ;
196+
197+ output . emit ( 'resize' ) ;
198+
199+ expect ( renderFn ) . toHaveBeenCalledTimes ( 2 ) ;
200+ } ) ;
201+
161202 it ( 'should update single line' , ( ) => {
162203 mock . setIsTestMode ( false ) ;
163204 const value = randomUUID ( ) ;
@@ -188,4 +229,50 @@ describe('Prompt', () => {
188229 expect ( outputSpy ) . toHaveBeenCalledWith ( value ) ;
189230 expect ( outputSpy ) . toHaveBeenCalledWith ( newValue ) ;
190231 } ) ;
232+
233+ it ( 'should emit cursor events for movement keys' , ( ) => {
234+ const keys = [ 'up' , 'down' , 'left' , 'right' ] ;
235+ const eventSpy = jest . fn ( ) ;
236+ const instance = new Prompt ( {
237+ input,
238+ output,
239+ render : ( ) => 'foo' ,
240+ } ) ;
241+
242+ instance . on ( 'cursor' , eventSpy ) ;
243+
244+ instance . prompt ( ) ;
245+
246+ for ( const key of keys ) {
247+ input . emit ( 'keypress' , key , { name : key } ) ;
248+ expect ( eventSpy ) . toBeCalledWith ( key ) ;
249+ }
250+ } ) ;
251+
252+ it ( 'should emit cursor events for movement key aliases when not tracking' , ( ) => {
253+ const keys = [
254+ [ 'k' , 'up' ] ,
255+ [ 'j' , 'down' ] ,
256+ [ 'h' , 'left' ] ,
257+ [ 'l' , 'right' ] ,
258+ ] ;
259+ const eventSpy = jest . fn ( ) ;
260+ const instance = new Prompt (
261+ {
262+ input,
263+ output,
264+ render : ( ) => 'foo' ,
265+ } ,
266+ false
267+ ) ;
268+
269+ instance . on ( 'cursor' , eventSpy ) ;
270+
271+ instance . prompt ( ) ;
272+
273+ for ( const [ alias , key ] of keys ) {
274+ input . emit ( 'keypress' , alias , { name : alias } ) ;
275+ expect ( eventSpy ) . toBeCalledWith ( key ) ;
276+ }
277+ } ) ;
191278} ) ;
0 commit comments