1- import { describe , expect , it } from 'vitest'
1+ import { describe , expect , it , test } from 'vitest'
22import {
33 warnMissingParamParsers ,
44 collectMissingParamParsers ,
@@ -8,13 +8,17 @@ import {
88 generatePathParamsOptions ,
99 generateCustomParamParsersList ,
1010 generateNormalizedParamParsersDeclarations ,
11+ scanParamParserFiles ,
1112 type ParamParsersMap ,
1213} from './generateParamParsers'
1314import { PrefixTree } from '../core/tree'
14- import { resolveOptions } from '../options'
15+ import { DEFAULT_PARAM_PARSERS_OPTIONS , resolveOptions } from '../options'
1516import { ImportsMap } from '../core/utils'
1617import type { TreePathParam } from '../core/treeNodeValue'
1718import { mockWarn } from '../../tests/vitest-mock-warn'
19+ import { mkdirSync , mkdtempSync , rmSync , writeFileSync } from 'node:fs'
20+ import { tmpdir } from 'node:os'
21+ import { join } from 'node:path'
1822
1923const DEFAULT_OPTIONS = resolveOptions ( { } )
2024
@@ -785,3 +789,69 @@ describe('generateNormalizedParamParsersDeclarations', () => {
785789 )
786790 } )
787791} )
792+
793+ // Per-test temp folder via the recommended vitest `test.extend` fixture pattern.
794+ // Each test gets a fresh isolated directory; cleanup runs after `use` resolves.
795+ const parsersTest = test . extend < { parsersDir : string } > ( {
796+ parsersDir : async ( { } , use ) => {
797+ const dir = mkdtempSync ( join ( tmpdir ( ) , 'vue-router-param-parsers-' ) )
798+ writeFileSync ( join ( dir , 'uuid.ts' ) , 'export const parser = {}' )
799+ writeFileSync ( join ( dir , 'slug.ts' ) , 'export const parser = {}' )
800+ writeFileSync ( join ( dir , 'uuid.test.ts' ) , 'test code' )
801+ writeFileSync ( join ( dir , 'slug.spec.ts' ) , 'test code' )
802+ writeFileSync ( join ( dir , 'legacy.js' ) , 'module.exports = {}' )
803+ writeFileSync ( join ( dir , 'legacy.test.js' ) , 'module.exports = {}' )
804+ writeFileSync ( join ( dir , 'README.md' ) , '# parsers' )
805+ mkdirSync ( join ( dir , 'nested' ) )
806+ writeFileSync ( join ( dir , 'nested' , 'deep.ts' ) , 'export const parser = {}' )
807+ await use ( dir )
808+ rmSync ( dir , { recursive : true , force : true } )
809+ } ,
810+ } )
811+
812+ describe ( 'scanParamParserFiles' , ( ) => {
813+ parsersTest (
814+ 'picks parsers and ignores tests/specs/nested by default' ,
815+ async ( { parsersDir } ) => {
816+ const files = await scanParamParserFiles (
817+ parsersDir ,
818+ DEFAULT_PARAM_PARSERS_OPTIONS . include ,
819+ DEFAULT_PARAM_PARSERS_OPTIONS . exclude
820+ )
821+ expect ( files . sort ( ) ) . toEqual ( [ 'slug.ts' , 'uuid.ts' ] )
822+ }
823+ )
824+
825+ parsersTest (
826+ 'respects a custom include that adds js' ,
827+ async ( { parsersDir } ) => {
828+ const files = await scanParamParserFiles (
829+ parsersDir ,
830+ [ '*.{ts,js}' ] ,
831+ DEFAULT_PARAM_PARSERS_OPTIONS . exclude
832+ )
833+ expect ( files . sort ( ) ) . toEqual ( [ 'legacy.js' , 'slug.ts' , 'uuid.ts' ] )
834+ }
835+ )
836+
837+ parsersTest ( 'respects a custom exclude' , async ( { parsersDir } ) => {
838+ const files = await scanParamParserFiles ( parsersDir , [ '*.ts' ] , [ 'uuid*' ] )
839+ expect ( files . sort ( ) ) . toEqual ( [ 'slug.spec.ts' , 'slug.ts' ] )
840+ } )
841+
842+ parsersTest (
843+ 'returns no files when include is empty' ,
844+ async ( { parsersDir } ) => {
845+ const files = await scanParamParserFiles ( parsersDir , [ ] , [ ] )
846+ expect ( files ) . toEqual ( [ ] )
847+ }
848+ )
849+
850+ parsersTest (
851+ 'never picks nested files even without exclude' ,
852+ async ( { parsersDir } ) => {
853+ const files = await scanParamParserFiles ( parsersDir , [ '*.ts' ] , [ ] )
854+ expect ( files . some ( f => f . includes ( 'nested' ) ) ) . toBe ( false )
855+ }
856+ )
857+ } )
0 commit comments