From ad3f63822aec80dfb002e44bc1dd4a8962eb8fc4 Mon Sep 17 00:00:00 2001 From: Arpad Ryszka Date: Tue, 28 Oct 2025 01:19:38 +0100 Subject: [PATCH] finish testing markdown --- markdown.go | 8 +- markdown_test.go | 222 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 218 insertions(+), 12 deletions(-) diff --git a/markdown.go b/markdown.go index 6d0187e..41ea307 100644 --- a/markdown.go +++ b/markdown.go @@ -13,7 +13,7 @@ func escapeMarkdown(s string, additional ...rune) string { var ( rr []rune isNumberOnNewLine bool - isLinkOpen, isLinkClosed, isLinkLabel bool + isLinkOpen, isLinkClosed, isLinkValue bool ) isNewLine := true @@ -45,7 +45,7 @@ func escapeMarkdown(s string, additional ...rune) string { default: rr = append(rr, ri) } - case isLinkLabel: + case isLinkValue: switch ri { case ')': rr = append(rr, '\\', ri) @@ -63,9 +63,9 @@ func escapeMarkdown(s string, additional ...rune) string { isNumberOnNewLine = (isNewLine || isNumberOnNewLine) && ri >= '0' && ri <= '9' isNewLine = ri == '\n' - isLinkOpen = !isLinkLabel && ri == '[' || isLinkOpen && ri != ']' + isLinkValue = isLinkClosed && ri == '(' || isLinkValue && ri != ')' isLinkClosed = isLinkOpen && ri == ']' - isLinkLabel = isLinkClosed && ri == '(' || isLinkLabel && ri != ')' + isLinkOpen = !isLinkValue && ri == '[' || isLinkOpen && ri != ']' } return string(rr) diff --git a/markdown_test.go b/markdown_test.go index cb02e9f..1ede752 100644 --- a/markdown_test.go +++ b/markdown_test.go @@ -8,19 +8,173 @@ import ( func TestMarkdown(t *testing.T) { t.Run("invalid", func(t *testing.T) { - t.Fatal() + var b bytes.Buffer + if err := textfmt.Markdown(&b, textfmt.Doc(textfmt.Entry{})); err == nil { + t.Fatal("failed to fail") + } }) t.Run("empty", func(t *testing.T) { - t.Fatal() + var b bytes.Buffer + if err := textfmt.Markdown(&b, textfmt.Doc()); err != nil { + t.Fatal(err) + } + + if b.String() != "" { + t.Fatal(b.String()) + } }) t.Run("example", func(t *testing.T) { - t.Fatal() + doc := textfmt.Doc( + textfmt.Title(0, "Example Text"), + + textfmt.Wrap( + textfmt.Indent( + textfmt.Paragraph(textfmt.Text("Below you can find some test text, with various text items.")), + 0, + 8, + ), + 30, + ), + + textfmt.Title(1, "Document syntax:"), + + textfmt.Indent( + textfmt.Syntax( + textfmt.Symbol("textfmt.Doc"), + textfmt.Symbol("("), + textfmt.ZeroOrMore(textfmt.Symbol("Entry")), + textfmt.Symbol(")"), + ), + 0, + 8, + ), + + textfmt.Title(1, "Entries:"), + + textfmt.Paragraph(textfmt.Text("textfmt supports the following entries:")), + + textfmt.List( + textfmt.Item(textfmt.Text("CodeBlock")), + textfmt.Item(textfmt.Text("DefinitionList")), + textfmt.Item(textfmt.Text("List")), + textfmt.Item(textfmt.Text("NumberedDefinitionList")), + textfmt.Item(textfmt.Text("NumberedList")), + textfmt.Item(textfmt.Text("Paragraph")), + textfmt.Item(textfmt.Text("Syntax")), + textfmt.Item(textfmt.Text("Table")), + textfmt.Item(textfmt.Text("Title")), + ), + + textfmt.Title(1, "Entry explanations:"), + + textfmt.Wrap( + textfmt.DefinitionList( + textfmt.Definition( + textfmt.Text("CodeBlock"), + textfmt.Text("a multiline block of code"), + ), + textfmt.Definition( + textfmt.Text("DefinitionList"), + textfmt.Text("a list of definitions like this one"), + ), + textfmt.Definition( + textfmt.Text("List"), + textfmt.Text("a list of items"), + ), + textfmt.Definition( + textfmt.Text("NumberedDefinitionList"), + textfmt.Text("numbered definitions"), + ), + textfmt.Definition( + textfmt.Text("NumberedList"), + textfmt.Text("numbered list"), + ), + textfmt.Definition( + textfmt.Text("Paragraph"), + textfmt.Text("paragraph of text"), + ), + textfmt.Definition( + textfmt.Text("Syntax"), + textfmt.Text("a syntax expression"), + ), + textfmt.Definition( + textfmt.Text("Table"), + textfmt.Text("a table"), + ), + textfmt.Definition( + textfmt.Text("Title"), + textfmt.Text("a title"), + ), + ), + 48, + ), + ) + + var b bytes.Buffer + if err := textfmt.Markdown(&b, doc); err != nil { + t.Fatal(err) + } + + const expect = ` +# Example Text + +Below you can find some test +text, with various text items. + +## Document syntax: + +` + "```" + ` +textfmt.Doc ( [Entry]... ) +` + "```" + ` + +## Entries: + +textfmt supports the following entries: + +- CodeBlock +- DefinitionList +- List +- NumberedDefinitionList +- NumberedList +- Paragraph +- Syntax +- Table +- Title + +## Entry explanations: + +- CodeBlock: a multiline block of code +- DefinitionList: a list of definitions like + this one +- List: a list of items +- NumberedDefinitionList: numbered definitions +- NumberedList: numbered list +- Paragraph: paragraph of text +- Syntax: a syntax expression +- Table: a table +- Title: a title +` + + if "\n"+b.String() != expect { + t.Log("\n" + b.String()) + t.Log(expect) + logBytes(t, "\n"+b.String()) + logBytes(t, expect) + t.Fatal() + } }) t.Run("write error", func(t *testing.T) { - t.Fatal() + w := &failingWriter{failAfter: 15} + doc := textfmt.Doc( + textfmt.Paragraph(textfmt.Text("Some sample text...\non multiple lines.")), + ) + + if err := textfmt.Markdown(w, doc); err == nil { + t.Fatal("failed to fail") + } }) t.Run("title", func(t *testing.T) { @@ -241,19 +395,71 @@ func TestMarkdown(t *testing.T) { }) t.Run("escape", func(t *testing.T) { - t.Fatal() + doc := textfmt.Doc( + textfmt.Paragraph( + textfmt.Text("\\`*_[]#<>"), + ), + ) + + var b bytes.Buffer + if err := textfmt.Markdown(&b, doc); err != nil { + t.Fatal(err) + } + + if b.String() != "\\\\\\`\\*\\_\\[\\]\\#\\<\\>\n" { + t.Fatal(b.String()) + } }) t.Run("escape link", func(t *testing.T) { - t.Fatal() + doc := textfmt.Doc( + textfmt.Paragraph( + textfmt.Text("[looks-like-a-link](https://foo.bar)"), + ), + ) + + var b bytes.Buffer + if err := textfmt.Markdown(&b, doc); err != nil { + t.Fatal(err) + } + + if b.String() != "\\[looks-like-a-link\\]\\(https://foo.bar\\)\n" { + t.Fatal(b.String()) + } }) t.Run("escape negative number on line start", func(t *testing.T) { - t.Fatal() + doc := textfmt.Doc( + textfmt.Paragraph( + textfmt.Text("-42 policemen jumped on the bus"), + ), + ) + + var b bytes.Buffer + if err := textfmt.Markdown(&b, doc); err != nil { + t.Fatal(err) + } + + if b.String() != "\\-42 policemen jumped on the bus\n" { + t.Fatal(b.String()) + } }) t.Run("escape year on line start", func(t *testing.T) { - t.Fatal() + doc := textfmt.Doc( + textfmt.Paragraph( + textfmt.Text("2005. was the year when it started, and not 2002. tbh"), + ), + ) + + var b bytes.Buffer + if err := textfmt.Markdown(&b, doc); err != nil { + t.Fatal(err) + } + + if b.String() != "2005\\. was the year when it started, and not 2002. tbh\n" { + t.Fatal(b.String()) + } }) })