mirror of https://github.com/usememos/memos
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
4.3 KiB
Go
177 lines
4.3 KiB
Go
package renderer
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/yuin/goldmark"
|
|
"github.com/yuin/goldmark/extension"
|
|
"github.com/yuin/goldmark/parser"
|
|
"github.com/yuin/goldmark/text"
|
|
|
|
"github.com/usememos/memos/plugin/markdown/extensions"
|
|
)
|
|
|
|
func TestMarkdownRenderer(t *testing.T) {
|
|
// Create goldmark instance with all extensions
|
|
md := goldmark.New(
|
|
goldmark.WithExtensions(
|
|
extension.GFM,
|
|
extensions.TagExtension,
|
|
),
|
|
goldmark.WithParserOptions(
|
|
parser.WithAutoHeadingID(),
|
|
),
|
|
)
|
|
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "simple text",
|
|
input: "Hello world",
|
|
expected: "Hello world",
|
|
},
|
|
{
|
|
name: "paragraph with newlines",
|
|
input: "First paragraph\n\nSecond paragraph",
|
|
expected: "First paragraph\n\nSecond paragraph",
|
|
},
|
|
{
|
|
name: "emphasis",
|
|
input: "This is *italic* and **bold** text",
|
|
expected: "This is *italic* and **bold** text",
|
|
},
|
|
{
|
|
name: "headings",
|
|
input: "# Heading 1\n\n## Heading 2\n\n### Heading 3",
|
|
expected: "# Heading 1\n\n## Heading 2\n\n### Heading 3",
|
|
},
|
|
{
|
|
name: "link",
|
|
input: "Check [this link](https://example.com)",
|
|
expected: "Check [this link](https://example.com)",
|
|
},
|
|
{
|
|
name: "image",
|
|
input: "",
|
|
expected: "",
|
|
},
|
|
{
|
|
name: "code inline",
|
|
input: "This is `inline code` here",
|
|
expected: "This is `inline code` here",
|
|
},
|
|
{
|
|
name: "code block fenced",
|
|
input: "```go\nfunc main() {\n}\n```",
|
|
expected: "```go\nfunc main() {\n}\n```",
|
|
},
|
|
{
|
|
name: "unordered list",
|
|
input: "- Item 1\n- Item 2\n- Item 3",
|
|
expected: "- Item 1\n- Item 2\n- Item 3",
|
|
},
|
|
{
|
|
name: "ordered list",
|
|
input: "1. First\n2. Second\n3. Third",
|
|
expected: "1. First\n2. Second\n3. Third",
|
|
},
|
|
{
|
|
name: "blockquote",
|
|
input: "> This is a quote\n> Second line",
|
|
expected: "> This is a quote\n> Second line",
|
|
},
|
|
{
|
|
name: "horizontal rule",
|
|
input: "Text before\n\n---\n\nText after",
|
|
expected: "Text before\n\n---\n\nText after",
|
|
},
|
|
{
|
|
name: "strikethrough",
|
|
input: "This is ~~deleted~~ text",
|
|
expected: "This is ~~deleted~~ text",
|
|
},
|
|
{
|
|
name: "task list",
|
|
input: "- [x] Completed task\n- [ ] Incomplete task",
|
|
expected: "- [x] Completed task\n- [ ] Incomplete task",
|
|
},
|
|
{
|
|
name: "tag",
|
|
input: "This has #tag in it",
|
|
expected: "This has #tag in it",
|
|
},
|
|
{
|
|
name: "multiple tags",
|
|
input: "#work #important meeting notes",
|
|
expected: "#work #important meeting notes",
|
|
},
|
|
{
|
|
name: "complex mixed content",
|
|
input: "# Meeting Notes\n\n**Date**: 2024-01-01\n\n## Attendees\n- Alice\n- Bob\n\n## Discussion\n\nWe discussed #project status.\n\n```python\nprint('hello')\n```",
|
|
expected: "# Meeting Notes\n\n**Date**: 2024-01-01\n\n## Attendees\n\n- Alice\n- Bob\n\n## Discussion\n\nWe discussed #project status.\n\n```python\nprint('hello')\n```",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Parse the input
|
|
source := []byte(tt.input)
|
|
reader := text.NewReader(source)
|
|
doc := md.Parser().Parse(reader)
|
|
require.NotNil(t, doc)
|
|
|
|
// Render back to markdown
|
|
renderer := NewMarkdownRenderer()
|
|
result := renderer.Render(doc, source)
|
|
|
|
// For debugging
|
|
if result != tt.expected {
|
|
t.Logf("Input: %q", tt.input)
|
|
t.Logf("Expected: %q", tt.expected)
|
|
t.Logf("Got: %q", result)
|
|
}
|
|
|
|
assert.Equal(t, tt.expected, result)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMarkdownRendererPreservesStructure(t *testing.T) {
|
|
// Test that parsing and rendering preserves structure
|
|
md := goldmark.New(
|
|
goldmark.WithExtensions(
|
|
extension.GFM,
|
|
extensions.TagExtension,
|
|
),
|
|
)
|
|
|
|
inputs := []string{
|
|
"# Title\n\nParagraph",
|
|
"**Bold** and *italic*",
|
|
"- List\n- Items",
|
|
"#tag #another",
|
|
"> Quote",
|
|
}
|
|
|
|
renderer := NewMarkdownRenderer()
|
|
|
|
for _, input := range inputs {
|
|
t.Run(input, func(t *testing.T) {
|
|
source := []byte(input)
|
|
reader := text.NewReader(source)
|
|
doc := md.Parser().Parse(reader)
|
|
|
|
result := renderer.Render(doc, source)
|
|
|
|
// The result should be structurally similar
|
|
// (may have minor formatting differences)
|
|
assert.NotEmpty(t, result)
|
|
})
|
|
}
|
|
}
|