v0.6.1 3d41bc5

smoke_test.go RawHistoryFolder

1package selection
2
3import (
4	"bufio"
5	"context"
6	"fmt"
7	"os"
8	"strconv"
9	"strings"
10	"testing"
11	"time"
12
13	"github.com/stretchr/testify/assert"
14	"github.com/stretchr/testify/require"
15
16	"github.com/bnema/nefercap/internal/ports"
17)
18
19// TestSmokeSelect opens the real overlays. It needs a Wayland compositor with
20// layer-shell and Vulkan plus an input driver, so it runs only when
21// NEFERCAP_SELECTION_SMOKE names the expected result: "region" (on the first
22// output), "monitor" (whole monitor of output number NEFERCAP_SELECTION_WANT,
23// default 1) or "abort". NEFERCAP_SELECTION_OUTPUTS lists output names,
24// comma-separated; output IDs are their 1-based positions.
25func TestSmokeSelect(t *testing.T) {
26	want := os.Getenv("NEFERCAP_SELECTION_SMOKE")
27	if want == "" {
28		t.Skip("set NEFERCAP_SELECTION_SMOKE=region|monitor|abort on a Wayland session")
29	}
30	var outs []ports.Output
31	for i, name := range strings.Split(os.Getenv("NEFERCAP_SELECTION_OUTPUTS"), ",") {
32		outs = append(outs, ports.Output{ID: uint32(i + 1), Name: name})
33	}
34	ctx, cancel := context.WithTimeout(context.Background(), 40*time.Second)
35	defer cancel()
36	peak := samplePeakRSS(ctx)
37	sel, ok, err := New(ports.Record, ports.VideoSettings{}, nil, false).Select(ctx, outs)
38	cancel()
39	fmt.Printf("SMOKE outputs=%d peak_rss_kib=%d\n", len(outs), <-peak)
40	require.NoError(t, err)
41	switch want {
42	case "abort":
43		assert.False(t, ok)
44	case "monitor":
45		n, _ := strconv.Atoi(os.Getenv("NEFERCAP_SELECTION_WANT"))
46		n = max(n, 1)
47		require.True(t, ok)
48		assert.Equal(t, ports.Target{OutputID: uint32(n)}, sel.Target)
49		assert.Equal(t, DefaultFPS, sel.Video.FPS)
50	case "region":
51		require.True(t, ok)
52		assert.Equal(t, ports.Target{OutputID: 1, Region: ports.Region{X: 100, Y: 80, Width: 200, Height: 120}}, sel.Target)
53	}
54}
55
56// samplePeakRSS reports the highest VmRSS of this process seen until ctx ends.
57func samplePeakRSS(ctx context.Context) <-chan int {
58	out := make(chan int, 1)
59	go func() {
60		peak := 0
61		for t := time.NewTicker(50 * time.Millisecond); ; {
62			select {
63			case <-ctx.Done():
64				out <- peak
65				return
66			case <-t.C:
67				peak = max(peak, vmRSS())
68			}
69		}
70	}()
71	return out
72}
73
74func vmRSS() int {
75	f, err := os.Open("/proc/self/status")
76	if err != nil {
77		return 0
78	}
79	defer f.Close()
80	sc := bufio.NewScanner(f)
81	for sc.Scan() {
82		if v, ok := strings.CutPrefix(sc.Text(), "VmRSS:"); ok {
83			n, _ := strconv.Atoi(strings.Fields(v)[0])
84			return n
85		}
86	}
87	return 0
88}

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 2

Tags 9

↑↓ moveenter openesc close