1package ansi_test
2
3import (
4 "bytes"
5 "testing"
6
7 vt "github.com/bnema/vev-vt"
8 "github.com/bnema/vev-vt/ansi"
9)
10
11func TestBidirectionalScrollReplay(t *testing.T) {
12 for _, down := range []bool{false, true} {
13 for _, count := range []int{1, 3} {
14 frame := vt.NewFrame(12, 10)
15 for y := range frame.Height {
16 frame.FillRow(y, 0, frame.Width, vt.Cell{Rune: rune('a' + y), Style: vt.Style{Foreground: y, Background: -1}})
17 }
18 r := ansi.New(ansi.Capabilities{})
19 terminal := vt.NewScreen(frame.Width, frame.Height)
20 initial, err := r.Draw(frame, nil)
21 if err != nil {
22 t.Fatal(err)
23 }
24 terminal.Write(initial)
25 kind, exposed := vt.DamageScrollUp, 8-count
26 if down {
27 kind, exposed = vt.DamageScrollDown, 2
28 frame.ScrollDown(2, 7, count)
29 } else {
30 frame.ScrollUp(2, 7, count)
31 }
32 for y := exposed; y < exposed+count; y++ {
33 frame.FillRow(y, 0, frame.Width, vt.Cell{Rune: 'X', Style: vt.DefaultStyle()})
34 }
35 damage := []vt.Damage{
36 {Kind: kind, Y: 2, Width: 12, Height: 6, Count: count},
37 {Kind: vt.DamageText, Y: exposed, Width: 12, Height: count},
38 }
39 prepared, err := r.Prepare(frame, damage, false)
40 if err != nil {
41 t.Fatal(err)
42 }
43 if !bytes.Contains(prepared.Bytes(), []byte("\x1b[3;8r")) {
44 t.Fatalf("missing scroll region: %q", prepared.Bytes())
45 }
46 terminal.Write(prepared.Bytes())
47 prepared.Commit()
48 for y := range frame.Height {
49 for x := range frame.Width {
50 if !frame.Cell(x, y).Equal(terminal.Cell(x, y)) {
51 t.Fatalf("down=%v count=%d cell %d,%d mismatch", down, count, x, y)
52 }
53 }
54 }
55 if err := frame.CheckInvariants(); err != nil {
56 t.Fatal(err)
57 }
58 unchanged, err := r.Draw(frame, nil)
59 if err != nil || len(unchanged) != 0 {
60 t.Fatalf("committed shadow differs: %q, %v", unchanged, err)
61 }
62 }
63 }
64}
65
66func TestDownwardScrollMismatchFallsBack(t *testing.T) {
67 committed := vt.NewFrame(10, 8)
68 frame := committed.Clone()
69 frame.Set(0, 4, vt.Cell{Rune: 'X', Style: vt.DefaultStyle()})
70 for _, width := range []int{9, 10} {
71 candidate, err := ansi.PlanDelta(frame, []vt.Damage{{Kind: vt.DamageScrollDown, Y: 1, Width: width, Height: 6, Count: 1}}, committed, false)
72 if err != nil {
73 t.Fatal(err)
74 }
75 if !candidate.Plan.Snapshot || candidate.Plan.Scroll.Height != 0 {
76 t.Fatalf("unsafe scroll accepted: %+v", candidate.Plan)
77 }
78 }
79}