/* eslint-disable @typescript-eslint/naming-convention */ import { decodeData } from "@vuepress/helper"; import MarkdownIt from "markdown-it"; import { describe, expect, it } from "vitest"; import { sandpack } from "../../src/node/markdown-it/sandpack/index.js"; const decodeFiles = (content: string): Record => JSON.parse(decodeData(content)) as Record; const getTemplate = (renderResult: string): string | null => { const result = renderResult.match(/template="(.*?)"/s); if (!result) return null; return result[1]; }; const getFiles = (renderResult: string): Record | null => { const result = renderResult.match(/files="(.*?)"/s); if (!result) return null; return decodeFiles(result[1]); }; const getOptions = (renderResult: string): Record | null => { const result = renderResult.match(/options="(.*?)"/s); if (!result) return null; return JSON.parse(decodeData(result[1])) as Record; }; const getCustomSetup = ( renderResult: string, ): Record | null => { const result = renderResult.match(/customSetup="(.*?)"/s); if (!result) return null; return JSON.parse(decodeData(result[1])) as Record; }; describe("Sandpack", () => { const markdownIt = MarkdownIt({ linkify: true }).use(sandpack); it("Should resolve sandpack info", () => { const result = markdownIt.render( ` ::: sandpack#vue Sandpack demo @file App.vue \`\`\`vue \`\`\` @file Comp.vue \`\`\`vue \`\`\` ::: `, {}, ); expect(result).toMatchSnapshot(); const template = getTemplate(result); const files = getFiles(result); const options = getOptions(result); const customSetup = getCustomSetup(result); expect(template).toEqual("vue"); expect(files).toEqual({ "App.vue": `\ `, "Comp.vue": `\ `, }); expect(options).toEqual({}); expect(customSetup).toEqual({}); }); it("Should resolve sandpack info with options", () => { const result = markdownIt.render( ` ::: sandpack Sandpack demo with options @file App.vue \`\`\`vue \`\`\` @file Comp.vue \`\`\`vue \`\`\` @options \`\`\`js { readOnly: true, showReadOnly: false } \`\`\` ::: `, {}, ); expect(result).toMatchSnapshot(); const template = getTemplate(result); const file = getFiles(result); const options = getOptions(result); const customSetup = getCustomSetup(result); expect(template).toEqual(null); expect(file).toEqual({ "App.vue": `\ `, "Comp.vue": `\ `, }); expect(options).toEqual({ readOnly: true, showReadOnly: false, }); expect(customSetup).toEqual({}); }); it("Should resolve sandpack info with customSetup", () => { const result = markdownIt.render( ` ::: sandpack#vue Sandpack demo with customSetup @file App.vue \`\`\`vue \`\`\` @options \`\`\`js { readOnly: true, showReadOnly: false } \`\`\` @setup \`\`\`js { entry: "/index.js", } \`\`\` ::: `, {}, ); expect(result).toMatchSnapshot(); const template = getTemplate(result); const file = getFiles(result); const options = getOptions(result); const customSetup = getCustomSetup(result); expect(template).toEqual("vue"); expect(file).toEqual({ "App.vue": `\ `, }); expect(options).toEqual({ readOnly: true, showReadOnly: false, }); expect(customSetup).toEqual({ entry: "/index.js", }); }); it("Should resolve sandpack info with file attrs", () => { const result = markdownIt.render( ` ::: sandpack Sandpack demo with options @file /src/App.vue [readOnly hidden] \`\`\`vue \`\`\` @file /src/Comp.vue [active] \`\`\`vue \`\`\` @file Comp2.vue \\[hidden] \`\`\`vue \`\`\` ::: `, {}, ); expect(result).toMatchSnapshot(); const template = getTemplate(result); const file = getFiles(result); const options = getOptions(result); const customSetup = getCustomSetup(result); expect(template).toEqual(null); expect(file).toEqual({ "/src/App.vue": { code: `\ `, active: false, hidden: true, readOnly: true, }, "/src/Comp.vue": { code: `\ `, active: true, hidden: false, readOnly: false, }, "Comp2.vue": `\ `, }); expect(options).toEqual({}); expect(customSetup).toEqual({}); }); it("Should resolve sandpack info with file attrs and customSetup", () => { const result = markdownIt.render( ` ::: sandpack Sandpack demo with file attrs and customSetup [rtl theme=dark] @file /src/App.vue [readOnly] \`\`\`vue \`\`\` @file /src/Comp.vue [active] \`\`\`vue \`\`\` @setup \`\`\`js { dependencies: { "@vueuse/core": "latest", "@vueuse/shared": "latest", "vue-demi": "latest", } } \`\`\` ::: `, {}, ); expect(result).toMatchSnapshot(); expect(result).includes("rtl"); expect(result).includes('theme="dark"'); const template = getTemplate(result); const file = getFiles(result); const options = getOptions(result); const customSetup = getCustomSetup(result); expect(template).toEqual(null); expect(file).toEqual({ "/src/App.vue": { code: `\ `, active: false, hidden: false, readOnly: true, }, "/src/Comp.vue": { code: `\ `, active: true, hidden: false, readOnly: false, }, }); expect(options).toEqual({}); expect(customSetup).toEqual({ dependencies: { "@vueuse/core": "latest", "@vueuse/shared": "latest", "vue-demi": "latest", }, }); }); });