@@ -2,8 +2,9 @@ import { mkdir, readFile, rm, writeFile } from 'node:fs/promises'
22import { join } from 'node:path'
33import { fileURLToPath } from 'node:url'
44import { mkdist } from 'mkdist'
5- import { afterAll , describe , expect , it } from 'vitest'
5+ import { afterAll , describe , expect , it , vi } from 'vitest'
66import { vueLoader } from '../src/mkdist'
7+ import { cleanupBreakLine , defineDefaultBlockLoader } from '../src/utils/mkdist'
78
89describe ( '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 } )
0 commit comments