import { ribbit } from './setup'; const lib = ribbit(); const editor = new lib.Editor({}); const hopdown = editor.converter; const H = (md: string) => hopdown.toHTML(md); const M = (html: string) => hopdown.toMarkdown(html); const rt = (md: string) => M(H(md)); describe('Markdown → HTML', () => { describe('inline formatting', () => { it('bold', () => expect(H('**bold**')).toBe('

bold

')); it('italic', () => expect(H('*italic*')).toBe('

italic

')); it('inline code', () => expect(H('`code`')).toBe('

code

')); it('link', () => expect(H('[t](http://x)')).toBe('

t

')); it('bold+italic', () => expect(H('***bi***')).toBe('

bi

')); it('mixed', () => expect(H('a **b** *c* `d`')).toBe('

a b c d

')); it('code before bold', () => expect(H('`a` **b**')).toBe('

a b

')); }); describe('headings', () => { it.each([1, 2, 3, 4, 5, 6])('h%i', (level) => { const prefix = '#'.repeat(level); expect(H(`${prefix} Sub`)).toContain(` expect(H('## Hello World')).toContain("id='HelloWorld'")); it('heading inline md', () => expect(H('## **Bold** text')).toContain('Bold')); }); describe('horizontal rules', () => { it('***', () => expect(H('***')).toBe('
')); it('---', () => expect(H('---')).toBe('
')); it('___', () => expect(H('___')).toBe('
')); }); describe('lists', () => { it('ul *', () => expect(H('* a\n* b')).toBe('')); it('ul -', () => expect(H('- a\n- b')).toBe('')); it('ol', () => expect(H('1. a\n2. b')).toBe('
  1. a
  2. b
')); it('ul inline', () => expect(H('* **bold** item')).toContain('bold')); }); describe('blockquotes', () => { it('basic', () => expect(H('> text')).toContain('
')); it('content', () => expect(H('> hello')).toContain('hello')); it('multi-line', () => expect(H('> a\n> b')).toContain('a')); }); describe('fenced code', () => { it('basic', () => expect(H('```\nx = 1\n```')).toContain('
'));
        it('content', () => expect(H('```\nx = 1\n```')).toContain('x = 1'));
        it('language', () => expect(H('```js\nvar x;\n```')).toContain('language-js'));
        it('escapes html', () => expect(H('```\n
\n```')).toContain('<div>')); it('no lang when none', () => expect(H('```\nplain\n```')).not.toContain('language-')); }); describe('tables', () => { const tbl = '| a | b |\n|---|---|\n| 1 | 2 |'; it('table tag', () => expect(H(tbl)).toContain('')); it('thead', () => expect(H(tbl)).toContain('')); it('th cells', () => expect(H(tbl)).toContain('')); it('td cells', () => expect(H(tbl)).toContain('')); it('center align', () => expect(H('| C |\n|:--:|\n| x |')).toContain('text-align:center')); it('right align', () => expect(H('| R |\n|--:|\n| x |')).toContain('text-align:right')); it('inline md', () => expect(H('| **b** |\n|---|\n| x |')).toContain('b')); }); describe('paragraphs', () => { it('single', () => expect(H('hello')).toBe('

hello

')); it('two', () => expect(H('a\n\nb')).toBe('

a

\n

b

')); it('soft break', () => expect(H('a\nb')).toBe('

a\nb

')); }); describe('edge cases', () => { it('empty', () => expect(H('')).toBe('')); it('whitespace', () => expect(H(' ')).toBe('')); it('html entities', () => expect(H('a & b < c')).toContain('&')); it('html in code', () => expect(H('`
`')).toContain('<div>')); it('para then heading', () => expect(H('text\n\n## H')).toContain(' expect(H('- a\n\ntext')).toContain('

text

')); }); }); describe('HTML → Markdown', () => { it('strong→**', () => expect(M('

b

')).toBe('**b**')); it('em→*', () => expect(M('

i

')).toBe('*i*')); it('code→`', () => expect(M('

c

')).toBe('`c`')); it('a→[]', () => expect(M('t')).toBe('[t](http://x)')); it('h1→#', () => expect(M('

T

')).toBe('# T')); it('hr→---', () => expect(M('
')).toBe('---')); it('ul→-', () => expect(M('
  • a
  • b
')).toBe('- a\n- b')); it('ol→1.', () => expect(M('
  1. a
  2. b
')).toBe('1. a\n2. b')); it('bq→>', () => expect(M('

q

')).toContain('> ')); it('pre→```', () => expect(M('
x
')).toContain('```')); it('pre lang', () => expect(M('
x
')).toContain('```py')); it('table→pipes', () => { const html = '
a1
ab
12
'; expect(M(html)).toContain('| a | b |'); }); }); describe('Round-trips', () => { it.each([ ['paragraph', 'Hello world'], ['bold', '**bold**'], ['italic', '*italic*'], ['code', '`code`'], ['link', '[t](http://x)'], ['h1', '# Title'], ['h2', '## Sub'], ['ul', '- a\n- b'], ['ol', '1. a\n2. b'], ])('%s', (_, md) => expect(rt(md)).toBe(md)); it('hr', () => expect(rt('---')).toBe('---')); it('blockquote', () => expect(rt('> quoted')).toContain('> ')); it('code block', () => expect(rt('```\nx = 1\n```')).toContain('```')); it('table', () => expect(rt('| a | b |\n|---|---|\n| 1 | 2 |')).toContain('| a | b |')); }); describe('Nested inline', () => { it('bold wraps italic', () => expect(H('**a *b* c**')).toBe('

a b c

')); it('italic wraps bold', () => expect(H('*a **b** c*')).toBe('

a b c

')); it('bold wraps code', () => expect(H('**a `b` c**')).toBe('

a b c

')); it('bold wraps link', () => expect(H('**[t](u)**')).toBe('

t

')); it('link with bold', () => expect(H('[**t**](u)')).toBe('

t

')); it('link with code', () => expect(H('[`t`](u)')).toBe('

t

')); }); describe('Nested blocks', () => { it('bq > heading', () => expect(H('> # Title')).toContain(' list', () => expect(H('> - a\n> - b')).toContain('