64566e9327
После ребейза на develop версии-когерентность (#481, общий one-shot флаг) и chunk-load boundary (#495, оконный guard) были сведены к ОДНОМУ общему оконному бюджету в @/lib/reload-guard: не более одного авто-reload за RELOAD_WINDOW_MS суммарно по обоим путям, при этом второй деплой в той же вкладке восстанавливается. - reload-guard.test.ts: переписаны под оконную семантику (ключ chunk-reload-at хранит таймстамп, а не флаг); сюда же перенесены чистые тесты shouldAutoReload. - chunk-load-error-boundary.test.ts: убран импорт shouldAutoReload (переехал в reload-guard). - chunk-load-error-boundary.tsx: handleError экспортирован для теста инварианта. - reload-budget.integration.test.tsx: инвариант (a) на РЕАЛЬНОМ guard — reload на одном пути тратит общий бюджет для другого в пределах окна, после окна восстановление, при недоступном sessionStorage ни один путь не перезагружает. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
38 lines
1.4 KiB
TypeScript
38 lines
1.4 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { isChunkLoadError } from "./chunk-load-error-boundary";
|
|
|
|
// The detector decides whether a caught render error is a stale-deploy chunk-404
|
|
// (→ auto-reload to fetch the new manifest) vs a genuine app error (→ generic
|
|
// recovery UI, no reload). A false negative on a real chunk failure re-blanks the
|
|
// app; a false positive would auto-reload on an ordinary error. Pin both sides.
|
|
describe("isChunkLoadError", () => {
|
|
it("detects the ChunkLoadError name", () => {
|
|
expect(isChunkLoadError({ name: "ChunkLoadError", message: "x" })).toBe(true);
|
|
});
|
|
|
|
it.each([
|
|
"Failed to fetch dynamically imported module: https://x/assets/index-abc.js",
|
|
"error loading dynamically imported module",
|
|
"Importing a module script failed.",
|
|
])("detects the dynamic-import failure message %#", (message) => {
|
|
expect(isChunkLoadError({ name: "TypeError", message })).toBe(true);
|
|
});
|
|
|
|
it("is case-insensitive on the message", () => {
|
|
expect(
|
|
isChunkLoadError({ message: "FAILED TO FETCH DYNAMICALLY IMPORTED MODULE" }),
|
|
).toBe(true);
|
|
});
|
|
|
|
it.each([
|
|
null,
|
|
undefined,
|
|
{},
|
|
{ name: "TypeError", message: "Cannot read properties of undefined" },
|
|
{ message: "Network request failed" },
|
|
new Error("some ordinary render error"),
|
|
])("returns false for a non-chunk error %#", (err) => {
|
|
expect(isChunkLoadError(err)).toBe(false);
|
|
});
|
|
});
|