* A fake whose grammar load takes `loadMs` (or never finishes, with `null`), and * which records when it finished loading and when it was terminated.
| 254 | * which records when it finished loading and when it was terminated. |
| 255 | */ |
| 256 | class SlowLoadWorker implements ParsePoolWorker { |
| 257 | private msgCb?: (m: unknown) => void; |
| 258 | private exitCb?: (code: number) => void; |
| 259 | loadedAt: number | null = null; |
| 260 | terminatedAt: number | null = null; |
| 261 | constructor(private loadMs: number | null) {} |
| 262 | on(event: string, cb: (...args: any[]) => void): void { |
| 263 | if (event === 'message') this.msgCb = cb; |
| 264 | else if (event === 'exit') this.exitCb = cb; |
| 265 | } |
| 266 | postMessage(msg: unknown): void { |
| 267 | if ((msg as { type: string }).type !== 'load-grammars' || this.loadMs === null) return; |
| 268 | setTimeout(() => { |
| 269 | if (this.terminatedAt !== null) return; |
| 270 | this.loadedAt = performance.now(); |
| 271 | this.msgCb?.({ type: 'grammars-loaded' }); |
| 272 | }, this.loadMs); |
| 273 | } |
| 274 | exit(code: number): void { this.exitCb?.(code); } |
| 275 | terminate(): Promise<number> { this.terminatedAt = performance.now(); return Promise.resolve(0); } |
| 276 | } |
| 277 | |
| 278 | describe('teardown never terminates a worker mid-load', () => { |
| 279 | // Terminating a worker whose grammar WASM is still compiling can crash the |
nothing calls this directly
no outgoing calls
no test coverage detected