Skip to content

Commit cb5cbe1

Browse files
committed
add handle timeout for prompter tester
1 parent 4d9046d commit cb5cbe1

File tree

1 file changed

+31
-12
lines changed

1 file changed

+31
-12
lines changed

packages/core/src/test/shared/wizards/prompterTester.ts

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,26 @@ import assert from 'assert'
77
import { TestInputBox, TestQuickPick } from '../vscode/quickInput'
88
import { getTestWindow, TestWindow } from '../vscode/window'
99

10+
interface PrompterTesterConfig {
11+
testWindow?: TestWindow
12+
handlerTimeout?: number
13+
}
14+
1015
export 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

Comments
 (0)