v0.8.0 446d1e3

shm_rects_test.go RawHistoryFolder

1package vulkan
2
3import (
4	"image"
5	"math/rand"
6	"testing"
7
8	"github.com/bnema/neferwl/internal/ports"
9)
10
11// disjointRects keeps the union of the damage, clipped to the buffer, and
12// covers no pixel twice.
13func TestDisjointRectsCoverUnionOnce(t *testing.T) {
14	const w, h = 24, 16
15	rng := rand.New(rand.NewSource(1))
16	var scratch = disjointRects(nil, nil, w, h)
17	for range 500 {
18		rects := make([]ports.Rect, 1+rng.Intn(6))
19		var want [w * h]bool
20		for i := range rects {
21			rects[i] = ports.Rect{X: rng.Intn(w+8) - 4, Y: rng.Intn(h+8) - 4, W: rng.Intn(14), H: rng.Intn(10)}
22			for y := rects[i].Y; y < rects[i].Y+rects[i].H; y++ {
23				for x := rects[i].X; x < rects[i].X+rects[i].W; x++ {
24					if x >= 0 && x < w && y >= 0 && y < h {
25						want[y*w+x] = true
26					}
27				}
28			}
29		}
30		scratch = disjointRects(scratch[:0], rects, w, h)
31		var got [w * h]int
32		for _, r := range scratch {
33			if r.Empty() {
34				t.Fatalf("empty rect in %v for %v", scratch, rects)
35			}
36			for y := r.Min.Y; y < r.Max.Y; y++ {
37				for x := r.Min.X; x < r.Max.X; x++ {
38					got[y*w+x]++
39				}
40			}
41		}
42		for i := range got {
43			if (got[i] > 0) != want[i] || got[i] > 1 {
44				t.Fatalf("pixel %d covered %d times (want %v) for %v -> %v", i, got[i], want[i], rects, scratch)
45			}
46		}
47	}
48}
49
50// Client damage that would cut into too many pieces falls back to its
51// bounding box: the work stays bounded and every damaged pixel is copied.
52func TestDisjointRectsBoundsAdversarialDamage(t *testing.T) {
53	const w, h = 1024, 1024
54	rects := make([]ports.Rect, 128)
55	for i := range rects {
56		rects[i] = ports.Rect{X: i * 3, Y: i * 3, W: w - i*6, H: 4 + i}
57	}
58	got := disjointRects(nil, rects, w, h)
59	if len(got) != 1 {
60		t.Fatalf("%d pieces, want the bounding box", len(got))
61	}
62	for _, rc := range rects {
63		r := image.Rect(rc.X, rc.Y, rc.X+rc.W, rc.Y+rc.H)
64		if !r.In(got[0]) {
65			t.Fatalf("damage %v outside %v", r, got[0])
66		}
67	}
68}
69
70// With a reused scratch slice the helper allocates nothing.
71func TestDisjointRectsNoAllocs(t *testing.T) {
72	rects := []ports.Rect{{X: 0, Y: 0, W: 10, H: 10}, {X: 5, Y: 5, W: 10, H: 10}, {X: 2, Y: 8, W: 4, H: 4}}
73	scratch := disjointRects(nil, rects, 32, 32)
74	if n := testing.AllocsPerRun(100, func() { scratch = disjointRects(scratch[:0], rects, 32, 32) }); n != 0 {
75		t.Fatalf("%v allocs", n)
76	}
77}

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