fix(test): stop preflight mocks leaking into shared workers (#157207)

This commit is contained in:
Vincent Koc
2026-09-24 23:46:44 +08:00
committed by GitHub
parent 02ad6b76b1
commit c4333da677
+46 -8
View File
@@ -2,7 +2,11 @@ import { createServer } from "node:http";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { assertUiE2ePreflight } from "./vitest/vitest.ui-e2e-preflight.ts";
vi.mock("node:http", { spy: true });
vi.mock("node:http", async (importOriginal) => {
const actual = await importOriginal<typeof import("node:http")>();
// Native HTTP and socket prototypes outlive a test file in shared workers.
return { ...actual, createServer: vi.fn(actual.createServer) };
});
const listeners: Array<{
server: ReturnType<typeof createServer>;
@@ -22,14 +26,19 @@ beforeEach(async () => {
});
afterEach(async () => {
// Keep a failed cleanup assertion from leaking its real listener into later tests.
for (const { server } of listeners) {
server.closeAllConnections();
if (server.listening) {
await new Promise<void>((resolve, reject) => {
server.close((error) => (error ? reject(error) : resolve()));
});
try {
// Keep a failed cleanup assertion from leaking its real listener into later tests.
for (const { server } of listeners) {
server.closeAllConnections();
if (server.listening) {
await new Promise<void>((resolve, reject) => {
server.close((error) => (error ? reject(error) : resolve()));
});
}
}
} finally {
// restoreAllMocks does not reset module spies' custom implementations.
vi.mocked(createServer).mockRestore();
}
});
@@ -43,6 +52,35 @@ function expectListenerClosed() {
}
describe("UI E2E environment preflight", () => {
it("preserves native HTTP and socket implementations for later shared-worker consumers", () => {
const nativeHttp = process.getBuiltinModule("node:http");
const nativeNet = process.getBuiltinModule("node:net");
for (const implementation of [
nativeHttp.Server,
nativeHttp.Agent,
nativeHttp.IncomingMessage,
nativeHttp.OutgoingMessage,
nativeHttp.ServerResponse,
nativeHttp.ClientRequest,
nativeHttp.createServer,
nativeNet.Socket,
]) {
expect(vi.isMockFunction(implementation)).toBe(false);
}
for (const [prototype, method] of [
[nativeHttp.IncomingMessage.prototype, "read"],
[nativeHttp.OutgoingMessage.prototype, "write"],
[nativeHttp.OutgoingMessage.prototype, "end"],
[nativeHttp.globalAgent, "createConnection"],
[nativeNet.Socket.prototype, "write"],
] as const) {
expect(prototype).toHaveProperty(
method,
expect.toSatisfy((implementation) => !vi.isMockFunction(implementation)),
);
}
});
it("proves the owned HTTP response and releases its listener", async () => {
const fetchImpl = vi.fn<typeof fetch>(fetch);
await assertUiE2ePreflight({ fetchImpl });