@mswjs/interceptors 0.21.1 → 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-UVNTVJHD.js → chunk-PRX3F52M.js} +17 -17
  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-Z5JAVEOB.mjs → chunk-SWJ33XIS.mjs} +10 -10
  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 +11 -9
  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 +107 -85
  28. package/src/interceptors/ClientRequest/NodeClientRequest.ts +14 -6
  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
@@ -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
  }
@@ -1,29 +1,30 @@
1
+ import { describe, it, expect } from 'vitest'
1
2
  import { getCleanUrl } from './getCleanUrl'
2
3
 
3
4
  describe('getCleanUrl', () => {
4
5
  describe('given a URL without query parameters', () => {
5
- test('should return url href as-is', () => {
6
+ it('should return url href as-is', () => {
6
7
  const url = new URL('https://github.com')
7
8
  expect(getCleanUrl(url)).toEqual('https://github.com/')
8
9
  })
9
10
  })
10
11
 
11
12
  describe('given a URL with query parameters', () => {
12
- test('should return url without parameters', () => {
13
+ it('should return url without parameters', () => {
13
14
  const url = new URL('https://github.com/mswjs/?userId=abc-123')
14
15
  expect(getCleanUrl(url)).toEqual('https://github.com/mswjs/')
15
16
  })
16
17
  })
17
18
 
18
19
  describe('given a URL with a hash', () => {
19
- test('should return a url without hash', () => {
20
+ it('should return a url without hash', () => {
20
21
  const url = new URL('https://github.com/mswjs/#hello-world')
21
22
  expect(getCleanUrl(url)).toEqual('https://github.com/mswjs/')
22
23
  })
23
24
  })
24
25
 
25
26
  describe('given an absolute URL ', () => {
26
- test('should return a clean relative URL', () => {
27
+ it('should return a clean relative URL', () => {
27
28
  const url = new URL('/login?query=value', 'https://github.com')
28
29
  expect(getCleanUrl(url, false)).toEqual('/login')
29
30
  })
@@ -1,8 +1,9 @@
1
+ import { it, expect } from 'vitest'
1
2
  import { Agent as HttpAgent } from 'http'
2
3
  import { RequestOptions, Agent as HttpsAgent } from 'https'
3
4
  import { getUrlByRequestOptions } from './getUrlByRequestOptions'
4
5
 
5
- test('returns a URL based on the basic RequestOptions', () => {
6
+ it('returns a URL based on the basic RequestOptions', () => {
6
7
  const options: RequestOptions = {
7
8
  protocol: 'https:',
8
9
  host: '127.0.0.1',
@@ -15,7 +16,7 @@ test('returns a URL based on the basic RequestOptions', () => {
15
16
  expect(url).toHaveProperty('href', 'https://127.0.0.1/resource')
16
17
  })
17
18
 
18
- test('inherits protocol and port from http.Agent, if set', () => {
19
+ it('inherits protocol and port from http.Agent, if set', () => {
19
20
  const options: RequestOptions = {
20
21
  host: '127.0.0.1',
21
22
  path: '/',
@@ -29,7 +30,7 @@ test('inherits protocol and port from http.Agent, if set', () => {
29
30
  expect(url).toHaveProperty('href', 'http://127.0.0.1/')
30
31
  })
31
32
 
32
- test('inherits protocol and port from https.Agent, if set', () => {
33
+ it('inherits protocol and port from https.Agent, if set', () => {
33
34
  const options: RequestOptions = {
34
35
  host: '127.0.0.1',
35
36
  path: '/',
@@ -45,7 +46,7 @@ test('inherits protocol and port from https.Agent, if set', () => {
45
46
  expect(url).toHaveProperty('href', 'https://127.0.0.1:3080/')
46
47
  })
47
48
 
48
- test('resolves protocol to "http" given no explicit protocol and no certificate', () => {
49
+ it('resolves protocol to "http" given no explicit protocol and no certificate', () => {
49
50
  const options: RequestOptions = {
50
51
  host: '127.0.0.1',
51
52
  path: '/',
@@ -58,7 +59,7 @@ test('resolves protocol to "http" given no explicit protocol and no certificate'
58
59
  expect(url).toHaveProperty('href', 'http://127.0.0.1/')
59
60
  })
60
61
 
61
- test('resolves protocol to "https" given no explicit protocol, but certificate', () => {
62
+ it('resolves protocol to "https" given no explicit protocol, but certificate', () => {
62
63
  const options: RequestOptions = {
63
64
  host: '127.0.0.1',
64
65
  path: '/secure',
@@ -72,7 +73,7 @@ test('resolves protocol to "https" given no explicit protocol, but certificate',
72
73
  expect(url).toHaveProperty('href', 'https://127.0.0.1/secure')
73
74
  })
74
75
 
75
- test('resolves protocol to "https" given no explicit protocol, but port is 443', () => {
76
+ it('resolves protocol to "https" given no explicit protocol, but port is 443', () => {
76
77
  const options: RequestOptions = {
77
78
  host: '127.0.0.1',
78
79
  port: 443,
@@ -85,7 +86,7 @@ test('resolves protocol to "https" given no explicit protocol, but port is 443',
85
86
  expect(url).toHaveProperty('href', 'https://127.0.0.1/resource')
86
87
  })
87
88
 
88
- test('resolves protocol to "https" given no explicit protocol, but agent port is 443', () => {
89
+ it('resolves protocol to "https" given no explicit protocol, but agent port is 443', () => {
89
90
  const options: RequestOptions = {
90
91
  host: '127.0.0.1',
91
92
  agent: new HttpsAgent({
@@ -100,7 +101,7 @@ test('resolves protocol to "https" given no explicit protocol, but agent port is
100
101
  expect(url).toHaveProperty('href', 'https://127.0.0.1/resource')
101
102
  })
102
103
 
103
- test('inherits "port" if given', () => {
104
+ it('inherits "port" if given', () => {
104
105
  const options = {
105
106
  protocol: 'http:',
106
107
  host: '127.0.0.1',
@@ -115,7 +116,7 @@ test('inherits "port" if given', () => {
115
116
  expect(url).toHaveProperty('href', 'http://127.0.0.1:4002/')
116
117
  })
117
118
 
118
- test('inherits "username" and "password"', () => {
119
+ it('inherits "username" and "password"', () => {
119
120
  const options: RequestOptions = {
120
121
  protocol: 'https:',
121
122
  host: '127.0.0.1',
@@ -131,7 +132,7 @@ test('inherits "username" and "password"', () => {
131
132
  expect(url).toHaveProperty('href', 'https://admin:abc-123@127.0.0.1/user')
132
133
  })
133
134
 
134
- test('resolves hostname to localhost if none provided', () => {
135
+ it('resolves hostname to localhost if none provided', () => {
135
136
  const url = getUrlByRequestOptions({})
136
137
 
137
138
  expect(url).toBeInstanceOf(URL)
@@ -68,6 +68,15 @@ function getAuthByRequestOptions(options: ResolvedRequestOptions) {
68
68
  }
69
69
  }
70
70
 
71
+ /**
72
+ * Returns true if host looks like an IPv6 address without surrounding brackets
73
+ * It assumes any host containing `:` is definitely not IPv4 and probably IPv6,
74
+ * but note that this could include invalid IPv6 addresses as well.
75
+ */
76
+ function isRawIPv6Address(host: string): boolean {
77
+ return host.includes(':') && !host.startsWith('[') && !host.endsWith(']')
78
+ }
79
+
71
80
  /**
72
81
  * Creates a `URL` instance from a given `RequestOptions` object.
73
82
  */
@@ -85,7 +94,11 @@ export function getUrlByRequestOptions(options: ResolvedRequestOptions): URL {
85
94
  debug('port', port)
86
95
  debug('path', path)
87
96
 
88
- const baseUrl = `${protocol}//${host}`
97
+ /**
98
+ * @note As of Node >= 17, hosts (including "localhost") can resolve to IPv6
99
+ * addresses, so construct valid URL by surrounding the IPv6 host with brackets.
100
+ */
101
+ const baseUrl = `${protocol}//${isRawIPv6Address(host) ? `[${host}]` : host}`
89
102
  debug('base URL:', baseUrl)
90
103
 
91
104
  const url = options.uri ? new URL(options.uri.href) : new URL(path, baseUrl)
@@ -1,16 +1,17 @@
1
+ import { it, expect } from 'vitest'
1
2
  import { isObject } from './isObject'
2
3
 
3
- test('resolves given an object', () => {
4
+ it('resolves given an object', () => {
4
5
  expect(isObject({})).toBe(true)
5
6
  expect(isObject({ a: 1 })).toBe(true)
6
7
  })
7
8
 
8
- test('rejects given an object-like instance', () => {
9
+ it('rejects given an object-like instance', () => {
9
10
  expect(isObject([1])).toBe(false)
10
11
  expect(isObject(function () {})).toBe(false)
11
12
  })
12
13
 
13
- test('rejects given a non-object instance', () => {
14
+ it('rejects given a non-object instance', () => {
14
15
  expect(isObject(null)).toBe(false)
15
16
  expect(isObject(undefined)).toBe(false)
16
17
  expect(isObject(false)).toBe(false)
@@ -1,9 +1,10 @@
1
+ import { it, expect } from 'vitest'
1
2
  import { parseJson } from './parseJson'
2
3
 
3
- test('parses a given string into JSON', () => {
4
+ it('parses a given string into JSON', () => {
4
5
  expect(parseJson('{"id":1}')).toEqual({ id: 1 })
5
6
  })
6
7
 
7
- test('returns null given invalid JSON string', () => {
8
+ it('returns null given invalid JSON string', () => {
8
9
  expect(parseJson('{"o:2\'')).toBeNull()
9
10
  })