@@ -34,40 +34,75 @@ describe('cli', () => {
3434 'mdsvex' ,
3535 'paraglide=languageTags:en,es+demo:yes' ,
3636 'mcp=ide:claude-code,cursor,gemini,opencode,vscode,other+setup:local'
37+ // 'storybook' // No storybook addon during tests!
3738 ]
3839 }
3940 ] ;
4041
41- it . for ( testCases ) ( 'should create a new project with name $projectName' , async ( testCase ) => {
42- const { projectName, args } = testCase ;
43- const svBinPath = path . resolve ( monoRepoPath , 'packages' , 'cli' , 'dist' , 'bin.js' ) ;
44- const testOutputPath = path . resolve ( monoRepoPath , '.test-output' , 'cli' , projectName ) ;
42+ it . for ( testCases ) (
43+ 'should create a new project with name $projectName' ,
44+ { timeout : 10_000 } ,
45+ async ( testCase ) => {
46+ const { projectName, args } = testCase ;
47+ const svBinPath = path . resolve ( monoRepoPath , 'packages' , 'cli' , 'dist' , 'bin.js' ) ;
48+ const testOutputPath = path . resolve ( monoRepoPath , '.test-output' , 'cli' , projectName ) ;
4549
46- const result = await exec (
47- 'node' ,
48- [
49- svBinPath ,
50- 'create' ,
51- testOutputPath ,
52- '--template' ,
53- 'minimal' ,
54- '--types' ,
55- 'ts' ,
56- '--no-install' ,
57- ...args
58- ] ,
59- { nodeOptions : { stdio : 'ignore ' } }
60- ) ;
50+ const result = await exec (
51+ 'node' ,
52+ [
53+ svBinPath ,
54+ 'create' ,
55+ testOutputPath ,
56+ '--template' ,
57+ 'minimal' ,
58+ '--types' ,
59+ 'ts' ,
60+ '--no-install' ,
61+ ...args
62+ ] ,
63+ { nodeOptions : { stdio : 'pipe ' } }
64+ ) ;
6165
62- // cli finished well
63- expect ( result . exitCode ) . toBe ( 0 ) ;
66+ // cli finished well
67+ expect ( result . exitCode ) . toBe ( 0 ) ;
6468
65- // test output path exists
66- expect ( fs . existsSync ( testOutputPath ) ) . toBe ( true ) ;
69+ // test output path exists
70+ expect ( fs . existsSync ( testOutputPath ) ) . toBe ( true ) ;
6771
68- // package.json has a name
69- const packageJsonPath = path . resolve ( testOutputPath , 'package.json' ) ;
70- const packageJson = parseJson ( fs . readFileSync ( packageJsonPath , 'utf-8' ) ) ;
71- expect ( packageJson . name ) . toBe ( projectName ) ;
72- } ) ;
72+ // package.json has a name
73+ const packageJsonPath = path . resolve ( testOutputPath , 'package.json' ) ;
74+ const packageJson = parseJson ( fs . readFileSync ( packageJsonPath , 'utf-8' ) ) ;
75+ expect ( packageJson . name ) . toBe ( projectName ) ;
76+
77+ const snapPath = path . resolve (
78+ monoRepoPath ,
79+ 'packages' ,
80+ 'cli' ,
81+ 'tests' ,
82+ 'snapshots' ,
83+ projectName
84+ ) ;
85+ const relativeFiles = fs . readdirSync ( testOutputPath , { recursive : true } ) as string [ ] ;
86+ for ( const relativeFile of relativeFiles ) {
87+ if ( ! fs . statSync ( path . resolve ( testOutputPath , relativeFile ) ) . isFile ( ) ) continue ;
88+ if ( [ '.svg' , '.env' ] . some ( ( ext ) => relativeFile . endsWith ( ext ) ) ) continue ;
89+
90+ let generated = fs . readFileSync ( path . resolve ( testOutputPath , relativeFile ) , 'utf-8' ) ;
91+ if ( relativeFile === 'package.json' ) {
92+ const generatedPackageJson = parseJson ( generated ) ;
93+ // remove @types /node from generated package.json as we test on different node versions
94+ delete generatedPackageJson . devDependencies [ '@types/node' ] ;
95+ generated = JSON . stringify ( generatedPackageJson , null , 3 ) . replaceAll ( ' ' , '\t' ) ;
96+ }
97+
98+ generated = generated . replaceAll ( '\r\n' , '\n' ) ; // make it work on Windows too
99+ if ( ! generated . endsWith ( '\n' ) ) generated += '\n' ; // ensure trailing newline
100+
101+ await expect ( generated ) . toMatchFileSnapshot (
102+ path . resolve ( snapPath , relativeFile ) ,
103+ `file "${ relativeFile } " does not match snapshot`
104+ ) ;
105+ }
106+ }
107+ ) ;
73108} ) ;
0 commit comments