@mswjs/interceptors 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/lib/browser/interceptors/XMLHttpRequest/index.js +0 -4
  2. package/lib/browser/interceptors/XMLHttpRequest/index.mjs +0 -4
  3. package/lib/node/RemoteHttpInterceptor.js +11 -15
  4. package/lib/node/RemoteHttpInterceptor.mjs +5 -9
  5. package/lib/node/{chunk-ZSI7MX3V.mjs → chunk-37CATPNG.mjs} +0 -34
  6. package/lib/node/{chunk-ZWCZGO3W.mjs → chunk-CYWTKHFI.mjs} +2 -7
  7. package/lib/node/{chunk-CIN5URNI.mjs → chunk-G6ZTHYZQ.mjs} +1 -1
  8. package/lib/node/{chunk-HDUJCCWF.js → chunk-GGD5JOGB.js} +9 -14
  9. package/lib/node/{chunk-JISWS3Y3.mjs → chunk-KZEQH4YW.mjs} +1 -1
  10. package/lib/node/{chunk-VKKFXSTL.js → chunk-PRX3F52M.js} +31 -24
  11. package/lib/node/{chunk-KZJG2UW7.js → chunk-Q56TMOP5.js} +2 -2
  12. package/lib/node/{chunk-6GWWOJ23.js → chunk-SNNL2EXF.js} +3 -3
  13. package/lib/node/{chunk-FCIAOT7W.mjs → chunk-SWJ33XIS.mjs} +24 -17
  14. package/lib/node/{chunk-QMIXLBOU.js → chunk-WWHITCCI.js} +2 -36
  15. package/lib/node/index.js +4 -4
  16. package/lib/node/index.mjs +3 -3
  17. package/lib/node/interceptors/ClientRequest/index.js +3 -4
  18. package/lib/node/interceptors/ClientRequest/index.mjs +2 -3
  19. package/lib/node/interceptors/XMLHttpRequest/index.js +4 -5
  20. package/lib/node/interceptors/XMLHttpRequest/index.mjs +3 -4
  21. package/lib/node/interceptors/fetch/index.js +2 -2
  22. package/lib/node/interceptors/fetch/index.mjs +1 -1
  23. package/package.json +17 -11
  24. package/src/BatchInterceptor.test.ts +8 -7
  25. package/src/Interceptor.test.ts +6 -5
  26. package/src/RemoteHttpInterceptor.ts +0 -1
  27. package/src/interceptors/ClientRequest/NodeClientRequest.test.ts +108 -86
  28. package/src/interceptors/ClientRequest/NodeClientRequest.ts +40 -22
  29. package/src/interceptors/ClientRequest/index.test.ts +20 -8
  30. package/src/interceptors/ClientRequest/utils/cloneIncomingMessage.test.ts +2 -1
  31. package/src/interceptors/ClientRequest/utils/createRequest.test.ts +1 -0
  32. package/src/interceptors/ClientRequest/utils/createRequest.ts +0 -1
  33. package/src/interceptors/ClientRequest/utils/createResponse.test.ts +1 -3
  34. package/src/interceptors/ClientRequest/utils/createResponse.ts +0 -1
  35. package/src/interceptors/ClientRequest/utils/getIncomingMessageBody.test.ts +5 -4
  36. package/src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.test.ts +19 -18
  37. package/src/interceptors/ClientRequest/utils/normalizeClientRequestEndArgs.test.ts +6 -5
  38. package/src/interceptors/ClientRequest/utils/normalizeClientRequestWriteArgs.test.ts +5 -4
  39. package/src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts +0 -1
  40. package/src/interceptors/XMLHttpRequest/utils/concateArrayBuffer.test.ts +1 -3
  41. package/src/interceptors/XMLHttpRequest/utils/createEvent.test.ts +4 -5
  42. package/src/interceptors/XMLHttpRequest/utils/createResponse.ts +0 -1
  43. package/src/interceptors/fetch/index.ts +1 -2
  44. package/src/utils/AsyncEventEmitter.test.ts +8 -7
  45. package/src/utils/bufferUtils.test.ts +1 -0
  46. package/src/utils/cloneObject.test.ts +6 -5
  47. package/src/utils/getCleanUrl.test.ts +5 -4
  48. package/src/utils/getUrlByRequestOptions.test.ts +11 -10
  49. package/src/utils/getUrlByRequestOptions.ts +14 -1
  50. package/src/utils/isObject.test.ts +4 -3
  51. package/src/utils/parseJson.test.ts +3 -2
  52. package/lib/node/chunk-6V3JXLBF.js +0 -6093
  53. package/lib/node/chunk-NNVTJLQA.mjs +0 -6093
@@ -17,6 +17,7 @@ import { createResponse } from './utils/createResponse'
17
17
  import { createRequest } from './utils/createRequest'
18
18
  import { toInteractiveRequest } from '../../utils/toInteractiveRequest'
19
19
  import { uuidv4 } from '../../utils/uuid'
20
+ import { DeferredPromise } from '@open-draft/deferred-promise'
20
21
 
21
22
  export type Protocol = 'http' | 'https'
22
23
 
@@ -176,6 +177,20 @@ export class NodeClientRequest extends ClientRequest {
176
177
  }).then(([resolverException, mockedResponse]) => {
177
178
  this.log('the listeners promise awaited!')
178
179
 
180
+ /**
181
+ * @fixme We are in the "end()" method that still executes in parallel
182
+ * to our mocking logic here. This can be solved by migrating to the
183
+ * Proxy-based approach and deferring the passthrough "end()" properly.
184
+ * @see https://github.com/mswjs/interceptors/issues/346
185
+ */
186
+ if (!this.headersSent) {
187
+ // Forward any request headers that the "request" listener
188
+ // may have modified before proceeding with this request.
189
+ for (const [headerName, headerValue] of capturedRequest.headers) {
190
+ this.setHeader(headerName, headerValue)
191
+ }
192
+ }
193
+
179
194
  // Halt the request whenever the resolver throws an exception.
180
195
  if (resolverException) {
181
196
  this.log(
@@ -188,12 +203,6 @@ export class NodeClientRequest extends ClientRequest {
188
203
  return this
189
204
  }
190
205
 
191
- // Forward any request headers that the "request" listener
192
- // may have modified before proceeding with this request.
193
- for (const [headerName, headerValue] of capturedRequest.headers) {
194
- this.setHeader(headerName, headerValue)
195
- }
196
-
197
206
  if (mockedResponse) {
198
207
  const responseClone = mockedResponse.clone()
199
208
 
@@ -372,11 +381,18 @@ export class NodeClientRequest extends ClientRequest {
372
381
  }
373
382
  this.log('mocked response headers ready:', headers)
374
383
 
384
+ const isResponseStreamRead = new DeferredPromise<void>()
385
+
375
386
  const closeResponseStream = () => {
387
+ this.log('closing response stream...')
388
+
376
389
  // Push "null" to indicate that the response body is complete
377
390
  // and shouldn't be written to anymore.
378
391
  this.response.push(null)
379
392
  this.response.complete = true
393
+
394
+ isResponseStreamRead.resolve()
395
+ this.log('closed response stream!')
380
396
  }
381
397
 
382
398
  if (body) {
@@ -400,24 +416,26 @@ export class NodeClientRequest extends ClientRequest {
400
416
  closeResponseStream()
401
417
  }
402
418
 
403
- /**
404
- * Set the internal "res" property to the mocked "OutgoingMessage"
405
- * to make the "ClientRequest" instance think there's data received
406
- * from the socket.
407
- * @see https://github.com/nodejs/node/blob/9c405f2591f5833d0247ed0fafdcd68c5b14ce7a/lib/_http_client.js#L501
408
- */
409
- // @ts-ignore
410
- this.res = this.response
411
-
412
- this.finished = true
413
- Object.defineProperty(this, 'writableEnded', {
414
- value: true,
415
- })
419
+ isResponseStreamRead.then(() => {
420
+ /**
421
+ * Set the internal "res" property to the mocked "OutgoingMessage"
422
+ * to make the "ClientRequest" instance think there's data received
423
+ * from the socket.
424
+ * @see https://github.com/nodejs/node/blob/9c405f2591f5833d0247ed0fafdcd68c5b14ce7a/lib/_http_client.js#L501
425
+ */
426
+ // @ts-ignore
427
+ this.res = this.response
428
+
429
+ this.finished = true
430
+ Object.defineProperty(this, 'writableEnded', {
431
+ value: true,
432
+ })
416
433
 
417
- this.emit('finish')
418
- this.emit('response', this.response)
434
+ this.emit('finish')
435
+ this.emit('response', this.response)
419
436
 
420
- this.terminate()
437
+ this.terminate()
438
+ })
421
439
  }
422
440
 
423
441
  /**
@@ -1,6 +1,7 @@
1
- import * as http from 'http'
1
+ import { it, expect, beforeAll, afterAll } from 'vitest'
2
+ import http from 'http'
2
3
  import { HttpServer } from '@open-draft/test-server/http'
3
- import { Response } from '@remix-run/web-fetch'
4
+ import { DeferredPromise } from '@open-draft/deferred-promise'
4
5
  import { ClientRequestInterceptor } from '.'
5
6
 
6
7
  const httpServer = new HttpServer((app) => {
@@ -15,8 +16,8 @@ const httpServer = new HttpServer((app) => {
15
16
  const interceptor = new ClientRequestInterceptor()
16
17
 
17
18
  beforeAll(async () => {
18
- await httpServer.listen()
19
19
  interceptor.apply()
20
+ await httpServer.listen()
20
21
  })
21
22
 
22
23
  afterAll(async () => {
@@ -24,22 +25,33 @@ afterAll(async () => {
24
25
  await httpServer.close()
25
26
  })
26
27
 
27
- it('forbids calling "respondWith" multiple times for the same request', (done) => {
28
+ it('forbids calling "respondWith" multiple times for the same request', async () => {
28
29
  const requestUrl = httpServer.http.url('/')
29
30
 
30
- interceptor.on('request', (request) => {
31
+ interceptor.on('request', function firstRequestListener(request) {
31
32
  request.respondWith(new Response())
32
33
  })
33
34
 
34
- interceptor.on('request', (request) => {
35
+ const secondRequestEmitted = new DeferredPromise<void>()
36
+ interceptor.on('request', function secondRequestListener(request) {
35
37
  expect(() =>
36
38
  request.respondWith(new Response(null, { status: 301 }))
37
39
  ).toThrow(
38
40
  `Failed to respond to "GET ${requestUrl}" request: the "request" event has already been responded to.`
39
41
  )
40
42
 
41
- done()
43
+ secondRequestEmitted.resolve()
44
+ })
45
+
46
+ const request = http.get(requestUrl)
47
+ await secondRequestEmitted
48
+
49
+ const responseReceived = new DeferredPromise<http.IncomingMessage>()
50
+ request.on('response', (response) => {
51
+ responseReceived.resolve(response)
42
52
  })
43
53
 
44
- http.get(requestUrl)
54
+ const response = await responseReceived
55
+ expect(response.statusCode).toBe(200)
56
+ expect(response.statusMessage).toBe('')
45
57
  })
@@ -1,9 +1,10 @@
1
+ import { it, expect } from 'vitest'
1
2
  import { Socket } from 'net'
2
3
  import { IncomingMessage } from 'http'
3
4
  import { Stream, Readable, EventEmitter } from 'stream'
4
5
  import { cloneIncomingMessage, IS_CLONE } from './cloneIncomingMessage'
5
6
 
6
- test('clones a given IncomingMessage', () => {
7
+ it('clones a given IncomingMessage', () => {
7
8
  const message = new IncomingMessage(new Socket())
8
9
  message.statusCode = 200
9
10
  message.statusMessage = 'OK'
@@ -1,3 +1,4 @@
1
+ import { it, expect } from 'vitest'
1
2
  import { debug } from 'debug'
2
3
  import { HttpRequestEventMap } from '../../..'
3
4
  import { AsyncEventEmitter } from '../../../utils/AsyncEventEmitter'
@@ -1,4 +1,3 @@
1
- import { Request } from '@remix-run/web-fetch'
2
1
  import { Headers } from 'headers-polyfill'
3
2
  import type { NodeClientRequest } from '../NodeClientRequest'
4
3
 
@@ -1,6 +1,4 @@
1
- /**
2
- * @jest-environment node
3
- */
1
+ import { it, expect } from 'vitest'
4
2
  import { Socket } from 'net'
5
3
  import * as http from 'http'
6
4
  import { createResponse } from './createResponse'
@@ -1,5 +1,4 @@
1
1
  import type { IncomingMessage } from 'http'
2
- import { Response, ReadableStream } from '@remix-run/web-fetch'
3
2
  import { objectToHeaders } from 'headers-polyfill'
4
3
 
5
4
  /**
@@ -1,9 +1,10 @@
1
+ import { it, expect } from 'vitest'
1
2
  import { IncomingMessage } from 'http'
2
3
  import { Socket } from 'net'
3
4
  import * as zlib from 'zlib'
4
5
  import { getIncomingMessageBody } from './getIncomingMessageBody'
5
6
 
6
- test('returns utf8 string given a utf8 response body', async () => {
7
+ it('returns utf8 string given a utf8 response body', async () => {
7
8
  const utfBuffer = Buffer.from('one')
8
9
  const message = new IncomingMessage(new Socket())
9
10
 
@@ -14,7 +15,7 @@ test('returns utf8 string given a utf8 response body', async () => {
14
15
  expect(await pendingResponseBody).toEqual('one')
15
16
  })
16
17
 
17
- test('returns utf8 string given a gzipped response body', async () => {
18
+ it('returns utf8 string given a gzipped response body', async () => {
18
19
  const utfBuffer = zlib.gzipSync(Buffer.from('two'))
19
20
  const message = new IncomingMessage(new Socket())
20
21
  message.headers = {
@@ -28,7 +29,7 @@ test('returns utf8 string given a gzipped response body', async () => {
28
29
  expect(await pendingResponseBody).toEqual('two')
29
30
  })
30
31
 
31
- test('returns utf8 string given a gzipped response body with incorrect "content-lenght"', async () => {
32
+ it('returns utf8 string given a gzipped response body with incorrect "content-lenght"', async () => {
32
33
  const utfBuffer = zlib.gzipSync(Buffer.from('three'))
33
34
  const message = new IncomingMessage(new Socket())
34
35
  message.headers = {
@@ -43,7 +44,7 @@ test('returns utf8 string given a gzipped response body with incorrect "content-
43
44
  expect(await pendingResponseBody).toEqual('three')
44
45
  })
45
46
 
46
- test('returns empty string given an empty body', async () => {
47
+ it('returns empty string given an empty body', async () => {
47
48
  const message = new IncomingMessage(new Socket())
48
49
 
49
50
  const pendingResponseBody = getIncomingMessageBody(message)
@@ -1,10 +1,11 @@
1
+ import { it, expect } from 'vitest'
1
2
  import { parse } from 'url'
2
3
  import { globalAgent as httpGlobalAgent, RequestOptions } from 'http'
3
4
  import { Agent as HttpsAgent, globalAgent as httpsGlobalAgent } from 'https'
4
5
  import { getUrlByRequestOptions } from '../../../utils/getUrlByRequestOptions'
5
6
  import { normalizeClientRequestArgs } from './normalizeClientRequestArgs'
6
7
 
7
- test('handles [string, callback] input', () => {
8
+ it('handles [string, callback] input', () => {
8
9
  const [url, options, callback] = normalizeClientRequestArgs(
9
10
  'https:',
10
11
  'https://mswjs.io/resource',
@@ -24,7 +25,7 @@ test('handles [string, callback] input', () => {
24
25
  expect(callback?.name).toEqual('cb')
25
26
  })
26
27
 
27
- test('handles [string, RequestOptions, callback] input', () => {
28
+ it('handles [string, RequestOptions, callback] input', () => {
28
29
  const initialOptions = {
29
30
  headers: {
30
31
  'Content-Type': 'text/plain',
@@ -47,7 +48,7 @@ test('handles [string, RequestOptions, callback] input', () => {
47
48
  expect(callback?.name).toEqual('cb')
48
49
  })
49
50
 
50
- test('handles [URL, callback] input', () => {
51
+ it('handles [URL, callback] input', () => {
51
52
  const [url, options, callback] = normalizeClientRequestArgs(
52
53
  'https:',
53
54
  new URL('https://mswjs.io/resource'),
@@ -67,7 +68,7 @@ test('handles [URL, callback] input', () => {
67
68
  expect(callback?.name).toEqual('cb')
68
69
  })
69
70
 
70
- test('handles [Absolute Legacy URL, callback] input', () => {
71
+ it('handles [Absolute Legacy URL, callback] input', () => {
71
72
  const [url, options, callback] = normalizeClientRequestArgs(
72
73
  'https:',
73
74
  parse('https://cherry:durian@mswjs.io:12345/resource?apple=banana'),
@@ -93,7 +94,7 @@ test('handles [Absolute Legacy URL, callback] input', () => {
93
94
  expect(callback?.name).toEqual('cb')
94
95
  })
95
96
 
96
- test('handles [Relative Legacy URL, RequestOptions without path set, callback] input', () => {
97
+ it('handles [Relative Legacy URL, RequestOptions without path set, callback] input', () => {
97
98
  const [url, options, callback] = normalizeClientRequestArgs(
98
99
  'http:',
99
100
  parse('/resource?apple=banana'),
@@ -115,7 +116,7 @@ test('handles [Relative Legacy URL, RequestOptions without path set, callback] i
115
116
  expect(callback?.name).toEqual('cb')
116
117
  })
117
118
 
118
- test('handles [Relative Legacy URL, RequestOptions with path set, callback] input', () => {
119
+ it('handles [Relative Legacy URL, RequestOptions with path set, callback] input', () => {
119
120
  const [url, options, callback] = normalizeClientRequestArgs(
120
121
  'http:',
121
122
  parse('/resource?apple=banana'),
@@ -137,7 +138,7 @@ test('handles [Relative Legacy URL, RequestOptions with path set, callback] inpu
137
138
  expect(callback?.name).toEqual('cb')
138
139
  })
139
140
 
140
- test('handles [Relative Legacy URL, callback] input', () => {
141
+ it('handles [Relative Legacy URL, callback] input', () => {
141
142
  const [url, options, callback] = normalizeClientRequestArgs(
142
143
  'http:',
143
144
  parse('/resource?apple=banana'),
@@ -157,7 +158,7 @@ test('handles [Relative Legacy URL, callback] input', () => {
157
158
  expect(callback?.name).toEqual('cb')
158
159
  })
159
160
 
160
- test('handles [Relative Legacy URL] input', () => {
161
+ it('handles [Relative Legacy URL] input', () => {
161
162
  const [url, options, callback] = normalizeClientRequestArgs(
162
163
  'http:',
163
164
  parse('/resource?apple=banana')
@@ -176,7 +177,7 @@ test('handles [Relative Legacy URL] input', () => {
176
177
  expect(callback).toBeUndefined()
177
178
  })
178
179
 
179
- test('handles [URL, RequestOptions, callback] input', () => {
180
+ it('handles [URL, RequestOptions, callback] input', () => {
180
181
  const [url, options, callback] = normalizeClientRequestArgs(
181
182
  'https:',
182
183
  new URL('https://mswjs.io/resource'),
@@ -211,7 +212,7 @@ test('handles [URL, RequestOptions, callback] input', () => {
211
212
  expect(callback?.name).toEqual('cb')
212
213
  })
213
214
 
214
- test('handles [RequestOptions, callback] input', () => {
215
+ it('handles [RequestOptions, callback] input', () => {
215
216
  const initialOptions = {
216
217
  method: 'POST',
217
218
  protocol: 'https:',
@@ -241,7 +242,7 @@ test('handles [RequestOptions, callback] input', () => {
241
242
  expect(callback?.name).toEqual('cb')
242
243
  })
243
244
 
244
- test('handles [Empty RequestOptions, callback] input', () => {
245
+ it('handles [Empty RequestOptions, callback] input', () => {
245
246
  const [_, options, callback] = normalizeClientRequestArgs(
246
247
  'https:',
247
248
  {},
@@ -257,7 +258,7 @@ test('handles [Empty RequestOptions, callback] input', () => {
257
258
  /**
258
259
  * @see https://github.com/mswjs/interceptors/issues/19
259
260
  */
260
- test('handles [PartialRequestOptions, callback] input', () => {
261
+ it('handles [PartialRequestOptions, callback] input', () => {
261
262
  const initialOptions = {
262
263
  method: 'GET',
263
264
  port: '50176',
@@ -291,7 +292,7 @@ test('handles [PartialRequestOptions, callback] input', () => {
291
292
  expect(callback?.name).toEqual('cb')
292
293
  })
293
294
 
294
- test('sets fallback Agent based on the URL protocol', () => {
295
+ it('sets fallback Agent based on the URL protocol', () => {
295
296
  const [url, options] = normalizeClientRequestArgs(
296
297
  'https:',
297
298
  'https://github.com'
@@ -303,7 +304,7 @@ test('sets fallback Agent based on the URL protocol', () => {
303
304
  expect(agent).toHaveProperty('protocol', url.protocol)
304
305
  })
305
306
 
306
- test('does not set any fallback Agent given "agent: false" option', () => {
307
+ it('does not set any fallback Agent given "agent: false" option', () => {
307
308
  const [, options] = normalizeClientRequestArgs(
308
309
  'https:',
309
310
  'https://github.com',
@@ -313,7 +314,7 @@ test('does not set any fallback Agent given "agent: false" option', () => {
313
314
  expect(options.agent).toEqual(false)
314
315
  })
315
316
 
316
- test('sets the default Agent for HTTP request', () => {
317
+ it('sets the default Agent for HTTP request', () => {
317
318
  const [, options] = normalizeClientRequestArgs(
318
319
  'http:',
319
320
  'http://github.com',
@@ -323,7 +324,7 @@ test('sets the default Agent for HTTP request', () => {
323
324
  expect(options._defaultAgent).toEqual(httpGlobalAgent)
324
325
  })
325
326
 
326
- test('sets the default Agent for HTTPS request', () => {
327
+ it('sets the default Agent for HTTPS request', () => {
327
328
  const [, options] = normalizeClientRequestArgs(
328
329
  'https:',
329
330
  'https://github.com',
@@ -333,7 +334,7 @@ test('sets the default Agent for HTTPS request', () => {
333
334
  expect(options._defaultAgent).toEqual(httpsGlobalAgent)
334
335
  })
335
336
 
336
- test('preserves a custom default Agent when set', () => {
337
+ it('preserves a custom default Agent when set', () => {
337
338
  const [, options] = normalizeClientRequestArgs(
338
339
  'https:',
339
340
  'https://github.com',
@@ -348,7 +349,7 @@ test('preserves a custom default Agent when set', () => {
348
349
  expect(options._defaultAgent).toEqual(httpGlobalAgent)
349
350
  })
350
351
 
351
- test('merges URL-based RequestOptions with the custom RequestOptions', () => {
352
+ it('merges URL-based RequestOptions with the custom RequestOptions', () => {
352
353
  const [url, options] = normalizeClientRequestArgs(
353
354
  'https:',
354
355
  'https://github.com/graphql',
@@ -1,6 +1,7 @@
1
+ import { it, expect } from 'vitest'
1
2
  import { normalizeClientRequestEndArgs } from './normalizeClientRequestEndArgs'
2
3
 
3
- test('returns [null, null, cb] given only the callback', () => {
4
+ it('returns [null, null, cb] given only the callback', () => {
4
5
  const callback = () => {}
5
6
  expect(normalizeClientRequestEndArgs(callback)).toEqual([
6
7
  null,
@@ -9,11 +10,11 @@ test('returns [null, null, cb] given only the callback', () => {
9
10
  ])
10
11
  })
11
12
 
12
- test('returns [chunk, null, null] given only the chunk', () => {
13
+ it('returns [chunk, null, null] given only the chunk', () => {
13
14
  expect(normalizeClientRequestEndArgs('chunk')).toEqual(['chunk', null, null])
14
15
  })
15
16
 
16
- test('returns [chunk, cb] given the chunk and the callback', () => {
17
+ it('returns [chunk, cb] given the chunk and the callback', () => {
17
18
  const callback = () => {}
18
19
  expect(normalizeClientRequestEndArgs('chunk', callback)).toEqual([
19
20
  'chunk',
@@ -22,7 +23,7 @@ test('returns [chunk, cb] given the chunk and the callback', () => {
22
23
  ])
23
24
  })
24
25
 
25
- test('returns [chunk, encoding] given the chunk with the encoding', () => {
26
+ it('returns [chunk, encoding] given the chunk with the encoding', () => {
26
27
  expect(normalizeClientRequestEndArgs('chunk', 'utf8')).toEqual([
27
28
  'chunk',
28
29
  'utf8',
@@ -30,7 +31,7 @@ test('returns [chunk, encoding] given the chunk with the encoding', () => {
30
31
  ])
31
32
  })
32
33
 
33
- test('returns [chunk, encoding, cb] given all three arguments', () => {
34
+ it('returns [chunk, encoding, cb] given all three arguments', () => {
34
35
  const callback = () => {}
35
36
  expect(normalizeClientRequestEndArgs('chunk', 'utf8', callback)).toEqual([
36
37
  'chunk',
@@ -1,6 +1,7 @@
1
+ import { it, expect } from 'vitest'
1
2
  import { normalizeClientRequestWriteArgs } from './normalizeClientRequestWriteArgs'
2
3
 
3
- test('returns a triplet of null given no chunk, encoding, or callback', () => {
4
+ it('returns a triplet of null given no chunk, encoding, or callback', () => {
4
5
  expect(
5
6
  normalizeClientRequestWriteArgs([
6
7
  // @ts-ignore
@@ -11,7 +12,7 @@ test('returns a triplet of null given no chunk, encoding, or callback', () => {
11
12
  ).toEqual([undefined, undefined, undefined])
12
13
  })
13
14
 
14
- test('returns [chunk, null, null] given only a chunk', () => {
15
+ it('returns [chunk, null, null] given only a chunk', () => {
15
16
  expect(normalizeClientRequestWriteArgs(['chunk', undefined])).toEqual([
16
17
  'chunk',
17
18
  undefined,
@@ -19,7 +20,7 @@ test('returns [chunk, null, null] given only a chunk', () => {
19
20
  ])
20
21
  })
21
22
 
22
- test('returns [chunk, encoding] given only chunk and encoding', () => {
23
+ it('returns [chunk, encoding] given only chunk and encoding', () => {
23
24
  expect(normalizeClientRequestWriteArgs(['chunk', 'utf8'])).toEqual([
24
25
  'chunk',
25
26
  'utf8',
@@ -27,7 +28,7 @@ test('returns [chunk, encoding] given only chunk and encoding', () => {
27
28
  ])
28
29
  })
29
30
 
30
- test('returns [chunk, encoding, cb] given all three arguments', () => {
31
+ it('returns [chunk, encoding, cb] given all three arguments', () => {
31
32
  const callbackFn = () => {}
32
33
  expect(
33
34
  normalizeClientRequestWriteArgs(['chunk', 'utf8', callbackFn])
@@ -1,5 +1,4 @@
1
1
  import type { Debugger } from 'debug'
2
- import { Headers, Request } from '@remix-run/web-fetch'
3
2
  import { headersToString } from 'headers-polyfill'
4
3
  import { concatArrayBuffer } from './utils/concatArrayBuffer'
5
4
  import { createEvent } from './utils/createEvent'
@@ -1,6 +1,4 @@
1
- /**
2
- * @jest-environment node
3
- */
1
+ import { it, expect } from 'vitest'
4
2
  import { concatArrayBuffer } from './concatArrayBuffer'
5
3
 
6
4
  const encoder = new TextEncoder()
@@ -1,13 +1,12 @@
1
- /**
2
- * @jest-environment jsdom
3
- */
1
+ // @vitest-environment jsdom
2
+ import { it, expect } from 'vitest'
4
3
  import { createEvent } from './createEvent'
5
4
  import { EventPolyfill } from '../polyfills/EventPolyfill'
6
5
 
7
6
  const request = new XMLHttpRequest()
8
7
  request.open('POST', '/user')
9
8
 
10
- test('returns an EventPolyfill instance with the given target set', () => {
9
+ it('returns an EventPolyfill instance with the given target set', () => {
11
10
  const event = createEvent(request, 'my-event')
12
11
  const target = event.target as XMLHttpRequest
13
12
 
@@ -15,7 +14,7 @@ test('returns an EventPolyfill instance with the given target set', () => {
15
14
  expect(target).toBeInstanceOf(XMLHttpRequest)
16
15
  })
17
16
 
18
- test('returns the ProgressEvent instance', () => {
17
+ it('returns the ProgressEvent instance', () => {
19
18
  const event = createEvent(request, 'load', {
20
19
  loaded: 100,
21
20
  total: 500,
@@ -1,4 +1,3 @@
1
- import { Response } from '@remix-run/web-fetch'
2
1
  import { stringToHeaders } from 'headers-polyfill'
3
2
 
4
3
  export function createResponse(
@@ -1,5 +1,4 @@
1
1
  import { invariant } from 'outvariant'
2
- import type { Response as ResponsePolyfill } from '@remix-run/web-fetch'
3
2
  import { HttpRequestEventMap, IS_PATCHED_MODULE } from '../../glossary'
4
3
  import { Interceptor } from '../../Interceptor'
5
4
  import { uuidv4 } from '../../utils/uuid'
@@ -81,7 +80,7 @@ export class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
81
80
  this.log('no mocked response received!')
82
81
 
83
82
  return pureFetch(request).then((response) => {
84
- const responseClone = response.clone() as ResponsePolyfill
83
+ const responseClone = response.clone()
85
84
  this.log('original fetch performed', responseClone)
86
85
 
87
86
  this.emitter.emit(
@@ -1,13 +1,14 @@
1
+ import { vi, it, expect, afterEach } from 'vitest'
1
2
  import { AsyncEventEmitter } from './AsyncEventEmitter'
2
3
  import { sleep } from '../../test/helpers'
3
4
 
4
5
  afterEach(() => {
5
- jest.useRealTimers()
6
+ vi.useRealTimers()
6
7
  })
7
8
 
8
9
  it('emits and listens to events', () => {
9
10
  const emitter = new AsyncEventEmitter<{ hello: [string] }>()
10
- const listener = jest.fn()
11
+ const listener = vi.fn()
11
12
  emitter.on('hello', listener)
12
13
  emitter.emit('hello', 'John')
13
14
 
@@ -19,10 +20,10 @@ it('resolves "untilIdle" when all the event listeners are done', async () => {
19
20
  const emitter = new AsyncEventEmitter<{ speak: [string] }>()
20
21
 
21
22
  const results: string[] = []
22
- const firstListener = jest.fn(() => results.push('first'))
23
+ const firstListener = vi.fn(() => results.push('first'))
23
24
  emitter.on('speak', firstListener)
24
25
 
25
- const secondListener = jest.fn(async () => {
26
+ const secondListener = vi.fn(async () => {
26
27
  await sleep(150)
27
28
  results.push('second')
28
29
  })
@@ -43,7 +44,7 @@ it('resolves "untilIdle" only for the relevant listeners', async () => {
43
44
  const emitter = new AsyncEventEmitter<{ signal: [number] }>()
44
45
 
45
46
  const results: number[] = []
46
- const listener = jest.fn(async (code: number) => {
47
+ const listener = vi.fn(async (code: number) => {
47
48
  if (code !== 1) {
48
49
  // Delay listener based on the signal code.
49
50
  await sleep(150)
@@ -79,7 +80,7 @@ it('propagates listener exceptions to "untilIdle" promise', async () => {
79
80
  const emitter = new AsyncEventEmitter<{ ping: never }>()
80
81
 
81
82
  const error = new Error('oops')
82
- const listener = jest.fn(() => {
83
+ const listener = vi.fn(() => {
83
84
  throw error
84
85
  })
85
86
  emitter.on('ping', listener)
@@ -91,7 +92,7 @@ it('propagates listener exceptions to "untilIdle" promise', async () => {
91
92
  it('does not emit events once the emitter was deactivated', () => {
92
93
  const emitter = new AsyncEventEmitter<{ ping: never }>()
93
94
 
94
- const listener = jest.fn()
95
+ const listener = vi.fn()
95
96
  emitter.on('ping', listener)
96
97
  emitter.deactivate()
97
98
 
@@ -1,3 +1,4 @@
1
+ import { it, expect } from 'vitest'
1
2
  import { decodeBuffer, encodeBuffer } from './bufferUtils'
2
3
 
3
4
  it('encodes utf-8 string', () => {
@@ -1,6 +1,7 @@
1
+ import { it, expect } from 'vitest'
1
2
  import { cloneObject } from './cloneObject'
2
3
 
3
- test('clones a shallow object', () => {
4
+ it('clones a shallow object', () => {
4
5
  const original = { a: 1, b: 2, c: [1, 2, 3] }
5
6
  const clone = cloneObject(original)
6
7
 
@@ -18,7 +19,7 @@ test('clones a shallow object', () => {
18
19
  expect(original).toHaveProperty('c', [1, 2, 3])
19
20
  })
20
21
 
21
- test('clones a nested object', () => {
22
+ it('clones a nested object', () => {
22
23
  const original = { a: { b: 1 }, c: { d: { e: 2 } } }
23
24
  const clone = cloneObject(original)
24
25
 
@@ -33,7 +34,7 @@ test('clones a nested object', () => {
33
34
  expect(original).toHaveProperty(['c', 'd', 'e'], 2)
34
35
  })
35
36
 
36
- test('clones a class instance', () => {
37
+ it('clones a class instance', () => {
37
38
  class Car {
38
39
  public manufacturer: string
39
40
  constructor() {
@@ -53,7 +54,7 @@ test('clones a class instance', () => {
53
54
  expect(clone.getManufacturer()).toEqual('Audi')
54
55
  })
55
56
 
56
- test('ignores nested class instances', () => {
57
+ it('ignores nested class instances', () => {
57
58
  class Car {
58
59
  name: string
59
60
  constructor(name: string) {
@@ -81,7 +82,7 @@ test('ignores nested class instances', () => {
81
82
  expect(original.car.getName()).toEqual('Audi')
82
83
  })
83
84
 
84
- test('clones an object with null prototype', () => {
85
+ it('clones an object with null prototype', () => {
85
86
  const original = {
86
87
  key: Object.create(null),
87
88
  }