refactor(emulator): Fold mock terminal into vt package.#962
Conversation
📝 WalkthroughWalkthroughMigrates and consolidates the mock terminal API from the removed Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
demos/styles/styles_test.go (1)
43-49: Fix Attr field access: use Style.Attr() method instead of direct field access.Line 45 accesses
.Attras a direct field on the MockCell returned byGetCell(). However, theCellstruct (vt/emulate.go:123) does not expose anAttrfield. The attributes are accessible via theSfield (aStyleinterface) using theAttr()method.Change line 45 to:
if attr := mt.GetCell(vt.Coord{X: vt.Col(x), Y: vt.Row(y)}).S.Attr(); attr != lastAttr {The same issue affects
demos/hello/hello_test.goline 88, which also needs to call.S.Attr()instead of accessing a nonexistent.Attrfield.demos/hello/hello_test.go (1)
78-91: Update test to access style information through the S field.The test accesses
cell.Fg,cell.Bg, andcell.Attrfields that do not exist onvt.MockCell. TheMockCellstruct embedsCell(defined in vt/emulate.go:123-126), which has onlyC(content) andS(style) fields. TheSfield is of typeStyleinterface, which provides accessor methodsFg(),Bg(), andAttr().Update the comparisons to use:
cell.S.Fg()instead ofcell.Fgcell.S.Bg()instead ofcell.Bgcell.S.Attr()instead ofcell.AttrThis pattern is already used correctly in vt/mock_test.go (lines 86, 93, 96).
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
color_test.godemos/beep/beep_test.godemos/hello/hello_test.godemos/styles/styles_test.gomock/term.gotscreen_test.govt/mock.govt/mock_test.go
💤 Files with no reviewable changes (1)
- mock/term.go
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-12-18T02:50:48.847Z
Learnt from: gdamore
Repo: gdamore/tcell PR: 908
File: stdin_unix.go:128-155
Timestamp: 2025-12-18T02:50:48.847Z
Learning: In the tcell Tty interface implementations (stdin_unix.go, tty_unix.go, tty_win.go, tty_plan9.go), the caller is responsible for providing synchronization/mutual exclusion guarantees for method calls like NotifyResize. The Tty implementations themselves do not need internal locking for these methods, as documented in tty.go. The tscreen.go layer handles the synchronization.
Applied to files:
tscreen_test.govt/mock_test.godemos/styles/styles_test.govt/mock.go
📚 Learning: 2025-12-31T22:01:49.486Z
Learnt from: gdamore
Repo: gdamore/tcell PR: 959
File: vt/emulate.go:0-0
Timestamp: 2025-12-31T22:01:49.486Z
Learning: In vt/emulate.go, the autoWrap (pending wrap) flag behavior is directional: backward/leftward cursor movements always clear autoWrap because they move away from the right column, while forward movements may or may not clear it depending on the specific action. CHT (cursor forward tab) intentionally does not clear autoWrap, aligning with HT (horizontal tab) behavior.
Applied to files:
vt/mock_test.go
🧬 Code graph analysis (7)
tscreen_test.go (2)
vt/mock.go (3)
MockOpt(464-464)MockTerm(124-147)NewMockTerm(150-156)mock/term.go (4)
mt(110-113)NewMockTerm(150-156)mt(105-107)Tty(124-147)
demos/beep/beep_test.go (2)
vt/mock.go (1)
NewMockTerm(150-156)mock/term.go (7)
mt(110-113)mt(105-107)mt(86-88)mt(75-77)mt(36-38)mt(42-44)mt(68-72)
vt/mock_test.go (4)
vt/mock.go (2)
MockTerm(124-147)MockBackend(167-184)vt/coord.go (3)
Col(25-25)Row(22-22)Coord(28-31)vt/attr.go (13)
Attr(18-18)Plain(21-21)Bold(22-22)Dim(25-25)Underline(28-28)DoubleUnderline(33-33)CurlyUnderline(34-34)DottedUnderline(35-35)DashedUnderline(36-36)StrikeThrough(27-27)Reverse(24-24)Overline(29-29)Blink(23-23)vt/kbd.go (1)
KbdEvent(17-24)
demos/styles/styles_test.go (2)
vt/mock.go (1)
NewMockTerm(150-156)mock/term.go (2)
Tty(124-147)mt(110-113)
demos/hello/hello_test.go (2)
vt/mock.go (2)
NewMockTerm(150-156)MockOptColors(472-472)mock/term.go (3)
Tty(124-147)NewMockTerm(150-156)mt(110-113)
color_test.go (4)
tscreen_test.go (1)
NewMockScreen(72-89)vt/mock.go (1)
MockOptSize(467-467)mock/term.go (2)
mt(110-113)Tty(124-147)mock/term_test.go (1)
TestTitler(767-787)
vt/mock.go (6)
vt/emulate.go (1)
Emulator(36-68)vt/backend.go (1)
Backend(24-60)vt/coord.go (1)
Coord(28-31)vt/kbd.go (1)
KbdEvent(17-24)vt/mode.go (5)
PrivateMode(23-23)ModeStatus(64-64)ModeOn(68-68)ModeOff(69-69)PmShowCursor(30-30)vt/attr.go (1)
Attr(18-18)
🪛 GitHub Actions: linux
demos/hello/hello_test.go
[error] 82-82: Command failed: go test -coverpkg=github.com/gdamore/tcell/v3/... -covermode=count -coverprofile=coverage.txt ./...; demos/hello/hello_test.go:82:19: cell.Fg undefined (type vt.MockCell has no field or method Fg)
🪛 GitHub Actions: macos
demos/hello/hello_test.go
[error] 82-82: go test failed: demos/hello/hello_test.go:82:19: cell.Fg undefined (type vt.MockCell has no field or method Fg). Command: 'go test -coverpkg="github.com/gdamore/tcell/v3/..." -covermode=count -coverprofile="coverage.txt" ./...'
🪛 GitHub Actions: windows
demos/hello/hello_test.go
[error] 82-82: demos/hello/hello_test.go:82:19: cell.Fg undefined (type vt.MockCell has no field or method Fg)
🔇 Additional comments (17)
demos/hello/hello_test.go (1)
16-16: Migration to vt-based mock looks correct.The change from
mock.NewMockTermtovt.NewMockTerm(vt.MockOptColors(8))properly aligns with the new vt-based mock API.vt/mock.go (8)
15-22: Package migration completed correctly.The package declaration and imports are appropriate for the vt-based mock implementation.
24-156: Mock terminal implementation looks sound.The
mockTermimplementation correctly delegates to the backend and emulator. The Escape key delay (lines 98-101) is appropriately documented for sequence disambiguation.Based on learnings, the absence of internal locking in methods like
NotifyResizeis correct, as the caller (tscreen layer) provides synchronization guarantees.
158-184: MockCell and MockBackend interfaces are well-structured.The interface composition and Coord-based API provide good type safety. However, note that
MockCellembedsCell, and theCelltype must expose fields or methods for accessing foreground color, background color, and attributes to support existing test patterns (see critical issue in demos/hello/hello_test.go).
225-267: Cell update logic correctly handles content and styles.The
PutRuneandPutGraphememethods properly:
- Handle erasure when content is zero/empty
- Update both content (
C) and style (S) fields- Clear adjacent cells for wide characters
- Perform bounds checking via the
indexhelper
303-321: Color capability handling looks correct.The
pickColormethod appropriately validates colors against terminal capabilities and handles thecolor.Resetcase by returning the default color.
363-403: Resize and reset logic is correctly implemented.The
SetSizemethod properly:
- Initializes new cells with
BaseStyle- Preserves existing cell content within the new bounds
- Clips the cursor position
- Uses non-blocking notification for resize events
The
Resetmethod correctly restores default state including style, modes, and cursor position.
405-460: Blit implementation correctly handles overlapping regions.The blit logic properly:
- Clips source and destination to valid bounds
- Chooses forward or reverse copy direction based on overlap to prevent corruption
- Uses efficient index arithmetic in the inner loops
476-504: Mock backend initialization is correct.The
NewMockBackendconstructor properly:
- Sets reasonable defaults (80×24, 256 colors)
- Applies options before dependent initialization
- Initializes the style with default colors when color support is enabled
- Creates and initializes all cells with
BaseStyle- Sets up the mode map with appropriate defaults
demos/beep/beep_test.go (1)
14-14: Migration to vt-based mock is correct.The change from
mock.NewMockTerm()tovt.NewMockTerm()properly uses the new vt-based mock API.demos/styles/styles_test.go (1)
17-17: Migration to vt-based mock is correct.The change from
mock.NewMockTerm()tovt.NewMockTerm()properly uses the new vt-based mock API.color_test.go (2)
22-22: Import migration is correct.The change from importing
mocktovtaligns with the package refactoring.
55-55: MockOptSize usage updated correctly.The change from
mock.MockOptSizetovt.MockOptSizeproperly uses the type from the new location.tscreen_test.go (1)
22-22: LGTM! Clean refactoring to use vt package.The migration from
mocktovtpackage is correctly applied. The function signature, import, and constructor call are all consistently updated.Also applies to: 72-72, 78-78
vt/mock_test.go (3)
15-15: LGTM! Package change enables private state inspection.The change from external test (
package vt_test) to internal test (package vt) correctly aligns with the PR objective to allow tests to inspect private state of the vt package.
71-99: LGTM! Type references correctly updated.All type references are consistently updated to use local package types (removing
vt.prefix forKbdEvent,Coord,Col,Row,Attr, modifier constants, and key codes). The helper functions are correctly refactored to work with the local types.Also applies to: 489-596, 619-689
163-167: The project'sgo.modspecifies Go 1.24.0, which fully supports range-over-integer syntax (available since Go 1.23). No action required.
This will allow better testing code as tests can be written to inspect private state.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #962 +/- ##
==========================================
+ Coverage 70.47% 70.48% +0.01%
==========================================
Files 37 36 -1
Lines 3441 3439 -2
==========================================
- Hits 2425 2424 -1
+ Misses 871 870 -1
Partials 145 145 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
vt/mock.go (1)
95-102: Consider the test performance impact of the Escape delay.The 150ms sleep after each Escape key event could significantly slow down tests that simulate multiple Escape key presses. While the delay is necessary to disambiguate Escape from other sequences, consider whether this duration could be:
- Made configurable via a MockOpt
- Reduced if testing in a controlled environment where disambiguation timing is less critical
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
color_test.godemos/beep/beep_test.godemos/hello/hello_test.godemos/styles/styles_test.gomock/term.gotscreen_test.govt/mock.govt/mock_test.go
💤 Files with no reviewable changes (1)
- mock/term.go
🚧 Files skipped from review as they are similar to previous changes (2)
- color_test.go
- demos/styles/styles_test.go
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-12-31T22:01:49.486Z
Learnt from: gdamore
Repo: gdamore/tcell PR: 959
File: vt/emulate.go:0-0
Timestamp: 2025-12-31T22:01:49.486Z
Learning: In vt/emulate.go, the autoWrap (pending wrap) flag behavior is directional: backward/leftward cursor movements always clear autoWrap because they move away from the right column, while forward movements may or may not clear it depending on the specific action. CHT (cursor forward tab) intentionally does not clear autoWrap, aligning with HT (horizontal tab) behavior.
Applied to files:
vt/mock_test.go
📚 Learning: 2025-12-18T02:50:48.847Z
Learnt from: gdamore
Repo: gdamore/tcell PR: 908
File: stdin_unix.go:128-155
Timestamp: 2025-12-18T02:50:48.847Z
Learning: In the tcell Tty interface implementations (stdin_unix.go, tty_unix.go, tty_win.go, tty_plan9.go), the caller is responsible for providing synchronization/mutual exclusion guarantees for method calls like NotifyResize. The Tty implementations themselves do not need internal locking for these methods, as documented in tty.go. The tscreen.go layer handles the synchronization.
Applied to files:
vt/mock_test.govt/mock.gotscreen_test.go
🧬 Code graph analysis (5)
demos/beep/beep_test.go (3)
vt/mock.go (1)
NewMockTerm(150-156)mock/term.go (7)
mt(110-113)mt(105-107)mt(86-88)mt(75-77)mt(36-38)mt(42-44)mt(68-72)mock/term_test.go (3)
TestTitler(767-787)TestBell(206-222)TestAutoMargin(367-443)
demos/hello/hello_test.go (4)
vt/mock.go (2)
NewMockTerm(150-156)MockOptColors(472-472)vt/attr.go (1)
Attr(18-18)mock/term.go (2)
Tty(124-147)mt(86-88)mock/backend.go (1)
cells(55-70)
vt/mock_test.go (4)
vt/mock.go (2)
MockTerm(124-147)MockBackend(167-184)vt/coord.go (3)
Col(25-25)Row(22-22)Coord(28-31)vt/attr.go (14)
Attr(18-18)Plain(21-21)Bold(22-22)Dim(25-25)Italic(26-26)Underline(28-28)DoubleUnderline(33-33)CurlyUnderline(34-34)DottedUnderline(35-35)DashedUnderline(36-36)StrikeThrough(27-27)Reverse(24-24)Overline(29-29)Blink(23-23)vt/kbd.go (16)
KbdEvent(17-24)KcReturn(62-62)KcEsc(63-63)KcF1(193-193)KcF2(194-194)KcF3(195-195)KcF4(196-196)KcF5(197-197)KcF6(198-198)KcF7(199-199)KcF8(200-200)KcF9(201-201)KcF20(212-212)KcHelp(75-75)KcF15(207-207)KcMenu(70-70)
vt/mock.go (7)
vt/emulate.go (3)
Emulator(36-68)NewEmulator(131-152)Cell(123-126)vt/backend.go (3)
Resizer(92-95)Backend(24-60)Blitter(110-112)vt/coord.go (1)
Coord(28-31)vt/kbd.go (2)
KbdEvent(17-24)KcEsc(63-63)vt/mode.go (6)
PrivateMode(23-23)ModeStatus(64-64)ModeOn(68-68)ModeOff(69-69)PmShowCursor(30-30)PmGraphemeClusters(39-39)vt/attr.go (1)
Attr(18-18)mock/backend.go (2)
Backend(33-50)cells(55-70)
tscreen_test.go (1)
vt/mock.go (3)
MockOpt(464-464)MockTerm(124-147)NewMockTerm(150-156)
🔇 Additional comments (17)
demos/beep/beep_test.go (1)
14-14: LGTM!The migration from
mock.NewMockTerm()tovt.NewMockTerm()correctly reflects the consolidation of the mock terminal implementation into the vt package.demos/hello/hello_test.go (2)
16-16: LGTM!The migration to
vt.NewMockTerm(vt.MockOptColors(8))correctly uses the new vt-based mock API with the color option.
82-89: LGTM!The change from direct field access to accessor methods (
cell.S.Fg(),cell.S.Bg(),cell.S.Attr()) correctly adapts to the new MockCell structure where style information is accessed through theSfield's methods.tscreen_test.go (1)
72-72: LGTM!The function signature and implementation correctly migrated to use
vt.MockOptandvt.NewMockTerm, aligning with the consolidation of mock functionality into the vt package.Also applies to: 78-78
vt/mock.go (8)
149-156: LGTM!The
NewMockTermconstructor correctly initializes the mock terminal with a backend and emulator, and sets the terminal identification.
158-184: LGTM!The
MockCellstructure andMockBackendinterface are well-designed. The MockCell appropriately extends Cell with width information, and MockBackend cleanly combines Backend, Blitter, and mock-specific capabilities.
225-267: LGTM!The
PutRuneandPutGraphememethods correctly handle wide characters by clearing the adjacent cell when width is 2, preventing display corruption.
303-341: LGTM!The
pickColormethod properly validates colors against the terminal's color capability and handles thecolor.Resetspecial case to restore defaults. The color setter methods correctly use theWithFg/WithBg/WithAttrstyle builder pattern.
363-388: LGTM!The
SetSizemethod correctly handles terminal resizing:
- New cells are properly initialized with
BaseStyle- Content is copied from the old grid up to the minimum dimensions
- Cursor position is clamped to the new size
- Resize notification is non-blocking via select/default pattern
390-403: LGTM!The
Resetmethod comprehensively restores the terminal to its initial state, correctly handling style, colors, cursor position, and private modes.
405-460: LGTM!The
Blitmethod correctly handles cell region copying with:
- Proper clipping to visible source and destination boundaries
- Forward copy for non-overlapping regions
- Reverse copy for overlapping regions to prevent corruption
- Efficient indexing with gap calculation for row advancement
476-503: LGTM!The
NewMockBackendconstructor properly initializes all backend state:
- Sensible defaults (80x24, 256 colors, silver/black)
- Applies configuration options
- Initializes all cells with
BaseStyle- Sets default private modes (cursor shown, grapheme clusters off)
vt/mock_test.go (5)
71-99: LGTM!The test helper functions are correctly updated to use local types (
Col,Row,Coord,Attr) and style accessor methods (S.Attr(),S.Fg(),S.Bg()). The changes are consistent with the new mock API structure.
163-187: LGTM!The test correctly uses local types throughout, with the
range Row(3)andrange Col(5)iteration pattern and consistent use ofcheckAttrsandcheckContenthelpers.
360-427: LGTM!The
TestAutoMarginfunction is properly updated to useCoord{X: x, Y: y}for cell access and local types throughout. The automargin behavior tests remain comprehensive and correct.
489-609: LGTM!The keyboard event tests are comprehensively updated to use local
KbdEventtype and key code constants. The test coverage for legacy key protocol remains thorough, including function keys, modifiers, and special key combinations.
1020-1104: LGTM!The backend blit tests are properly updated to use local
CoordandAttrtypes. The tests maintain comprehensive coverage of both forward and reverse copy scenarios, ensuring overlapping region handling works correctly.
This will allow better testing code as tests can be written to inspect private state.
Summary by CodeRabbit
Refactor
Tests
✏️ Tip: You can customize this high-level summary in your review settings.