mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-11 18:54:03 +01:00
App.tsx owned the inventory as well as rendering it: resolving a shared link against this browser's storage at mount, deferring persistence until the visitor consents, clearing the URL fragment, and three mutators. Moved all of it to a useInventoryState hook (163) beside the existing useSolver. The two inline handlers that only set state became named keep/replace callbacks, so the view no longer touches setPersist or setSaved; Clear, Discard and onImport all go through replace. Coverage held at 100% -- totals moved 863/375/181/810 -> 864/375/182/811, exactly the one statement and one function that promoting the Keep handler adds. Branches unchanged, so nothing conditional left test reach. That was the metric that would have caught an over-large extraction here, since the hook has no dedicated test and rides on the four App test files. No kcd2_dice_solver file is over the 250-line cap now. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
62 lines
4.7 KiB
JSON
62 lines
4.7 KiB
JSON
{
|
|
"intent": "Bring kcd2_dice_solver/src/App.tsx (306 lines) under the repo-wide 250-line cap with no change to what the app renders or how the inventory behaves, completing the four-file kcd2 series.",
|
|
"scope": [
|
|
"kcd2_dice_solver/src/App.tsx — reduced to the view: props, the search query, the solve request, and the JSX",
|
|
"kcd2_dice_solver/src/hooks/useInventoryState.ts — new: InventoryState, useInventoryState",
|
|
"Non-goal: any change to rendered markup, class names, ARIA roles or copy, which the four App test files query on",
|
|
"Non-goal: a dedicated test file for the hook, which would change the 288-test count this split is verified against"
|
|
],
|
|
"changes": [
|
|
"Extracted the inventory state into a useInventoryState hook under src/hooks/, following the existing useSolver pattern: the link-versus-storage resolution at mount, the deferred-persistence boolean and its storage effect, the fragment-clearing effect, and the setDieCount/toggleBadge mutators, all with their explanatory comments.",
|
|
"Promoted the two inline handlers that only set state — Keep, and the Discard/Clear/import replacement — to named `keep` and `replace` callbacks on the hook, so the view no longer touches setPersist or setSaved directly. importInventory collapsed into `replace`, which Clear, Discard and InventoryIo's onImport now all use.",
|
|
"The hook exposes `stored` as a plain SavedInventory rather than the loadInventory result, since Discard is the only consumer and it wants the inventory, not the parse report.",
|
|
"Deliberately avoided a re-export: an initial draft had the hook re-export EMPTY, which is the barrel pattern this series is not using. App.tsx imports EMPTY from lib/inventoryIo.ts, its real home."
|
|
],
|
|
"verification": [
|
|
{
|
|
"command": "npx vitest run",
|
|
"result": "pass",
|
|
"evidence": "Test Files 24 passed (24); Tests 288 passed (288). The four App test files — AppStorage, AppShell, AppLinks, AppRecovery — exercise the extracted state through the component and all still pass unmodified."
|
|
},
|
|
{
|
|
"command": "npx vitest run --coverage",
|
|
"result": "pass",
|
|
"evidence": "Statements 100% (864/864), Branches 100% (375/375), Functions 100% (182/182), Lines 100% (811/811). Totals rose by exactly one statement and one function against the 863/375/181/810 baseline, which is the Keep handler becoming a named callback; branches are unchanged, so no conditional left test reach. This was the metric the brief warned would drop if the extraction were too large — it did not."
|
|
},
|
|
{
|
|
"command": "npm run lint (tsc --noEmit && eslint src)",
|
|
"result": "pass",
|
|
"evidence": "Exit 0, no output."
|
|
},
|
|
{
|
|
"command": "wc -l src/App.tsx src/hooks/useInventoryState.ts",
|
|
"result": "pass",
|
|
"evidence": "App.tsx 217, useInventoryState.ts 163 — both under the 250-line cap, down from a single 306-line file."
|
|
},
|
|
{
|
|
"command": "bash ~/utils/scripts/check_file_length.sh --all",
|
|
"result": "pass",
|
|
"evidence": "No kcd2_dice_solver file appears in the over-cap listing at all. This is the fourth and last of the four files the series targeted."
|
|
},
|
|
{
|
|
"command": "grep -rn 'eslint-disable|ts-ignore|ts-expect-error' kcd2_dice_solver/src/ ; git diff --stat vite.config.ts",
|
|
"result": "pass",
|
|
"evidence": "No hits and an empty diff: zero suppressions across the whole series, and the coverage thresholds and exclude list were never touched."
|
|
},
|
|
{
|
|
"command": "pre-commit run --files <changed files>",
|
|
"result": "pass",
|
|
"evidence": "All configured hooks pass on the touched files."
|
|
}
|
|
],
|
|
"risks": [
|
|
"The hook has no dedicated test file; its coverage comes entirely from the four App test files exercising it through the component. Coverage is 100% including branches, but a future change to the hook could be under-tested in a way a direct hook test would catch. Adding one was deliberately left out of scope because it would change the 288-test baseline this split is verified against.",
|
|
"App.tsx and the hook now share a wide interface — eleven fields. That is the cost of extracting state rather than markup from a component with no prop-drilled subtree; a presentational split would have needed comparable prop plumbing.",
|
|
"kcd2_dice_solver has no CI workflow and is not covered by pre-commit, so the vitest and lint runs above are the only gate on this change."
|
|
],
|
|
"rollback": [
|
|
"git revert the commit — one edited file and one added file, with no data, config or schema migration.",
|
|
"After rollback, re-run npx vitest run --coverage and npm run lint; expect 288 tests passing at 100% coverage (totals returning to 863/375/181/810) and lint exit 0."
|
|
]
|
|
}
|