Skip to content

Commit 599b44b

Browse files
authored
test(module-runner): simplify server-hmr tests (#23300)
1 parent 4a261f2 commit 599b44b

1 file changed

Lines changed: 59 additions & 83 deletions

File tree

packages/vite/src/node/ssr/runtime/__tests__/server-hmr.spec.ts

Lines changed: 59 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { describe, expect, onTestFinished } from 'vitest'
1+
import { assert, describe, expect, onTestFinished, vi } from 'vitest'
2+
import { promiseWithResolvers } from '../../../../shared/utils'
23
import { createModuleRunnerTester } from './utils'
34

45
describe(
@@ -26,21 +27,26 @@ describe(
2627
const fixtureC = '/fixtures/c.ts'
2728
const fixtureD = '/fixtures/d.ts'
2829

29-
expect(runner.hmrClient!.hotModulesMap.size).toBe(2)
30-
expect(runner.hmrClient!.dataMap.size).toBe(2)
31-
expect(runner.hmrClient!.ctxToListenersMap.size).toBe(2)
30+
assert(runner.hmrClient)
31+
expect(runner.hmrClient.hotModulesMap.size).toBe(2)
32+
expect(runner.hmrClient.dataMap.size).toBe(2)
33+
expect(runner.hmrClient.ctxToListenersMap.size).toBe(2)
3234

3335
for (const fixture of [fixtureC, fixtureD]) {
34-
expect(runner.hmrClient!.hotModulesMap.has(fixture)).toBe(true)
35-
expect(runner.hmrClient!.dataMap.has(fixture)).toBe(true)
36-
expect(runner.hmrClient!.ctxToListenersMap.has(fixture)).toBe(true)
36+
expect(runner.hmrClient.hotModulesMap.has(fixture)).toBe(true)
37+
expect(runner.hmrClient.dataMap.has(fixture)).toBe(true)
38+
expect(runner.hmrClient.ctxToListenersMap.has(fixture)).toBe(true)
3739
}
3840
})
3941

4042
it('does not expose partial exports during concurrent updates', async ({
4143
runner,
4244
}) => {
4345
const testGlobal = globalThis as any
46+
const sharedUrl = '/fixtures/hmr-reexport-race/shared.js'
47+
const coreUrl = '/fixtures/hmr-reexport-race/core.js'
48+
const entryAUrl = '/fixtures/hmr-reexport-race/entry-a.js'
49+
const entryBUrl = '/fixtures/hmr-reexport-race/entry-b.js'
4450

4551
testGlobal.__vite_ssr_hmr_reexport_race__ = {
4652
wait: () => Promise.resolve(),
@@ -49,34 +55,22 @@ describe(
4955
delete testGlobal.__vite_ssr_hmr_reexport_race__
5056
})
5157

52-
await runner.import('/fixtures/hmr-reexport-race/entry-a.js')
53-
await runner.import('/fixtures/hmr-reexport-race/entry-b.js')
54-
55-
const sharedModule = runner.evaluatedModules.getModuleByUrl(
56-
'/fixtures/hmr-reexport-race/shared.js',
57-
)
58-
const coreModule = runner.evaluatedModules.getModuleByUrl(
59-
'/fixtures/hmr-reexport-race/core.js',
60-
)
61-
const entryAModule = runner.evaluatedModules.getModuleByUrl(
62-
'/fixtures/hmr-reexport-race/entry-a.js',
63-
)
64-
const entryBModule = runner.evaluatedModules.getModuleByUrl(
65-
'/fixtures/hmr-reexport-race/entry-b.js',
66-
)
67-
expect(sharedModule).toBeDefined()
68-
expect(coreModule).toBeDefined()
69-
expect(entryAModule).toBeDefined()
70-
expect(entryBModule).toBeDefined()
71-
72-
let waitStarted!: () => void
73-
const waitStartedPromise = new Promise<void>((resolve) => {
74-
waitStarted = resolve
75-
})
76-
let releaseWait!: () => void
77-
const waitPromise = new Promise<void>((resolve) => {
78-
releaseWait = resolve
79-
})
58+
await runner.import(entryAUrl)
59+
await runner.import(entryBUrl)
60+
61+
const sharedModule = runner.evaluatedModules.getModuleByUrl(sharedUrl)
62+
const coreModule = runner.evaluatedModules.getModuleByUrl(coreUrl)
63+
const entryAModule = runner.evaluatedModules.getModuleByUrl(entryAUrl)
64+
const entryBModule = runner.evaluatedModules.getModuleByUrl(entryBUrl)
65+
assert(sharedModule)
66+
assert(coreModule)
67+
assert(entryAModule)
68+
assert(entryBModule)
69+
70+
const { promise: waitStartedPromise, resolve: waitStarted } =
71+
promiseWithResolvers<void>()
72+
const { promise: waitPromise, resolve: releaseWait } =
73+
promiseWithResolvers<void>()
8074

8175
testGlobal.__vite_ssr_hmr_reexport_race__ = {
8276
wait: () => {
@@ -86,31 +80,26 @@ describe(
8680
}
8781

8882
for (const module of [
89-
entryAModule!,
90-
entryBModule!,
91-
sharedModule!,
92-
coreModule!,
83+
entryAModule,
84+
entryBModule,
85+
sharedModule,
86+
coreModule,
9387
]) {
9488
runner.evaluatedModules.invalidateModule(module)
9589
}
9690

97-
const importA = runner.import('/fixtures/hmr-reexport-race/entry-a.js')
91+
const importA = runner.import(entryAUrl)
9892
await waitStartedPromise
9993

100-
const importB = runner.import('/fixtures/hmr-reexport-race/entry-b.js')
94+
const importB = runner.import(entryBUrl)
10195
// Wait deterministically until entry-b has reached the point where it
10296
// observes shared as in-flight. The `mod.imports.add(depMod.id)` line
10397
// in `request()` runs synchronously immediately before `cachedRequest`
10498
// executes its cycle-detection prefix, so observing this edge means
10599
// the buggy/fixed branch has either just run or is about to run on
106100
// the same microtask. `imports` is cleared by invalidateModule, so
107101
// this is a fresh signal (unlike `importers`, which is preserved).
108-
const entryBNode = runner.evaluatedModules.getModuleByUrl(
109-
'/fixtures/hmr-reexport-race/entry-b.js',
110-
)!
111-
while (!entryBNode.imports.has(sharedModule!.id)) {
112-
await new Promise((resolve) => setImmediate(resolve))
113-
}
102+
await vi.waitUntil(() => entryBModule.imports.has(sharedModule.id))
114103
releaseWait()
115104
const results = await Promise.allSettled([importA, importB] as const)
116105

@@ -125,13 +114,10 @@ describe(
125114
},
126115
])
127116

128-
const hmrListeners = runner.hmrClient!.hotModulesMap
129-
expect(hmrListeners.has('/fixtures/hmr-reexport-race/entry-a.js')).toBe(
130-
true,
131-
)
132-
expect(hmrListeners.has('/fixtures/hmr-reexport-race/entry-b.js')).toBe(
133-
true,
134-
)
117+
assert(runner.hmrClient)
118+
const hmrListeners = runner.hmrClient.hotModulesMap
119+
expect(hmrListeners.has(entryAUrl)).toBe(true)
120+
expect(hmrListeners.has(entryBUrl)).toBe(true)
135121
})
136122

137123
it('does not treat evaluated imports as live circular requests', async ({
@@ -154,27 +140,21 @@ describe(
154140
const sharedModule = runner.evaluatedModules.getModuleByUrl(sharedUrl)
155141
const evaluatedModule =
156142
runner.evaluatedModules.getModuleByUrl(evaluatedUrl)
157-
expect(sharedModule).toBeDefined()
158-
expect(evaluatedModule).toBeDefined()
143+
assert(sharedModule)
144+
assert(evaluatedModule)
145+
146+
const { promise: waitStartedPromise, resolve: waitStarted } =
147+
promiseWithResolvers<void>()
148+
const { promise: waitPromise, resolve: releaseWait } =
149+
promiseWithResolvers<void>()
150+
const {
151+
promise: evaluatedWaitStartedPromise,
152+
resolve: evaluatedWaitStarted,
153+
} = promiseWithResolvers<void>()
154+
const { promise: evaluatedWaitPromise, resolve: releaseEvaluatedWait } =
155+
promiseWithResolvers<void>()
159156

160-
let waitStarted!: () => void
161-
const waitStartedPromise = new Promise<void>((resolve) => {
162-
waitStarted = resolve
163-
})
164-
let releaseWait!: () => void
165-
const waitPromise = new Promise<void>((resolve) => {
166-
releaseWait = resolve
167-
})
168-
let evaluatedWaitStarted!: () => void
169-
const evaluatedWaitStartedPromise = new Promise<void>((resolve) => {
170-
evaluatedWaitStarted = resolve
171-
})
172-
let releaseEvaluatedWait!: () => void
173-
const evaluatedWaitPromise = new Promise<void>((resolve) => {
174-
releaseEvaluatedWait = resolve
175-
})
176157
let evaluatedRequestCount = 0
177-
178158
testGlobal.__vite_ssr_hmr_evaluated_import_race__ = {
179159
wait: () => {
180160
waitStarted()
@@ -190,14 +170,14 @@ describe(
190170
},
191171
}
192172

193-
runner.evaluatedModules.invalidateModule(sharedModule!)
173+
runner.evaluatedModules.invalidateModule(sharedModule)
194174

195175
const sharedRequest = runner.import(sharedUrl)
196176
await waitStartedPromise
197-
expect(sharedModule!.imports.has(evaluatedModule!.id)).toBe(true)
177+
expect(sharedModule.imports.has(evaluatedModule.id)).toBe(true)
198178

199179
// Start an evaluation that pauses before dynamically importing shared.
200-
runner.evaluatedModules.invalidateModule(evaluatedModule!)
180+
runner.evaluatedModules.invalidateModule(evaluatedModule)
201181

202182
let staleEvaluatedRequestSettled = false
203183
const staleEvaluatedRequest = runner
@@ -210,16 +190,12 @@ describe(
210190

211191
// Simulate HMR restarting evaluated while the older evaluation is still
212192
// paused. The newer evaluation completes without importing shared.
213-
runner.evaluatedModules.invalidateModule(evaluatedModule!)
193+
runner.evaluatedModules.invalidateModule(evaluatedModule)
214194
await runner.import(evaluatedUrl)
215-
expect(evaluatedModule!.evaluated).toBe(true)
195+
expect(evaluatedModule.evaluated).toBe(true)
216196

217197
releaseEvaluatedWait()
218-
while (!evaluatedModule!.imports.has(sharedModule!.id)) {
219-
await new Promise((resolve) => setImmediate(resolve))
220-
}
221-
222-
await new Promise((resolve) => setImmediate(resolve))
198+
await vi.waitUntil(() => evaluatedModule.imports.has(sharedModule.id))
223199
expect(staleEvaluatedRequestSettled).toBe(false)
224200

225201
releaseWait()

0 commit comments

Comments
 (0)