import { expect } from '@open-wc/testing'; import { markdownToHtml, looksLikeMarkdown, inlineToHtml } from './markdown-parse'; import { defaultSchema, htmlToDoc, docToMarkdown } from './index'; describe('markdown-parse', () => { describe('markdownToHtml — blocks', () => { it('parses headings', () => { expect(markdownToHtml('# One')).to.equal('

One

'); expect(markdownToHtml('### Three')).to.equal('

Three

'); expect(markdownToHtml('## Trailing ##')).to.equal('

Trailing

'); }); it('parses paragraphs and hard breaks', () => { expect(markdownToHtml('one\ntwo\n\nthree')).to.equal( '

one
two

three

' ); }); it('parses blockquotes with lazy continuation', () => { expect(markdownToHtml('> quoted\ncontinues')).to.equal( '

quoted
continues

' ); }); it('parses fenced code blocks with language', () => { expect(markdownToHtml('```js\nconst a = 1 < 2;\n```')).to.equal( '
const a = 1 < 2;
' ); }); it('keeps markdown syntax literal inside code fences', () => { expect(markdownToHtml('```\n# not a heading\n**not bold**\n```')).to.equal( '
# not a heading\n**not bold**
' ); }); it('parses horizontal rules but not list dashes', () => { expect(markdownToHtml('---')).to.equal('
'); expect(markdownToHtml('- item')).to.equal(''); }); it('parses nested bullet lists', () => { expect(markdownToHtml('- a\n - b')).to.equal( '' ); }); it('parses ordered lists with a start offset', () => { expect(markdownToHtml('3. three\n4. four')).to.equal( '
  1. three

  2. four

' ); }); it('splits sibling lists when the marker type changes', () => { expect(markdownToHtml('- a\n1. b')).to.equal( '
  1. b

' ); }); it('parses task lists without converting plain neighbours', () => { expect(markdownToHtml('- plain\n- [x] done')).to.equal( '' + '' ); }); it('parses GFM tables with header cells', () => { expect(markdownToHtml('| A | B |\n| - | - |\n| 1 | 2 |')).to.equal( '' + '

A

B

1

2

' ); }); }); describe('inlineToHtml — marks', () => { it('converts the inline marks', () => { expect(inlineToHtml('**b** *i* ~~s~~ `c`')).to.equal( 'b i s c' ); }); it('converts links and images', () => { expect(inlineToHtml('[x](https://a.b)')).to.equal('x'); expect(inlineToHtml('![y](https://a.b/i.png)')).to.equal( 'y' ); }); it('escapes HTML in text and keeps code spans literal', () => { expect(inlineToHtml('hi')).to.equal('<b>hi</b>'); expect(inlineToHtml('`*literal*`')).to.equal('*literal*'); }); it('honors backslash escapes', () => { expect(inlineToHtml('\\*not italic\\*')).to.equal('*not italic*'); }); it('does not read mid-word underscores as emphasis', () => { expect(inlineToHtml('snake_case_name')).to.equal('snake_case_name'); }); }); describe('round-trip with docToMarkdown', () => { it('survives a structural round-trip', () => { const source = [ '# Title', '', 'Some **bold** and *italic* text.', '', '- one', '- two', '', '```js', 'const x = 1;', '```', ].join('\n'); const doc = htmlToDoc(defaultSchema, markdownToHtml(source)); expect(docToMarkdown(doc).trim()).to.equal(source); }); it('round-trips task lists', () => { const source = '- [ ] todo\n- [x] done'; const doc = htmlToDoc(defaultSchema, markdownToHtml(source)); expect(docToMarkdown(doc).trim()).to.equal(source); }); }); describe('looksLikeMarkdown', () => { it('detects block constructs', () => { expect(looksLikeMarkdown('# Heading')).to.be.true; expect(looksLikeMarkdown('- a list item')).to.be.true; expect(looksLikeMarkdown('1. ordered')).to.be.true; expect(looksLikeMarkdown('> quote')).to.be.true; expect(looksLikeMarkdown('```\ncode\n```')).to.be.true; }); it('detects unambiguous inline constructs', () => { expect(looksLikeMarkdown('some **bold** text')).to.be.true; expect(looksLikeMarkdown('a [link](https://x.y) here')).to.be.true; }); it('rejects plain text and HTML', () => { expect(looksLikeMarkdown('just a sentence.')).to.be.false; expect(looksLikeMarkdown('2 * 3 = 6 and 4 - 2 = 2')).to.be.false; expect(looksLikeMarkdown('

markup

')).to.be.false; }); }); });