@@ -7,19 +7,26 @@ import assert from 'assert'
77import { TestInputBox , TestQuickPick } from '../vscode/quickInput'
88import { getTestWindow , TestWindow } from '../vscode/window'
99
10+ interface PrompterTesterConfig {
11+ testWindow ?: TestWindow
12+ handlerTimeout ?: number
13+ }
14+
1015export class PrompterTester {
1116 private quickPickHandlers : Map < string , ( input : TestQuickPick ) => void > = new Map ( )
1217 private inputBoxHanlder : Map < string , ( input : TestInputBox ) => void > = new Map ( )
1318 private testWindow : TestWindow
1419 private callLog = Array < string > ( )
20+ private handlerTimout : number = 3000 // Default timeout to 3 seconds
1521 private callLogCount = new Map < string , number > ( )
1622
17- private constructor ( testWindow ?: TestWindow ) {
18- this . testWindow = testWindow || getTestWindow ( )
23+ private constructor ( config ?: PrompterTesterConfig ) {
24+ this . testWindow = config ?. testWindow || getTestWindow ( )
25+ this . handlerTimout = config ?. handlerTimeout || this . handlerTimout
1926 }
2027
21- static init ( testWindow ?: TestWindow ) : PrompterTester {
22- return new PrompterTester ( testWindow )
28+ static init ( config ?: PrompterTesterConfig ) : PrompterTester {
29+ return new PrompterTester ( config )
2330 }
2431
2532 handleQuickPick ( titlePattern : string , handler : ( input : TestQuickPick ) => void ) : PrompterTester {
@@ -96,15 +103,27 @@ export class PrompterTester {
96103 return [ ...this . quickPickHandlers . keys ( ) , ...this . inputBoxHanlder . keys ( ) ]
97104 }
98105
99- private handle ( input : any , handlers : any ) {
100- for ( const [ pattern , handler ] of handlers ) {
101- if ( input . title ?. includes ( pattern ) ) {
102- handler ( input )
103- this . record ( pattern )
104- return
105- }
106+ private async handle ( input : any , handlers : any ) {
107+ const handler = handlers . get ( input . title )
108+
109+ if ( handler === undefined ) {
110+ return this . handleUnknownPrompter ( input )
111+ }
112+
113+ try {
114+ const timeoutPromise = new Promise < never > ( ( _ , reject ) => {
115+ setTimeout ( ( ) => {
116+ reject ( new Error ( `Handler for "${ input . title } " exceeded ${ this . handlerTimout } ms timeout` ) )
117+ } , this . handlerTimout )
118+ } )
119+
120+ await Promise . race ( [ handler ( input ) , timeoutPromise ] )
121+ } catch ( e ) {
122+ // clean up UI on callback function early exit (e.g assertion failure)
123+ await input . dispose ( )
124+ throw e
106125 }
107- this . handleUnknownPrompter ( input )
126+ this . record ( input . title )
108127 }
109128
110129 private handleUnknownPrompter ( input : any ) {
0 commit comments