Closed as done. All five workstreams are worked through — three by writing tests, two by measuring them away. Coverage went 71.89% to 74.95% of statements over four PRs, and three defects turned up along the way. Figures below, so the next audit does not re-file the parts that were declined.
What was done
| PR |
what |
| #519 |
eleven of the thirteen components that are ours and had no coverage: PageCardGroup, SidebarLayout + six wrappers, Navbar + three |
| #521 |
ModalDialogClose, the twelfth; plus utils/overlay.ts, utils/link.ts, utils/content.ts |
| #522 |
the two keyboard paths we hand-wrote: CommandPalette's Backspace, FileUpload's Enter/Space |
Coverage: 71.89 → 74.95% statements, 69.93 → 72.10 branches, 71.19 → 74.04 functions, 71.44 → 74.47 lines.
Defects found while writing them
The measure that changed everything
"Has no spec file named after it" is not "untested", and it overstated every count in this issue. Two better measures:
Is it imported by any spec? 68 of 182 components were not — but 55 of those exist in nuxt/ui@v4, where they have no specs either. Thirteen were ours. Those thirteen were the real gap, and twelve are now covered (ModalDialogClose was the last testable one).
Is it executed? For src/runtime/utils, coverage answered directly: prototype-guard.ts looked like the prize — 81 lines, entirely ours, closing two prototype-pollution holes — and was already at 100%, exercised through get/set and getAtPath/setAtPath.
What was declined, and why
Locale key-parity. Measured: all 20 locales carry the same 78 keys, no missing, no extra. And they have never drifted — src/runtime/locale/en.ts has been touched by exactly one commit in the repository's history, which changed all 21 locale files together. A guard here would be a guard for something that has not happened.
Most of the keyboard workstream. It reads as a large gap — arrow keys, Home/End, Escape across menus, tabs, accordion, palette, pagination. All of that is reka-ui's roving focus and typeahead. Five places in src/runtime handle a key themselves; three already had specs, and the two that did not are covered by #522.
Upstream components and composables. 55 components and most of the remaining utils. The rule settled with the maintainer: we do write tests for code we ship but did not write — a test lives in test/ and does not diverge from upstream the way a rewrite does — but filtered to what a user can see. Under that filter, three utils qualified and are done. ai.ts (streaming-state predicates, visible only inside a chat UI), virtualizer.ts (71%, the rest is measurement arithmetic) and editor.ts (12% of 587 lines) did not.
Still open elsewhere
Priority: was P2.
Original text, June 2026
1. Components without any spec — 76 of 178
- 24 top-level:
App, ContextMenuContent, DropdownMenuContent, EditorEmojiMenu, EditorMentionMenu, EditorSuggestionMenu, Empty, LinkBase, ModalDialogClose, Navbar, NavbarDivider, NavbarSection, NavbarSpacer, OverlayProvider, PageCardGroup, Sidebar ×8 (see the vitest-globs bug issue), Toaster.
*Content/LinkBase are partially exercised via parent specs, but Toaster, Empty, Navbar family, PageCardGroup, App are user-facing with zero coverage. Toaster + untested useToast means the entire toast lifecycle (queueing, auto-dismiss timers) is untested.
- 46 of 47 prose components (only
ProsePrompt has a spec), all 5 color-mode/*, locale/LocaleSelect.vue.
2. Composables — 5 of 24 tested
Tested: defineShortcuts, useComponentProps, useEditorMenu, useOverlay, useScrollShadow. Untested logic carriers: useFormField, useToast, useFileUpload, useFilter, useKbd, useLocale, useIMEGuard, useResizable, useScrollspy, useSpeechRecognition, usePortal, useConfetti, useDevice, useFieldGroup, useForwardProps, useAvatarGroup, useComponentIcons, useContentSearch, defineLocale.
3. Utils — 2 of 12 runtime modules touched
Untested: ai.ts, content.ts, dashboard.ts, editor.ts, fuse.ts (see the XSS issue — needs a regression test anyway), link.ts, locale.ts, overlay.ts, tv.ts (the theme merge engine!), virtualizer.ts; plus all 4 build-time src/utils/*.
4. Locale key-parity (cheap, high value)
20 locale files in src/runtime/locale/, no test validating completeness. A ~10-line it.each comparing flattened keys of each locale against en.ts catches missing/extra keys on every locale PR.
5. Keyboard interaction is essentially nil
keydown/keyup appears in only 2 spec files (ChatPrompt.spec.ts, composables/defineShortcuts.spec.ts). No arrow-key/Home/End/Escape tests for menus, tabs, accordion, palette, pagination. Specifics beyond #63: CommandPalette.spec.ts (185 lines) has zero trigger/emitted/setValue — no filtering/selection/highlight tests even though #76 fixed a highlight bug there; Editor.spec.ts is 29 lines for the richest component in the kit; #63's behavioral starter set is half-done (Select/SelectMenu ✅, Accordion and Modal still none).
Form.spec.ts (728 lines: zod/yup/joi/valibot, nested forms, touched/dirty) is the in-repo model to copy.
Priority: P2 — the sync pipeline's safety net (#75) is only as good as this coverage. Suggest tackling top-down: Toaster/useToast → useFormField/useFilter/tv.ts → locale parity → keyboard set.
Closed as done. All five workstreams are worked through — three by writing tests, two by measuring them away. Coverage went 71.89% to 74.95% of statements over four PRs, and three defects turned up along the way. Figures below, so the next audit does not re-file the parts that were declined.
What was done
PageCardGroup,SidebarLayout+ six wrappers,Navbar+ threeModalDialogClose, the twelfth; plusutils/overlay.ts,utils/link.ts,utils/content.tsCommandPalette's Backspace,FileUpload's Enter/SpaceCoverage: 71.89 → 74.95% statements, 69.93 → 72.10 branches, 71.19 → 74.04 functions, 71.44 → 74.47 lines.
Defects found while writing them
SidebarLayoutrendereddata-state="isLoading ? 'loading' : 'show'"as a literal string — the binding was missing its colon, so every layout put the source of the expression into the DOM. Fixed in test: cover the eleven components we wrote that nothing tested #519.offContentScrollbaris a public prop onSidebarLayoutthat does nothing: both branches of its variant are empty strings and the one compound reading it has itsclassblock commented out. Reported, not fixed — it is a decision about public API shape.isActionon components that cannot honour it #517 removedisActionfrom ten types that advertised it and could not honour it.The measure that changed everything
"Has no spec file named after it" is not "untested", and it overstated every count in this issue. Two better measures:
Is it imported by any spec? 68 of 182 components were not — but 55 of those exist in
nuxt/ui@v4, where they have no specs either. Thirteen were ours. Those thirteen were the real gap, and twelve are now covered (ModalDialogClosewas the last testable one).Is it executed? For
src/runtime/utils, coverage answered directly:prototype-guard.tslooked like the prize — 81 lines, entirely ours, closing two prototype-pollution holes — and was already at 100%, exercised throughget/setandgetAtPath/setAtPath.What was declined, and why
Locale key-parity. Measured: all 20 locales carry the same 78 keys, no missing, no extra. And they have never drifted —
src/runtime/locale/en.tshas been touched by exactly one commit in the repository's history, which changed all 21 locale files together. A guard here would be a guard for something that has not happened.Most of the keyboard workstream. It reads as a large gap — arrow keys, Home/End, Escape across menus, tabs, accordion, palette, pagination. All of that is reka-ui's roving focus and typeahead. Five places in
src/runtimehandle a key themselves; three already had specs, and the two that did not are covered by #522.Upstream components and composables. 55 components and most of the remaining utils. The rule settled with the maintainer: we do write tests for code we ship but did not write — a test lives in
test/and does not diverge from upstream the way a rewrite does — but filtered to what a user can see. Under that filter, three utils qualified and are done.ai.ts(streaming-state predicates, visible only inside a chat UI),virtualizer.ts(71%, the rest is measurement arithmetic) andeditor.ts(12% of 587 lines) did not.Still open elsewhere
editor.tsat 12% is the largest single uncovered surface left. refactor(Editor): the command-handler debt is upstream's, not ours — not diverging for it #88 closed as not-planned for rewriting it; testing it is a separate question and a slice of its own.offContentScrollbarneeds a decision.Priority: was P2.
Original text, June 2026
1. Components without any spec — 76 of 178
App,ContextMenuContent,DropdownMenuContent,EditorEmojiMenu,EditorMentionMenu,EditorSuggestionMenu,Empty,LinkBase,ModalDialogClose,Navbar,NavbarDivider,NavbarSection,NavbarSpacer,OverlayProvider,PageCardGroup,Sidebar×8 (see the vitest-globs bug issue),Toaster.*Content/LinkBaseare partially exercised via parent specs, butToaster,Empty,Navbarfamily,PageCardGroup,Appare user-facing with zero coverage.Toaster+ untesteduseToastmeans the entire toast lifecycle (queueing, auto-dismiss timers) is untested.ProsePrompthas a spec), all 5color-mode/*,locale/LocaleSelect.vue.2. Composables — 5 of 24 tested
Tested:
defineShortcuts,useComponentProps,useEditorMenu,useOverlay,useScrollShadow. Untested logic carriers:useFormField,useToast,useFileUpload,useFilter,useKbd,useLocale,useIMEGuard,useResizable,useScrollspy,useSpeechRecognition,usePortal,useConfetti,useDevice,useFieldGroup,useForwardProps,useAvatarGroup,useComponentIcons,useContentSearch,defineLocale.3. Utils — 2 of 12 runtime modules touched
Untested:
ai.ts,content.ts,dashboard.ts,editor.ts,fuse.ts(see the XSS issue — needs a regression test anyway),link.ts,locale.ts,overlay.ts,tv.ts(the theme merge engine!),virtualizer.ts; plus all 4 build-timesrc/utils/*.4. Locale key-parity (cheap, high value)
20 locale files in
src/runtime/locale/, no test validating completeness. A ~10-lineit.eachcomparing flattened keys of each locale againsten.tscatches missing/extra keys on every locale PR.5. Keyboard interaction is essentially nil
keydown/keyupappears in only 2 spec files (ChatPrompt.spec.ts,composables/defineShortcuts.spec.ts). No arrow-key/Home/End/Escape tests for menus, tabs, accordion, palette, pagination. Specifics beyond #63:CommandPalette.spec.ts(185 lines) has zerotrigger/emitted/setValue— no filtering/selection/highlight tests even though #76 fixed a highlight bug there;Editor.spec.tsis 29 lines for the richest component in the kit; #63's behavioral starter set is half-done (Select/SelectMenu ✅, Accordion and Modal still none).Form.spec.ts(728 lines: zod/yup/joi/valibot, nested forms, touched/dirty) is the in-repo model to copy.Priority: P2 — the sync pipeline's safety net (#75) is only as good as this coverage. Suggest tackling top-down: Toaster/useToast → useFormField/useFilter/tv.ts → locale parity → keyboard set.