|
2 | 2 |
|
3 | 3 | const { test } = require('node:test') |
4 | 4 | const assert = require('node:assert') |
5 | | -const { install } = require('../index') |
| 5 | +const undici = require('../index') |
| 6 | +const { installedExports } = require('../lib/global') |
6 | 7 |
|
7 | | -test('install() should add WHATWG fetch classes to globalThis', () => { |
8 | | - // Save original globals to restore later |
9 | | - const originalFetch = globalThis.fetch |
10 | | - const originalHeaders = globalThis.Headers |
11 | | - const originalResponse = globalThis.Response |
12 | | - const originalRequest = globalThis.Request |
13 | | - const originalFormData = globalThis.FormData |
14 | | - const originalWebSocket = globalThis.WebSocket |
15 | | - const originalCloseEvent = globalThis.CloseEvent |
16 | | - const originalErrorEvent = globalThis.ErrorEvent |
17 | | - const originalMessageEvent = globalThis.MessageEvent |
18 | | - const originalEventSource = globalThis.EventSource |
| 8 | +test('install() should overwrite only specified elements in globalThis', () => { |
| 9 | + const exportsToCheck = new Set(installedExports) |
19 | 10 |
|
20 | | - try { |
21 | | - // Remove any existing globals |
22 | | - delete globalThis.fetch |
23 | | - delete globalThis.Headers |
24 | | - delete globalThis.Response |
25 | | - delete globalThis.Request |
26 | | - delete globalThis.FormData |
27 | | - delete globalThis.WebSocket |
28 | | - delete globalThis.CloseEvent |
29 | | - delete globalThis.ErrorEvent |
30 | | - delete globalThis.MessageEvent |
31 | | - delete globalThis.EventSource |
| 11 | + // Use a Proxy to verify that only the expected globals are set |
| 12 | + // and no other properties are added to globalThis by undici.install(). |
| 13 | + const proxyGlobalThis = new Proxy(globalThis, { |
| 14 | + set (target, prop, value) { |
| 15 | + if (exportsToCheck.has(prop)) { |
| 16 | + target[prop] = value |
| 17 | + exportsToCheck.delete(prop) |
| 18 | + return true |
| 19 | + } |
| 20 | + throw new Error(`Unexpected global set: ${String(prop)}`) |
| 21 | + } |
| 22 | + }) |
32 | 23 |
|
33 | | - // Verify they're not defined |
34 | | - assert.strictEqual(globalThis.fetch, undefined) |
35 | | - assert.strictEqual(globalThis.Headers, undefined) |
36 | | - assert.strictEqual(globalThis.Response, undefined) |
37 | | - assert.strictEqual(globalThis.Request, undefined) |
38 | | - assert.strictEqual(globalThis.FormData, undefined) |
39 | | - assert.strictEqual(globalThis.WebSocket, undefined) |
40 | | - assert.strictEqual(globalThis.CloseEvent, undefined) |
41 | | - assert.strictEqual(globalThis.ErrorEvent, undefined) |
42 | | - assert.strictEqual(globalThis.MessageEvent, undefined) |
43 | | - assert.strictEqual(globalThis.EventSource, undefined) |
| 24 | + // eslint-disable-next-line no-global-assign |
| 25 | + globalThis = proxyGlobalThis |
44 | 26 |
|
45 | | - // Call install() |
46 | | - install() |
| 27 | + undici.install() |
47 | 28 |
|
48 | | - // Verify all classes are now installed |
49 | | - assert.strictEqual(typeof globalThis.fetch, 'function') |
50 | | - assert.strictEqual(typeof globalThis.Headers, 'function') |
51 | | - assert.strictEqual(typeof globalThis.Response, 'function') |
52 | | - assert.strictEqual(typeof globalThis.Request, 'function') |
53 | | - assert.strictEqual(typeof globalThis.FormData, 'function') |
54 | | - assert.strictEqual(typeof globalThis.WebSocket, 'function') |
55 | | - assert.strictEqual(typeof globalThis.CloseEvent, 'function') |
56 | | - assert.strictEqual(typeof globalThis.ErrorEvent, 'function') |
57 | | - assert.strictEqual(typeof globalThis.MessageEvent, 'function') |
58 | | - assert.strictEqual(typeof globalThis.EventSource, 'function') |
| 29 | + assert.strictEqual(exportsToCheck.size, 0, `Some expected globals were not set: ${[...exportsToCheck].join(', ')}`) |
59 | 30 |
|
60 | | - // Test that the installed classes are functional |
61 | | - const headers = new globalThis.Headers([['content-type', 'application/json']]) |
62 | | - assert.strictEqual(headers.get('content-type'), 'application/json') |
| 31 | + // Verify that the installed globals match the exports from undici |
| 32 | + for (const name of installedExports) { |
| 33 | + assert.strictEqual(globalThis[name], undici[name]) |
| 34 | + } |
63 | 35 |
|
64 | | - const request = new globalThis.Request('https://example.com') |
65 | | - assert.strictEqual(request.url, 'https://example.com/') |
| 36 | + // Test that the installed classes are functional |
| 37 | + const headers = new globalThis.Headers([['content-type', 'application/json']]) |
| 38 | + assert.strictEqual(headers.get('content-type'), 'application/json') |
66 | 39 |
|
67 | | - const response = new globalThis.Response('test body') |
68 | | - assert.strictEqual(response.status, 200) |
| 40 | + const request = new globalThis.Request('https://example.com') |
| 41 | + assert.strictEqual(request.url, 'https://example.com/') |
69 | 42 |
|
70 | | - const formData = new globalThis.FormData() |
71 | | - formData.append('key', 'value') |
72 | | - assert.strictEqual(formData.get('key'), 'value') |
73 | | - } finally { |
74 | | - // Restore original globals |
75 | | - if (originalFetch !== undefined) { |
76 | | - globalThis.fetch = originalFetch |
77 | | - } else { |
78 | | - delete globalThis.fetch |
79 | | - } |
80 | | - if (originalHeaders !== undefined) { |
81 | | - globalThis.Headers = originalHeaders |
82 | | - } else { |
83 | | - delete globalThis.Headers |
84 | | - } |
85 | | - if (originalResponse !== undefined) { |
86 | | - globalThis.Response = originalResponse |
87 | | - } else { |
88 | | - delete globalThis.Response |
89 | | - } |
90 | | - if (originalRequest !== undefined) { |
91 | | - globalThis.Request = originalRequest |
92 | | - } else { |
93 | | - delete globalThis.Request |
94 | | - } |
95 | | - if (originalFormData !== undefined) { |
96 | | - globalThis.FormData = originalFormData |
97 | | - } else { |
98 | | - delete globalThis.FormData |
99 | | - } |
100 | | - if (originalWebSocket !== undefined) { |
101 | | - globalThis.WebSocket = originalWebSocket |
102 | | - } else { |
103 | | - delete globalThis.WebSocket |
104 | | - } |
105 | | - if (originalCloseEvent !== undefined) { |
106 | | - globalThis.CloseEvent = originalCloseEvent |
107 | | - } else { |
108 | | - delete globalThis.CloseEvent |
109 | | - } |
110 | | - if (originalErrorEvent !== undefined) { |
111 | | - globalThis.ErrorEvent = originalErrorEvent |
112 | | - } else { |
113 | | - delete globalThis.ErrorEvent |
114 | | - } |
115 | | - if (originalMessageEvent !== undefined) { |
116 | | - globalThis.MessageEvent = originalMessageEvent |
117 | | - } else { |
118 | | - delete globalThis.MessageEvent |
119 | | - } |
120 | | - if (originalEventSource !== undefined) { |
121 | | - globalThis.EventSource = originalEventSource |
122 | | - } else { |
123 | | - delete globalThis.EventSource |
124 | | - } |
125 | | - } |
| 43 | + const response = new globalThis.Response('test body') |
| 44 | + assert.strictEqual(response.status, 200) |
| 45 | + |
| 46 | + const formData = new globalThis.FormData() |
| 47 | + formData.append('key', 'value') |
| 48 | + assert.strictEqual(formData.get('key'), 'value') |
126 | 49 | }) |
0 commit comments