/** * @vitest-environment jsdom */ /* eslint-disable vue/one-component-per-file */ import { describe, expect, it, vi } from 'vitest' import { renderToString } from 'vue/server-renderer' import { format } from 'prettier' import { contentToVNode } from '~/composables/content-render' import type { ContentParseOptions } from '~~/composables/content-parse' describe('content-rich', () => { it('empty', async () => { const { formatted } = await render('') expect(formatted).toMatchSnapshot() }) it('link + mention', async () => { // https://fosstodon.org/@ayo/109383002937620723 const { formatted } = await render('
Happy 🤗 we’re now using @vitest (migrated from chai+mocha) https://github.com/ayoayco/astro-reactive-library/pull/203
') expect(formatted).toMatchSnapshot() }) it ('block with backticks', async () => { const { formatted } = await render('```
[(`number string) (`tag string)]
```
Inline code with link: `https://api.iconify.design/noto.css?icons=1st-place-medal,2nd-place-medal`
') expect(formatted).toMatchSnapshot() }) it('handles html within code blocks', async () => { const { formatted } = await render('HTML block code:
```html
<span class="icon--noto icon--noto--1st-place-medal"></span>
<span class="icon--noto icon--noto--2nd-place-medal-medal"></span>
```
Does the following formatting come through accurately for you?
Testing code block
```ts
import { useMouse, usePreferredDark } from '@vueuse/core'
// tracks mouse position
const { x, y } = useMouse()
// is the user prefers dark theme
const isDark = usePreferredDark()
```
@antfu Testing
```ts
const a = hello
```
```
hello world
```
no lang
```
```
@elk @elk content @antfu @daniel @sxzz @patak content
', { collapseMentionLink: true, }) expect(formatted).toMatchInlineSnapshot(` " " `) }) it ('block with injected html, without language', async () => { const { formatted } = await render(`
<a href="javascript:alert(1)">click me</a>
`)
expect(formatted).toMatchSnapshot()
})
it ('block with injected html, with an unknown language', async () => {
const { formatted } = await render(`
<a href="javascript:alert(1)">click me</a>
`)
expect(formatted).toMatchSnapshot()
})
it ('block with injected html, with a known language', async () => {
const { formatted } = await render(`
<a href="javascript:alert(1)">click me</a>
`)
expect(formatted).toMatchSnapshot()
})
})
async function render(content: string, options?: ContentParseOptions) {
const vnode = contentToVNode(content, options)
const html = (await renderToString(vnode))
.replace(//g, '')
let formatted = ''
try {
formatted = format(html, {
parser: 'html',
})
}
catch (e) {
formatted = html
}
return {
vnode,
html,
formatted,
}
}
// mocks
vi.mock('vue-router', () => {
return {
RouterLink: defineComponent((attrs) => {
return () => h('a', attrs)
}),
}
})
vi.mock('~/composables/dialog.ts', () => {
return {}
})
vi.mock('shiki-es', async (importOriginal) => {
const mod = await importOriginal()
return {
...(mod as any),
setCDN() {},
}
})
vi.mock('~/components/content/ContentMentionGroup.vue', () => {
return {
default: defineComponent({
setup(props, { slots }) {
return () => h('mention-group', null, { default: () => slots?.default?.() })
},
}),
}
})
vi.mock('~/components/account/AccountHoverWrapper.vue', () => {
return {
default: defineComponent({
props: ['handle', 'class'],
setup(_, { slots }) {
return () => slots?.default?.()
},
}),
}
})