test(tui): extend coverage gate to Ink components + App.tsx (closes #1501)#1538
Open
cliffhall wants to merge 8 commits into
Open
test(tui): extend coverage gate to Ink components + App.tsx (closes #1501)#1538cliffhall wants to merge 8 commits into
cliffhall wants to merge 8 commits into
Conversation
Add ink-testing-library and renderer-based tests for useSelectableList, SelectableItem, and Tabs. Widen the vitest include glob to .test.tsx and lift these files from the interim React-surface coverage exclusion. The blanket src/components/**/*.tsx exclude is expanded into an explicit per-file list so remaining components can be lifted incrementally. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…1501) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…1501) Add ink-testing-library tests for the 12 Ink components (InfoTab, AuthTab, ResourcesTab, PromptsTab, ToolsTab, NotificationsTab, HistoryTab, RequestsTab, and the Tool/Resource/Prompt test modals + DetailsModal), mounting them through the ink-scroll-view / ink-form passthrough doubles and driving keypresses via stdin. Modal components render position:absolute (empty frame under the test renderer) so their tests assert on behavior — injected InspectorClient fakes and onClose — while the passthrough ScrollView still mounts the inner JSX for coverage. Lift these 12 components from the interim React-surface exclusion in vitest.config.ts; only App.tsx remains excluded. All files clear the uniform 90/90/90/90 per-file gate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mock the full @inspector/core surface (InspectorClient, the 7 managed-state classes, the 8 react hooks, transport + auth) behind a controllable harness, plus the ink-scroll-view/ink-form passthroughs, so App renders under ink-testing-library and its keyboard state machine can be driven via stdin. Concurrent ink mounts share raw-mode stdin, so each render is unmounted in afterEach. Foundation covers server-list nav, tab accelerators, connect/ disconnect, OAuth-tab gating, and connected-status rendering (~50% baseline). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…xclusion (#1501) Extend App.test.tsx to 67 tests driving the keyboard state machine, tab content, modals, OAuth flows, and connect/disconnect across the controllable @inspector/core mock. App.tsx now clears the 90/90/90/90 per-file gate (94.6/90.6/94.5/96.6). Remove the last React-surface exclusion (src/App.tsx) from clients/tui/vitest.config.ts. The whole clients/tui/src tree is now under the uniform per-file coverage gate with no React-surface exclusions, completing the interim-scope lift from #1484. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…1501) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3 tasks
…ns (#1501) Add targeted App.tsx tests for the OAuth handlers' non-Error throw arms (quick onCallback, guided start/advance, run-to-completion) and a re-entrant quick-auth guard, lifting App.tsx branch coverage 90.6% -> 91.48% for a safer margin above the 90 gate. Harden the App renderer tests against the heavier v8 coverage instrumentation, where React+ink's multi-macrotask render scheduling races fixed ticks: - press() now settles two ticks per key so focus/tab changes flush before the next key is routed (ink re-subscribes useInput on re-render); - expectFrame()/waitUntil() poll for frame content and async flow state (callbackServer opts) instead of asserting after a single fixed tick; - ResourcesTab's content-clear test polls for fetched content likewise. Plain 'npm test' (the CI path) was already stable; this makes the local coverage gate stable too (13/13 clean runs vs ~2/8 flaky before). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Member
Author
|
Follow-up: bumped App.tsx branch coverage from 90.6% → 91.48% for a safer margin above the 90 gate — added tests for the OAuth handlers' non-Error throw arms (quick onCallback, guided start/advance, run-to-completion) and a re-entrant quick-auth guard. Also hardened the App renderer tests against the heavier v8 coverage instrumentation (where React+ink's multi-macrotask render scheduling races fixed ticks): |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1501.
Summary
Lifts the interim React-surface coverage exclusion in the TUI client (the follow-up to #1484 / #1532). The whole
clients/tui/srctree now clears the uniform 90/90/90/90 per-file gate with no React-surface exclusions — App.tsx, every Ink component, and theuseSelectableListhook are all exercised under coverage.Test-only change: no source files were modified.
How it's tested
Added
ink-testing-libraryand renderer-based tests that mount components in-process and drive keypresses throughstdin. Two shared passthrough doubles in__tests__/helpers/make the components mountable under the non-TTY test renderer:inkScrollViewMock.tsx— the realScrollViewrenders a placeholder minimap and never mounts its children in a non-TTY env; the double renders children directly and stubs the imperative ref API (scrollBy/scrollTo/getViewportHeight).inkFormMock.tsx— the realink-formFormis hard to drive field-by-field; the double firesonSubmiton Enter.Per-component approach:
useSelectableList,SelectableItem,Tabs): assert on rendered frame text and drive list navigation / scroll keys.DetailsModal): these renderposition="absolute", which produces an empty frame under the renderer, so their tests assert on behavior — injectedInspectorClientfakes being called,onClose, and state transitions — while the passthroughScrollViewstill mounts the inner JSX for coverage.@inspector/coresurface (InspectorClient, the 7 managed-state classes, the 8 react hooks, transport, auth) plus the callback server. 67 tests drive the keyboard state machine, per-tab content, modal-open flows, OAuth (guided/quick/clear, success + error), and connect/disconnect. Each render is unmounted inafterEach(concurrent ink mounts share raw-mode stdin and interfere withuseInput).Verification
clients/tuinpm run validate— clean (format / lint / build / test).clients/tuinpm run test:coverage— green, 260 tests, every file ≥90 on all four dimensions, no ERROR lines. App.tsx: 94.6 stmts / 90.6 branch / 94.5 funcs / 96.6 lines.Config
clients/tui/vitest.config.ts: removed all React-surface entries from the coverageexclude(only the pure re-exporttui-servers.tsand test/type globs remain) and widened theincludeglob to*.test.tsx. The interim-scope comment from #1484 is updated to reflect the completed lift.🤖 Generated with Claude Code