1778 lines
39 KiB
Go
1778 lines
39 KiB
Go
package textfmt_test
|
|
|
|
import (
|
|
"bytes"
|
|
"code.squareroundforest.org/arpio/textfmt"
|
|
"testing"
|
|
)
|
|
|
|
func TestMarkdown(t *testing.T) {
|
|
t.Run("invalid", func(t *testing.T) {
|
|
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) {
|
|
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) {
|
|
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(")"),
|
|
),
|
|
8,
|
|
0,
|
|
),
|
|
|
|
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) {
|
|
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) {
|
|
t.Run("top level", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Title(0, "This is a title"))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "# This is a title\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("second level", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Title(1, "This is a title"))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "## This is a title\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("fourth level", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Title(3, "This is a title"))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "#### This is a title\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("sixth level", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Title(5, "This is a title"))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "###### This is a title\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("overflow level", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Title(6, "This is a title"))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "###### This is a title\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("indent ignored", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Indent(textfmt.Title(1, "This is a title"), 4, 0))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "## This is a title\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("wrap ignored", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Wrap(textfmt.Title(1, "This is a title"), 6))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "## This is a title\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("paragraph", func(t *testing.T) {
|
|
t.Run("simple", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Paragraph(textfmt.Text("This is a sample paragraph.")))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "This is a sample paragraph.\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("wrap", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Wrap(textfmt.Paragraph(textfmt.Text("This is a sample paragraph.")), 6))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "This\nis a\nsample\nparagraph.\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("ignore indent", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Indent(textfmt.Paragraph(textfmt.Text("This is a sample paragraph.")), 4, 0))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "This is a sample paragraph.\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("cat", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Paragraph(
|
|
textfmt.Cat(
|
|
textfmt.Text("This is"),
|
|
textfmt.Text("a sample"),
|
|
textfmt.Text("paragraph."),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "This is a sample paragraph.\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("bold", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Paragraph(
|
|
textfmt.Cat(
|
|
textfmt.Text("This is"),
|
|
textfmt.Bold(textfmt.Text("a sample")),
|
|
textfmt.Text("paragraph."),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "This is **a sample** paragraph.\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("italic", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Paragraph(
|
|
textfmt.Cat(
|
|
textfmt.Text("This is"),
|
|
textfmt.Italic(textfmt.Text("a sample")),
|
|
textfmt.Text("paragraph."),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "This is _a sample_ paragraph.\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("bold italic", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Paragraph(
|
|
textfmt.Cat(
|
|
textfmt.Italic(textfmt.Text("This is")),
|
|
textfmt.Italic(textfmt.Bold(textfmt.Text("a sample"))),
|
|
textfmt.Italic(textfmt.Text("paragraph.")),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "_This is_ **_a sample_** _paragraph._\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("link", func(t *testing.T) {
|
|
t.Run("normal", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Paragraph(
|
|
textfmt.Cat(
|
|
textfmt.Text("This is a "),
|
|
textfmt.Link("link", "https://foo.bar"),
|
|
textfmt.Text("alright."),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "This is a [link](https://foo.bar) alright.\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("without label", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Paragraph(
|
|
textfmt.Cat(
|
|
textfmt.Text("This is a "),
|
|
textfmt.Link("", "https://foo.bar"),
|
|
textfmt.Text("alright."),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "This is a https://foo.bar alright.\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("escape", func(t *testing.T) {
|
|
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) {
|
|
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 non link", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Paragraph(
|
|
textfmt.Text("[looks-like-a-link] but it's not"),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "\\[looks-like-a-link\\] but it's not\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("escape negative number on line start", func(t *testing.T) {
|
|
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) {
|
|
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())
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("list", func(t *testing.T) {
|
|
t.Run("simple", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.List(
|
|
textfmt.Item(textfmt.Text("item one")),
|
|
textfmt.Item(textfmt.Text("item two")),
|
|
textfmt.Item(textfmt.Text("item three")),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
- item one
|
|
- item two
|
|
- item three
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("indent ignored", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Indent(
|
|
textfmt.List(
|
|
textfmt.Item(textfmt.Text("item one")),
|
|
textfmt.Item(textfmt.Text("item two")),
|
|
textfmt.Item(textfmt.Text("item three")),
|
|
),
|
|
4,
|
|
0,
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
- item one
|
|
- item two
|
|
- item three
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("wrapped", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Wrap(
|
|
textfmt.List(
|
|
textfmt.Item(textfmt.Text("item one")),
|
|
textfmt.Item(textfmt.Text("item two")),
|
|
textfmt.Item(textfmt.Text("item three")),
|
|
),
|
|
6,
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
- item
|
|
one
|
|
- item
|
|
two
|
|
- item
|
|
three
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("numbered list", func(t *testing.T) {
|
|
t.Run("simple", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.NumberedList(
|
|
textfmt.Item(textfmt.Text("item one")),
|
|
textfmt.Item(textfmt.Text("item two")),
|
|
textfmt.Item(textfmt.Text("item three")),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
1. item one
|
|
2. item two
|
|
3. item three
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
logBytes(t, expect)
|
|
logBytes(t, "\n"+b.String())
|
|
t.Log(expect)
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("indent ignored", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Indent(
|
|
textfmt.NumberedList(
|
|
textfmt.Item(textfmt.Text("item one")),
|
|
textfmt.Item(textfmt.Text("item two")),
|
|
textfmt.Item(textfmt.Text("item three")),
|
|
),
|
|
4,
|
|
0,
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
1. item one
|
|
2. item two
|
|
3. item three
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
logBytes(t, expect)
|
|
logBytes(t, "\n"+b.String())
|
|
t.Log(expect)
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("wrap", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Wrap(
|
|
textfmt.NumberedList(
|
|
textfmt.Item(textfmt.Text("item one")),
|
|
textfmt.Item(textfmt.Text("item two")),
|
|
textfmt.Item(textfmt.Text("item three")),
|
|
),
|
|
9,
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
1. item
|
|
one
|
|
2. item
|
|
two
|
|
3. item
|
|
three
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
logBytes(t, expect)
|
|
logBytes(t, "\n"+b.String())
|
|
t.Log(expect)
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("long list", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Wrap(
|
|
textfmt.NumberedList(
|
|
textfmt.Item(textfmt.Text("item one")),
|
|
textfmt.Item(textfmt.Text("item two")),
|
|
textfmt.Item(textfmt.Text("item three")),
|
|
textfmt.Item(textfmt.Text("item four")),
|
|
textfmt.Item(textfmt.Text("item five")),
|
|
textfmt.Item(textfmt.Text("item six")),
|
|
textfmt.Item(textfmt.Text("item seven")),
|
|
textfmt.Item(textfmt.Text("item eight")),
|
|
textfmt.Item(textfmt.Text("item nine")),
|
|
textfmt.Item(textfmt.Text("item ten")),
|
|
textfmt.Item(textfmt.Text("item eleven")),
|
|
textfmt.Item(textfmt.Text("item twelve")),
|
|
),
|
|
9,
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
1. item
|
|
one
|
|
2. item
|
|
two
|
|
3. item
|
|
three
|
|
4. item
|
|
four
|
|
5. item
|
|
five
|
|
6. item
|
|
six
|
|
7. item
|
|
seven
|
|
8. item
|
|
eight
|
|
9. item
|
|
nine
|
|
10. item
|
|
ten
|
|
11. item
|
|
eleven
|
|
12. item
|
|
twelve
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
logBytes(t, expect)
|
|
logBytes(t, "\n"+b.String())
|
|
t.Log(expect)
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("definitions", func(t *testing.T) {
|
|
t.Run("simple", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.DefinitionList(
|
|
textfmt.Definition(textfmt.Text("red"), textfmt.Text("looks like strawberry")),
|
|
textfmt.Definition(textfmt.Text("green"), textfmt.Text("looks like grass")),
|
|
textfmt.Definition(textfmt.Text("blue"), textfmt.Text("looks like sky")),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
- red: looks like strawberry
|
|
- green: looks like grass
|
|
- blue: looks like sky
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("indent ignored", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Indent(
|
|
textfmt.DefinitionList(
|
|
textfmt.Definition(textfmt.Text("red"), textfmt.Text("looks like strawberry")),
|
|
textfmt.Definition(textfmt.Text("green"), textfmt.Text("looks like grass")),
|
|
textfmt.Definition(textfmt.Text("blue"), textfmt.Text("looks like sky")),
|
|
),
|
|
4,
|
|
0,
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
- red: looks like strawberry
|
|
- green: looks like grass
|
|
- blue: looks like sky
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("wrap", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Wrap(
|
|
textfmt.DefinitionList(
|
|
textfmt.Definition(textfmt.Text("red"), textfmt.Text("looks like strawberry")),
|
|
textfmt.Definition(textfmt.Text("green"), textfmt.Text("looks like grass")),
|
|
textfmt.Definition(textfmt.Text("blue"), textfmt.Text("looks like sky")),
|
|
),
|
|
15,
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
- red: looks
|
|
like
|
|
strawberry
|
|
- green: looks
|
|
like grass
|
|
- blue: looks
|
|
like sky
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("numbered definitions", func(t *testing.T) {
|
|
t.Run("simple", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.NumberedDefinitionList(
|
|
textfmt.Definition(textfmt.Text("red"), textfmt.Text("looks like strawberry")),
|
|
textfmt.Definition(textfmt.Text("green"), textfmt.Text("looks like grass")),
|
|
textfmt.Definition(textfmt.Text("blue"), textfmt.Text("looks like sky")),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
1. red: looks like strawberry
|
|
2. green: looks like grass
|
|
3. blue: looks like sky
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("indent ignored", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Indent(
|
|
textfmt.NumberedDefinitionList(
|
|
textfmt.Definition(textfmt.Text("red"), textfmt.Text("looks like strawberry")),
|
|
textfmt.Definition(textfmt.Text("green"), textfmt.Text("looks like grass")),
|
|
textfmt.Definition(textfmt.Text("blue"), textfmt.Text("looks like sky")),
|
|
),
|
|
4,
|
|
0,
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
1. red: looks like strawberry
|
|
2. green: looks like grass
|
|
3. blue: looks like sky
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("wrap", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Wrap(
|
|
textfmt.NumberedDefinitionList(
|
|
textfmt.Definition(textfmt.Text("red"), textfmt.Text("looks like strawberry")),
|
|
textfmt.Definition(textfmt.Text("green"), textfmt.Text("looks like grass")),
|
|
textfmt.Definition(textfmt.Text("blue"), textfmt.Text("looks like sky")),
|
|
),
|
|
16,
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
1. red: looks
|
|
like
|
|
strawberry
|
|
2. green: looks
|
|
like grass
|
|
3. blue: looks
|
|
like sky
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("long list", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Wrap(
|
|
textfmt.NumberedDefinitionList(
|
|
textfmt.Definition(textfmt.Text("one"), textfmt.Text("this is an item")),
|
|
textfmt.Definition(textfmt.Text("two"), textfmt.Text("this is another item")),
|
|
textfmt.Definition(textfmt.Text("three"), textfmt.Text("this is the third item")),
|
|
textfmt.Definition(textfmt.Text("four"), textfmt.Text("this is the fourth item")),
|
|
textfmt.Definition(textfmt.Text("five"), textfmt.Text("this is the fifth item")),
|
|
textfmt.Definition(textfmt.Text("six"), textfmt.Text("this is the sixth item")),
|
|
textfmt.Definition(textfmt.Text("seven"), textfmt.Text("this is the seventh item")),
|
|
textfmt.Definition(textfmt.Text("eight"), textfmt.Text("this is the eighth item")),
|
|
textfmt.Definition(textfmt.Text("nine"), textfmt.Text("this is the nineth item")),
|
|
textfmt.Definition(textfmt.Text("ten"), textfmt.Text("this is the tenth item")),
|
|
textfmt.Definition(textfmt.Text("eleven"), textfmt.Text("this is the eleventh item")),
|
|
textfmt.Definition(textfmt.Text("twelve"), textfmt.Text("this is the twelfth item")),
|
|
),
|
|
21,
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
1. one: this is an
|
|
item
|
|
2. two: this is
|
|
another item
|
|
3. three: this is
|
|
the third
|
|
item
|
|
4. four: this is the
|
|
fourth item
|
|
5. five: this is the
|
|
fifth item
|
|
6. six: this is the
|
|
sixth item
|
|
7. seven: this is
|
|
the seventh
|
|
item
|
|
8. eight: this is
|
|
the eighth
|
|
item
|
|
9. nine: this is the
|
|
nineth item
|
|
10. ten: this is the
|
|
tenth item
|
|
11. eleven: this is
|
|
the eleventh
|
|
item
|
|
12. twelve: this is
|
|
the twelfth
|
|
item
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("table", func(t *testing.T) {
|
|
t.Run("no rows", func(t *testing.T) {
|
|
var b bytes.Buffer
|
|
doc := textfmt.Doc(textfmt.Table())
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("no columns", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Table(
|
|
textfmt.Row(),
|
|
textfmt.Row(),
|
|
textfmt.Row(),
|
|
),
|
|
)
|
|
|
|
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("basic", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Table(
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("1")), textfmt.Cell(textfmt.Text("2")), textfmt.Cell(textfmt.Text("3")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("4")), textfmt.Cell(textfmt.Text("5")), textfmt.Cell(textfmt.Text("6")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("7")), textfmt.Cell(textfmt.Text("8")), textfmt.Cell(textfmt.Text("9")),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| \- | \- | \- |
|
|
|----|----|----|
|
|
| 1 | 2 | 3 |
|
|
| 4 | 5 | 6 |
|
|
| 7 | 8 | 9 |
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("basic with header", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Table(
|
|
textfmt.Header(
|
|
textfmt.Cell(textfmt.Text("1")), textfmt.Cell(textfmt.Text("-1")), textfmt.Cell(textfmt.Text("0")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("1")), textfmt.Cell(textfmt.Text("2")), textfmt.Cell(textfmt.Text("3")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("4")), textfmt.Cell(textfmt.Text("5")), textfmt.Cell(textfmt.Text("6")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("7")), textfmt.Cell(textfmt.Text("8")), textfmt.Cell(textfmt.Text("9")),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| 1 | \-1 | 0 |
|
|
|---|-----|---|
|
|
| 1 | 2 | 3 |
|
|
| 4 | 5 | 6 |
|
|
| 7 | 8 | 9 |
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("header without rows", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Table(
|
|
textfmt.Header(
|
|
textfmt.Cell(textfmt.Text("foo")),
|
|
textfmt.Cell(textfmt.Text("bar")),
|
|
textfmt.Cell(textfmt.Text("baz")),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| foo | bar | baz |
|
|
|-----|-----|-----|
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("single row", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Table(
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("1")),
|
|
textfmt.Cell(textfmt.Text("2")),
|
|
textfmt.Cell(textfmt.Text("3")),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| \- | \- | \- |
|
|
|----|----|----|
|
|
| 1 | 2 | 3 |
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("single row with header", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Table(
|
|
textfmt.Header(
|
|
textfmt.Cell(textfmt.Text("foo")),
|
|
textfmt.Cell(textfmt.Text("bar")),
|
|
textfmt.Cell(textfmt.Text("baz")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("1")),
|
|
textfmt.Cell(textfmt.Text("2")),
|
|
textfmt.Cell(textfmt.Text("3")),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| foo | bar | baz |
|
|
|-----|-----|-----|
|
|
| 1 | 2 | 3 |
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("single column", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Table(
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("1")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("4")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("7")),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| \- |
|
|
|----|
|
|
| 1 |
|
|
| 4 |
|
|
| 7 |
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("single column with header", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Table(
|
|
textfmt.Header(
|
|
textfmt.Cell(textfmt.Text("foo")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("1")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("4")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("7")),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| foo |
|
|
|-----|
|
|
| 1 |
|
|
| 4 |
|
|
| 7 |
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("single row and single column", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Table(
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("1")),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| \- |
|
|
|----|
|
|
| 1 |
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("single row and single column with header", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Table(
|
|
textfmt.Header(
|
|
textfmt.Cell(textfmt.Text("foo")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("1")),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| foo |
|
|
|-----|
|
|
| 1 |
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("unequal number of row cells", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Table(
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("1")), textfmt.Cell(textfmt.Text("2")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("4")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("7")), textfmt.Cell(textfmt.Text("8")), textfmt.Cell(textfmt.Text("9")),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| \- | \- | \- |
|
|
|----|----|----|
|
|
| 1 | 2 | |
|
|
| 4 | | |
|
|
| 7 | 8 | 9 |
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("unequal number of row cells with header", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Table(
|
|
textfmt.Header(
|
|
textfmt.Cell(textfmt.Text("1")), textfmt.Cell(textfmt.Text("-1")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("1")), textfmt.Cell(textfmt.Text("2")), textfmt.Cell(textfmt.Text("3")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("4")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("")), textfmt.Cell(textfmt.Text("8")), textfmt.Cell(textfmt.Text("9")),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| 1 | \-1 | \- |
|
|
|---|-----|----|
|
|
| 1 | 2 | 3 |
|
|
| 4 | | |
|
|
| | 8 | 9 |
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("all empty cells", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Wrap(
|
|
textfmt.Table(
|
|
textfmt.Header(textfmt.Cell(textfmt.Text("")), textfmt.Cell(textfmt.Text(""))),
|
|
textfmt.Row(textfmt.Cell(textfmt.Text("")), textfmt.Cell(textfmt.Text(""))),
|
|
textfmt.Row(textfmt.Cell(textfmt.Text("")), textfmt.Cell(textfmt.Text(""))),
|
|
),
|
|
72,
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| \- | \- |
|
|
|----|----|
|
|
| | |
|
|
| | |
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("ignore indent", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Indent(
|
|
textfmt.Table(
|
|
textfmt.Header(
|
|
textfmt.Cell(textfmt.Text("one")),
|
|
textfmt.Cell(textfmt.Text("two")),
|
|
textfmt.Cell(textfmt.Text("three")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("Walking through the mixed forests of Brandenburg in early autumn")),
|
|
textfmt.Cell(textfmt.Text("one notices the dominant presence of Scots pine (Pinus sylvestris)")),
|
|
textfmt.Cell(textfmt.Text("interspersed with sessile oak (Quercus petraea)")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("and silver birch (Betula pendula)")),
|
|
textfmt.Cell(textfmt.Text("their canopies creating a mosaic of light")),
|
|
textfmt.Cell(textfmt.Text("and shadow on the forest floor")),
|
|
),
|
|
),
|
|
4,
|
|
0,
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| one | two | three |
|
|
|------------------------------------------------------------------|--------------------------------------------------------------------|-------------------------------------------------|
|
|
| Walking through the mixed forests of Brandenburg in early autumn | one notices the dominant presence of Scots pine (Pinus sylvestris) | interspersed with sessile oak (Quercus petraea) |
|
|
| and silver birch (Betula pendula) | their canopies creating a mosaic of light | and shadow on the forest floor |
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
logBytes(t, expect)
|
|
logBytes(t, "\n"+b.String())
|
|
t.Log(expect)
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("ignore wrap", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Wrap(
|
|
textfmt.Table(
|
|
textfmt.Header(
|
|
textfmt.Cell(textfmt.Text("one")),
|
|
textfmt.Cell(textfmt.Text("two")),
|
|
textfmt.Cell(textfmt.Text("three")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("Walking through the mixed forests of Brandenburg in early autumn")),
|
|
textfmt.Cell(textfmt.Text("one notices the dominant presence of Scots pine (Pinus sylvestris)")),
|
|
textfmt.Cell(textfmt.Text("interspersed with sessile oak (Quercus petraea)")),
|
|
),
|
|
textfmt.Row(
|
|
textfmt.Cell(textfmt.Text("and silver birch (Betula pendula)")),
|
|
textfmt.Cell(textfmt.Text("their canopies creating a mosaic of light")),
|
|
textfmt.Cell(textfmt.Text("and shadow on the forest floor")),
|
|
),
|
|
),
|
|
72,
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const expect = `
|
|
| one | two | three |
|
|
|------------------------------------------------------------------|--------------------------------------------------------------------|-------------------------------------------------|
|
|
| Walking through the mixed forests of Brandenburg in early autumn | one notices the dominant presence of Scots pine (Pinus sylvestris) | interspersed with sessile oak (Quercus petraea) |
|
|
| and silver birch (Betula pendula) | their canopies creating a mosaic of light | and shadow on the forest floor |
|
|
`
|
|
|
|
if "\n"+b.String() != expect {
|
|
logBytes(t, expect)
|
|
logBytes(t, "\n"+b.String())
|
|
t.Log(expect)
|
|
t.Fatal("\n" + b.String())
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("code", func(t *testing.T) {
|
|
t.Run("basic", func(t *testing.T) {
|
|
const code = `func() textfmt.Document {
|
|
return textfmt.Document(
|
|
textfmt.Paragraph(textfmt.Text("Hello, world!")),
|
|
)
|
|
}`
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, textfmt.Doc(textfmt.CodeBlock(code))); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\n"+code+"\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("indent ignored", func(t *testing.T) {
|
|
const code = `func() textfmt.Document {
|
|
return textfmt.Document(
|
|
textfmt.Paragraph(textfmt.Text("Hello, world!")),
|
|
)
|
|
}`
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, textfmt.Doc(textfmt.Indent(textfmt.CodeBlock(code), 4, 0))); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\n"+code+"\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("wrap has no effect", func(t *testing.T) {
|
|
const code = `func() textfmt.Document {
|
|
return textfmt.Document(
|
|
textfmt.Paragraph(textfmt.Text("Hello, world!")),
|
|
)
|
|
}`
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, textfmt.Doc(textfmt.Wrap(textfmt.CodeBlock(code), 12))); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\n"+code+"\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("syntax", func(t *testing.T) {
|
|
t.Run("symbol", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Syntax(textfmt.Symbol("foo")))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\nfoo\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("zero or more symbols", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Syntax(textfmt.ZeroOrMore(textfmt.Symbol("foo"))))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\n[foo]...\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("one or more", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Syntax(textfmt.OneOrMore(textfmt.Symbol("foo"))))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\n<foo>...\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("required symbol", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Syntax(textfmt.Required(textfmt.Symbol("foo"))))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\n<foo>\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("optional symbol", func(t *testing.T) {
|
|
doc := textfmt.Doc(textfmt.Syntax(textfmt.Optional(textfmt.Symbol("foo"))))
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\n[foo]\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("sequence implicit", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Syntax(
|
|
textfmt.Symbol("foo"),
|
|
textfmt.Symbol("bar"),
|
|
textfmt.Symbol("baz"),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\nfoo bar baz\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("sequence", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Syntax(
|
|
textfmt.Sequence(
|
|
textfmt.Symbol("foo"),
|
|
textfmt.Symbol("bar"),
|
|
textfmt.Symbol("baz"),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\nfoo bar baz\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("subsequence", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Syntax(
|
|
textfmt.Symbol("corge"),
|
|
textfmt.Sequence(
|
|
textfmt.Symbol("foo"),
|
|
textfmt.Symbol("bar"),
|
|
textfmt.Symbol("baz"),
|
|
),
|
|
textfmt.Symbol("garply"),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\ncorge (foo bar baz) garply\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("top level choice", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Syntax(
|
|
textfmt.Choice(
|
|
textfmt.Symbol("foo"),
|
|
textfmt.Symbol("bar"),
|
|
textfmt.Symbol("baz"),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\nfoo\nbar\nbaz\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("top level choice with sequence item", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Syntax(
|
|
textfmt.Choice(
|
|
textfmt.Symbol("foo"),
|
|
textfmt.Sequence(textfmt.Symbol("bar"), textfmt.Symbol("baz")),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\nfoo\nbar baz\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("choice", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Syntax(
|
|
textfmt.Symbol("corge"),
|
|
textfmt.Choice(
|
|
textfmt.Symbol("foo"),
|
|
textfmt.Symbol("bar"),
|
|
textfmt.Symbol("baz"),
|
|
),
|
|
textfmt.Symbol("garply"),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\ncorge (foo|bar|baz) garply\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
|
|
t.Run("example", func(t *testing.T) {
|
|
doc := textfmt.Doc(
|
|
textfmt.Syntax(
|
|
textfmt.Symbol("foo"),
|
|
textfmt.ZeroOrMore(textfmt.Symbol("options")),
|
|
textfmt.Required(textfmt.Symbol("filename")),
|
|
textfmt.ZeroOrMore(
|
|
textfmt.Choice(
|
|
textfmt.Symbol("string"),
|
|
textfmt.Symbol("number"),
|
|
),
|
|
),
|
|
),
|
|
)
|
|
|
|
var b bytes.Buffer
|
|
if err := textfmt.Markdown(&b, doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if b.String() != "```\nfoo [options]... <filename> [string|number]...\n```\n" {
|
|
t.Fatal(b.String())
|
|
}
|
|
})
|
|
})
|
|
}
|