The code cited its plan instead of saying why: `E28 review J4`, `(R6 S3b)`, `S1 justified…`,
`deep-review round 5`. That plan lives in the private ops repo, so for every reader of this one the
citation was noise, and a sentence whose subject was the plan step ("round 2 showed…") hid its
lesson behind an id. Each one is gone and the "why" kept: a bare citation is deleted, a sentence
carrying a lesson is reworded around it ("a later attempt showed…").
Measured (`scripts/audit_metrics.py`, product code): 652 lines in 270 files carried an epic code by
the definition the next commit holds (507 / 241 by the old, two-digit-only one) -> 0. Across all
code, tests, scripts and configs: ~1100 epic-code lines plus ~320 sprint/round ids.
Behaviour unchanged, checked mechanically: every changed .py file has the same AST once docstrings
are blanked; css/sh/toml/yml/json files are identical once comments are stripped; the only
non-comment changes in TS/JS are test titles, one description string in a contract table, and five
ESLint messages, whose text is all the gates snapshot diff holds. Not touched: Markdown (docs and
the changelog keep their history), Alembic migrations, TV episode notation (`S2 · E5`), DESIGN.md
ids (`C1`, `B4`, `S3h`), tracker ids (`SEC-16`, `DX-17`).
One stale claim fixed on the way: test_hls_reaper's docstring said the player checkpoints "every
10 s whether or not it is playing", which plex/stream.py calls wrong; it now says what the code does.
70 lines
2.8 KiB
TypeScript
70 lines
2.8 KiB
TypeScript
// @vitest-environment jsdom
|
|
//
|
|
// ONE test, ONE file, on purpose. This is the close→reclaim→run ordering contract of the palette
|
|
// (see closeTopOverlayThenRun), and it ASSERTS on a real useBackToClose entry driven through a real
|
|
// programmatic history.back() — which is why it cannot share module state with anything. (Any test
|
|
// rendering a real Modal can let an unstubbed back() go, too.)
|
|
//
|
|
// It cannot live in CommandPalette.dom.test.tsx. jsdom gives a test FILE a single session history,
|
|
// and history.ts's overlay bookkeeping is module-global, so the sibling tests there leave an
|
|
// in-flight programmatic back() behind — under which this one either hangs or, worse, goes green on
|
|
// somebody else's popstate. That is exactly how it used to pass: it asserted nothing on its own, and
|
|
// running it with `-t` failed. Its own file gives it clean module state.
|
|
import { useState } from "react";
|
|
import { describe, it, expect, vi, beforeAll } from "vitest";
|
|
import { render, screen, fireEvent, waitFor, act } from "@testing-library/react";
|
|
|
|
import CommandPalette, { type CommandGroup } from "./CommandPalette";
|
|
|
|
vi.mock("react-i18next", async (importOriginal) => {
|
|
const actual = await importOriginal<typeof import("react-i18next")>();
|
|
return { ...actual, useTranslation: () => ({ t: (k: string) => k }) };
|
|
});
|
|
|
|
beforeAll(() => {
|
|
// jsdom has no layout, so scrollIntoView is missing on the elements the active-row effect touches.
|
|
Element.prototype.scrollIntoView ??= () => {};
|
|
});
|
|
|
|
const ran: string[] = [];
|
|
|
|
function Harness() {
|
|
const [isOpen, setIsOpen] = useState(true);
|
|
const groups: CommandGroup[] = [
|
|
{
|
|
id: "channels",
|
|
label: "Channels",
|
|
items: [{ id: "ch:1", label: "TheVR Podcast", run: () => ran.push("ch:1") }],
|
|
},
|
|
];
|
|
return (
|
|
<CommandPalette
|
|
open={isOpen}
|
|
onClose={() => {
|
|
ran.push("closed");
|
|
setIsOpen(false);
|
|
}}
|
|
groups={groups}
|
|
/>
|
|
);
|
|
}
|
|
|
|
describe("CommandPalette · close-then-run ordering", () => {
|
|
it("closes, and runs the command only once the close has landed", async () => {
|
|
render(<Harness />);
|
|
// Load-bearing: useBackToClose pushes its entry from a coalesced microtask, so a click in the
|
|
// same synchronous tick as the render finds no entry to reclaim — no back(), no popstate.
|
|
await act(async () => {
|
|
await Promise.resolve();
|
|
});
|
|
|
|
fireEvent.click(screen.getByText("TheVR Podcast"));
|
|
expect(ran).toEqual(["closed"]);
|
|
|
|
// Well inside closeTopOverlayThenRun's 1500 ms give-up timer, so a pass means the RECLAIM ran the
|
|
// command — not the late path for a back() that never reports. (The margin used to be 200 ms
|
|
// under a 250 ms fallback, which made this load-sensitive by construction.)
|
|
await waitFor(() => expect(ran).toEqual(["closed", "ch:1"]), { timeout: 1000 });
|
|
});
|
|
});
|