Phase 0 of #2126. Lines 239-668 of clients/web/src/App.tsx were already at module scope — helpers, formatters, constants, and the toast subcomponents, none of which close over component state — so the whole block moves verbatim into files. App.tsx drops from 5,303 to 4,892 lines with no behavior change. Placement follows the lib-vs-utils rule in AGENTS.md: pure computation to utils/, anything touching the environment to lib/. EMPTY_SETTINGS and the two loose toast ids deliberately do NOT land in a new top-level src/constants.ts, which the issue suggested: the web coverage include is a whitelist naming components/hooks/theme/lib/utils/server, so a module there would have fallen out of the >=90 gate silently. They go under utils/ instead. ReAuthBannerBar is in the block but not in the issue's table — it was added after the issue was written (#2108). It moves to components/groups/ReAuthBanner/, beside the banner it wraps. Every new module is at 100% on all four coverage dimensions. Two v8 ignores, each justified in place: getAuthToken's typeof-window guard (a happy-dom inherent path) and replayProtocolRequest's provably-dead default case. Signed-off-by: cliffhall <cliff@futurescale.com>
66 lines
2 KiB
TypeScript
66 lines
2 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { errorCodeOf, errorMessage, formatErrorDetails } from "./errorFormat";
|
|
|
|
describe("errorMessage", () => {
|
|
it("returns an Error's message", () => {
|
|
expect(errorMessage(new Error("boom"))).toBe("boom");
|
|
});
|
|
|
|
it("stringifies a non-Error", () => {
|
|
expect(errorMessage("plain string")).toBe("plain string");
|
|
expect(errorMessage(undefined)).toBe("undefined");
|
|
expect(errorMessage(42)).toBe("42");
|
|
});
|
|
});
|
|
|
|
describe("errorCodeOf", () => {
|
|
it("reads a numeric `code` off a protocol error", () => {
|
|
expect(
|
|
errorCodeOf(Object.assign(new Error("nope"), { code: -32602 })),
|
|
).toBe(-32602);
|
|
});
|
|
|
|
it("returns undefined for a plain Error", () => {
|
|
expect(errorCodeOf(new Error("plain"))).toBeUndefined();
|
|
});
|
|
|
|
it("returns undefined when `code` is not a number", () => {
|
|
expect(errorCodeOf({ code: "-32602" })).toBeUndefined();
|
|
});
|
|
|
|
it("returns undefined for non-objects", () => {
|
|
expect(errorCodeOf(null)).toBeUndefined();
|
|
expect(errorCodeOf("boom")).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("formatErrorDetails", () => {
|
|
it("pretty-prints code/message/data when a code is present", () => {
|
|
const err = Object.assign(new Error("bad params"), {
|
|
code: -32602,
|
|
data: { field: "uri" },
|
|
});
|
|
expect(JSON.parse(formatErrorDetails(err))).toEqual({
|
|
code: -32602,
|
|
message: "bad params",
|
|
data: { field: "uri" },
|
|
});
|
|
});
|
|
|
|
it("pretty-prints when only `data` is present", () => {
|
|
expect(
|
|
JSON.parse(formatErrorDetails({ data: [1, 2], message: "m" })),
|
|
).toEqual({ message: "m", data: [1, 2] });
|
|
});
|
|
|
|
it("falls back to the plain message for a bare Error", () => {
|
|
expect(formatErrorDetails(new Error("just a message"))).toBe(
|
|
"just a message",
|
|
);
|
|
});
|
|
|
|
it("falls back to String() for a non-object", () => {
|
|
expect(formatErrorDetails("boom")).toBe("boom");
|
|
expect(formatErrorDetails(null)).toBe("null");
|
|
});
|
|
});
|