v0.1.0 602baa7

values_test.go RawHistoryFolder

1package xturbo_test
2
3import (
4	"bytes"
5	"encoding/binary"
6	"testing"
7
8	"bnema.dev/xturbo"
9	"bnema.dev/xturbo/internal/xtest"
10	"bnema.dev/xturbo/render"
11	"bnema.dev/xturbo/xproto"
12)
13
14func TestValueRequestGoldens(t *testing.T) {
15	for _, name := range []string{"xproto/ConfigureWindow", "xproto/ConfigureWindowSparse", "xproto/ConfigureWindowAll", "xproto/CreateWindow", "xproto/ChangeWindowAttributes", "render/CreatePicture"} {
16		t.Run(name, func(t *testing.T) {
17			want, err := xtest.LoadHex("testdata/golden/" + name + ".req.hex")
18			if err != nil {
19				t.Fatal(err)
20			}
21			u32 := func(off int) uint32 { return binary.LittleEndian.Uint32(want[off:]) }
22			b := xturbo.NewBuf(0)
23			var seq xturbo.Seq
24			switch name {
25			case "xproto/ConfigureWindow":
26				seq = xproto.ConfigureWindow(b, xproto.Window(u32(4)), &xproto.ConfigureWindowValues{})
27			case "xproto/ConfigureWindowSparse":
28				var v xproto.ConfigureWindowValues
29				if v.SetStackMode(xproto.StackModeAbove).SetWidth(80).SetX(-7) != &v {
30					t.Fatal("setter chaining")
31				}
32				seq = xproto.ConfigureWindow(b, xproto.Window(u32(4)), &v)
33			case "xproto/ConfigureWindowAll":
34				var v xproto.ConfigureWindowValues
35				v.SetStackMode(xproto.StackModeAbove).SetSibling(xproto.Window(u32(32))).SetBorderWidth(2).SetHeight(72).SetWidth(96).SetY(9).SetX(-3)
36				seq = xproto.ConfigureWindow(b, xproto.Window(u32(4)), &v)
37			case "xproto/CreateWindow":
38				var v xproto.CreateWindowValues
39				v.SetSaveUnder(false).SetOverrideRedirect(true).SetBackgroundPixel(0x123456)
40				seq = xproto.CreateWindow(b, 0, xproto.Window(u32(4)), xproto.Window(u32(8)), 0, 0, 64, 48, 0, xproto.WindowClassInputOutput, 0, &v)
41			case "xproto/ChangeWindowAttributes":
42				var v xproto.ChangeWindowAttributesValues
43				v.SetSaveUnder(true).SetOverrideRedirect(false)
44				seq = xproto.ChangeWindowAttributes(b, xproto.Window(u32(4)), &v)
45			case "render/CreatePicture":
46				var ext xturbo.ExtTable
47				ext.Set(xturbo.ExtRender, want[0], 0, 0)
48				b.Ext = &ext
49				var v render.CreatePictureValues
50				v.SetClipyorigin(7).SetClipxorigin(-5).SetRepeat(render.RepeatNormal)
51				seq = render.CreatePicture(b, render.Picture(u32(4)), xproto.Drawable(u32(8)), render.Pictformat(u32(12)), &v)
52			}
53			if seq != 1 || b.Err() != nil {
54				t.Fatalf("seq=%d err=%v", seq, b.Err())
55			}
56			if !bytes.Equal(b.Bytes(), want) {
57				t.Fatalf("got %x want %x", b.Bytes(), want)
58			}
59		})
60	}
61}
62
63func TestAllocValueRequests(t *testing.T) {
64	b := xturbo.NewBuf(0)
65	var ext xturbo.ExtTable
66	ext.Set(xturbo.ExtRender, 139, 0, 0)
67	b.Ext = &ext
68	var v xproto.ConfigureWindowValues
69	v.SetX(-1).SetY(-2).SetWidth(800).SetHeight(600).SetBorderWidth(1).SetSibling(2).SetStackMode(xproto.StackModeAbove)
70	var create xproto.CreateWindowValues
71	create.SetOverrideRedirect(true).SetSaveUnder(false)
72	var change xproto.ChangeWindowAttributesValues
73	change.SetOverrideRedirect(false).SetSaveUnder(true)
74	var pic render.CreatePictureValues
75	pic.SetRepeat(render.RepeatNormal).SetClipxorigin(-1)
76	if n := testing.AllocsPerRun(1000, func() {
77		b.Reset()
78		xproto.ConfigureWindow(b, 1, &v)
79		xproto.CreateWindow(b, 0, 1, 2, 0, 0, 80, 60, 0, xproto.WindowClassInputOutput, 0, &create)
80		xproto.ChangeWindowAttributes(b, 1, &change)
81		render.CreatePicture(b, 1, 1, 1, &pic)
82	}); n != 0 {
83		t.Fatal(n)
84	}
85	if b.Err() != nil {
86		t.Fatal(b.Err())
87	}
88}
89
90func TestValueRequestFailures(t *testing.T) {
91	b := xturbo.NewBuf(0)
92	b.Fail(xturbo.ErrBadLength)
93	if xproto.ConfigureWindow(b, 1, &xproto.ConfigureWindowValues{}) != 0 || b.Len() != 0 || b.Err() != xturbo.ErrBadLength {
94		t.Fatal("sticky error")
95	}
96	for _, ext := range []*xturbo.ExtTable{nil, {}} {
97		b := xturbo.NewBuf(0)
98		b.Ext = ext
99		if render.CreatePicture(b, 1, 1, 1, &render.CreatePictureValues{}) != 0 || b.Err() != xturbo.ErrExtMissing || b.Len() != 0 {
100			t.Fatal("missing extension")
101		}
102	}
103}

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 1

↑↓ moveenter openesc close