返回 slidev
snippet.test.ts
根目录 / packages / slidev / node / syntax / snippet.test.ts
1 import MarkdownExit from 'markdown-exit'
2 import path from 'pathe'
3 import { expect, it } from 'vitest'
4 import MarkdownItSnippet, { resolveSnippetImport } from './snippet'
5
6 const fixturesRoot = path.join(__dirname, '../../../../test/fixtures/')
7
8 const options = {
9 userRoot: fixturesRoot,
10 userWorkspaceRoot: fixturesRoot,
11 roots: [fixturesRoot],
12 data: {
13 watchFiles: {},
14 slides: [{
15 index: 0,
16 source: { filepath: path.join(fixturesRoot, 'test.md') },
17 }],
18 },
19 } as any
20
21 it('snippet import', async () => {
22 const md = MarkdownExit()
23 md.use(MarkdownItSnippet, options)
24
25 const result = await md.renderAsync('<<< @/snippets/snippet.ts#snippet', { id: 'slides.md__slidev_1.md' })
26
27 expect(result).toMatchInlineSnapshot(`
28 "<pre><code class="language-ts">function _foo() {
29 // ...
30 }
31 </code></pre>
32 "
33 `)
34 })
35
36 it('snippet in indented block', async () => {
37 const md = MarkdownExit()
38 md.use(MarkdownItSnippet, options)
39
40 const result = await md.renderAsync('- item\n <<< @/snippets/snippet.ts#snippet', { id: 'slides.md__slidev_1.md' })
41
42 expect(result).toMatchInlineSnapshot(`
43 "<ul>
44 <li>item<pre><code class="language-ts">function _foo() {
45 // ...
46 }
47 </code></pre>
48 </li>
49 </ul>
50 "
51 `)
52 })
53
54 it('not transform in code block', async () => {
55 const md = MarkdownExit()
56 md.use(MarkdownItSnippet, options)
57
58 const result = await md.renderAsync('```\n<<< @/snippets/snippet.ts\n```', { id: 'slides.md__slidev_1.md' })
59
60 expect(result).toMatchInlineSnapshot(`
61 "<pre><code>&lt;&lt;&lt; @/snippets/snippet.ts
62 </code></pre>
63 "
64 `)
65 })
66
67 it('resolves a snippet path that stays inside the allowed roots', () => {
68 const slide = { source: { filepath: path.join(fixturesRoot, 'test.md') } } as any
69 const result = resolveSnippetImport('<<< @/snippets/snippet.ts#snippet', fixturesRoot, slide, [fixturesRoot])
70 expect(result?.src).toBe(path.join(fixturesRoot, 'snippets/snippet.ts').replaceAll('\\', '/'))
71 })
72
73 it('throws when a snippet path escapes the allowed roots', () => {
74 const slide = { source: { filepath: path.join(fixturesRoot, 'test.md') } } as any
75 expect(() => resolveSnippetImport('<<< ../../../../../outside.ts', fixturesRoot, slide, [fixturesRoot]))
76 .toThrow(/escapes the project root/)
77 })
78
78 lines TYPESCRIPT