Skip to content

Commit a8cd779

Browse files
committed
test: add additional test cases
1 parent 92cc7f7 commit a8cd779

File tree

4 files changed

+172
-3
lines changed

4 files changed

+172
-3
lines changed

src/utils/template.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ export async function transpileVueTemplate(
193193
return s.toString()
194194
}
195195

196-
function replaceQuote(code: string, target: string, replace: string): string {
196+
export function replaceQuote(code: string, target: string, replace: string): string {
197197
let res = code
198198

199199
if (res.includes(target)) {

test/mkdist.test.ts

Lines changed: 151 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { mkdir, readFile, rm, writeFile } from 'node:fs/promises'
22
import { join } from 'node:path'
33
import { fileURLToPath } from 'node:url'
44
import { mkdist } from 'mkdist'
5-
import { afterAll, describe, expect, it } from 'vitest'
5+
import { afterAll, describe, expect, it, vi } from 'vitest'
66
import { vueLoader } from '../src/mkdist'
7+
import { cleanupBreakLine, defineDefaultBlockLoader } from '../src/utils/mkdist'
78

89
describe('transform typescript script setup', () => {
910
const tmpDir = fileURLToPath(new URL('../node_modules/.tmp/fixtures', import.meta.url))
@@ -249,6 +250,155 @@ describe('transform typescript script setup', () => {
249250
"
250251
`)
251252
})
253+
it('generates contents with multiple blocks', async () => {
254+
const src = `
255+
<template>
256+
<div>Hello World</div>
257+
</template>
258+
259+
<script lang="ts">
260+
export default { name: 'App' }
261+
</script>
262+
263+
<style scoped>
264+
div { color: red; }
265+
</style>`
266+
267+
expect(await fixture(src)).toMatchInlineSnapshot(`
268+
"<template>
269+
<div>Hello World</div>
270+
</template>
271+
272+
<script>
273+
export default { name: "App" };
274+
</script>
275+
276+
<style scoped>
277+
div { color: red; }
278+
</style>
279+
"
280+
`)
281+
})
282+
283+
it('handles empty blocks gracefully', async () => {
284+
const src = `
285+
<template></template>
286+
<script></script>
287+
<style></style>`
288+
289+
expect(await fixture(src)).toMatchInlineSnapshot(`
290+
"
291+
<template></template>
292+
<script></script>
293+
<style></style>"
294+
`)
295+
})
296+
297+
it('sorts blocks by offset', async () => {
298+
const src = `
299+
<style scoped>
300+
div { color: red; }
301+
</style>
302+
303+
<script lang="ts">
304+
export default { name: 'App' }
305+
</script>
306+
307+
<template>
308+
<div>Hello World</div>
309+
</template>`
310+
311+
expect(await fixture(src)).toMatchInlineSnapshot(`
312+
"<style scoped>
313+
div { color: red; }
314+
</style>
315+
316+
<script>
317+
export default { name: "App" };
318+
</script>
319+
320+
<template>
321+
<div>Hello World</div>
322+
</template>
323+
"
324+
`)
325+
})
326+
327+
it('handles attributes in blocks', async () => {
328+
const src = `
329+
<template lang="html">
330+
<div>Hello World</div>
331+
</template>
332+
333+
<script lang="ts">
334+
export default { name: 'App' }
335+
</script>`
336+
337+
expect(await fixture(src)).toMatchInlineSnapshot(`
338+
"<template lang="html">
339+
<div>Hello World</div>
340+
</template>
341+
342+
<script>
343+
export default { name: "App" };
344+
</script>
345+
"
346+
`)
347+
})
348+
349+
it('removes unnecessary break lines', async () => {
350+
const src = `
351+
<template>
352+
353+
354+
<div>Hello World</div>
355+
356+
357+
</template>
358+
359+
<script lang="ts">
360+
361+
362+
export default { name: 'App' }
363+
364+
365+
</script>`
366+
367+
expect(await fixture(src)).toMatchInlineSnapshot(`
368+
"<template>
369+
<div>Hello World</div>
370+
</template>
371+
372+
<script>
373+
export default { name: "App" };
374+
</script>
375+
"
376+
`)
377+
})
378+
379+
it('handles invalid .vue files gracefully', async () => {
380+
vi.spyOn(console, 'error').mockImplementation(() => {})
381+
const invalidVue = `<template><div></div>` // Missing closing tags
382+
await expect(fixture(invalidVue)).rejects.toThrowError()
383+
expect(console.error).toHaveBeenCalledWith(expect.objectContaining({ message: 'Element is missing end tag.' }))
384+
})
385+
386+
it('cleans up excessive break lines', () => {
387+
const input = '\n\n\n<div>Test</div>\n\n\n'
388+
const output = cleanupBreakLine(input)
389+
expect(output).toBe('<div>Test</div>')
390+
})
391+
392+
it('handles unsupported block types in defineDefaultBlockLoader', async () => {
393+
const unsupportedBlock = { type: 'unknown', attrs: {}, content: 'test' }
394+
// @ts-expect-error invalid unsupported block
395+
const result = await defineDefaultBlockLoader({ type: 'script', defaultLang: 'js' })(unsupportedBlock, {
396+
loadFile: async () => [],
397+
rawInput: { path: '', srcPath: '' },
398+
addOutput: () => {},
399+
})
400+
expect(result).toBeUndefined()
401+
})
252402

253403
async function fixture(src: string): Promise<string> {
254404
await rm(tmpDir, { force: true, recursive: true })

test/setup.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,13 @@ describe('transform typescript script setup', () => {
234234
await expect(fixture('<script setup lang="ts">defineModel("foo", "bar")</script>')).rejects.toThrow(`[vue-sfc-transformer] defineModel()'s second argument must be an object.`)
235235
})
236236

237+
it('handles edge cases in processDefineProps', async () => {
238+
const script = `<script setup lang=\"ts\">defineProps<{}>()</script>`
239+
const sfc = parse(script, { filename: 'test.vue', ignoreEmpty: true })
240+
const result = await preTranspileScriptSetup(sfc.descriptor, 'test.vue')
241+
expect(result.content).toContain('defineProps({})')
242+
})
243+
237244
async function fixture(src: string): Promise<string> {
238245
const sfc = parse(src, {
239246
filename: 'test.vue',

test/template.test.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createRequire } from 'node:module'
22
import { transform } from 'esbuild'
33
import { resolveModulePath } from 'exsolve'
44
import { describe, expect, it } from 'vitest'
5-
import { transpileVueTemplate } from '../src/utils/template'
5+
import { replaceQuote, transpileVueTemplate } from '../src/utils/template'
66

77
describe('transform typescript template', () => {
88
it('v-for', async () => {
@@ -172,6 +172,18 @@ describe('transform typescript template', () => {
172172
`)
173173
})
174174

175+
it('handles deeply nested templates', async () => {
176+
const nestedTemplate = `<div><span><p>{{ (data as any).value }}</p></span></div>`
177+
const result = await fixture(nestedTemplate)
178+
expect(result).toEqual('<div><span><p>{{ data.value }}</p></span></div>')
179+
})
180+
181+
it('replaces quotes correctly', () => {
182+
const input = `\"test\"`
183+
const output = replaceQuote(input, '\"', '\'')
184+
expect(output).toBe(`'test'`)
185+
})
186+
175187
async function fixture(src: string) {
176188
const requireFromVue = createRequire(resolveModulePath('vue'))
177189
const { parse } = requireFromVue('@vue/compiler-dom') as typeof import('@vue/compiler-dom')

0 commit comments

Comments
 (0)