okami.mom/ultraviolet

git clone https://git.nkp.pet/okami.mom/ultraviolet

Kieran Klukasfix(renderer): repaint when the screen changes height0de425e

upstream
2.1 KiB64 linesraw
1package conformance_test
2
3import (
4	"testing"
5
6	"github.com/charmbracelet/ultraviolet/internal/conformance"
7)
8
9// A screen that shrinks narrow enough to rewrap a row, then grows again, is the
10// case the nightly run kept finding and the corpus could not hold: the inputs
11// it minimised to were long, and what they were really exercising is short.
12//
13// Shrinking makes the terminal rewrap a row too wide to fit, which pushes
14// content onto rows that are off-screen at the time. Growing brings those rows
15// back, still holding it. The renderer never painted them, so nothing in its
16// model says they are dirty, and the residue used to survive every later frame.
17func TestReflowAcrossShrinkAndGrow(t *testing.T) {
18	const wave = "\U0001f44b\U0001f3ff" // four columns under legacy widths
19
20	wide := ""
21	for range 6 {
22		wide += wave
23	}
24
25	progs := map[string]conformance.Program{
26		// Rows wider than the screen, squeezed to a fifth of the width and
27		// then opened out past the original height.
28		"shrink then grow taller": {
29			Width: 26, Height: 2,
30			Ops: []conformance.Op{
31				{Kind: conformance.OpDrawLine, Y: 0, Text: wide},
32				{Kind: conformance.OpDrawLine, Y: 1, Text: wide},
33				{Kind: conformance.OpRender},
34				{Kind: conformance.OpResize, W: 5, H: 2},
35				{Kind: conformance.OpRender},
36				{Kind: conformance.OpResize, W: 23, H: 8},
37			},
38		},
39		// The same shape with the rows drawn out of order and a gentler
40		// shrink, which is how the fuzzer first hit it.
41		"shrink then grow, rows out of order": {
42			Width: 26, Height: 4,
43			Ops: []conformance.Op{
44				{Kind: conformance.OpDrawLine, Y: 2, Text: wide},
45				{Kind: conformance.OpDrawLine, Y: 0, Text: wide},
46				{Kind: conformance.OpDrawLine, Y: 1, Text: wide},
47				{Kind: conformance.OpRender},
48				{Kind: conformance.OpResize, W: 11, H: 2},
49				{Kind: conformance.OpRender},
50				{Kind: conformance.OpResize, W: 23, H: 8},
51			},
52		},
53	}
54
55	for name, prog := range progs {
56		t.Run(name, func(t *testing.T) {
57			for _, o := range oracles {
58				got := runIncremental(t, prog, o.mk)
59				want := runFullRepaint(t, prog, o.mk)
60				compare(t, prog, o.name, got, want)
61			}
62		})
63	}
64}