fix: Node.js v25 / Windows compatibility and locale-aware number formatting#407
Conversation
- testSetup.ts: polyfill localStorage when Node.js v22.12+ native global exposes it without a backing file (getItem/setItem not functions) - vitest.config.ts: add enforce:pre plugin to redirect /@solid-refresh to the real file path, avoiding fileURLToPath failure on Windows where the virtual module URL has no drive letter; remove deprecated poolOptions - MapDetail.tsx: pass i18n locale to toLocaleString() so thousands separator follows the active locale instead of the OS locale Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces localization for world size formatting in the Map Detail view and addresses environment-specific issues in the test suite. Key changes include a localStorage polyfill for Node.js environments where the native global is incomplete and a Vitest configuration fix for Windows-specific path resolution of @solid-refresh. Feedback was provided to improve the localStorage polyfill by using a null-prototype object for the internal store to prevent collisions with inherited properties.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
fank
left a comment
There was a problem hiding this comment.
Reviewed the diff and ran npm test locally — 1498/1498 pass. All three fixes look correct:
- MapDetail.tsx:
useI18n()returnslocaleas an Accessor signal (ui/src/i18n/i18n.ts:34), solocale()is the right call. - testSetup.ts: the
getItem !== "function"probe correctly identifies the broken Node 25 nativelocalStorageand swaps in an in-memoryStorage. - vitest.config.ts:
enforce: "pre"ensures the redirect runs beforevite-plugin-solid'sresolveIdclaims the virtual ID.require.resolve("solid-refresh/dist/solid-refresh.mjs")works because solid-refresh exports./dist/*. Minor nit —require.resolve("solid-refresh")would resolve via theimportcondition and be a bit less fragile to file renames, but the explicit path is fine.
Same Windows locale bug elsewhere
The thousands-separator fix in MapDetail.tsx patches one site, but the identical pattern exists in ui/src/pages/recording-selector/DetailSidebar.tsx at lines 128, 132, 136, 140, 168, 176 — six bare toLocaleString() calls (units, alive, dead, kills, playerKills). On a German Windows host these will render "30 720" and would break the same kind of test assertion this PR is fixing. Worth including here for consistency, or filing a follow-up.
|
I think I'll make same changes for these components as well, so I'm moving this PR into draft |
Pass locale() from useI18n() to all toLocaleString() calls (units, alive, dead, kills, playerKills) so number formatting follows the active locale instead of the OS locale. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…atting (OCAP2#407) * fix: Node.js v25 / Windows compatibility in ui tests - testSetup.ts: polyfill localStorage when Node.js v22.12+ native global exposes it without a backing file (getItem/setItem not functions) - vitest.config.ts: add enforce:pre plugin to redirect /@solid-refresh to the real file path, avoiding fileURLToPath failure on Windows where the virtual module URL has no drive letter; remove deprecated poolOptions - MapDetail.tsx: pass i18n locale to toLocaleString() so thousands separator follows the active locale instead of the OS locale Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: apply suggestion from @gemini-code-assist[bot] Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * fix: use i18n locale for toLocaleString in DetailSidebar Pass locale() from useI18n() to all toLocaleString() calls (units, alive, dead, kills, playerKills) so number formatting follows the active locale instead of the OS locale. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Summary
Fixes three test failures that appear when running
npm testlocally on Windows with Node.js v25 (CI uses Ubuntu + Node.js v24 where none of these manifest):localStorage.getItem is not a function— Node.js v22.12+ exposes a nativelocalStorageglobal (SQLite-backed in v25).Without
--localstorage-filethe object exists but its methods are not functions, silently overriding jsdom's storage mock.testSetup.tsnow detects this and replaces the broken global with a plain in-memoryStorageimplementation.TypeError: … Received 'file:///@solid-refresh'—vite-plugin-solidregisters/@solid-refreshas a virtual module ID; vitest 4 converts it tofile:///@solid-refresh. On Windows,fileURLToPathrejects that URL because the path has no driveletter. A new
enforce: "pre"plugin invitest.config.tsintercepts the ID and returns the real file path before solidPlugin can register the virtual one. Also removes the deprecatedpoolOptionsblock (removed in vitest 4).MapDetail.tsxcalledtoLocaleString()without a locale, so on a non-English Windows machine30720rendered as"30 720"instead of"30,720". Now passeslocale()fromuseI18n()explicitly.How to test
Optionally verify on Windows with Node.js v25 — previously produced 40 failed test files and 9 failed tests.
Checklist
go test ./...passescd ui && npm testpasses (if frontend changed)