memos/internal/markdown/parser/math_test.go

80 lines
2.9 KiB
Go

package parser
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/yuin/goldmark"
gast "github.com/yuin/goldmark/ast"
gparser "github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/text"
"github.com/yuin/goldmark/util"
mast "github.com/usememos/memos/internal/markdown/ast"
)
func TestInlineMathParserDollarBoundaries(t *testing.T) {
tests := []struct {
name string
source string
expected []string
}{
{name: "valid single dollar math", source: "$x$", expected: []string{"$x$"}},
{name: "currency stays literal", source: "$20,000 and $30,000"},
{
name: "multiline currency list stays literal",
source: `list of 10 houses
$140,000 max - buffer of ~10k
diy, add amount to down payment
no appliances covered
less than $1,000, client responsibilities
over $1,000 - owner responsibility
vacant is good to rent
for sale by owner
path to ownership -$50
rent insurance - my of`,
},
{name: "opening followed by whitespace", source: "$ x$"},
{name: "opening followed by tab", source: "$\tx$"},
{name: "opening followed by line ending", source: "$\nx$"},
{name: "opening followed by Unicode whitespace", source: "$\u00a0x$"},
{name: "opening followed by next line character", source: "$\u0085x$"},
{name: "closing preceded by whitespace", source: "$x $"},
{name: "closing preceded by tab", source: "$x\t$"},
{name: "closing followed by digit", source: "$x$2"},
{name: "retry after closer preceded by whitespace", source: "$x $ and $y$", expected: []string{"$y$"}},
{name: "retry after closer followed by digit", source: "$x$2 and $y$", expected: []string{"$y$"}},
{name: "retry after currency dollars", source: "$20 and $30 then $x$", expected: []string{"$x$"}},
{name: "closing followed by Unicode digit", source: "$x$٢", expected: []string{"$x$"}},
{name: "valid multiline math", source: "$x +\ny$", expected: []string{"$x +\ny$"}},
{name: "multiline closing at line start", source: "$x\n$"},
{name: "exact closing run", source: "$x$$ y$", expected: []string{"$x$$ y$"}},
{name: "opener after escaped dollar", source: `\$$x$`, expected: []string{"$x$"}},
{name: "multi-dollar boundaries unchanged", source: "$$ x $$2", expected: []string{"$$ x $$"}},
}
md := goldmark.New(
goldmark.WithParserOptions(
gparser.WithInlineParsers(
util.Prioritized(NewInlineMathParser(), 150),
),
),
)
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
document := md.Parser().Parse(text.NewReader([]byte(test.source)))
var actual []string
err := gast.Walk(document, func(node gast.Node, entering bool) (gast.WalkStatus, error) {
if entering {
if mathNode, ok := node.(*mast.InlineMathNode); ok {
actual = append(actual, string(mathNode.Source))
}
}
return gast.WalkContinue, nil
})
require.NoError(t, err)
assert.Equal(t, test.expected, actual)
})
}
}