Monorepo for Tangled
1package markup
2
3import (
4 "bytes"
5 "strings"
6 "testing"
7)
8
9func TestMermaidExtension(t *testing.T) {
10 tests := []struct {
11 name string
12 markdown string
13 contains string
14 notContains string
15 }{
16 {
17 name: "mermaid block produces pre.mermaid",
18 markdown: "```mermaid\ngraph TD\n A-->B\n```",
19 contains: `<pre class="mermaid">`,
20 notContains: `<code class="language-mermaid"`,
21 },
22 {
23 name: "mermaid block contains diagram source",
24 markdown: "```mermaid\ngraph TD\n A-->B\n```",
25 contains: "graph TD",
26 },
27 {
28 name: "non-mermaid code block is not affected",
29 markdown: "```go\nfunc main() {}\n```",
30 contains: `<pre class="chroma">`,
31 },
32 }
33
34 for _, tt := range tests {
35 t.Run(tt.name, func(t *testing.T) {
36 md := NewMarkdown("tangled.org")
37
38 var buf bytes.Buffer
39 if err := md.Convert([]byte(tt.markdown), &buf); err != nil {
40 t.Fatalf("failed to convert markdown: %v", err)
41 }
42
43 result := buf.String()
44 if !strings.Contains(result, tt.contains) {
45 t.Errorf("expected output to contain:\n%s\ngot:\n%s", tt.contains, result)
46 }
47 if tt.notContains != "" && strings.Contains(result, tt.notContains) {
48 t.Errorf("expected output NOT to contain:\n%s\ngot:\n%s", tt.notContains, result)
49 }
50 })
51 }
52}
53
54func TestAtExtension_Rendering(t *testing.T) {
55 tests := []struct {
56 name string
57 markdown string
58 expected string
59 }{
60 {
61 name: "renders simple at mention",
62 markdown: "Hello @user.tngl.sh!",
63 expected: `<p>Hello <a href="/user.tngl.sh" class="mention">@user.tngl.sh</a>!</p>`,
64 },
65 {
66 name: "renders multiple at mentions",
67 markdown: "Hi @alice.tngl.sh and @bob.example.com",
68 expected: `<p>Hi <a href="/alice.tngl.sh" class="mention">@alice.tngl.sh</a> and <a href="/bob.example.com" class="mention">@bob.example.com</a></p>`,
69 },
70 {
71 name: "renders at mention in parentheses",
72 markdown: "Check this out (@user.tngl.sh)",
73 expected: `<p>Check this out (<a href="/user.tngl.sh" class="mention">@user.tngl.sh</a>)</p>`,
74 },
75 {
76 name: "does not render email",
77 markdown: "Contact me at test@example.com",
78 expected: `<p>Contact me at <a href="mailto:test@example.com">test@example.com</a></p>`,
79 },
80 {
81 name: "renders at mention with hyphen",
82 markdown: "Follow @user-name.tngl.sh",
83 expected: `<p>Follow <a href="/user-name.tngl.sh" class="mention">@user-name.tngl.sh</a></p>`,
84 },
85 {
86 name: "renders at mention with numbers",
87 markdown: "@user123.test456.social",
88 expected: `<p><a href="/user123.test456.social" class="mention">@user123.test456.social</a></p>`,
89 },
90 {
91 name: "at mention at start of line",
92 markdown: "@user.tngl.sh is cool",
93 expected: `<p><a href="/user.tngl.sh" class="mention">@user.tngl.sh</a> is cool</p>`,
94 },
95 }
96
97 for _, tt := range tests {
98 t.Run(tt.name, func(t *testing.T) {
99 md := NewMarkdown("tangled.org")
100
101 var buf bytes.Buffer
102 if err := md.Convert([]byte(tt.markdown), &buf); err != nil {
103 t.Fatalf("failed to convert markdown: %v", err)
104 }
105
106 result := buf.String()
107 if result != tt.expected+"\n" {
108 t.Errorf("expected:\n%s\ngot:\n%s", tt.expected, result)
109 }
110 })
111 }
112}
113
114func TestAtExtension_WithOtherMarkdown(t *testing.T) {
115 tests := []struct {
116 name string
117 markdown string
118 contains string
119 }{
120 {
121 name: "at mention with bold",
122 markdown: "**Hello @user.tngl.sh**",
123 contains: `<strong>Hello <a href="/user.tngl.sh" class="mention">@user.tngl.sh</a></strong>`,
124 },
125 {
126 name: "at mention with italic",
127 markdown: "*Check @user.tngl.sh*",
128 contains: `<em>Check <a href="/user.tngl.sh" class="mention">@user.tngl.sh</a></em>`,
129 },
130 {
131 name: "at mention in list",
132 markdown: "- Item 1\n- @user.tngl.sh\n- Item 3",
133 contains: `<a href="/user.tngl.sh" class="mention">@user.tngl.sh</a>`,
134 },
135 {
136 name: "at mention in link",
137 markdown: "[@regnault.dev](https://regnault.dev)",
138 contains: `<a href="https://regnault.dev">@regnault.dev</a>`,
139 },
140 {
141 name: "at mention in link again",
142 markdown: "[check out @regnault.dev](https://regnault.dev)",
143 contains: `<a href="https://regnault.dev">check out @regnault.dev</a>`,
144 },
145 {
146 name: "at mention in link again, multiline",
147 markdown: "[\ncheck out @regnault.dev](https://regnault.dev)",
148 contains: "<a href=\"https://regnault.dev\">\ncheck out @regnault.dev</a>",
149 },
150 }
151
152 for _, tt := range tests {
153 t.Run(tt.name, func(t *testing.T) {
154 md := NewMarkdown("tangled.org")
155
156 var buf bytes.Buffer
157 if err := md.Convert([]byte(tt.markdown), &buf); err != nil {
158 t.Fatalf("failed to convert markdown: %v", err)
159 }
160
161 result := buf.String()
162 if !bytes.Contains([]byte(result), []byte(tt.contains)) {
163 t.Errorf("expected output to contain:\n%s\ngot:\n%s", tt.contains, result)
164 }
165 })
166 }
167}