import { assert } from 'chai' import markdownit from '../index.mjs' import forInline from 'markdown-it-for-inline' describe('API', function () { it('constructor', function () { assert.throws(function () { markdownit('bad preset') }) // options should override preset const md = markdownit('commonmark', { html: false }) assert.strictEqual(md.render(''), '
<!-- -->
\n') }) it('configure coverage', function () { const md = markdownit() // conditions coverage md.configure({}) assert.strictEqual(md.render('123'), '123
\n') assert.throws(function () { md.configure() }) }) it('plugin', function () { let succeeded = false function plugin (slf, opts) { if (opts === 'bar') { succeeded = true } } const md = markdownit() md.use(plugin, 'foo') assert.strictEqual(succeeded, false) md.use(plugin, 'bar') assert.strictEqual(succeeded, true) }) it('highlight', function () { const md = markdownit({ highlight: function (str) { return '==' + str + '==
'
}
})
assert.strictEqual(md.render('```\nhl\n```'), '==hl\n==
\n')
})
it('highlight escape by default', function () {
const md = markdownit({
highlight: function () {
return ''
}
})
assert.strictEqual(md.render('```\n&\n```'), '&\n
\n')
})
it('highlight arguments', function () {
const md = markdownit({
highlight: function (str, lang, attrs) {
assert.strictEqual(lang, 'a')
assert.strictEqual(attrs, 'b c d')
return '==' + str + '==
'
}
})
assert.strictEqual(md.render('``` a b c d \nhl\n```'), '==hl\n==
\n')
})
it('force hardbreaks', function () {
const md = markdownit({ breaks: true })
assert.strictEqual(md.render('a\nb'), 'a
\nb
a
\nb
a
\nb
a
\nb
foo\uFFFDbar
\n') }) it('Should correctly parse strings without tailing \\n', function () { const md = markdownit() assert.strictEqual(md.render('123'), '123
\n') assert.strictEqual(md.render('123\n'), '123
\n') assert.strictEqual(md.render(' codeblock'), 'codeblock\n
\n')
assert.strictEqual(md.render(' codeblock\n'), 'codeblock\n
\n')
})
it('Should quickly exit on empty string', function () {
const md = markdownit()
assert.strictEqual(md.render(''), '')
})
it('Should parse inlines only', function () {
const md = markdownit()
assert.strictEqual(md.renderInline('a *b* c'), 'a b c')
})
it('Renderer should have pluggable inline and block rules', function () {
const md = markdownit()
md.renderer.rules.em_open = function () { return '___foo___
\n') assert.strictEqual(md.renderInline('___foo___'), '___foo___') md.enable('emphasis') assert.strictEqual(md.render('___foo___'), 'foo
\n') assert.strictEqual(md.renderInline('___foo___'), 'foo') }) it('Should correctly check block termination rules when those are disabled (#13)', function () { const md = markdownit('zero') assert.strictEqual(md.render('foo\nbar'), 'foo\nbar
\n') }) it('Should render link target attr', function () { const md = markdownit() .use(forInline, 'target', 'link_open', function (tokens, idx) { tokens[idx].attrs.push(['target', '_blank']) }) assert.strictEqual(md.render('[foo](bar)'), '\n') }) it('Should normalize CR to LF', function () { const md = markdownit() assert.strictEqual( md.render('# test\r\r - hello\r - world\r'), md.render('# test\n\n - hello\n - world\n') ) }) it('Should normalize CR+LF to LF', function () { const md = markdownit() assert.strictEqual( md.render('# test\r\n\r\n - hello\r\n - world\r\n'), md.render('# test\n\n - hello\n - world\n') ) }) it('Should escape surrogate pairs (coverage)', function () { const md = markdownit() assert.strictEqual(md.render('\\\uD835\uDC9C'), '\\\uD835\uDC9C
\n') assert.strictEqual(md.render('\\\uD835x'), '\\\uD835x
\n') assert.strictEqual(md.render('\\\uD835'), '\\\uD835
\n') }) }) describe('Url normalization', function () { it('Should be overridable', function () { const md = markdownit({ linkify: true }) md.normalizeLink = function (url) { assert(url.match(/example\.com/), 'wrong url passed') return 'LINK' } md.normalizeLinkText = function (url) { assert(url.match(/example\.com/), 'wrong url passed') return 'TEXT' } assert.strictEqual(md.render('foo@example.com'), '\n') assert.strictEqual(md.render('http://example.com'), '\n') assert.strictEqual(md.render('foo@example.com
\n') assert.strictEqual(md.render('http://example.com'), 'http://example.com
\n') assert.strictEqual(md.render('<foo@example.com>
\n') assert.strictEqual(md.render('<http://example.com>
\n') assert.strictEqual(md.render('[test](http://example.com)'), '[test](http://example.com)
\n') assert.strictEqual(md.render('![test](http://example.com)'), '![test](http://example.com)
\n') }) }) describe('maxNesting', function () { it('Block parser should not nest above limit', function () { const md = markdownit({ maxNesting: 2 }) assert.strictEqual( md.render('>foo\n>>bar\n>>>baz'), '\n\n' ) }) it('Inline parser should not nest above limit', function () { const md = markdownit({ maxNesting: 1 }) assert.strictEqual( md.render('[`foo`]()'), '\n' ) }) it('Inline nesting coverage', function () { const md = markdownit({ maxNesting: 2 }) assert.strictEqual( md.render('[[[[[[[[[[[[[[[[[[foo]()'), 'foo
\n\n
[[[[[[[[[[[[[[[[[[foo]()
\n' ) }) }) describe('smartquotes', function () { const md = markdownit({ typographer: true, // all strings have different length to make sure // we didn't accidentally count the wrong one quotes: ['[[[', ']]', '(((((', '))))'] }) it('Should support multi-character quotes', function () { assert.strictEqual( md.render('"foo" \'bar\''), '[[[foo]] (((((bar))))
\n' ) }) it('Should support nested multi-character quotes', function () { assert.strictEqual( md.render('"foo \'bar\' baz"'), '[[[foo (((((bar)))) baz]]
\n' ) }) it('Should support multi-character quotes in different tags', function () { assert.strictEqual( md.render('"a *b \'c *d* e\' f* g"'), '[[[a b (((((c d e)))) f g]]
\n' ) }) }) describe('Ordered list info', function () { const md = markdownit() function type_filter (tokens, type) { return tokens.filter(function (t) { return t.type === type }) } it('Should mark ordered list item tokens with info', function () { let tokens = md.parse('1. Foo\n2. Bar\n20. Fuzz') assert.strictEqual(type_filter(tokens, 'ordered_list_open').length, 1) tokens = type_filter(tokens, 'list_item_open') assert.strictEqual(tokens.length, 3) assert.strictEqual(tokens[0].info, '1') assert.strictEqual(tokens[0].markup, '.') assert.strictEqual(tokens[1].info, '2') assert.strictEqual(tokens[1].markup, '.') assert.strictEqual(tokens[2].info, '20') assert.strictEqual(tokens[2].markup, '.') tokens = md.parse(' 1. Foo\n2. Bar\n 20. Fuzz\n 199. Flp') assert.strictEqual(type_filter(tokens, 'ordered_list_open').length, 1) tokens = type_filter(tokens, 'list_item_open') assert.strictEqual(tokens.length, 4) assert.strictEqual(tokens[0].info, '1') assert.strictEqual(tokens[0].markup, '.') assert.strictEqual(tokens[1].info, '2') assert.strictEqual(tokens[1].markup, '.') assert.strictEqual(tokens[2].info, '20') assert.strictEqual(tokens[2].markup, '.') assert.strictEqual(tokens[3].info, '199') assert.strictEqual(tokens[3].markup, '.') }) }) describe('Token attributes', function () { it('.attrJoin', function () { const md = markdownit() const tokens = md.parse('```') const t = tokens[0] t.attrJoin('class', 'foo') t.attrJoin('class', 'bar') assert.strictEqual( md.renderer.render(tokens, md.options), '
\n'
)
})
it('.attrSet', function () {
const md = markdownit()
const tokens = md.parse('```')
const t = tokens[0]
t.attrSet('class', 'foo')
assert.strictEqual(
md.renderer.render(tokens, md.options),
'
\n'
)
t.attrSet('class', 'bar')
assert.strictEqual(
md.renderer.render(tokens, md.options),
'
\n'
)
})
it('.attrGet', function () {
const md = markdownit()
const tokens = md.parse('```')
const t = tokens[0]
assert.strictEqual(t.attrGet('myattr'), null)
t.attrSet('myattr', 'myvalue')
assert.strictEqual(t.attrGet('myattr'), 'myvalue')
})
})