detached ac01c75

test(picker): keep preview regression lightweight

commit
ac01c756796a7123f783efbd970ccc178e4113b4
author
brice · · 2026-07-14 12:33 UTC
parent
cfff95a
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +1 -50
M internal/usecase/daemon/picker_test.go +1 -50
@@ -2,7 +2,6 @@ package daemon
22
33 import (
44 "context"
5- "runtime"
65 "strings"
76 "testing"
87 "time"
@@ -638,15 +637,11 @@ func TestCaptureOverlayLayersResizeRecomposesPickerWithoutStalePreview(t *testin
638637 }
639638 }
640639
641-func TestPickerPreviewAllocationsAreIndependentOfTenThousandScrollbackRows(t *testing.T) {
642- empty := newPickerPreviewTabWithHistoryRows(0)
640+func TestPickerPreviewContainsOnlyVisibleFrameRowsWithLargeScrollback(t *testing.T) {
643641 withScrollback := newPickerPreviewTabWithHistoryRows(10_000)
644- require.Zero(t, empty.focusedPane().screen.History().Len())
645642 require.Equal(t, 10_000, withScrollback.focusedPane().screen.History().Len())
646643
647644 preview := snapshotPickerPreview(withScrollback)
648- emptyPreview := snapshotPickerPreview(empty)
649- require.Equal(t, emptyPreview, preview, "identical visible tabs must produce identical previews")
650645 require.Equal(t, 10, preview.Width)
651646 require.Equal(t, 3, preview.Height)
652647 require.Len(t, preview.Rows, preview.Height)
@@ -665,20 +660,6 @@ func TestPickerPreviewAllocationsAreIndependentOfTenThousandScrollbackRows(t *te
665660 }(), "\n")
666661 require.Contains(t, got, "NOW")
667662 require.NotContains(t, got, "history-only-marker")
668-
669- emptyResult := benchmarkPickerPreview(empty, snapshotPickerPreview)
670- scrollbackResult := benchmarkPickerPreview(withScrollback, snapshotPickerPreview)
671- require.Equal(t, emptyResult.AllocsPerOp(), scrollbackResult.AllocsPerOp(), "preview allocations must not depend on retained scrollback")
672- require.Equal(t, emptyResult.AllocedBytesPerOp(), scrollbackResult.AllocedBytesPerOp(), "preview allocated bytes must not depend on retained scrollback")
673-
674- // The local seam deliberately clones every history row. Its larger result
675- // demonstrates that the allocation assertion would fail if preview capture
676- // regressed to copying scrollback, without changing production code to make
677- // this test red.
678- cloningEmptyResult := benchmarkPickerPreview(empty, snapshotPickerPreviewWithClonedHistoryForTest)
679- cloningScrollbackResult := benchmarkPickerPreview(withScrollback, snapshotPickerPreviewWithClonedHistoryForTest)
680- require.Greater(t, cloningScrollbackResult.AllocsPerOp(), cloningEmptyResult.AllocsPerOp())
681- require.Greater(t, cloningScrollbackResult.AllocedBytesPerOp(), cloningEmptyResult.AllocedBytesPerOp())
682663 }
683664
684665 func newPickerPreviewTabWithHistoryRows(historyRows int) *tab {
@@ -691,36 +672,6 @@ func newPickerPreviewTabWithHistoryRows(historyRows int) *tab {
691672 return tb
692673 }
693674
694-func benchmarkPickerPreview(tb *tab, snapshot func(*tab) picker.Preview) testing.BenchmarkResult {
695- return testing.Benchmark(func(b *testing.B) {
696- b.ReportAllocs()
697- for range b.N {
698- runtime.KeepAlive(snapshot(tb))
699- }
700- })
701-}
702-
703-func snapshotPickerPreviewWithClonedHistoryForTest(tb *tab) picker.Preview {
704- tb.mu.Lock()
705- p := tb.focusedPane()
706- if p == nil {
707- tb.mu.Unlock()
708- return picker.Preview{}
709- }
710- p.mu.Lock()
711- history := p.screen.History().View()
712- p.mu.Unlock()
713- tb.mu.Unlock()
714-
715- var cloned [][]renderer.Cell
716- history.Range(func(row []renderer.Cell) bool {
717- cloned = append(cloned, append([]renderer.Cell(nil), row...))
718- return true
719- })
720- runtime.KeepAlive(cloned)
721- return snapshotPickerPreview(tb)
722-}
723-
724675 func TestPickerPreviewSinglePaneSnapshotsFocusedPane(t *testing.T) {
725676 tb := newTab(nil, domain.Size{Cols: 10, Rows: 3})
726677 p := tb.focusedPane()
@@ -2,7 +2,6 @@ package daemon
2 2
3 import (3 import (
4 "context"4 "context"
5- "runtime"
6 "strings"5 "strings"
7 "testing"6 "testing"
8 "time"7 "time"
@@ -638,15 +637,11 @@ func TestCaptureOverlayLayersResizeRecomposesPickerWithoutStalePreview(t *testin
638 }637 }
639 }638 }
640 639
641-func TestPickerPreviewAllocationsAreIndependentOfTenThousandScrollbackRows(t *testing.T) {640+func TestPickerPreviewContainsOnlyVisibleFrameRowsWithLargeScrollback(t *testing.T) {
642- empty := newPickerPreviewTabWithHistoryRows(0)
643 withScrollback := newPickerPreviewTabWithHistoryRows(10_000)641 withScrollback := newPickerPreviewTabWithHistoryRows(10_000)
644- require.Zero(t, empty.focusedPane().screen.History().Len())
645 require.Equal(t, 10_000, withScrollback.focusedPane().screen.History().Len())642 require.Equal(t, 10_000, withScrollback.focusedPane().screen.History().Len())
646 643
647 preview := snapshotPickerPreview(withScrollback)644 preview := snapshotPickerPreview(withScrollback)
648- emptyPreview := snapshotPickerPreview(empty)
649- require.Equal(t, emptyPreview, preview, "identical visible tabs must produce identical previews")
650 require.Equal(t, 10, preview.Width)645 require.Equal(t, 10, preview.Width)
651 require.Equal(t, 3, preview.Height)646 require.Equal(t, 3, preview.Height)
652 require.Len(t, preview.Rows, preview.Height)647 require.Len(t, preview.Rows, preview.Height)
@@ -665,20 +660,6 @@ func TestPickerPreviewAllocationsAreIndependentOfTenThousandScrollbackRows(t *te
665 }(), "\n")660 }(), "\n")
666 require.Contains(t, got, "NOW")661 require.Contains(t, got, "NOW")
667 require.NotContains(t, got, "history-only-marker")662 require.NotContains(t, got, "history-only-marker")
668-
669- emptyResult := benchmarkPickerPreview(empty, snapshotPickerPreview)
670- scrollbackResult := benchmarkPickerPreview(withScrollback, snapshotPickerPreview)
671- require.Equal(t, emptyResult.AllocsPerOp(), scrollbackResult.AllocsPerOp(), "preview allocations must not depend on retained scrollback")
672- require.Equal(t, emptyResult.AllocedBytesPerOp(), scrollbackResult.AllocedBytesPerOp(), "preview allocated bytes must not depend on retained scrollback")
673-
674- // The local seam deliberately clones every history row. Its larger result
675- // demonstrates that the allocation assertion would fail if preview capture
676- // regressed to copying scrollback, without changing production code to make
677- // this test red.
678- cloningEmptyResult := benchmarkPickerPreview(empty, snapshotPickerPreviewWithClonedHistoryForTest)
679- cloningScrollbackResult := benchmarkPickerPreview(withScrollback, snapshotPickerPreviewWithClonedHistoryForTest)
680- require.Greater(t, cloningScrollbackResult.AllocsPerOp(), cloningEmptyResult.AllocsPerOp())
681- require.Greater(t, cloningScrollbackResult.AllocedBytesPerOp(), cloningEmptyResult.AllocedBytesPerOp())
682 }663 }
683 664
684 func newPickerPreviewTabWithHistoryRows(historyRows int) *tab {665 func newPickerPreviewTabWithHistoryRows(historyRows int) *tab {
@@ -691,36 +672,6 @@ func newPickerPreviewTabWithHistoryRows(historyRows int) *tab {
691 return tb672 return tb
692 }673 }
693 674
694-func benchmarkPickerPreview(tb *tab, snapshot func(*tab) picker.Preview) testing.BenchmarkResult {
695- return testing.Benchmark(func(b *testing.B) {
696- b.ReportAllocs()
697- for range b.N {
698- runtime.KeepAlive(snapshot(tb))
699- }
700- })
701-}
702-
703-func snapshotPickerPreviewWithClonedHistoryForTest(tb *tab) picker.Preview {
704- tb.mu.Lock()
705- p := tb.focusedPane()
706- if p == nil {
707- tb.mu.Unlock()
708- return picker.Preview{}
709- }
710- p.mu.Lock()
711- history := p.screen.History().View()
712- p.mu.Unlock()
713- tb.mu.Unlock()
714-
715- var cloned [][]renderer.Cell
716- history.Range(func(row []renderer.Cell) bool {
717- cloned = append(cloned, append([]renderer.Cell(nil), row...))
718- return true
719- })
720- runtime.KeepAlive(cloned)
721- return snapshotPickerPreview(tb)
722-}
723-
724 func TestPickerPreviewSinglePaneSnapshotsFocusedPane(t *testing.T) {675 func TestPickerPreviewSinglePaneSnapshotsFocusedPane(t *testing.T) {
725 tb := newTab(nil, domain.Size{Cols: 10, Rows: 3})676 tb := newTab(nil, domain.Size{Cols: 10, Rows: 3})
726 p := tb.focusedPane()677 p := tb.focusedPane()

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close