package markdown
import (
"strings"
"testing"
"github.com/yuin/goldmark/ast"
)
func TestParserParse(t *testing.T) {
t.Parallel()
cases := []struct {
name string
input string
want int
}{
{"empty", "", 0},
{"single_paragraph", "hello world", 1},
{"two_paragraphs", "hello\n\nworld", 2},
{"heading", "# title\n\nbody", 2},
{"list", "- one\n- two\n- three", 1},
{"fenced_code", "```go\nfmt.Println()\n```\n", 1},
}
p := NewParser()
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
doc, err := p.Parse([]byte(tc.input))
if err != nil {
t.Fatalf("Parse returned error: %v", err)
}
if doc == nil {
t.Fatal("Parse returned nil document")
}
got := doc.Root.ChildCount()
if got != tc.want {
t.Errorf("child count = %d, want %d", got, tc.want)
}
})
}
}
func TestParserParseReader(t *testing.T) {
t.Parallel()
p := NewParser()
doc, err := p.ParseReader(strings.NewReader("hello"))
if err != nil {
t.Fatalf("ParseReader: %v", err)
}
if doc.Root.ChildCount() != 1 {
t.Errorf("expected 1 child, got %d", doc.Root.ChildCount())
}
}
func TestParserWithOptions(t *testing.T) {
t.Parallel()
cases := []struct {
name string
opts []Option
input string
find string
}{
{"gfm_strikethrough", []Option{WithGFM()}, "~~gone~~", "gone"},
{"footnotes", []Option{WithFootnotes()}, "note[^1]\n\n[^1]: defn", "defn"},
{"auto_heading_id", []Option{WithAutoHeadingID()}, "# Hello World", "Hello World"},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
p := NewParser(tc.opts...)
doc, err := p.Parse([]byte(tc.input))
if err != nil {
t.Fatalf("Parse: %v", err)
}
var found bool
_ = ast.Walk(doc.Root, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
if !entering {
return ast.WalkContinue, nil
}
if t, ok := n.(*ast.Text); ok {
if strings.Contains(string(t.Segment.Value(doc.Source)), tc.find) {
found = true
return ast.WalkStop, nil
}
}
return ast.WalkContinue, nil
})
if !found {
t.Errorf("text %q not found in parsed tree", tc.find)
}
})
}
}
func TestDocumentTextOf(t *testing.T) {
t.Parallel()
p := NewParser()
doc, err := p.Parse([]byte("a *b* c"))
if err != nil {
t.Fatalf("Parse: %v", err)
}
var para ast.Node
_ = ast.Walk(doc.Root, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
if entering {
if _, ok := n.(*ast.Paragraph); ok {
para = n
return ast.WalkStop, nil
}
}
return ast.WalkContinue, nil
})
if para == nil {
t.Fatal("no paragraph found")
}
got := doc.TextOf(para)
if !strings.Contains(got, "a") {
t.Errorf("TextOf = %q, expected to contain 'a'", got)
}
}
func TestParseNilRootIsSafe(t *testing.T) {
t.Parallel()
t.Helper()
p := NewParser()
doc, err := p.Parse(nil)
if err != nil {
t.Fatalf("Parse(nil): %v", err)
}
if doc.Root == nil {
t.Fatal("Root should never be nil")
}
}