tui: improve testability and simplify code#2551
Merged
dgageot merged 3 commits intodocker:mainfrom Apr 28, 2026
Merged
Conversation
…yout/title helpers, inject transcriber via interface
… own file - centralise the chatPage/editor/dialog/completions Update boilerplate in dispatch.go (forwardX returns (m, cmd); updateXCmd returns just cmd for batching) - move tab restore/persist/lookup logic from tui.go to tabs.go - extract copyToClipboard helper to deduplicate clipboard handlers - replace isErrTitleGenerating string comparison with errors.Is - inline persistSplitDiffView helper for the userconfig save
- editorname.FromEnv: capitalise the first rune (not byte) so editor binary names beginning with multi-byte UTF-8 characters survive the round-trip; add a regression test. - tui_exit_test.go: fix data race between the safety-net goroutine spawned by cleanupAll and subsequent tests by shrinking shutdownTimeout in neutralizeExitFunc, waiting for the goroutine to observe the no-op exitFunc, and removing t.Parallel() from tests that mutate the package-level exitFunc/shutdownTimeout. go test -race now passes for the whole pkg/tui tree. - tui_speak_test.go: drop the misleading containsErrorNotification helper and the unused fakeTranscriber.lastHandler/mu; assert the produced message is a notification.ShowMsg with TypeError instead. - tui_helpers_test.go: drop hand-rolled contains() helper; use strings.Contains.
trungutt
approved these changes
Apr 28, 2026
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.
Summary
This PR improves the TUI's testability and simplifies its code without removing any feature.
Testability
pkg/tui/internal/editornamepackage: hostsFromEnv(visual, editorEnv) string(previously duplicated verbatim inpkg/tui/tui.goandpkg/tui/page/chat/chat.go— the chat copy was dead code with the only test). Added a regression test for non-ASCII editor names.Transcriberinterface inpkg/tuiwith aWithTranscriberoption, decouplingappModelfrom the concrete*transcribe.Transcriber. Tests can now drive the speech handlers via a fake without audio hardware or network.parseCtrlNumberKeyhitTestLeanRegion,hitTestFullRegion— extracted as pure free functions)formatWindowTitle— extracted as a pure helper)handleStartSpeak,handleStopSpeak)Simplification
pkg/tui/dispatch.go: centralises theUpdate → type-assert → reassignboilerplate behindupdateChatCmd/updateEditorCmd/updateDialogCmd/updateCompletionsCmdand the matchingforwardXshortcuts. ~30 repetitions of the 5-line pattern intui.go/handlers.gocollapse to one-liners.pkg/tui/tabs.go: tab persistence and lookup logic (persistActiveTab,persistFreshTab,restoreTabs,persistedSessionID,findTabByPersistedID) lifted out oftui.go.copyToClipboard(text, successMsg)helper deduplicates the two clipboard handlers.isErrTitleGenerating(string-comparison) replaced witherrors.Is(err, app.ErrTitleGenerating).persistSplitDiffView(enabled bool)replaces an anonymous goroutine inhandleToggleSplitDiff.applyThemeChangedshrinks from 12 lines of boilerplate to a 3-linetea.Batch.Bug fixes (found during self-review)
editorname.FromEnv(carried over from the original duplicated copy): the fallback capitalisationstrings.ToUpper(baseName[:1]) + baseName[1:]slices by byte, not rune, mangling editor names that begin with multi-byte UTF-8 characters (e.g.édit→ garbled output). Now usesutf8.DecodeRuneInString+unicode.ToUpper. Regression test added.tui_exit_test.go(pre-existing, exposed bygo test -race):neutralizeExitFuncmutated the package-levelexitFuncwhile the safety-net goroutine spawned bycleanupAllstill read from it, and two parallel tests both mutated the global. Fix: shrinkshutdownTimeoutin tests, wait for the safety-net goroutine before restoring originals, and removet.Parallel()from tests that mutate package globals.go test -race ./pkg/tui/...now passes for the whole subtree.Stats
pkg/tui/tui.go: 2544 → 2301 lines (-243).pkg/tui/handlers.go: 674 → 660 lines.pkg/tui/dispatch.go(82 lines),pkg/tui/tabs.go(171 lines),pkg/tui/internal/editorname/(76 + 130 lines test).pkg/tui/tui_helpers_test.go(243 lines),pkg/tui/tui_speak_test.go(~130 lines).Validation
go build ./...✅go vet ./pkg/tui/...✅go test ./pkg/tui/...✅go test -race ./pkg/tui/...✅golangci-lint run ./pkg/tui/...✅ (0 issues)Assisted-By: docker-agent