llm browser
This commit is contained in:
1 parent
afed023152
commit
a4dbb75195
39 files changed
+3709
-58
No files matched your search
@@ -0,0 +1,107 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { parseInline, parseMarkdown } from '../src/components/markdown/parse'
|
||||
import type { InlineSpan } from '../src/components/markdown/parse'
|
||||
|
||||
/* Parser tests pin the shapes the Go converter emits — this renderer never
|
||||
sees arbitrary markdown, so these cases are the whole contract. */
|
||||
|
||||
function text(spans: InlineSpan[]): string {
|
||||
return spans.map(span => (span.kind === 'text' ? span.text : '')).join('')
|
||||
}
|
||||
|
||||
describe('parseMarkdown blocks', () => {
|
||||
it('parses headings, paragraphs and rules', () => {
|
||||
const blocks = parseMarkdown('# Title\n\nBody text.\n\n---\n\n### Deep')
|
||||
expect(blocks).toEqual([
|
||||
{ kind: 'heading', level: 1, spans: [{ kind: 'text', text: 'Title' }] },
|
||||
{ kind: 'paragraph', spans: [{ kind: 'text', text: 'Body text.' }] },
|
||||
{ kind: 'hr' },
|
||||
{ kind: 'heading', level: 3, spans: [{ kind: 'text', text: 'Deep' }] },
|
||||
])
|
||||
})
|
||||
|
||||
it('parses fenced code with language', () => {
|
||||
const blocks = parseMarkdown('```go\nfmt.Println("hi")\n```')
|
||||
expect(blocks).toEqual([{ kind: 'code', language: 'go', text: 'fmt.Println("hi")' }])
|
||||
})
|
||||
|
||||
it('parses blockquotes by re-parsing their content', () => {
|
||||
const blocks = parseMarkdown('> quoted\n> more')
|
||||
expect(blocks).toEqual([
|
||||
{
|
||||
kind: 'quote',
|
||||
blocks: [{ kind: 'paragraph', spans: [{ kind: 'text', text: 'quoted more' }] }],
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it('parses flat and nested lists', () => {
|
||||
const blocks = parseMarkdown('- one\n- two\n 1. inner\n3. three')
|
||||
expect(blocks).toEqual([
|
||||
{
|
||||
kind: 'list',
|
||||
ordered: false,
|
||||
start: 1,
|
||||
items: [
|
||||
{ spans: [{ kind: 'text', text: 'one' }] },
|
||||
{
|
||||
spans: [{ kind: 'text', text: 'two' }],
|
||||
sub: {
|
||||
kind: 'list',
|
||||
ordered: true,
|
||||
start: 1,
|
||||
items: [{ spans: [{ kind: 'text', text: 'inner' }] }],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
kind: 'list',
|
||||
ordered: true,
|
||||
start: 3,
|
||||
items: [{ spans: [{ kind: 'text', text: 'three' }] }],
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it('parses GFM tables', () => {
|
||||
const blocks = parseMarkdown('| A | B |\n| --- | --- |\n| 1 | 2 |')
|
||||
expect(blocks).toEqual([{ kind: 'table', head: ['A', 'B'], rows: [['1', '2']] }])
|
||||
})
|
||||
})
|
||||
|
||||
describe('parseInline', () => {
|
||||
it('splits links, code and emphasis', () => {
|
||||
const spans = parseInline('see [Docs](https://x.test/d) and `code` plus **bold** *em* ~~gone~~')
|
||||
expect(spans).toEqual([
|
||||
{ kind: 'text', text: 'see ' },
|
||||
{ kind: 'link', href: 'https://x.test/d', spans: [{ kind: 'text', text: 'Docs' }] },
|
||||
{ kind: 'text', text: ' and ' },
|
||||
{ kind: 'code', text: 'code' },
|
||||
{ kind: 'text', text: ' plus ' },
|
||||
{ kind: 'strong', spans: [{ kind: 'text', text: 'bold' }] },
|
||||
{ kind: 'text', text: ' ' },
|
||||
{ kind: 'em', spans: [{ kind: 'text', text: 'em' }] },
|
||||
{ kind: 'text', text: ' ' },
|
||||
{ kind: 'del', spans: [{ kind: 'text', text: 'gone' }] },
|
||||
])
|
||||
})
|
||||
|
||||
it('parses images with alt text', () => {
|
||||
const spans = parseInline('')
|
||||
expect(spans).toEqual([{ kind: 'image', alt: 'Logo', src: 'https://x.test/l.png' }])
|
||||
})
|
||||
|
||||
it('keeps link titles out of the href', () => {
|
||||
const spans = parseInline('[API](https://x.test "the api")')
|
||||
expect(spans).toEqual([
|
||||
{ kind: 'link', href: 'https://x.test', spans: [{ kind: 'text', text: 'API' }] },
|
||||
])
|
||||
})
|
||||
|
||||
it('leaves plain text untouched', () => {
|
||||
const spans = parseInline('just words')
|
||||
expect(spans).toHaveLength(1)
|
||||
expect(text(spans)).toBe('just words')
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user