detached 87105ad

test(daemon): cover restored terminal capability fallback

commit
87105adca8920d2c5f15767fc8ebb6a49bdd4885
author
brice · · 2026-08-02 11:14 UTC
parent
604afe4
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +60 -25
M internal/usecase/daemon/snapshot_restore_test.go +60 -25
@@ -306,34 +306,69 @@ func TestSnapshotRuntimeRestorePreservesConsumedAndExpelledPaneLayout(t *testing
306306 }
307307
308308 func TestSnapshotRestoreUsesDaemonTerminalCapabilities(t *testing.T) {
309- snapshot := restoreAcceptanceSession(t, "restored")
310- pty, release := newBlockingPTY(t)
311- defer release()
312-
313- var gotEnv []string
314- factory := portsmocks.NewMockPTYFactory(t)
315- factory.EXPECT().Open(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
316- RunAndReturn(func(_ context.Context, _ string, _ []string, env []string, _ string, _ domain.Size) (ports.PTY, error) {
317- gotEnv = append([]string(nil), env...)
318- return pty, nil
319- }).Once()
320-
321- d := newTestDaemon(t, factory, stubClock{})
322- d.baseEnv = []string{
323- "TERM=xterm-kitty",
324- "COLORTERM=truecolor",
325- "XDG_RUNTIME_DIR=/run/user/1000",
326- "WAYLAND_DISPLAY=wayland-1",
309+ tests := []struct {
310+ name string
311+ baseEnv []string
312+ wantTerm string
313+ wantColorTerm string
314+ notWantEntries []string
315+ }{
316+ {
317+ name: "truecolor",
318+ baseEnv: []string{
319+ "TERM=xterm-kitty",
320+ "COLORTERM=truecolor",
321+ "XDG_RUNTIME_DIR=/run/user/1000",
322+ "WAYLAND_DISPLAY=wayland-1",
323+ },
324+ wantTerm: "TERM=xterm-direct",
325+ wantColorTerm: "COLORTERM=truecolor",
326+ notWantEntries: []string{"TERM=xterm-kitty"},
327+ },
328+ {
329+ name: "256-color fallback",
330+ baseEnv: []string{
331+ "TERM=xterm-256color",
332+ "COLORTERM=old",
333+ "XDG_RUNTIME_DIR=/run/user/1000",
334+ "WAYLAND_DISPLAY=wayland-1",
335+ },
336+ wantTerm: "TERM=xterm-256color",
337+ notWantEntries: []string{"COLORTERM=old", "COLORTERM=truecolor"},
338+ },
327339 }
328340
329- tabs, err := d.restoreSnapshotTabs(context.Background(), d.serveCtx, snapshot)
330- require.NoError(t, err)
331- defer closeRestoredTabs(tabs)
341+ for _, tt := range tests {
342+ t.Run(tt.name, func(t *testing.T) {
343+ snapshot := restoreAcceptanceSession(t, "restored")
344+ pty, release := newBlockingPTY(t)
345+ defer release()
346+
347+ var gotEnv []string
348+ factory := portsmocks.NewMockPTYFactory(t)
349+ factory.EXPECT().Open(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
350+ RunAndReturn(func(_ context.Context, _ string, _ []string, env []string, _ string, _ domain.Size) (ports.PTY, error) {
351+ gotEnv = append([]string(nil), env...)
352+ return pty, nil
353+ }).Once()
354+
355+ d := newTestDaemon(t, factory, stubClock{})
356+ d.baseEnv = tt.baseEnv
357+ tabs, err := d.restoreSnapshotTabs(context.Background(), d.serveCtx, snapshot)
358+ require.NoError(t, err)
359+ defer closeRestoredTabs(tabs)
332360
333- require.Contains(t, gotEnv, "TERM=xterm-direct")
334- require.Contains(t, gotEnv, "COLORTERM=truecolor")
335- require.Contains(t, gotEnv, "XDG_RUNTIME_DIR=/run/user/1000")
336- require.Contains(t, gotEnv, "WAYLAND_DISPLAY=wayland-1")
361+ require.Contains(t, gotEnv, tt.wantTerm)
362+ if tt.wantColorTerm != "" {
363+ require.Contains(t, gotEnv, tt.wantColorTerm)
364+ }
365+ require.Contains(t, gotEnv, "XDG_RUNTIME_DIR=/run/user/1000")
366+ require.Contains(t, gotEnv, "WAYLAND_DISPLAY=wayland-1")
367+ for _, notWant := range tt.notWantEntries {
368+ require.NotContains(t, gotEnv, notWant)
369+ }
370+ })
371+ }
337372 }
338373
339374 func captureConsumedAndExpelledPaneLayout(t *testing.T) paneLayoutSnapshotFixture {
@@ -306,34 +306,69 @@ func TestSnapshotRuntimeRestorePreservesConsumedAndExpelledPaneLayout(t *testing
306 }306 }
307 307
308 func TestSnapshotRestoreUsesDaemonTerminalCapabilities(t *testing.T) {308 func TestSnapshotRestoreUsesDaemonTerminalCapabilities(t *testing.T) {
309- snapshot := restoreAcceptanceSession(t, "restored")309+ tests := []struct {
310- pty, release := newBlockingPTY(t)310+ name string
311- defer release()311+ baseEnv []string
312-312+ wantTerm string
313- var gotEnv []string313+ wantColorTerm string
314- factory := portsmocks.NewMockPTYFactory(t)314+ notWantEntries []string
315- factory.EXPECT().Open(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).315+ }{
316- RunAndReturn(func(_ context.Context, _ string, _ []string, env []string, _ string, _ domain.Size) (ports.PTY, error) {316+ {
317- gotEnv = append([]string(nil), env...)317+ name: "truecolor",
318- return pty, nil318+ baseEnv: []string{
319- }).Once()319+ "TERM=xterm-kitty",
320-320+ "COLORTERM=truecolor",
321- d := newTestDaemon(t, factory, stubClock{})321+ "XDG_RUNTIME_DIR=/run/user/1000",
322- d.baseEnv = []string{322+ "WAYLAND_DISPLAY=wayland-1",
323- "TERM=xterm-kitty",323+ },
324- "COLORTERM=truecolor",324+ wantTerm: "TERM=xterm-direct",
325- "XDG_RUNTIME_DIR=/run/user/1000",325+ wantColorTerm: "COLORTERM=truecolor",
326- "WAYLAND_DISPLAY=wayland-1",326+ notWantEntries: []string{"TERM=xterm-kitty"},
327+ },
328+ {
329+ name: "256-color fallback",
330+ baseEnv: []string{
331+ "TERM=xterm-256color",
332+ "COLORTERM=old",
333+ "XDG_RUNTIME_DIR=/run/user/1000",
334+ "WAYLAND_DISPLAY=wayland-1",
335+ },
336+ wantTerm: "TERM=xterm-256color",
337+ notWantEntries: []string{"COLORTERM=old", "COLORTERM=truecolor"},
338+ },
327 }339 }
328 340
329- tabs, err := d.restoreSnapshotTabs(context.Background(), d.serveCtx, snapshot)341+ for _, tt := range tests {
330- require.NoError(t, err)342+ t.Run(tt.name, func(t *testing.T) {
331- defer closeRestoredTabs(tabs)343+ snapshot := restoreAcceptanceSession(t, "restored")
344+ pty, release := newBlockingPTY(t)
345+ defer release()
346+
347+ var gotEnv []string
348+ factory := portsmocks.NewMockPTYFactory(t)
349+ factory.EXPECT().Open(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
350+ RunAndReturn(func(_ context.Context, _ string, _ []string, env []string, _ string, _ domain.Size) (ports.PTY, error) {
351+ gotEnv = append([]string(nil), env...)
352+ return pty, nil
353+ }).Once()
354+
355+ d := newTestDaemon(t, factory, stubClock{})
356+ d.baseEnv = tt.baseEnv
357+ tabs, err := d.restoreSnapshotTabs(context.Background(), d.serveCtx, snapshot)
358+ require.NoError(t, err)
359+ defer closeRestoredTabs(tabs)
332 360
333- require.Contains(t, gotEnv, "TERM=xterm-direct")361+ require.Contains(t, gotEnv, tt.wantTerm)
334- require.Contains(t, gotEnv, "COLORTERM=truecolor")362+ if tt.wantColorTerm != "" {
335- require.Contains(t, gotEnv, "XDG_RUNTIME_DIR=/run/user/1000")363+ require.Contains(t, gotEnv, tt.wantColorTerm)
336- require.Contains(t, gotEnv, "WAYLAND_DISPLAY=wayland-1")364+ }
365+ require.Contains(t, gotEnv, "XDG_RUNTIME_DIR=/run/user/1000")
366+ require.Contains(t, gotEnv, "WAYLAND_DISPLAY=wayland-1")
367+ for _, notWant := range tt.notWantEntries {
368+ require.NotContains(t, gotEnv, notWant)
369+ }
370+ })
371+ }
337 }372 }
338 373
339 func captureConsumedAndExpelledPaneLayout(t *testing.T) paneLayoutSnapshotFixture {374 func captureConsumedAndExpelledPaneLayout(t *testing.T) paneLayoutSnapshotFixture {

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