okami.mom/ultraviolet

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

Ayman Bagabasrefactor: rename style attribute types and optimize style diffing2ac17c4

upstream
8.0 KiB233 linesraw
1package uv
2
3import (
4	"testing"
5)
6
7func TestBorderConstructors(t *testing.T) {
8	t.Run("NormalBorder", func(t *testing.T) {
9		b := NormalBorder()
10		if b.Top.Content != "─" || b.Bottom.Content != "─" || b.Left.Content != "│" || b.Right.Content != "│" {
11			t.Fatalf("unexpected sides for NormalBorder")
12		}
13		if b.TopLeft.Content != "┌" || b.TopRight.Content != "┐" || b.BottomLeft.Content != "└" || b.BottomRight.Content != "┘" {
14			t.Fatalf("unexpected corners for NormalBorder")
15		}
16	})
17
18	t.Run("RoundedBorder", func(t *testing.T) {
19		b := RoundedBorder()
20		if b.Top.Content != "─" || b.Bottom.Content != "─" || b.Left.Content != "│" || b.Right.Content != "│" {
21			t.Fatalf("unexpected sides for RoundedBorder")
22		}
23		if b.TopLeft.Content != "╭" || b.TopRight.Content != "╮" || b.BottomLeft.Content != "╰" || b.BottomRight.Content != "╯" {
24			t.Fatalf("unexpected corners for RoundedBorder")
25		}
26	})
27
28	t.Run("BlockBorder", func(t *testing.T) {
29		b := BlockBorder()
30		if b.Top.Content != "█" || b.Bottom.Content != "█" || b.Left.Content != "█" || b.Right.Content != "█" {
31			t.Fatalf("unexpected sides for BlockBorder")
32		}
33		if b.TopLeft.Content != "█" || b.TopRight.Content != "█" || b.BottomLeft.Content != "█" || b.BottomRight.Content != "█" {
34			t.Fatalf("unexpected corners for BlockBorder")
35		}
36	})
37
38	t.Run("OuterHalfBlockBorder", func(t *testing.T) {
39		b := OuterHalfBlockBorder()
40		if b.Top.Content != "▀" || b.Bottom.Content != "▄" || b.Left.Content != "▌" || b.Right.Content != "▐" {
41			t.Fatalf("unexpected sides for OuterHalfBlockBorder")
42		}
43		if b.TopLeft.Content != "▛" || b.TopRight.Content != "▜" || b.BottomLeft.Content != "▙" || b.BottomRight.Content != "▟" {
44			t.Fatalf("unexpected corners for OuterHalfBlockBorder")
45		}
46	})
47
48	t.Run("InnerHalfBlockBorder", func(t *testing.T) {
49		b := InnerHalfBlockBorder()
50		if b.Top.Content != "▄" || b.Bottom.Content != "▀" || b.Left.Content != "▐" || b.Right.Content != "▌" {
51			t.Fatalf("unexpected sides for InnerHalfBlockBorder")
52		}
53		if b.TopLeft.Content != "▗" || b.TopRight.Content != "▖" || b.BottomLeft.Content != "▝" || b.BottomRight.Content != "▘" {
54			t.Fatalf("unexpected corners for InnerHalfBlockBorder")
55		}
56	})
57
58	t.Run("ThickBorder", func(t *testing.T) {
59		b := ThickBorder()
60		if b.Top.Content != "━" || b.Bottom.Content != "━" || b.Left.Content != "┃" || b.Right.Content != "┃" {
61			t.Fatalf("unexpected sides for ThickBorder")
62		}
63		if b.TopLeft.Content != "┏" || b.TopRight.Content != "┓" || b.BottomLeft.Content != "┗" || b.BottomRight.Content != "┛" {
64			t.Fatalf("unexpected corners for ThickBorder")
65		}
66	})
67
68	t.Run("DoubleBorder", func(t *testing.T) {
69		b := DoubleBorder()
70		if b.Top.Content != "═" || b.Bottom.Content != "═" || b.Left.Content != "║" || b.Right.Content != "║" {
71			t.Fatalf("unexpected sides for DoubleBorder")
72		}
73		if b.TopLeft.Content != "╔" || b.TopRight.Content != "╗" || b.BottomLeft.Content != "╚" || b.BottomRight.Content != "╝" {
74			t.Fatalf("unexpected corners for DoubleBorder")
75		}
76	})
77
78	t.Run("HiddenBorder", func(t *testing.T) {
79		b := HiddenBorder()
80		if b.Top.Content != " " || b.Bottom.Content != " " || b.Left.Content != " " || b.Right.Content != " " {
81			t.Fatalf("unexpected sides for HiddenBorder")
82		}
83		if b.TopLeft.Content != " " || b.TopRight.Content != " " || b.BottomLeft.Content != " " || b.BottomRight.Content != " " {
84			t.Fatalf("unexpected corners for HiddenBorder")
85		}
86	})
87
88	t.Run("MarkdownBorder", func(t *testing.T) {
89		b := MarkdownBorder()
90		if b.Left.Content != "|" || b.Right.Content != "|" {
91			t.Fatalf("unexpected sides for MarkdownBorder left/right")
92		}
93		if b.TopLeft.Content != "|" || b.TopRight.Content != "|" || b.BottomLeft.Content != "|" || b.BottomRight.Content != "|" {
94			t.Fatalf("unexpected corners for MarkdownBorder")
95		}
96		if b.Top.Content != "" || b.Bottom.Content != "" {
97			t.Fatalf("unexpected top/bottom content for MarkdownBorder")
98		}
99	})
100
101	t.Run("ASCIIBorder", func(t *testing.T) {
102		b := ASCIIBorder()
103		if b.Top.Content != "-" || b.Bottom.Content != "-" || b.Left.Content != "|" || b.Right.Content != "|" {
104			t.Fatalf("unexpected sides for ASCIIBorder")
105		}
106		if b.TopLeft.Content != "+" || b.TopRight.Content != "+" || b.BottomLeft.Content != "+" || b.BottomRight.Content != "+" {
107			t.Fatalf("unexpected corners for ASCIIBorder")
108		}
109	})
110}
111
112func TestBorderStyleAndLink(t *testing.T) {
113	base := NormalBorder()
114	style := Style{Attrs: AttrBold}
115	link := NewLink("https://example.com", "id=1")
116
117	b := base.Style(style).Link(link)
118
119	if !b.Top.Style.Equal(&style) || !b.Bottom.Style.Equal(&style) || !b.Left.Style.Equal(&style) || !b.Right.Style.Equal(&style) {
120		t.Fatalf("style not applied to all sides")
121	}
122	if !b.TopLeft.Style.Equal(&style) || !b.TopRight.Style.Equal(&style) || !b.BottomLeft.Style.Equal(&style) || !b.BottomRight.Style.Equal(&style) {
123		t.Fatalf("style not applied to all corners")
124	}
125	if !b.Top.Link.Equal(&link) || !b.Bottom.Link.Equal(&link) || !b.Left.Link.Equal(&link) || !b.Right.Link.Equal(&link) {
126		t.Fatalf("link not applied to all sides")
127	}
128	if !b.TopLeft.Link.Equal(&link) || !b.TopRight.Link.Equal(&link) || !b.BottomLeft.Link.Equal(&link) || !b.BottomRight.Link.Equal(&link) {
129		t.Fatalf("link not applied to all corners")
130	}
131
132	if !base.Top.Style.IsZero() || !base.Top.Link.IsZero() {
133		t.Fatalf("base border modified by Style/Link")
134	}
135}
136
137func TestBorderDrawNormal(t *testing.T) {
138	dst := NewScreenBuffer(20, 10)
139	area := Rect(1, 1, 6, 4)
140	b := NormalBorder()
141	b.Draw(&dst, area)
142
143	if c := dst.CellAt(1, 1); c == nil || c.Content != "┌" {
144		t.Fatalf("expected top-left corner")
145	}
146	if c := dst.CellAt(6, 1); c == nil || c.Content != "┐" {
147		t.Fatalf("expected top-right corner")
148	}
149	if c := dst.CellAt(1, 4); c == nil || c.Content != "└" {
150		t.Fatalf("expected bottom-left corner")
151	}
152	if c := dst.CellAt(6, 4); c == nil || c.Content != "┘" {
153		t.Fatalf("expected bottom-right corner")
154	}
155
156	for x := 2; x <= 5; x++ {
157		if c := dst.CellAt(x, 1); c == nil || c.Content != "─" {
158			t.Fatalf("expected top edge at x=%d", x)
159		}
160		if c := dst.CellAt(x, 4); c == nil || c.Content != "─" {
161			t.Fatalf("expected bottom edge at x=%d", x)
162		}
163	}
164	for y := 2; y <= 3; y++ {
165		if c := dst.CellAt(1, y); c == nil || c.Content != "│" {
166			t.Fatalf("expected left edge at y=%d", y)
167		}
168		if c := dst.CellAt(6, y); c == nil || c.Content != "│" {
169			t.Fatalf("expected right edge at y=%d", y)
170		}
171	}
172
173	for y := 2; y <= 3; y++ {
174		for x := 2; x <= 5; x++ {
175			if c := dst.CellAt(x, y); c == nil || c.Content != " " {
176				t.Fatalf("expected interior to be blank at %d,%d", x, y)
177			}
178		}
179	}
180}
181
182func TestBorderDrawHiddenStyleLink(t *testing.T) {
183	dst := NewScreenBuffer(10, 6)
184	area := Rect(2, 2, 5, 3)
185	style := Style{Attrs: AttrBold}
186	link := NewLink("https://example.com")
187	b := HiddenBorder().Style(style).Link(link)
188	b.Draw(&dst, area)
189
190	checkPos := []struct{ x, y int }{
191		{2, 2}, {6, 2}, {2, 4}, {6, 4},
192	}
193	for x := 3; x <= 5; x++ {
194		checkPos = append(checkPos, struct{ x, y int }{x, 2})
195		checkPos = append(checkPos, struct{ x, y int }{x, 4})
196	}
197	for y := 3; y <= 3; y++ {
198		checkPos = append(checkPos, struct{ x, y int }{2, y})
199		checkPos = append(checkPos, struct{ x, y int }{6, y})
200	}
201
202	for _, p := range checkPos {
203		c := dst.CellAt(p.x, p.y)
204		if c == nil || c.Content != " " || !c.Style.Equal(&style) || !c.Link.Equal(&link) {
205			t.Fatalf("expected styled/link space at %d,%d", p.x, p.y)
206		}
207	}
208
209	c := dst.CellAt(4, 3)
210	if c == nil || c.Content != " " || !c.Style.IsZero() || !c.Link.IsZero() {
211		t.Fatalf("interior should be default space without style/link")
212	}
213}
214
215func TestBorderDrawSmallAreas(t *testing.T) {
216	dst := NewScreenBuffer(3, 3)
217	b := NormalBorder()
218
219	area1 := Rect(0, 0, 1, 1)
220	b.Draw(&dst, area1)
221	if c := dst.CellAt(0, 0); c == nil || c.Content != "┌" {
222		t.Fatalf("expected single-cell area to use top-left corner")
223	}
224
225	area2 := Rect(0, 1, 1, 2)
226	b.Draw(&dst, area2)
227	if c := dst.CellAt(0, 1); c == nil || c.Content != "┌" {
228		t.Fatalf("expected top-left at 0,1")
229	}
230	if c := dst.CellAt(0, 2); c == nil || c.Content != "└" {
231		t.Fatalf("expected bottom-left at 0,2")
232	}
233}