internal/termtext/markdown_test.go
101 lines · 3132 bytes
1package termtext
2
3import (
4 "flag"
5 "os"
6 "path/filepath"
7 "strings"
8 "testing"
9)
10
11var update = flag.Bool("update", false, "rewrite golden files")
12
13func golden(t *testing.T, name, got string) {
14 t.Helper()
15 path := filepath.Join("testdata", name)
16 if *update {
17 os.WriteFile(path, []byte(got), 0o644)
18 }
19 want, err := os.ReadFile(path)
20 if err != nil {
21 t.Fatal(err)
22 }
23 if got != string(want) {
24 t.Errorf("%s differs:\n--- got\n%s\n--- want\n%s", name, got, want)
25 }
26}
27
28func TestMarkdownGolden(t *testing.T) {
29 src, err := os.ReadFile("testdata/doc.md")
30 if err != nil {
31 t.Fatal(err)
32 }
33 for _, o := range []struct {
34 name string
35 opt Options
36 }{
37 {"doc.md.plain.golden", Options{Base: "https://forge.test"}},
38 {"doc.md.60.golden", Options{Width: 60, Base: "https://forge.test"}},
39 {"doc.md.60color.golden", Options{Width: 60, Color: true, Base: "https://forge.test"}},
40 } {
41 golden(t, o.name, Markdown(string(src), o.opt))
42 }
43}
44
45func TestMarkdownWidth(t *testing.T) {
46 src, _ := os.ReadFile("testdata/doc.md")
47 out := Markdown(string(src), Options{Width: 60, Color: true})
48 inCode := false
49 for _, line := range strings.Split(out, "\n") {
50 plain := stripSGR(line)
51 if strings.HasPrefix(plain, " ") {
52 inCode = true
53 } else if plain != "" {
54 inCode = false
55 }
56 if !inCode && cells(plain) > 60 {
57 t.Errorf("line of %d cells: %q", cells(plain), plain)
58 }
59 }
60}
61
62// TestWrappedColorClosesAtLineEnd covers a bold span that wraps mid-run:
63// the style must not bleed across the line break onto the unstyled
64// list-hang prefix, and stripping colour must reproduce the plain
65// rendering exactly.
66func TestWrappedColorClosesAtLineEnd(t *testing.T) {
67 src := "- item with **some very long bold phrase spanning many words here** and more text after it to force a wrap"
68 color := Markdown(src, Options{Width: 30, Color: true})
69 plain := Markdown(src, Options{Width: 30})
70
71 if got := stripSGR(color); got != plain {
72 t.Errorf("stripSGR(color) = %q, want %q", got, plain)
73 }
74
75 // Both continuation lines land wholly inside the wrapped bold span
76 // (the first) or start inside it (the second): the plain prefix
77 // always comes before the reopened style, never styled itself, and
78 // a run left open at wrap time is closed again at line's end.
79 lines := strings.Split(strings.TrimRight(color, "\n"), "\n")
80 for _, i := range []int{1, 2} {
81 if !strings.HasPrefix(lines[i], " \x1b[1m") {
82 t.Errorf("line %d: styled run starts before the plain prefix, or is missing: %q", i, lines[i])
83 }
84 }
85 if !strings.HasSuffix(lines[1], sgrReset) {
86 t.Errorf("line 1: open run never closed: %q", lines[1])
87 }
88 if want := " \x1b[1mbold phrase spanning many\x1b[0m"; lines[1] != want {
89 t.Errorf("line 1 = %q, want %q", lines[1], want)
90 }
91 if want := " \x1b[1mwords here\x1b[0m and more text"; lines[2] != want {
92 t.Errorf("line 2 = %q, want %q", lines[2], want)
93 }
94}
95
96func TestInlineDropsLinkTargets(t *testing.T) {
97 got := Inline("referenced in commit [6c4d1e1454](/krz/gitbay/commit/6c4d) by [cmc](/cmc): landing", "md")
98 if got != "referenced in commit 6c4d1e1454 by cmc: landing" {
99 t.Errorf("Inline = %q", got)
100 }
101}