mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 11:07:18 -04:00 
			
		
		
		
	* Fix #27645 * Add config options `MATH_CODE_BLOCK_DETECTION`, problematic syntaxes are disabled by default * Fix #33639 * Add config options `RENDER_OPTIONS_*`, old behaviors are kept
		
			
				
	
	
		
			311 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			311 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2024 The Gitea Authors. All rights reserved.
 | |
| // SPDX-License-Identifier: MIT
 | |
| 
 | |
| package markdown
 | |
| 
 | |
| import (
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| 
 | |
| 	"code.gitea.io/gitea/modules/markup"
 | |
| 	"code.gitea.io/gitea/modules/setting"
 | |
| 	"code.gitea.io/gitea/modules/test"
 | |
| 
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| )
 | |
| 
 | |
| const nl = "\n"
 | |
| 
 | |
| func TestMathRender(t *testing.T) {
 | |
| 	setting.Markdown.MathCodeBlockOptions = setting.MarkdownMathCodeBlockOptions{ParseInlineDollar: true, ParseInlineParentheses: true}
 | |
| 	testcases := []struct {
 | |
| 		testcase string
 | |
| 		expected string
 | |
| 	}{
 | |
| 		{
 | |
| 			"$a$",
 | |
| 			`<p><code class="language-math">a</code></p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			"$ a $",
 | |
| 			`<p><code class="language-math">a</code></p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			"$a$ $b$",
 | |
| 			`<p><code class="language-math">a</code> <code class="language-math">b</code></p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			`\(a\) \(b\)`,
 | |
| 			`<p><code class="language-math">a</code> <code class="language-math">b</code></p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			`$a$.`,
 | |
| 			`<p><code class="language-math">a</code>.</p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			`.$a$`,
 | |
| 			`<p>.$a$</p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			`$a a$b b$`,
 | |
| 			`<p>$a a$b b$</p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			`a a$b b`,
 | |
| 			`<p>a a$b b</p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			`a$b $a a$b b$`,
 | |
| 			`<p>a$b $a a$b b$</p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			"a$x$",
 | |
| 			`<p>a$x$</p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			"$x$a",
 | |
| 			`<p>$x$a</p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			"$a$ ($b$) [$c$] {$d$}",
 | |
| 			`<p><code class="language-math">a</code> (<code class="language-math">b</code>) [$c$] {$d$}</p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			"$$a$$",
 | |
| 			`<p><code class="language-math">a</code></p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			"$$a$$ test",
 | |
| 			`<p><code class="language-math">a</code> test</p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			"test $$a$$",
 | |
| 			`<p>test <code class="language-math">a</code></p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			`foo $x=\$$ bar`,
 | |
| 			`<p>foo <code class="language-math">x=\$</code> bar</p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			`$\text{$b$}$`,
 | |
| 			`<p><code class="language-math">\text{$b$}</code></p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			"a$`b`$c",
 | |
| 			`<p>a<code class="language-math">b</code>c</p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			"a $`b`$ c",
 | |
| 			`<p>a <code class="language-math">b</code> c</p>` + nl,
 | |
| 		},
 | |
| 		{
 | |
| 			"a$``b``$c x$```y```$z",
 | |
| 			`<p>a<code class="language-math">b</code>c x<code class="language-math">y</code>z</p>` + nl,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, test := range testcases {
 | |
| 		t.Run(test.testcase, func(t *testing.T) {
 | |
| 			res, err := RenderString(markup.NewTestRenderContext(), test.testcase)
 | |
| 			assert.NoError(t, err)
 | |
| 			assert.Equal(t, test.expected, string(res))
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestMathRenderBlockIndent(t *testing.T) {
 | |
| 	setting.Markdown.MathCodeBlockOptions = setting.MarkdownMathCodeBlockOptions{ParseBlockDollar: true, ParseBlockSquareBrackets: true}
 | |
| 	testcases := []struct {
 | |
| 		name     string
 | |
| 		testcase string
 | |
| 		expected string
 | |
| 	}{
 | |
| 		{
 | |
| 			"indent-0",
 | |
| 			`
 | |
| \[
 | |
| \alpha
 | |
| \]
 | |
| `,
 | |
| 			`<pre class="code-block is-loading"><code class="language-math display">
 | |
| \alpha
 | |
| </code></pre>
 | |
| `,
 | |
| 		},
 | |
| 		{
 | |
| 			"indent-1",
 | |
| 			`
 | |
|  \[
 | |
|  \alpha
 | |
|  \]
 | |
| `,
 | |
| 			`<pre class="code-block is-loading"><code class="language-math display">
 | |
| \alpha
 | |
| </code></pre>
 | |
| `,
 | |
| 		},
 | |
| 		{
 | |
| 			"indent-2-mismatch",
 | |
| 			`
 | |
|   \[
 | |
| a
 | |
|  b
 | |
|   c
 | |
|    d
 | |
|   \]
 | |
| `,
 | |
| 			`<pre class="code-block is-loading"><code class="language-math display">
 | |
| a
 | |
| b
 | |
| c
 | |
|  d
 | |
| </code></pre>
 | |
| `,
 | |
| 		},
 | |
| 		{
 | |
| 			"indent-2",
 | |
| 			`
 | |
|   \[
 | |
|   a
 | |
|    b
 | |
|   c
 | |
|   \]
 | |
| `,
 | |
| 			`<pre class="code-block is-loading"><code class="language-math display">
 | |
| a
 | |
|  b
 | |
| c
 | |
| </code></pre>
 | |
| `,
 | |
| 		},
 | |
| 		{
 | |
| 			"indent-0-oneline",
 | |
| 			`$$ x $$
 | |
| foo`,
 | |
| 			`<code class="language-math display"> x </code>
 | |
| <p>foo</p>
 | |
| `,
 | |
| 		},
 | |
| 		{
 | |
| 			"indent-3-oneline",
 | |
| 			`   $$ x $$<SPACE>
 | |
| foo`,
 | |
| 			`<code class="language-math display"> x </code>
 | |
| <p>foo</p>
 | |
| `,
 | |
| 		},
 | |
| 		{
 | |
| 			"quote-block",
 | |
| 			`
 | |
| > \[
 | |
| > a
 | |
| > \]
 | |
| > \[
 | |
| > b
 | |
| > \]
 | |
| `,
 | |
| 			`<blockquote>
 | |
| <pre class="code-block is-loading"><code class="language-math display">
 | |
| a
 | |
| </code></pre>
 | |
| <pre class="code-block is-loading"><code class="language-math display">
 | |
| b
 | |
| </code></pre>
 | |
| </blockquote>
 | |
| `,
 | |
| 		},
 | |
| 		{
 | |
| 			"list-block",
 | |
| 			`
 | |
| 1. a
 | |
|    \[
 | |
|    x
 | |
|    \]
 | |
| 2. b`,
 | |
| 			`<ol>
 | |
| <li>a
 | |
| <pre class="code-block is-loading"><code class="language-math display">
 | |
| x
 | |
| </code></pre>
 | |
| </li>
 | |
| <li>b</li>
 | |
| </ol>
 | |
| `,
 | |
| 		},
 | |
| 		{
 | |
| 			"inline-non-math",
 | |
| 			`\[x]`,
 | |
| 			`<p>[x]</p>` + nl,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, test := range testcases {
 | |
| 		t.Run(test.name, func(t *testing.T) {
 | |
| 			res, err := RenderString(markup.NewTestRenderContext(), strings.ReplaceAll(test.testcase, "<SPACE>", " "))
 | |
| 			assert.NoError(t, err)
 | |
| 			assert.Equal(t, test.expected, string(res), "unexpected result for test case:\n%s", test.testcase)
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestMathRenderOptions(t *testing.T) {
 | |
| 	setting.Markdown.MathCodeBlockOptions = setting.MarkdownMathCodeBlockOptions{}
 | |
| 	defer test.MockVariableValue(&setting.Markdown.MathCodeBlockOptions)
 | |
| 	test := func(t *testing.T, expected, input string) {
 | |
| 		res, err := RenderString(markup.NewTestRenderContext(), input)
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(res)), "input: %s", input)
 | |
| 	}
 | |
| 
 | |
| 	// default (non-conflict) inline syntax
 | |
| 	test(t, `<p><code class="language-math">a</code></p>`, "$`a`$")
 | |
| 
 | |
| 	// ParseInlineDollar
 | |
| 	test(t, `<p>$a$</p>`, `$a$`)
 | |
| 	setting.Markdown.MathCodeBlockOptions.ParseInlineDollar = true
 | |
| 	test(t, `<p><code class="language-math">a</code></p>`, `$a$`)
 | |
| 
 | |
| 	// ParseInlineParentheses
 | |
| 	test(t, `<p>(a)</p>`, `\(a\)`)
 | |
| 	setting.Markdown.MathCodeBlockOptions.ParseInlineParentheses = true
 | |
| 	test(t, `<p><code class="language-math">a</code></p>`, `\(a\)`)
 | |
| 
 | |
| 	// ParseBlockDollar
 | |
| 	test(t, `<p>$$
 | |
| a
 | |
| $$</p>
 | |
| `, `
 | |
| $$
 | |
| a
 | |
| $$
 | |
| `)
 | |
| 	setting.Markdown.MathCodeBlockOptions.ParseBlockDollar = true
 | |
| 	test(t, `<pre class="code-block is-loading"><code class="language-math display">
 | |
| a
 | |
| </code></pre>
 | |
| `, `
 | |
| $$
 | |
| a
 | |
| $$
 | |
| `)
 | |
| 
 | |
| 	// ParseBlockSquareBrackets
 | |
| 	test(t, `<p>[
 | |
| a
 | |
| ]</p>
 | |
| `, `
 | |
| \[
 | |
| a
 | |
| \]
 | |
| `)
 | |
| 	setting.Markdown.MathCodeBlockOptions.ParseBlockSquareBrackets = true
 | |
| 	test(t, `<pre class="code-block is-loading"><code class="language-math display">
 | |
| a
 | |
| </code></pre>
 | |
| `, `
 | |
| \[
 | |
| a
 | |
| \]
 | |
| `)
 | |
| }
 |