1
0
textfmt/markdown_test.go

1491 lines
32 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) {
t.Fatal()
})
t.Run("empty", func(t *testing.T) {
t.Fatal()
})
t.Run("example", func(t *testing.T) {
t.Fatal()
})
t.Run("write error", func(t *testing.T) {
t.Fatal()
})
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("escape", func(t *testing.T) {
t.Fatal()
})
t.Run("escape link", func(t *testing.T) {
t.Fatal()
})
t.Run("escape negative number on line start", func(t *testing.T) {
t.Fatal()
})
t.Run("escape year on line start", func(t *testing.T) {
t.Fatal()
})
})
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("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())
}
})
})
}