import { test } from 'uvu'
import * as assert from 'uvu/assert'
import { visit } from 'unist-util-visit'
import { rehype } from 'rehype'
import dedent from 'dedent'
import rehypePrism from './index.js'
/**
* Mock meta in code block
*/
const addMeta = (metastring) => {
if (!metastring) return
return (tree) => {
visit(tree, 'element', (node, index, parent) => {
if (node.tagName === 'code') {
node.data = { meta: metastring }
}
})
}
}
const processHtml = (html, options, metastring) => {
return rehype()
.data('settings', { fragment: true })
.use(addMeta, metastring)
.use(rehypePrism, options)
.processSync(html)
.toString()
}
test('adds a code-highlight class to the code and pre tag', () => {
const result = processHtml(dedent`
`)
const expected = dedent`
`
assert.is(result, expected)
})
test('add span with class code line for each line', () => {
const result = processHtml(
dedent`
x = 6
`
)
const expected = dedent`x = 6
`
assert.is(result, expected)
})
test('finds code and highlights', () => {
const result = processHtml(dedent`
`).trim()
const expected = dedent`
`
assert.is(result, expected)
})
test('respects line spacing', () => {
const result = processHtml(dedent`
`).trim()
const expected = dedent`
`
assert.is(result, expected)
})
test('handles uppercase correctly', () => {
const result = processHtml(dedent`
`).trim()
const expected = dedent`
`
assert.is(result, expected)
})
test('each line of code should be a separate div', async () => {
const result = processHtml(dedent`
`).trim()
const codeLineCount = (result.match(//g) || []).length
assert.is(codeLineCount, 2)
})
test('should highlight line', async () => {
const meta = '{1}'
const result = processHtml(
dedent`
`,
{},
meta
).trim()
const codeHighlightCount = (result.match(//g) || []).length
assert.is(codeHighlightCount, 1)
})
test('should highlight comma separated lines', async () => {
const meta = '{1,3}'
const result = processHtml(
dedent`
`,
{},
meta
).trim()
const codeHighlightCount = (result.match(//g) || []).length
assert.is(codeHighlightCount, 2)
})
test('should should parse ranges with a space in between', async () => {
const meta = '{1, 3}'
const result = processHtml(
dedent`
`,
{},
meta
).trim()
const codeHighlightCount = (result.match(//g) || []).length
assert.is(codeHighlightCount, 2)
})
test('should highlight range separated lines', async () => {
const meta = '{1-3}'
const result = processHtml(
dedent`
`,
{},
meta
).trim()
const codeHighlightCount = (result.match(//g) || []).length
assert.is(codeHighlightCount, 3)
})
test('showLineNumbers option add line numbers', async () => {
const result = processHtml(
dedent`
`,
{ showLineNumbers: true }
).trim()
assert.ok(result.match(/line="1"/g))
assert.ok(result.match(/line="2"/g))
assert.not(result.match(/line="3"/g))
})
test('not show line number when showLineNumbers=false', async () => {
const meta = 'showLineNumbers=false'
const result = processHtml(
dedent`
`,
{ showLineNumbers: true },
meta
).trim()
assert.not(result.match(/line="1"/g))
assert.not(result.match(/line="2"/g))
})
test('not show line number when showLineNumbers={false}', async () => {
const meta = 'showLineNumbers={false}'
const result = processHtml(
dedent`
`,
{ showLineNumbers: true },
meta
).trim()
assert.not(result.match(/line="1"/g))
assert.not(result.match(/line="2"/g))
})
test('showLineNumbers property works in meta field', async () => {
const meta = 'showLineNumbers'
const result = processHtml(
dedent`
`,
{},
meta
).trim()
assert.ok(result.match(/line="1"/g))
assert.ok(result.match(/line="2"/g))
assert.not(result.match(/line="3"/g))
})
test('showLineNumbers property with custom index works in meta field', async () => {
const meta = 'showLineNumbers=5'
const result = processHtml(
dedent`
`,
{},
meta
).trim()
assert.ok(result.match(/line="5"/g))
assert.ok(result.match(/line="6"/g))
assert.not(result.match(/line="7"/g))
})
test('should support both highlighting and add line number', async () => {
const meta = '{1} showLineNumbers'
const result = processHtml(
dedent`
`,
{},
meta
).trim()
const codeHighlightCount = (result.match(/highlight-line/g) || []).length
assert.is(codeHighlightCount, 1)
assert.ok(result.match(/line="1"/g))
assert.ok(result.match(/line="2"/g))
})
test('throw error with fake language- class', () => {
assert.throws(
() =>
processHtml(dedent`
x = 6
`),
/Unknown language/
)
})
test('with options.ignoreMissing, does nothing to code block with fake language- class', () => {
const result = processHtml(
dedent`
x = 6
`,
{ ignoreMissing: true }
)
const expected = dedent`x = 6
`
assert.is(result, expected)
})
test('should work with multiline code / comments', () => {
const result = processHtml(
dedent`
/**
* My comment
*/
`,
{ ignoreMissing: true }
)
const expected = dedent`
`
assert.is(result, expected)
})
test('adds inserted or deleted to code-line if lang=diff', async () => {
const result = processHtml(
dedent`
`
).trim()
assert.ok(result.includes(``))
assert.ok(result.includes(``))
assert.ok(result.includes(``))
})
test.run()