v0.6.0 b250c5e

damage_plan_test.go RawHistoryFolder

1package ansi
2
3import (
4	"math"
5	"reflect"
6	"testing"
7)
8
9func TestBuildDamagePlan(t *testing.T) {
10	tests := []struct {
11		name   string
12		frame  Frame
13		damage []Damage
14		want   []Span
15		full   bool
16	}{
17		{
18			name:  "merges reverse overlaps",
19			frame: NewFrame(10, 2),
20			damage: []Damage{
21				{Kind: DamageText, X: 4, Y: 0, Width: 5, Height: 1},
22				{Kind: DamageText, X: 0, Y: 0, Width: 5, Height: 1},
23			},
24			want: []Span{{Y: 0, X: 0, Width: 9}},
25		},
26		{
27			name:  "merges text and clear",
28			frame: NewFrame(10, 1),
29			damage: []Damage{
30				{Kind: DamageClear, X: 5, Y: 0, Width: 4, Height: 1},
31				{Kind: DamageText, X: 0, Y: 0, Width: 5, Height: 1},
32			},
33			want: []Span{{Y: 0, X: 0, Width: 9}},
34		},
35		{
36			name:  "orders multi-row spans",
37			frame: NewFrame(10, 3),
38			damage: []Damage{
39				{Kind: DamageText, X: 5, Y: 2, Width: 2, Height: 1},
40				{Kind: DamageText, X: 4, Y: 0, Width: 2, Height: 2},
41				{Kind: DamageText, X: 1, Y: 0, Width: 2, Height: 2},
42				{Kind: DamageScrollUp, X: 0, Y: 0, Width: 10, Height: 3, Count: 1},
43			},
44			want: []Span{
45				{Y: 0, X: 1, Width: 2}, {Y: 0, X: 4, Width: 2},
46				{Y: 1, X: 1, Width: 2}, {Y: 1, X: 4, Width: 2},
47				{Y: 2, X: 5, Width: 2},
48			},
49		},
50		{
51			name:  "clamps rectangles",
52			frame: NewFrame(10, 3),
53			damage: []Damage{
54				{Kind: DamageText, X: -2, Y: -1, Width: 5, Height: 3},
55				{Kind: DamageClear, X: 8, Y: 1, Width: 5, Height: 3},
56			},
57			want: []Span{{Y: 0, X: 0, Width: 3}, {Y: 1, X: 0, Width: 3}, {Y: 1, X: 8, Width: 2}, {Y: 2, X: 8, Width: 2}},
58		},
59		{
60			name:  "does not mutate input",
61			frame: NewFrame(10, 2),
62			damage: []Damage{
63				{Kind: DamageText, X: 5, Y: 1, Width: 2, Height: 1},
64				{Kind: DamageText, X: 1, Y: 0, Width: 2, Height: 1},
65			},
66			want: []Span{{Y: 0, X: 1, Width: 2}, {Y: 1, X: 5, Width: 2}},
67		},
68		{
69			name:   "exceeding budget requests full redraw",
70			frame:  NewFrame(1, maxPlannedDamageSpans+1),
71			damage: []Damage{{Kind: DamageText, X: 0, Y: 0, Width: 1, Height: maxPlannedDamageSpans + 1}},
72			want:   nil,
73			full:   true,
74		},
75	}
76
77	for _, tt := range tests {
78		t.Run(tt.name, func(t *testing.T) {
79			original := append([]Damage(nil), tt.damage...)
80			got, full := buildDamagePlan(tt.frame, tt.damage, nil)
81			if full != tt.full || !reflect.DeepEqual(got, tt.want) {
82				t.Fatalf("buildDamagePlan() = %#v, full = %v; want %#v, %v", got, full, tt.want, tt.full)
83			}
84			if !reflect.DeepEqual(tt.damage, original) {
85				t.Fatalf("buildDamagePlan mutated damage: got %#v, want %#v", tt.damage, original)
86			}
87		})
88	}
89}
90
91func TestClampRectRejectsOverflowingBounds(t *testing.T) {
92	frame := NewFrame(10, 10)
93	if _, _, _, _, ok := clampRect(frame, math.MaxInt-1, 0, 4, 1); ok {
94		t.Fatal("clampRect accepted overflowing x bound")
95	}
96	if _, _, _, _, ok := clampRect(frame, 0, math.MaxInt-1, 1, 4); ok {
97		t.Fatal("clampRect accepted overflowing y bound")
98	}
99}

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 2

Tags 13

↑↓ moveenter openesc close