Files
helder/test/markdown.test.ts
Jonathan van Rij e126182ae6
Some checks failed
CI / check (push) Has been cancelled
improvements
2026-07-31 13:29:22 +02:00

74 lines
3.1 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { renderMarkdown } from '../src/renderer/src/markdown'
describe('renderMarkdown', () => {
it('renders headings, bold, italic and links', () => {
const html = renderMarkdown('# Title\n\nSome **bold** and *italic* and [a](https://x.com).')
expect(html).toContain('<h1>Title</h1>')
expect(html).toContain('<strong>bold</strong>')
expect(html).toContain('<em>italic</em>')
expect(html).toContain('<a href="https://x.com" target="_blank" rel="noreferrer">a</a>')
})
it('restores code spans without colliding with surrounding digits', () => {
// " 0 " around the text used to clash with the placeholder index — guard it.
const html = renderMarkdown('I have 0 cats and `code` and 1 dog.')
expect(html).toContain('<code>code</code>')
expect(html).toContain('I have 0 cats')
expect(html).toContain('1 dog.')
expect(html).not.toContain('undefined')
})
it('escapes HTML and never passes through raw tags', () => {
const html = renderMarkdown('A <script>alert(1)</script> tag.')
expect(html).toContain('&lt;script&gt;')
expect(html).not.toContain('<script>')
})
it('drops dangerous link schemes but keeps the text', () => {
const html = renderMarkdown('[click](javascript:alert(1))')
expect(html).not.toContain('javascript:')
expect(html).toContain('click')
})
it('highlights fenced code blocks', () => {
const html = renderMarkdown('```js\nconst a = 1\n```')
expect(html).toContain('<pre class="md-code">')
expect(html).toContain('const')
})
it('renders unordered and ordered lists', () => {
expect(renderMarkdown('- a\n- b')).toContain('<ul><li>a</li><li>b</li></ul>')
expect(renderMarkdown('1. a\n2. b')).toContain('<ol><li>a</li><li>b</li></ol>')
})
it('renders a GFM table with header, body and inline markup', () => {
const html = renderMarkdown('| a | b |\n|---|---|\n| 1 | `x` |\n| 2 | **y** |')
expect(html).toContain('<table class="md-table">')
expect(html).toContain('<thead><tr><th>a</th><th>b</th></tr></thead>')
expect(html).toContain('<td>1</td><td><code>x</code></td>')
expect(html).toContain('<strong>y</strong>')
})
it('applies column alignment from the delimiter row', () => {
const html = renderMarkdown('| l | c | r |\n| :-- | :-: | --: |\n| 1 | 2 | 3 |')
expect(html).toContain('<th style="text-align:left">l</th>')
expect(html).toContain('<th style="text-align:center">c</th>')
expect(html).toContain('<th style="text-align:right">r</th>')
expect(html).toContain('<td style="text-align:center">2</td>')
})
it('handles escaped pipes, ragged rows and pipe-less prose after the table', () => {
const html = renderMarkdown('| a | b |\n|---|---|\n| x \\| y | 2 |\n| short |\n\nAfter.')
expect(html).toContain('<td>x | y</td>')
expect(html).toContain('<td>short</td><td></td>')
expect(html).toContain('<p>After.</p>')
})
it('leaves a pipe-bearing paragraph alone when no delimiter row follows', () => {
const html = renderMarkdown('a | b\nnot a table')
expect(html).not.toContain('<table')
expect(html).toContain('<p>a | b not a table</p>')
})
})