Skip to content

test: cover the last of the thirteen, and the three upstream helpers a user can see - #521

Merged
IgorShevchik merged 2 commits into
mainfrom
test/cover-our-untested-utils
Aug 31, 2026
Merged

test: cover the last of the thirteen, and the three upstream helpers a user can see#521
IgorShevchik merged 2 commits into
mainfrom
test/cover-our-untested-utils

Conversation

@IgorShevchik

@IgorShevchik IgorShevchik commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Linked issue

Refs #86.

Type of change

  • Documentation (updates to the documentation or readme)
  • Bug fix (a non-breaking change that fixes an issue)
  • Enhancement (improving an existing functionality)
  • New feature (a non-breaking change that adds functionality)
  • Chore (updates to the build process or auxiliary tools and libraries)
  • Revert (undoing a merged change — retitle this PR revert(Scope): ...)
  • Breaking change (fix or feature that would cause existing functionality to change)

No src/ changes at all — four new spec files.

1. ModalDialogClose — the last of the thirteen

#519 covered eleven of the thirteen components that are ours and had no coverage anywhere. This is the twelfth: a nineteen-line passthrough over reka-ui's DialogClose, used once, by SidebarLayout, to close the mobile sidebar.

Two things the spec had to get right, and one of them it got wrong first:

  • Mounted inside a real Modal. On its own, DialogClose has no dialog to close, and the test would assert that nothing happens.
  • open is bound, not a literal true. A literal is never written back, so the dialog stays open however well the click works. The first draft passed exactly that way and proved nothing.

Replacing DialogClose with a plain span reddens it.

2. A change of direction, and what it cost to establish

The plan recorded on #86 put the nine untested src/runtime/utils modules next. Measured first, that workstream is almost empty — "has no spec named after it" is not the same as uncovered:

statements ours?
ai.ts 0% byte-identical to nuxt/ui@v4
content.ts 0% +14 lines, all JSDoc bar one type widening
overlay.ts 0% byte-identical to upstream
editor.ts 12% +85 lines, none of them the as any (see #88)
link.ts 44%, 0% branches +21 lines, all JSDoc
virtualizer.ts 71% +4/−2 lines
dashboard.ts, link-keys.ts, prototype-guard.ts 100%

prototype-guard.ts looked like the prize — 81 lines, entirely ours, closing two prototype-pollution holes. It is already at 100%, exercised through get/set and getAtPath/setAtPath, including the case where set({}, 'toString.x', 1) reached Object.prototype.toString with no reserved word in the path.

So everything left uncovered there is upstream's logic, and the question became whether we test code we ship but did not write. Decided with the maintainer: yes, but only what a user can see. A test does not diverge from upstream the way a rewrite does — it lives in test/, src/ stays byte-identical, and nothing new conflicts on a sync. Upstream having no tests is the argument for writing them: when we port their changes, ours are the only safety net (#75).

3. The three that passed that filter

helper was what it sits under
utils/overlay.ts 0% whether a click beside a Modal, Drawer or Popover closes it
utils/link.ts 44% / 0% branches which navigation item is highlighted
utils/content.ts 0% the sidebar of any docs site built on this kit

pointerDownOutside has two branches, and both exist for a case where the honest answer — "the pointer went down outside, so close" — is wrong: a target that left the DOM between pointerdown and click (a toast dismissing itself on touch), and a click on the overlay's own scrollbar, which is painted outside the client box. Misfiring either way gives an overlay that will not close, or one that closes mid-drag.

isPartiallyEqual is what exactQuery: 'partial' means. The current route carries whatever else is in the URL; a link declaring ?tab=general has to stay highlighted through a search term and a page number. Keys the route adds are forgiven, keys the link declares are not — the asymmetry that makes it "partial" rather than "subset either way".

mapContentNavigationItem renames title to label and path to to for every entry in a @nuxt/content tree. Get it wrong and the sidebar is a column of blank, unclickable rows.

All three reach 100% of statements and branches. Every branch is mutation-checked: forgiving removed keys as well as added ones, dropping the isConnected guard, narrowing the scrollbar check to one axis, removing the deep limit, and four more each redden a named test.

Not covered, deliberately

ai.ts — streaming-state predicates, visible only inside a chat UI. virtualizer.ts — 71%, and what is left is measurement arithmetic. editor.ts — 12% of 587 lines, a slice of its own if it is worth one at all.

Gate

lint, typecheck, 336 test files / 7676 tests, and coverage 74.31 → 74.76% statements, 71.53 → 71.86 branches.

Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

claude added 2 commits August 31, 2026 12:28
#519 covered eleven of the thirteen components that are ours and had no
coverage anywhere. This is the twelfth and last that can be tested on its own —
a nineteen-line passthrough over reka-ui's `DialogClose`, used once, by
`SidebarLayout`, to close the mobile sidebar.

Mounted inside a real `Modal`, because `DialogClose` alone has no dialog to
close and the test would be asserting that nothing happens. `open` is bound
rather than passed as a literal `true`: a literal is never written back, so the
dialog stays open however well the click works — the first draft passed that
way and proved nothing. Replacing `DialogClose` with a plain `span` reddens it.

Refs #86
A change of direction, decided with the maintainer: we do write tests for code
we ship but did not write. A test does not diverge from upstream the way a
rewrite does — it lives in `test/`, and `src/` stays byte-identical, so nothing
new conflicts on a sync. And upstream having no tests is the argument for
writing them rather than against: when we port their changes, ours are the only
safety net (#75).

The filter is "what a user can see", not coverage. Three helpers qualified,
each sitting under something visible and each essentially unexercised:

`utils/overlay.ts` — 0% — decides whether a click beside a `Modal`, `Drawer` or
`Popover` closes it. Both of its branches exist for a case where the honest
answer is wrong: a target that left the DOM between pointerdown and click (a
toast dismissing itself on touch), and a click on the overlay's own scrollbar,
which is painted outside the client box. Misfiring either way is an overlay
that will not close, or one that closes mid-drag.

`utils/link.ts` — 44% statements, 0% branches — `isPartiallyEqual` is what
`exactQuery: 'partial'` means. The current route carries whatever else is in
the URL, and a link declaring `?tab=general` has to stay highlighted through a
search term and a page number. Keys the route adds are forgiven; keys the link
declares are not. Breaking it shows up as a navigation item highlighting when
it should not.

`utils/content.ts` — 0% — renames `title` to `label` and `path` to `to` for
every entry in a `@nuxt/content` tree, which is to say it builds the sidebar of
any docs site built on this kit. Get it wrong and the sidebar is a column of
blank, unclickable rows.

All three go to 100% of statements and branches; the suite total moves 74.31%
to 74.76%. Every branch is mutation-checked — forgiving removed keys as well as
added ones, dropping the `isConnected` guard, widening the scrollbar check,
removing the `deep` limit, and four more each redden a named test.

Not covered, and deliberately: `ai.ts` (streaming-state predicates, visible
only inside a chat UI), `virtualizer.ts` (71%, and what is left is measurement
arithmetic) and `editor.ts` (12% of 587 lines — a slice of its own, if it is
worth one at all).

Refs #86
@IgorShevchik IgorShevchik changed the title test(ModalDialogClose): cover the last of the thirteen test: cover the last of the thirteen, and the three upstream helpers a user can see Aug 31, 2026
@IgorShevchik
IgorShevchik merged commit 0914146 into main Aug 31, 2026
2 of 3 checks passed
@IgorShevchik
IgorShevchik deleted the test/cover-our-untested-utils branch August 31, 2026 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants