v0.5.0 5fd5066

slider_grid_test.go RawHistoryFolder

1package ui
2
3import (
4	"math"
5	"testing"
6
7	"github.com/bnema/nefergui/internal/layout"
8)
9
10func TestSliderGridDecimalAndExtremeRanges(t *testing.T) {
11	for _, tc := range []struct {
12		name              string
13		v, min, max, step float64
14		want              float64
15	}{
16		{"decimal last stop", 0.3, 0, 0.3, 0.1, 0.30000000000000004},
17		{"decimal end", 1, 0, 1, 0.1, 1},
18		{"partial final step", 10, 0, 10, 3, 9},
19		{"overflowing span clamps only", 1e308, -math.MaxFloat64, math.MaxFloat64, 1e-300, 1e308},
20		{"sub-precision grid clamps only", 0.5, 0, 1, 1e-20, 0.5},
21	} {
22		if got := sliderGrid(tc.v, tc.min, tc.max, tc.step); math.Abs(got-tc.want) > 1e-12*math.Max(1, math.Abs(tc.want)) {
23			t.Errorf("%s: sliderGrid = %v, want %v", tc.name, got, tc.want)
24		}
25	}
26}
27
28func TestSliderGridAndNonfiniteValues(t *testing.T) {
29	r := newRuntime()
30	v := math.NaN()
31	changed := false
32	view := func(f *Frame) { changed = f.Root().Slider("level", &v, 1, 8, 2).Changed() }
33	r.Build(view)
34	if !changed || v != 1 {
35		t.Fatalf("NaN normalization: changed=%v v=%v", changed, v)
36	}
37	r.Redraw()
38	r.Build(view)
39	if changed {
40		t.Fatal("unchanged slider reported change")
41	}
42	v = math.Inf(1)
43	r.Redraw()
44	r.Build(view)
45	if !changed || v != 1 {
46		t.Fatalf("Inf normalization: %v %v", changed, v)
47	}
48	v = 4.1
49	r.Redraw()
50	r.Build(view)
51	if !changed || v != 5 {
52		t.Fatalf("off-grid normalization: %v %v", changed, v)
53	}
54	r.Queue(inputEvent{Target: r.Target(0), Kind: "slider-key", Text: "right"})
55	r.Build(view)
56	if !changed || v != 7 {
57		t.Fatalf("key step: %v %v", changed, v)
58	}
59	r.Queue(inputEvent{Target: r.Target(0), Kind: "slider-key", Text: "end"})
60	r.Build(view)
61	if changed || v != 7 {
62		t.Fatalf("end must remain on last grid stop: %v %v", changed, v)
63	}
64	r.Queue(inputEvent{Target: r.Target(0), Kind: "slider-pointer", X: 80, Track: layout.Rect{X: 0, W: 100}})
65	r.Build(view)
66	if changed || v != 7 {
67		t.Fatalf("drag grid: %v %v", changed, v)
68	}
69	r.Queue(inputEvent{Target: r.Target(0), Kind: "slider-pointer", X: 35, Track: layout.Rect{X: 0, W: 100}})
70	r.Build(view)
71	if !changed || v != 3 {
72		t.Fatalf("drag quantization: %v %v", changed, v)
73	}
74}

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 1

Tags 12

↑↓ moveenter openesc close