Files
team/server/public/shared/markdown/inspect_test.go
2026-08-03 08:30:09 +03:00

178 lines
4.3 KiB
Go

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package markdown
import (
"fmt"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestInspect(t *testing.T) {
t.Run("base", func(t *testing.T) {
markdown := `
[foo]: bar
- a
> [![]()]()
> [![foo]][foo]
- d
`
visited := []string{}
level := 0
Inspect(markdown, func(blockOrInline any) bool {
if blockOrInline == nil {
level--
} else {
visited = append(visited, strings.Repeat(" ", level*4)+strings.TrimPrefix(fmt.Sprintf("%T", blockOrInline), "*markdown."))
level++
}
return true
})
assert.Equal(t, []string{
"Document",
" Paragraph",
" List",
" ListItem",
" Paragraph",
" Text",
" BlockQuote",
" Paragraph",
" InlineLink",
" InlineImage",
" SoftLineBreak",
" ReferenceLink",
" ReferenceImage",
" Text",
" ListItem",
" Paragraph",
" Text",
}, visited)
})
t.Run("visit nodes when len is smaller than maxLen", func(t *testing.T) {
n := MaxLen() / 5
markdown := strings.Repeat(`![`, n) + strings.Repeat(`]()`, n)
visited := []string{}
level := 0
Inspect(markdown, func(blockOrInline any) bool {
if blockOrInline == nil {
level--
} else {
visited = append(visited, strings.Repeat(" ", level*4)+strings.TrimPrefix(fmt.Sprintf("%T", blockOrInline), "*markdown."))
level++
}
return true
})
assert.NotEmpty(t, visited)
})
t.Run("do not visit any nodes when len is greater than maxLen", func(t *testing.T) {
n := (MaxLen() / 5) + 1
markdown := strings.Repeat(`![`, n) + strings.Repeat(`]()`, n)
visited := []string{}
level := 0
Inspect(markdown, func(blockOrInline any) bool {
if blockOrInline == nil {
level--
} else {
visited = append(visited, strings.Repeat(" ", level*4)+strings.TrimPrefix(fmt.Sprintf("%T", blockOrInline), "*markdown."))
level++
}
return true
})
assert.Empty(t, visited)
})
t.Run("a deeply nested single-line block quote is bounded rather than fully descended", func(t *testing.T) {
n := 20000
markdown := strings.Repeat("> ", n) + "x"
blockQuoteCount := 0
Inspect(markdown, func(blockOrInline any) bool {
if _, ok := blockOrInline.(*BlockQuote); ok {
blockQuoteCount++
}
return true
})
assert.Equal(t, maxNestingDepth-1, blockQuoteCount)
})
t.Run("a deeply nested single-line list is bounded rather than fully descended", func(t *testing.T) {
n := 20000
markdown := strings.Repeat("- ", n) + "x"
listCount := 0
Inspect(markdown, func(blockOrInline any) bool {
if _, ok := blockOrInline.(*List); ok {
listCount++
}
return true
})
assert.Equal(t, maxNestingDepth-1, listCount)
})
}
var counterSink int
func BenchmarkInspect(b *testing.B) {
text := `Some standard piece of text.
Has a link [post](https://github.com) and also has a blockquote.
> This is a famous quote.
Some bold text **Text for markdown?** to go with it.
At the end, some more lines`
for b.Loop() {
Inspect(text, func(_ any) bool {
counterSink++
return true
})
}
}
// BenchmarkInspectNestedBlockQuote and BenchmarkInspectNestedList measure the cost of parsing a
// single line made up of repeated block-quote/list markers. These benchmarks should scale roughly
// linearly with input size (i.e. per-op time should stay flat as the marker count grows), since the
// number of nested blocks actually created is capped at maxNestingDepth regardless of input size.
func BenchmarkInspectNestedBlockQuote(b *testing.B) {
for _, n := range []int{1_000, 10_000, 60_000} {
markdown := strings.Repeat("> ", n) + "x"
b.Run(fmt.Sprintf("n=%d", n), func(b *testing.B) {
for b.Loop() {
Inspect(markdown, func(_ any) bool {
counterSink++
return true
})
}
})
}
}
func BenchmarkInspectNestedList(b *testing.B) {
for _, n := range []int{1_000, 10_000, 60_000} {
markdown := strings.Repeat("- ", n) + "x"
b.Run(fmt.Sprintf("n=%d", n), func(b *testing.B) {
for b.Loop() {
Inspect(markdown, func(_ any) bool {
counterSink++
return true
})
}
})
}
}