gitea源码

markdown_math_test.go 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. // Copyright 2024 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package markdown
  4. import (
  5. "strings"
  6. "testing"
  7. "code.gitea.io/gitea/modules/markup"
  8. "code.gitea.io/gitea/modules/setting"
  9. "code.gitea.io/gitea/modules/test"
  10. "github.com/stretchr/testify/assert"
  11. )
  12. const nl = "\n"
  13. func TestMathRender(t *testing.T) {
  14. setting.Markdown.MathCodeBlockOptions = setting.MarkdownMathCodeBlockOptions{ParseInlineDollar: true, ParseInlineParentheses: true}
  15. testcases := []struct {
  16. testcase string
  17. expected string
  18. }{
  19. {
  20. "$a$",
  21. `<p><code class="language-math">a</code></p>` + nl,
  22. },
  23. {
  24. "$ a $",
  25. `<p><code class="language-math">a</code></p>` + nl,
  26. },
  27. {
  28. "$a$ $b$",
  29. `<p><code class="language-math">a</code> <code class="language-math">b</code></p>` + nl,
  30. },
  31. {
  32. `\(a\) \(b\)`,
  33. `<p><code class="language-math">a</code> <code class="language-math">b</code></p>` + nl,
  34. },
  35. {
  36. `$a$.`,
  37. `<p><code class="language-math">a</code>.</p>` + nl,
  38. },
  39. {
  40. `.$a$`,
  41. `<p>.$a$</p>` + nl,
  42. },
  43. {
  44. `$a a$b b$`,
  45. `<p>$a a$b b$</p>` + nl,
  46. },
  47. {
  48. `a a$b b`,
  49. `<p>a a$b b</p>` + nl,
  50. },
  51. {
  52. `a$b $a a$b b$`,
  53. `<p>a$b $a a$b b$</p>` + nl,
  54. },
  55. {
  56. "a$x$",
  57. `<p>a$x$</p>` + nl,
  58. },
  59. {
  60. "$x$a",
  61. `<p>$x$a</p>` + nl,
  62. },
  63. {
  64. "$a$ ($b$) [$c$] {$d$}",
  65. `<p><code class="language-math">a</code> (<code class="language-math">b</code>) [$c$] {$d$}</p>` + nl,
  66. },
  67. {
  68. "$$a$$",
  69. `<p><code class="language-math">a</code></p>` + nl,
  70. },
  71. {
  72. "$$a$$ test",
  73. `<p><code class="language-math">a</code> test</p>` + nl,
  74. },
  75. {
  76. "test $$a$$",
  77. `<p>test <code class="language-math">a</code></p>` + nl,
  78. },
  79. {
  80. `foo $x=\$$ bar`,
  81. `<p>foo <code class="language-math">x=\$</code> bar</p>` + nl,
  82. },
  83. {
  84. `$\text{$b$}$`,
  85. `<p><code class="language-math">\text{$b$}</code></p>` + nl,
  86. },
  87. {
  88. "a$`b`$c",
  89. `<p>a<code class="language-math">b</code>c</p>` + nl,
  90. },
  91. {
  92. "a $`b`$ c",
  93. `<p>a <code class="language-math">b</code> c</p>` + nl,
  94. },
  95. {
  96. "a$``b``$c x$```y```$z",
  97. `<p>a<code class="language-math">b</code>c x<code class="language-math">y</code>z</p>` + nl,
  98. },
  99. }
  100. for _, test := range testcases {
  101. t.Run(test.testcase, func(t *testing.T) {
  102. res, err := RenderString(markup.NewTestRenderContext(), test.testcase)
  103. assert.NoError(t, err)
  104. assert.Equal(t, test.expected, string(res))
  105. })
  106. }
  107. }
  108. func TestMathRenderBlockIndent(t *testing.T) {
  109. setting.Markdown.MathCodeBlockOptions = setting.MarkdownMathCodeBlockOptions{ParseBlockDollar: true, ParseBlockSquareBrackets: true}
  110. testcases := []struct {
  111. name string
  112. testcase string
  113. expected string
  114. }{
  115. {
  116. "indent-0",
  117. `
  118. \[
  119. \alpha
  120. \]
  121. `,
  122. `<pre class="code-block is-loading"><code class="language-math display">
  123. \alpha
  124. </code></pre>
  125. `,
  126. },
  127. {
  128. "indent-1",
  129. `
  130. \[
  131. \alpha
  132. \]
  133. `,
  134. `<pre class="code-block is-loading"><code class="language-math display">
  135. \alpha
  136. </code></pre>
  137. `,
  138. },
  139. {
  140. "indent-2-mismatch",
  141. `
  142. \[
  143. a
  144. b
  145. c
  146. d
  147. \]
  148. `,
  149. `<pre class="code-block is-loading"><code class="language-math display">
  150. a
  151. b
  152. c
  153. d
  154. </code></pre>
  155. `,
  156. },
  157. {
  158. "indent-2",
  159. `
  160. \[
  161. a
  162. b
  163. c
  164. \]
  165. `,
  166. `<pre class="code-block is-loading"><code class="language-math display">
  167. a
  168. b
  169. c
  170. </code></pre>
  171. `,
  172. },
  173. {
  174. "indent-0-oneline",
  175. `$$ x $$
  176. foo`,
  177. `<code class="language-math display"> x </code>
  178. <p>foo</p>
  179. `,
  180. },
  181. {
  182. "indent-3-oneline",
  183. ` $$ x $$<SPACE>
  184. foo`,
  185. `<code class="language-math display"> x </code>
  186. <p>foo</p>
  187. `,
  188. },
  189. {
  190. "quote-block",
  191. `
  192. > \[
  193. > a
  194. > \]
  195. > \[
  196. > b
  197. > \]
  198. `,
  199. `<blockquote>
  200. <pre class="code-block is-loading"><code class="language-math display">
  201. a
  202. </code></pre>
  203. <pre class="code-block is-loading"><code class="language-math display">
  204. b
  205. </code></pre>
  206. </blockquote>
  207. `,
  208. },
  209. {
  210. "list-block",
  211. `
  212. 1. a
  213. \[
  214. x
  215. \]
  216. 2. b`,
  217. `<ol>
  218. <li>a
  219. <pre class="code-block is-loading"><code class="language-math display">
  220. x
  221. </code></pre>
  222. </li>
  223. <li>b</li>
  224. </ol>
  225. `,
  226. },
  227. {
  228. "inline-non-math",
  229. `\[x]`,
  230. `<p>[x]</p>` + nl,
  231. },
  232. }
  233. for _, test := range testcases {
  234. t.Run(test.name, func(t *testing.T) {
  235. res, err := RenderString(markup.NewTestRenderContext(), strings.ReplaceAll(test.testcase, "<SPACE>", " "))
  236. assert.NoError(t, err)
  237. assert.Equal(t, test.expected, string(res), "unexpected result for test case:\n%s", test.testcase)
  238. })
  239. }
  240. }
  241. func TestMathRenderOptions(t *testing.T) {
  242. setting.Markdown.MathCodeBlockOptions = setting.MarkdownMathCodeBlockOptions{}
  243. defer test.MockVariableValue(&setting.Markdown.MathCodeBlockOptions)
  244. test := func(t *testing.T, expected, input string) {
  245. res, err := RenderString(markup.NewTestRenderContext(), input)
  246. assert.NoError(t, err)
  247. assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(res)), "input: %s", input)
  248. }
  249. // default (non-conflict) inline syntax
  250. test(t, `<p><code class="language-math">a</code></p>`, "$`a`$")
  251. // ParseInlineDollar
  252. test(t, `<p>$a$</p>`, `$a$`)
  253. setting.Markdown.MathCodeBlockOptions.ParseInlineDollar = true
  254. test(t, `<p><code class="language-math">a</code></p>`, `$a$`)
  255. // ParseInlineParentheses
  256. test(t, `<p>(a)</p>`, `\(a\)`)
  257. setting.Markdown.MathCodeBlockOptions.ParseInlineParentheses = true
  258. test(t, `<p><code class="language-math">a</code></p>`, `\(a\)`)
  259. // ParseBlockDollar
  260. test(t, `<p>$$
  261. a
  262. $$</p>
  263. `, `
  264. $$
  265. a
  266. $$
  267. `)
  268. setting.Markdown.MathCodeBlockOptions.ParseBlockDollar = true
  269. test(t, `<pre class="code-block is-loading"><code class="language-math display">
  270. a
  271. </code></pre>
  272. `, `
  273. $$
  274. a
  275. $$
  276. `)
  277. // ParseBlockSquareBrackets
  278. test(t, `<p>[
  279. a
  280. ]</p>
  281. `, `
  282. \[
  283. a
  284. \]
  285. `)
  286. setting.Markdown.MathCodeBlockOptions.ParseBlockSquareBrackets = true
  287. test(t, `<pre class="code-block is-loading"><code class="language-math display">
  288. a
  289. </code></pre>
  290. `, `
  291. \[
  292. a
  293. \]
  294. `)
  295. }