167 lines
3.8 KiB
TypeScript
167 lines
3.8 KiB
TypeScript
import type { App } from 'vuepress/core'
|
|
import type { ReplOptions } from '../src/shared/repl.js'
|
|
import { dirname } from 'node:path'
|
|
import { path } from '@vuepress/utils'
|
|
import { resolveModule } from 'local-pkg'
|
|
import MarkdownIt from 'markdown-it'
|
|
import { fs, vol } from 'memfs'
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { langReplPlugin } from '../src/node/container/langRepl.js'
|
|
|
|
vi.mock('node:fs', () => fs)
|
|
vi.mock('node:fs/promises', () => fs.promises)
|
|
|
|
beforeEach(() => vol.reset())
|
|
afterEach(() => vol.reset())
|
|
|
|
const FENCE = '```'
|
|
|
|
const themesPath = dirname(resolveModule('tm-themes', {
|
|
paths: [import.meta.url],
|
|
}) || '')
|
|
const grammarsPath = dirname(resolveModule('tm-grammars', {
|
|
paths: [import.meta.url],
|
|
}) || '')
|
|
|
|
async function createMarkdown(options: ReplOptions = {}) {
|
|
const md = new MarkdownIt()
|
|
md.options.highlight = (str, lang) => `<div class="language-${lang}"><pre><code>${str}</code></pre></div>`
|
|
const app = {
|
|
writeTemp: vi.fn((filepath: string, content: string) => {
|
|
filepath = path.join('/', filepath)
|
|
fs.mkdirSync(dirname(filepath), { recursive: true })
|
|
fs.writeFileSync(filepath, content)
|
|
}),
|
|
} as unknown as App
|
|
|
|
await langReplPlugin(app, md, options)
|
|
|
|
return { md, app }
|
|
}
|
|
|
|
function initFs() {
|
|
vol.fromJSON({
|
|
[path.join(themesPath, 'themes/github-light.json')]: '{ "theme": "github-light" }',
|
|
[path.join(themesPath, 'themes/github-dark.json')]: '{ "theme": "github-dark" }',
|
|
[path.join(grammarsPath, 'grammars/go.json')]: '{ "language": "go" }',
|
|
[path.join(grammarsPath, 'grammars/kotlin.json')]: '{ "language": "kotlin" }',
|
|
[path.join(grammarsPath, 'grammars/rust.json')]: '{ "language": "rust" }',
|
|
[path.join(grammarsPath, 'grammars/python.json')]: '{ "language": "python" }',
|
|
})
|
|
}
|
|
|
|
describe('langReplPlugin', () => {
|
|
const outputFile = '/internal/md-power/replEditorData.js'
|
|
|
|
const code = `\
|
|
::: go-repl
|
|
${FENCE}go
|
|
const a = 1
|
|
${FENCE}
|
|
:::
|
|
|
|
::: go-repl editable
|
|
${FENCE}go
|
|
const a = 1
|
|
${FENCE}
|
|
:::
|
|
|
|
::: kotlin-repl
|
|
${FENCE}kotlin
|
|
const a = 1
|
|
${FENCE}
|
|
:::
|
|
|
|
::: kotlin-repl editable
|
|
${FENCE}kotlin
|
|
const a = 1
|
|
${FENCE}
|
|
:::
|
|
|
|
::: rust-repl
|
|
${FENCE}rust
|
|
const a = 1
|
|
${FENCE}
|
|
:::
|
|
|
|
::: rust-repl editable
|
|
${FENCE}rust
|
|
const a = 1
|
|
${FENCE}
|
|
:::
|
|
|
|
::: rust-repl title="title"
|
|
${FENCE}rust
|
|
const a = 1
|
|
${FENCE}
|
|
:::
|
|
|
|
::: rust-repl editable title="title"
|
|
${FENCE}rust
|
|
const a = 1
|
|
${FENCE}
|
|
:::
|
|
|
|
::: python-repl
|
|
${FENCE}python
|
|
hello_world()
|
|
${FENCE}
|
|
:::
|
|
|
|
::: python-repl editable
|
|
${FENCE}python
|
|
hello_world()
|
|
${FENCE}
|
|
:::
|
|
|
|
::: python-repl title="title"
|
|
${FENCE}python
|
|
hello_world()
|
|
${FENCE}
|
|
:::
|
|
|
|
::: python-repl editable title="title"
|
|
${FENCE}python
|
|
hello_world()
|
|
${FENCE}
|
|
:::
|
|
`
|
|
it('should work with default options', async () => {
|
|
initFs()
|
|
const { md, app } = await createMarkdown()
|
|
|
|
expect(md.render(code)).toMatchSnapshot()
|
|
expect(app.writeTemp).toBeCalledWith(outputFile.slice(1), expect.any(String))
|
|
expect(fs.readFileSync(outputFile, 'utf-8')).toMatchSnapshot()
|
|
})
|
|
|
|
it('should work with custom options', async () => {
|
|
initFs()
|
|
const { md, app } = await createMarkdown({
|
|
go: true,
|
|
kotlin: true,
|
|
rust: true,
|
|
python: true,
|
|
})
|
|
|
|
expect(md.render(code)).toMatchSnapshot()
|
|
expect(app.writeTemp).toBeCalledWith(outputFile.slice(1), expect.any(String))
|
|
expect(fs.readFileSync(outputFile, 'utf-8')).toMatchSnapshot()
|
|
})
|
|
|
|
it('should work with custom theme', async () => {
|
|
initFs()
|
|
const { md, app } = await createMarkdown({
|
|
go: true,
|
|
kotlin: true,
|
|
rust: true,
|
|
python: true,
|
|
theme: 'vitesse-light',
|
|
})
|
|
|
|
expect(md.render(code)).toMatchSnapshot()
|
|
expect(app.writeTemp).toBeCalledWith(outputFile.slice(1), expect.any(String))
|
|
expect(fs.readFileSync(outputFile, 'utf-8')).toMatchSnapshot()
|
|
})
|
|
})
|