1package ports
2
3import (
4 "slices"
5 "testing"
6)
7
8func TestDamageSince(t *testing.T) {
9 a, b := Rect{X: 1, W: 2, H: 2}, Rect{Y: 5, W: 1, H: 1}
10 c := SurfaceContent{Seq: 7, DamageHistory: []SeqDamage{{Seq: 5, Rects: []Rect{a}}, {Seq: 6, Full: true}, {Seq: 7, Rects: []Rect{b}}}}
11 for _, tc := range []struct {
12 name string
13 since uint64
14 want []Rect
15 ok bool
16 }{
17 {"up to date", 7, nil, true},
18 {"one behind", 6, []Rect{b}, true},
19 {"across a full change", 5, nil, false},
20 {"history too short", 3, nil, false},
21 {"first content", 0, nil, false},
22 } {
23 got, ok := c.DamageSince(tc.since)
24 if ok != tc.ok || !slices.Equal(got, tc.want) {
25 t.Errorf("%s: %v %v", tc.name, got, ok)
26 }
27 }
28 c.DamageHistory[1] = SeqDamage{Seq: 6, Rects: []Rect{a}}
29 if got, ok := c.DamageSince(4); !ok || !slices.Equal(got, []Rect{a, a, b}) {
30 t.Fatalf("union %v %v", got, ok)
31 }
32 // A history not ending at the content is stale: redraw all.
33 c.Seq = 8
34 if _, ok := c.DamageSince(6); ok {
35 t.Fatal("stale history used")
36 }
37}
38
39func TestAppendDamageSince(t *testing.T) {
40 a, b := Rect{X: 1, W: 2, H: 2}, Rect{Y: 5, W: 1, H: 1}
41 c := SurfaceContent{Seq: 7, DamageHistory: []SeqDamage{{Seq: 6, Rects: []Rect{a}}, {Seq: 7, Rects: []Rect{b}}}}
42 keep := []Rect{{W: 9}}
43 if got, ok := c.AppendDamageSince(keep, 5); !ok || !slices.Equal(got, []Rect{{W: 9}, a, b}) {
44 t.Fatalf("append %v %v", got, ok)
45 }
46 // A refused history leaves dst as it was.
47 c.DamageHistory[1].Full = true
48 if got, ok := c.AppendDamageSince(keep, 5); ok || !slices.Equal(got, keep) {
49 t.Fatalf("full change: %v %v", got, ok)
50 }
51 // Reusing the slice allocates nothing.
52 c.DamageHistory[1].Full = false
53 buf := make([]Rect, 0, 4)
54 if n := testing.AllocsPerRun(20, func() { buf, _ = c.AppendDamageSince(buf[:0], 5) }); n != 0 {
55 t.Fatalf("allocs = %v", n)
56 }
57}