detached d2bbb2e

test(picker): pin the starting selection via table data, not a name check

commit
d2bbb2eab47c0a6056ef8903712b8b7f552cbf3c
author
brice · · 2026-07-29 14:43 UTC
parent
5720a2c
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +12 -7
M internal/usecase/picker/model_test.go +12 -7
@@ -417,7 +417,11 @@ func TestSelectNearestRow(t *testing.T) {
417417 name string
418418 idx int
419419 cfg SelectionConfig
420- want domain.SessionID
420+ // wantStart, when set, pins the selection New produced before
421+ // SelectNearestRow runs, so a case cannot silently degrade into one a
422+ // no-op implementation would also pass.
423+ wantStart domain.SessionID
424+ want domain.SessionID
421425 }{
422426 {name: "exact selectable row", idx: 3, cfg: SelectionConfig{Mode: SelectNavigationTab}, want: "b"},
423427 {name: "header row snaps to its tab", idx: 2, cfg: SelectionConfig{Mode: SelectNavigationTab}, want: "b"},
@@ -427,20 +431,21 @@ func TestSelectNearestRow(t *testing.T) {
427431 // would leave the selection on "c" and this case would fail; the
428432 // plain SelectNavigationTab config used above starts on "a" already,
429433 // which can't tell a real clamp-to-first from a no-op.
430- name: "negative clamps to first selectable",
431- idx: -2,
432- cfg: SelectionConfig{Mode: SelectNavigationTab, Current: SourceFilter{Session: "c", TabID: "tc"}},
433- want: "a",
434+ name: "negative clamps to first selectable",
435+ idx: -2,
436+ cfg: SelectionConfig{Mode: SelectNavigationTab, Current: SourceFilter{Session: "c", TabID: "tc"}},
437+ wantStart: "c",
438+ want: "a",
434439 },
435440 {name: "last row is a tab and stays put", idx: 5, cfg: SelectionConfig{Mode: SelectNavigationTab}, want: "c"},
436441 }
437442 for _, tc := range tests {
438443 t.Run(tc.name, func(t *testing.T) {
439444 m := New(sessions, tc.cfg)
440- if tc.name == "negative clamps to first selectable" {
445+ if tc.wantStart != "" {
441446 pre, ok := m.Selected()
442447 require.True(t, ok)
443- require.Equal(t, domain.SessionID("c"), pre.Session, "guard: starting selection must not already be the expected result")
448+ require.Equal(t, tc.wantStart, pre.Session, "guard: starting selection must not already be the expected result")
444449 }
445450 m.SelectNearestRow(tc.idx)
446451 target, ok := m.Selected()
@@ -417,7 +417,11 @@ func TestSelectNearestRow(t *testing.T) {
417 name string417 name string
418 idx int418 idx int
419 cfg SelectionConfig419 cfg SelectionConfig
420- want domain.SessionID420+ // wantStart, when set, pins the selection New produced before
421+ // SelectNearestRow runs, so a case cannot silently degrade into one a
422+ // no-op implementation would also pass.
423+ wantStart domain.SessionID
424+ want domain.SessionID
421 }{425 }{
422 {name: "exact selectable row", idx: 3, cfg: SelectionConfig{Mode: SelectNavigationTab}, want: "b"},426 {name: "exact selectable row", idx: 3, cfg: SelectionConfig{Mode: SelectNavigationTab}, want: "b"},
423 {name: "header row snaps to its tab", idx: 2, cfg: SelectionConfig{Mode: SelectNavigationTab}, want: "b"},427 {name: "header row snaps to its tab", idx: 2, cfg: SelectionConfig{Mode: SelectNavigationTab}, want: "b"},
@@ -427,20 +431,21 @@ func TestSelectNearestRow(t *testing.T) {
427 // would leave the selection on "c" and this case would fail; the431 // would leave the selection on "c" and this case would fail; the
428 // plain SelectNavigationTab config used above starts on "a" already,432 // plain SelectNavigationTab config used above starts on "a" already,
429 // which can't tell a real clamp-to-first from a no-op.433 // which can't tell a real clamp-to-first from a no-op.
430- name: "negative clamps to first selectable",434+ name: "negative clamps to first selectable",
431- idx: -2,435+ idx: -2,
432- cfg: SelectionConfig{Mode: SelectNavigationTab, Current: SourceFilter{Session: "c", TabID: "tc"}},436+ cfg: SelectionConfig{Mode: SelectNavigationTab, Current: SourceFilter{Session: "c", TabID: "tc"}},
433- want: "a",437+ wantStart: "c",
438+ want: "a",
434 },439 },
435 {name: "last row is a tab and stays put", idx: 5, cfg: SelectionConfig{Mode: SelectNavigationTab}, want: "c"},440 {name: "last row is a tab and stays put", idx: 5, cfg: SelectionConfig{Mode: SelectNavigationTab}, want: "c"},
436 }441 }
437 for _, tc := range tests {442 for _, tc := range tests {
438 t.Run(tc.name, func(t *testing.T) {443 t.Run(tc.name, func(t *testing.T) {
439 m := New(sessions, tc.cfg)444 m := New(sessions, tc.cfg)
440- if tc.name == "negative clamps to first selectable" {445+ if tc.wantStart != "" {
441 pre, ok := m.Selected()446 pre, ok := m.Selected()
442 require.True(t, ok)447 require.True(t, ok)
443- require.Equal(t, domain.SessionID("c"), pre.Session, "guard: starting selection must not already be the expected result")448+ require.Equal(t, tc.wantStart, pre.Session, "guard: starting selection must not already be the expected result")
444 }449 }
445 m.SelectNearestRow(tc.idx)450 m.SelectNearestRow(tc.idx)
446 target, ok := m.Selected()451 target, ok := m.Selected()

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