detached f2d166b

hdrcursor_test.go RawHistoryFolder

1package hdrcursor
2
3import (
4	"bytes"
5	"math"
6	"testing"
7)
8
9// vector is a 5×3 premultiplied BGRA image: alpha ramps up with one fully
10// transparent pixel (index 3).
11func vector() (pixels []byte, w, h int) {
12	w, h = 5, 3
13	pixels = make([]byte, w*h*4)
14	for i := range w * h {
15		a := byte(i * 255 / (w*h - 1))
16		if i == 3 {
17			a = 0
18		}
19		c := func(v int) byte { return byte(v * int(a) / 255) }
20		pixels[i*4], pixels[i*4+1], pixels[i*4+2], pixels[i*4+3] = c(i*37%256), c((i*91+20)%256), c((i*53+200)%256), a
21	}
22	return
23}
24
25// The conversion is byte-identical to the one the Vulkan renderer did
26// before it moved here (203 nits, cropped to 4×4).
27func TestConvertMatchesRecordedVector(t *testing.T) {
28	pixels, w, h := vector()
29	want := []byte{0x0, 0x0, 0x0, 0x0, 0x5, 0x7, 0x9, 0x12, 0xd, 0x13, 0xf, 0x24, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x31, 0x31, 0x5b, 0x3a, 0x1f, 0x20, 0x6d, 0x20, 0x39, 0x30, 0x7f, 0x33, 0x51, 0x46, 0x91, 0x4c, 0x58, 0x5f, 0xb6, 0x5f, 0x72, 0x5e, 0xc8, 0x6d, 0x4e, 0x4c, 0xda, 0x81, 0x75, 0x6c, 0xec}
30	var c Cache
31	if got := c.Convert(pixels, w, h, 4, 203); !bytes.Equal(got, want) {
32		t.Fatalf("converted\n got %#v\nwant %#v", got, want)
33	}
34}
35
36func TestPixelWhite(t *testing.T) {
37	p := []byte{255, 255, 255, 255}
38	Pixel(p, 203)
39	if p[3] != 255 || math.Abs(float64(p[0])-148) > 1 || p[0] != p[1] || p[1] != p[2] {
40		t.Fatalf("cursor white: %v", p)
41	}
42	if PQEncode(0) != 0 || math.Abs(PQEncode(10000)-1) > 1e-9 {
43		t.Fatal("PQ endpoints")
44	}
45}
46
47func TestCacheKeepsLastConversion(t *testing.T) {
48	var c Cache
49	px := []byte{255, 255, 255, 255}
50	a := c.Convert(px, 1, 1, 64, 203)
51	if c.Len() != 4 || a[0] != 148 {
52		t.Fatalf("len %d pixel %v", c.Len(), a)
53	}
54	first := c.Key()
55	if b := c.Convert(px, 1, 1, 64, 203); &a[0] != &b[0] {
56		t.Fatal("same image converted again")
57	}
58	for i := range 12 {
59		v := byte(i * 18)
60		c.Convert([]byte{v, v, v, 255}, 1, 1, 64, 203)
61		if c.Len() != 4 {
62			t.Fatalf("cache grew after image %d: %d", i, c.Len())
63		}
64	}
65	if c.Key() == first {
66		t.Fatal("conversion not replaced")
67	}
68	c.Convert(px, 1, 1, 64, 100)
69	if c.Key() == first {
70		t.Fatal("nits not part of the key")
71	}
72	c.Reset()
73	if c.Len() != 0 || c.Key() != [32]byte{} {
74		t.Fatal("reset left a conversion")
75	}
76}

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 23

Tags 10

↑↓ moveenter openesc close