md_test.gno

6.87 Kb ยท 361 lines
  1package md_test
  2
  3import (
  4	"testing"
  5
  6	"gno.land/p/moul/md"
  7)
  8
  9func TestHelpers(t *testing.T) {
 10	tests := []struct {
 11		name     string
 12		function func() string
 13		expected string
 14	}{
 15		{"Bold", func() string { return md.Bold("foo") }, "**foo**"},
 16		{"Italic", func() string { return md.Italic("foo") }, "*foo*"},
 17		{"Strikethrough", func() string { return md.Strikethrough("foo") }, "~~foo~~"},
 18		{"H1", func() string { return md.H1("foo") }, "# foo\n"},
 19		{"HorizontalRule", md.HorizontalRule, "---\n"},
 20		{"InlineCode", func() string { return md.InlineCode("foo") }, "`foo`"},
 21		{"CodeBlock", func() string { return md.CodeBlock("foo") }, "```\nfoo\n```"},
 22		{"LanguageCodeBlock", func() string { return md.LanguageCodeBlock("go", "foo") }, "```go\nfoo\n```"},
 23		{"Link", func() string { return md.Link("foo", "http://example.com") }, "[foo](http://example.com)"},
 24		{"UserLink", func() string { return md.UserLink("moul") }, "[@moul](/u/moul)"},
 25		{"Image", func() string { return md.Image("foo", "http://example.com") }, "![foo](http://example.com)"},
 26		{"InlineImageWithLink", func() string { return md.InlineImageWithLink("alt", "image-url", "link-url") }, "[![alt](image-url)](link-url)"},
 27		{"Footnote", func() string { return md.Footnote("foo", "bar") }, "[foo]: bar"},
 28		{"Paragraph", func() string { return md.Paragraph("foo") }, "foo\n\n"},
 29	}
 30
 31	for _, tt := range tests {
 32		t.Run(tt.name, func(t *testing.T) {
 33			result := tt.function()
 34			if result != tt.expected {
 35				t.Errorf("%s() = %q, want %q", tt.name, result, tt.expected)
 36			}
 37		})
 38	}
 39}
 40
 41func TestLists(t *testing.T) {
 42	t.Run("BulletList", func(t *testing.T) {
 43		items := []string{"foo", "bar"}
 44		expected := "- foo\n- bar\n"
 45		result := md.BulletList(items)
 46		if result != expected {
 47			t.Errorf("BulletList(%q) = %q, want %q", items, result, expected)
 48		}
 49	})
 50
 51	t.Run("OrderedList", func(t *testing.T) {
 52		items := []string{"foo", "bar"}
 53		expected := "1. foo\n2. bar\n"
 54		result := md.OrderedList(items)
 55		if result != expected {
 56			t.Errorf("OrderedList(%q) = %q, want %q", items, result, expected)
 57		}
 58	})
 59
 60	t.Run("TodoList", func(t *testing.T) {
 61		items := []string{"foo", "bar\nmore bar"}
 62		done := []bool{true, false}
 63		expected := "- [x] foo\n- [ ] bar\n  more bar\n"
 64		result := md.TodoList(items, done)
 65		if result != expected {
 66			t.Errorf("TodoList(%q, %q) = %q, want %q", items, done, result, expected)
 67		}
 68	})
 69}
 70
 71func TestUserLink(t *testing.T) {
 72	tests := []struct {
 73		name     string
 74		input    string
 75		expected string
 76	}{
 77		{"username", "moul", "[@moul](/u/moul)"},
 78		{"address", "g1blah", "[g1blah](/u/g1blah)"},
 79		{"username with special chars", "user_name", "[@user\\_name](/u/user_name)"},
 80		{"address with numbers", "g1abc123", "[g1abc123](/u/g1abc123)"},
 81	}
 82
 83	for _, tt := range tests {
 84		t.Run(tt.name, func(t *testing.T) {
 85			result := md.UserLink(tt.input)
 86			if result != tt.expected {
 87				t.Errorf("UserLink(%q) = %q, want %q", tt.input, result, tt.expected)
 88			}
 89		})
 90	}
 91}
 92
 93func TestNested(t *testing.T) {
 94	t.Run("Nested Single Level", func(t *testing.T) {
 95		content := "- foo\n- bar"
 96		expected := "  - foo\n  - bar"
 97		result := md.Nested(content, "  ")
 98		if result != expected {
 99			t.Errorf("Nested(%q) = %q, want %q", content, result, expected)
100		}
101	})
102
103	t.Run("Nested Double Level", func(t *testing.T) {
104		content := "  - foo\n  - bar"
105		expected := "    - foo\n    - bar"
106		result := md.Nested(content, "  ")
107		if result != expected {
108			t.Errorf("Nested(%q) = %q, want %q", content, result, expected)
109		}
110	})
111}
112
113func TestColumns(t *testing.T) {
114	tests := []struct {
115		name     string
116		input    []string
117		padded   bool
118		expected string
119	}{
120		{
121			name:     "no columns",
122			input:    []string{},
123			padded:   false,
124			expected: "",
125		},
126		{
127			name:     "no columns padded",
128			input:    []string{},
129			padded:   true,
130			expected: "",
131		},
132		{
133			name:   "one column",
134			input:  []string{"Column 1"},
135			padded: false,
136			expected: `<gno-columns>
137Column 1
138</gno-columns>
139`,
140		},
141		{
142			name:   "one column padded",
143			input:  []string{"Column 1"},
144			padded: true,
145			expected: `<gno-columns>
146Column 1
147|||
148
149|||
150
151|||
152
153</gno-columns>
154`,
155		},
156		{
157			name:   "two columns",
158			input:  []string{"Column 1", "Column 2"},
159			padded: false,
160			expected: `<gno-columns>
161Column 1
162|||
163Column 2
164</gno-columns>
165`,
166		},
167		{
168			name:   "two columns padded",
169			input:  []string{"Column 1", "Column 2"},
170			padded: true,
171			expected: `<gno-columns>
172Column 1
173|||
174Column 2
175|||
176
177|||
178
179</gno-columns>
180`,
181		},
182		{
183			name:   "four columns",
184			input:  []string{"A", "B", "C", "D"},
185			padded: false,
186			expected: `<gno-columns>
187A
188|||
189B
190|||
191C
192|||
193D
194</gno-columns>
195`,
196		},
197		{
198			name:   "four columns padded",
199			input:  []string{"A", "B", "C", "D"},
200			padded: true,
201			expected: `<gno-columns>
202A
203|||
204B
205|||
206C
207|||
208D
209</gno-columns>
210`,
211		},
212		{
213			name:   "more than four columns",
214			input:  []string{"1", "2", "3", "4", "5"},
215			padded: false,
216			expected: `<gno-columns>
2171
218|||
2192
220|||
2213
222|||
2234
224|||
2255
226</gno-columns>
227`,
228		},
229		{
230			name:   "more than four columns padded",
231			input:  []string{"1", "2", "3", "4", "5"},
232			padded: true,
233			expected: `<gno-columns>
2341
235|||
2362
237|||
2383
239|||
2404
241|||
2425
243|||
244
245|||
246
247|||
248
249</gno-columns>
250`,
251		},
252	}
253
254	for _, tt := range tests {
255		t.Run(tt.name, func(t *testing.T) {
256			result := md.Columns(tt.input, tt.padded)
257			if result != tt.expected {
258				t.Errorf("Columns(%v, %v) =\n%q\nwant:\n%q", tt.input, tt.padded, result, tt.expected)
259			}
260		})
261	}
262}
263
264func TestColumnsN(t *testing.T) {
265	tests := []struct {
266		name       string
267		content    []string
268		colsPerRow int
269		padded     bool
270		expected   string
271	}{
272		{
273			name:       "empty input",
274			content:    []string{},
275			colsPerRow: 2,
276			padded:     false,
277			expected:   "",
278		},
279		{
280			name:       "colsPerRow <= 0",
281			content:    []string{"A", "B", "C"},
282			colsPerRow: 0,
283			padded:     false,
284			expected: `<gno-columns>
285A
286|||
287B
288|||
289C
290</gno-columns>
291`,
292		},
293		{
294			name:       "exact full row, no padding",
295			content:    []string{"A", "B"},
296			colsPerRow: 2,
297			padded:     false,
298			expected: `<gno-columns>
299A
300|||
301B
302</gno-columns>
303`,
304		},
305		{
306			name:       "partial last row, no padding",
307			content:    []string{"A", "B", "C"},
308			colsPerRow: 2,
309			padded:     false,
310			expected: `<gno-columns>
311A
312|||
313B
314</gno-columns>
315<gno-columns>
316C
317</gno-columns>
318`,
319		},
320		{
321			name:       "partial last row, with padding",
322			content:    []string{"A", "B", "C"},
323			colsPerRow: 2,
324			padded:     true,
325			expected: `<gno-columns>
326A
327|||
328B
329</gno-columns>
330<gno-columns>
331C
332|||
333
334</gno-columns>
335`,
336		},
337		{
338			name:       "padded with more empty cells",
339			content:    []string{"X"},
340			colsPerRow: 3,
341			padded:     true,
342			expected: `<gno-columns>
343X
344|||
345
346|||
347
348</gno-columns>
349`,
350		},
351	}
352
353	for _, tt := range tests {
354		t.Run(tt.name, func(t *testing.T) {
355			result := md.ColumnsN(tt.content, tt.colsPerRow, tt.padded)
356			if result != tt.expected {
357				t.Errorf("ColumnsN(%v, %d, %v) =\n%q\nwant:\n%q", tt.content, tt.colsPerRow, tt.padded, result, tt.expected)
358			}
359		})
360	}
361}