@@ -2,8 +2,9 @@ import { mkdir, readFile, rm, writeFile } from 'node:fs/promises'
2
2
import { join } from 'node:path'
3
3
import { fileURLToPath } from 'node:url'
4
4
import { mkdist } from 'mkdist'
5
- import { afterAll , describe , expect , it } from 'vitest'
5
+ import { afterAll , describe , expect , it , vi } from 'vitest'
6
6
import { vueLoader } from '../src/mkdist'
7
+ import { cleanupBreakLine , defineDefaultBlockLoader } from '../src/utils/mkdist'
7
8
8
9
describe ( 'transform typescript script setup' , ( ) => {
9
10
const tmpDir = fileURLToPath ( new URL ( '../node_modules/.tmp/fixtures' , import . meta. url ) )
@@ -249,6 +250,155 @@ describe('transform typescript script setup', () => {
249
250
"
250
251
` )
251
252
} )
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
+ } )
252
402
253
403
async function fixture ( src : string ) : Promise < string > {
254
404
await rm ( tmpDir , { force : true , recursive : true } )
0 commit comments