Skip to content

Commit fb697f2

Browse files
committed
test: fix reconnect tests for deno
1 parent 3b13da7 commit fb697f2

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

test/helpers.ts

+42
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type {ServerResponse} from 'http'
12
import sinon, {type SinonSpy} from 'sinon'
23

34
import type {EventSourceClient} from '../src/types.js'
@@ -44,6 +45,47 @@ export function deferClose(es: EventSourceClient, timeout = 25): Promise<void> {
4445
return new Promise((resolve) => setTimeout(() => resolve(es.close()), timeout))
4546
}
4647

48+
export async function waitForClose(res: ServerResponse): Promise<void> {
49+
let resolve
50+
let reject
51+
const promise = new Promise<void>((_resolve, _reject) => {
52+
resolve = _resolve
53+
reject = _reject
54+
})
55+
56+
let hasTimedOut = false
57+
res.once('close', () => resolve())
58+
const timeout = setTimeout(() => {
59+
hasTimedOut = true
60+
reject(new Error('Timeout waiting for close'))
61+
}, 15000)
62+
63+
if (typeof globalThis.Deno === 'undefined') {
64+
return promise
65+
}
66+
67+
// Deno does not trigger close event, apparently, so we'll have to try to write,
68+
// then catch the error that occurs upon a close
69+
for (;;) {
70+
if (hasTimedOut) {
71+
return promise
72+
}
73+
74+
try {
75+
res.write(':\n')
76+
} catch (err: unknown) {
77+
if (err instanceof Error && err.message.includes('cannot close or enqueue')) {
78+
clearTimeout(timeout)
79+
resolve()
80+
return promise
81+
}
82+
throw err
83+
}
84+
85+
await new Promise((waitResolve) => setTimeout(waitResolve, 100))
86+
}
87+
}
88+
4789
export function expect(thing: unknown): {
4890
toBe(expected: unknown): void
4991
toBeLessThan(thanNum: number): void

test/server.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {resolve as resolvePath} from 'node:path'
66
import esbuild from 'esbuild'
77

88
import {unicodeLines} from './fixtures.js'
9+
import {waitForClose} from './helpers.js'
910

1011
const isDeno = typeof globalThis.Deno !== 'undefined'
1112
const idedListeners = new Map<string, Set<ServerResponse>>()
@@ -113,7 +114,7 @@ async function writeCounter(req: IncomingMessage, res: ServerResponse) {
113114
res.end()
114115
}
115116

116-
function writeIdentifiedListeners(req: IncomingMessage, res: ServerResponse) {
117+
async function writeIdentifiedListeners(req: IncomingMessage, res: ServerResponse) {
117118
const url = new URL(req.url || '/', 'http://localhost')
118119
const id = url.searchParams.get('id')
119120
if (!id) {
@@ -137,7 +138,9 @@ function writeIdentifiedListeners(req: IncomingMessage, res: ServerResponse) {
137138
})
138139
tryWrite(res, formatEvent({data: '', retry: 250}))
139140
tryWrite(res, formatEvent({data: `${idedListeners.size}`}))
140-
res.on('close', () => (idedListeners.get(id) || new Set()).delete(res))
141+
142+
await waitForClose(res)
143+
;(idedListeners.get(id) || new Set()).delete(res)
141144
return
142145
}
143146

0 commit comments

Comments
 (0)