recipe/packages/md-enhance/__tests__/unit/playground.spec.ts

478 lines
7.9 KiB
TypeScript
Raw Permalink Normal View History

2024-08-18 19:16:25 +08:00
/* eslint-disable @typescript-eslint/naming-convention */
import MarkdownIt from "markdown-it";
import { describe, expect, it } from "vitest";
import {
getTSPlaygroundPreset,
getUnoPlaygroundPreset,
getVuePlaygroundPreset,
playground,
} from "../../src/node/markdown-it/playground/index.js";
describe("playground", () => {
it("Should not throw", () => {
const markdownIt = MarkdownIt({ linkify: true }).use(playground, {
name: "test",
});
const result = markdownIt.render(
`
::: test demo
@file a.test
\`\`\`test
abc
\`\`\`
@import
\`\`\`json
{
"imports": {
"example": "https://example.com"
}
}
\`\`\`
:::
`,
{},
);
expect(result).toMatchSnapshot();
});
describe("basic", () => {
const markdownIt = MarkdownIt({ linkify: true }).use(playground, {
name: "playground",
component: "Playground",
propsGetter: (data) =>
Object.fromEntries(
Object.entries(data).map(([key, value]) => [
key,
JSON.stringify(value),
]),
),
});
it("Should resolve playground info", () => {
const result = markdownIt.render(
`
::: playground Playground demo
@file App.vue
\`\`\`vue
<script setup>
import { ref } from 'vue'
const msg = ref('Hello World!')
</script>
<template>
<h1>{{ msg }}</h1>
<input v-model="msg" />
</template>
\`\`\`
@file Comp.vue
\`\`\`vue
<template>
<div>Comp</div>
</template>
\`\`\`
:::
`,
{},
);
expect(result).toMatchSnapshot();
});
it("Should resolve playground info with imports and settings", () => {
const result = markdownIt.render(
`
::: playground Playground demo2
@file App.vue
\`\`\`vue
<script setup>
import { ref } from 'vue'
const msg = ref('Hello World!')
</script>
<template>
<h1>{{ msg }}</h1>
<input v-model="msg" />
</template>
\`\`\`
@import
\`\`\`json
{
"imports": {
"vue": "https://sfc.vuejs.org/vue.runtime.esm-browser.js"
}
}
\`\`\`
@setting
\`\`\`json
{
"service": "https://element-plus.run/"
}
\`\`\`
:::
`,
{},
);
expect(result).toMatchSnapshot();
});
});
describe("ts preset", () => {
const markdownItWithTSPreset = MarkdownIt({ linkify: true }).use(
playground,
getTSPlaygroundPreset({}),
);
it("Should work", () => {
const result1 = markdownItWithTSPreset.render(`
::: playground#ts TS demo 1
@file index.ts
\`\`\`ts
const msg = "hello world";
const speak = (msg: string) => console.info(msg);
speak(msg);
\`\`\`
:::
`);
const result2 = markdownItWithTSPreset.render(`
::: playground#ts TS demo 2
@file index.ts
\`\`\`ts
const msg = "hello world";
const speak = (msg: string) => console.info(msg);
speak(msg);
\`\`\`
@setting
\`\`\`json
{
"target": "es5",
"declaration": true
}
\`\`\`
:::
`);
expect(result1).toMatchSnapshot();
expect(result2).toMatchSnapshot();
});
});
describe("vue preset", () => {
const markdownItWithVuePreset = MarkdownIt({ linkify: true }).use(
playground,
getVuePlaygroundPreset({}),
);
const getVueFiles = (content: string): Record<string, string> | null => {
const result = decodeURIComponent(content).match(/link="(.*?)"/);
if (!result) return null;
const files = decodeURIComponent(result[1])
.split("#")[1]
.replace("__DEV__", "")
.replace("__SSR__", "");
return JSON.parse(Buffer.from(files, "base64").toString()) as Record<
string,
string
>;
};
it("Should work", () => {
const result1 = markdownItWithVuePreset.render(`
::: playground#vue Vue demo with customized imports
@file App.vue
\`\`\`vue
<script setup>
import { ref } from "vue";
import Comp from "./Comp.vue";
const msg = ref("Hello World!");
</script>
<template>
<h1>{{ msg }}</h1>
<input v-model="msg" />
<Comp />
</template>
\`\`\`
@file Comp.vue
\`\`\`vue
<template>
<div>Comp</div>
</template>
\`\`\`
@import
\`\`\`json
{
"imports": {
"vue": "https://sfc.vuejs.org/vue.runtime.esm-browser.js"
}
}
\`\`\`
:::
`);
const result2 = markdownItWithVuePreset.render(`
::: playground#vue Vue demo with customized settings
@file App.vue
\`\`\`vue
<script setup>
import { ref } from "vue";
const msg = ref("Hello Playground!");
</script>
<template>
<h1>{{ msg }}</h1>
<input v-model="msg" />
</template>
\`\`\`
@setting
\`\`\`json
{
"dev": true,
"ssr": true
}
\`\`\`
:::
`);
const result3 = markdownItWithVuePreset.render(`
::: playground#vue Vue demo with customized settings
@file App.vue
\`\`\`vue
<script setup>
import { ref } from "vue";
const msg = ref("Hello Playground!");
</script>
<template>
<h1>{{ msg }}</h1>
<input v-model="msg" />
</template>
\`\`\`
@import
\`\`\`json
{
"imports": {
"vue": "https://unpkg.com/vue/dist/vue.runtime.esm-browser.js"
}
}
\`\`\`
@setting
\`\`\`json
{
"dev": true,
"ssr": true
}
\`\`\`
:::
`);
expect(result1).toMatchSnapshot();
expect(result2).toMatchSnapshot();
expect(result3).toMatchSnapshot();
expect(result2).contains("__DEV__");
expect(result2).contains("__SSR__");
expect(result3).contains("__DEV__");
expect(result3).contains("__SSR__");
const files1 = getVueFiles(result1);
const files2 = getVueFiles(result2);
const files3 = getVueFiles(result3);
expect(files1).toEqual({
"App.vue": `\
<script setup>
import { ref } from "vue";
import Comp from "./Comp.vue";
const msg = ref("Hello World!");
</script>
<template>
<h1>{{ msg }}</h1>
<input v-model="msg" />
<Comp />
</template>
`,
"Comp.vue": `\
<template>
<div>Comp</div>
</template>
`,
"import-map.json": `\
{
"imports": {
"vue": "https://sfc.vuejs.org/vue.runtime.esm-browser.js"
}
}\
`,
});
expect(files2).toEqual({
"App.vue": `\
<script setup>
import { ref } from "vue";
const msg = ref("Hello Playground!");
</script>
<template>
<h1>{{ msg }}</h1>
<input v-model="msg" />
</template>
`,
"import-map.json": `\
{
"imports": {
"vue": "https://sfc.vuejs.org/vue.runtime.esm-browser.js",
"vue/server-renderer": "https://sfc.vuejs.org/server-renderer.esm-browser.js"
}
}\
`,
});
expect(files3).toEqual({
"App.vue": `\
<script setup>
import { ref } from "vue";
const msg = ref("Hello Playground!");
</script>
<template>
<h1>{{ msg }}</h1>
<input v-model="msg" />
</template>
`,
"import-map.json": `\
{
"imports": {
"vue": "https://unpkg.com/vue/dist/vue.runtime.esm-browser.js",
"vue/server-renderer": "https://sfc.vuejs.org/server-renderer.esm-browser.js"
}
}\
`,
});
});
});
describe("unocss preset", () => {
const markdownItWithUnoPreset = MarkdownIt({ linkify: true }).use(
playground,
getUnoPlaygroundPreset({}),
);
it("Should work", () => {
const result1 = markdownItWithUnoPreset.render(`
::: playground#unocss UnoCSS demo 1
@file index.html
\`\`\`html
<div class="text-red">UnoCSS TEST</div>
\`\`\`
:::
`);
const result2 = markdownItWithUnoPreset.render(`
::: playground#unocss UnoCSS demo 2
@file index.html
\`\`\`html
<div class="text-$fd-color">UnoCSS TEST 2</div>
\`\`\`
@file config.js
\`\`\`js
import {
defineConfig,
presetUno,
} from 'unocss'
export default defineConfig({
presets: [
presetUno(),
]
})
\`\`\`
@file custom.css
\`\`\`css
:root {
--fd-color: red;
}
\`\`\`
:::
`);
expect(result1).toMatchSnapshot();
expect(result2).toMatchSnapshot();
});
});
});