@@ -18,9 +18,73 @@ const templatesWithoutTypeCheck = new Set([
1818 'lib-vue-ts' ,
1919] ) ;
2020
21+ type ProjectPackage = {
22+ name : string ;
23+ scripts : Record < string , string > ;
24+ } ;
25+
26+ type SourceTemplate = {
27+ template : string ;
28+ sourceExtension : string ;
29+ testFile : string ;
30+ } ;
31+
32+ const sourceTemplates : SourceTemplate [ ] = [
33+ { template : 'app-vanilla-js' , sourceExtension : 'js' , testFile : 'dom.test.js' } ,
34+ { template : 'app-vanilla-ts' , sourceExtension : 'ts' , testFile : 'dom.test.ts' } ,
35+ { template : 'app-react-js' , sourceExtension : 'jsx' , testFile : 'index.test.jsx' } ,
36+ { template : 'app-react-ts' , sourceExtension : 'tsx' , testFile : 'index.test.tsx' } ,
37+ { template : 'app-preact-js' , sourceExtension : 'jsx' , testFile : 'index.test.jsx' } ,
38+ { template : 'app-preact-ts' , sourceExtension : 'tsx' , testFile : 'index.test.tsx' } ,
39+ { template : 'app-vue-js' , sourceExtension : 'js' , testFile : 'index.test.js' } ,
40+ { template : 'app-vue-ts' , sourceExtension : 'ts' , testFile : 'index.test.ts' } ,
41+ { template : 'app-lit-js' , sourceExtension : 'js' , testFile : 'index.test.js' } ,
42+ { template : 'app-lit-ts' , sourceExtension : 'ts' , testFile : 'index.test.ts' } ,
43+ { template : 'app-svelte-js' , sourceExtension : 'js' , testFile : 'index.test.js' } ,
44+ { template : 'app-svelte-ts' , sourceExtension : 'ts' , testFile : 'index.test.ts' } ,
45+ { template : 'app-solid-js' , sourceExtension : 'jsx' , testFile : 'index.test.jsx' } ,
46+ { template : 'app-solid-ts' , sourceExtension : 'tsx' , testFile : 'index.test.tsx' } ,
47+ { template : 'lib-node-js' , sourceExtension : 'js' , testFile : 'index.test.js' } ,
48+ { template : 'lib-node-ts' , sourceExtension : 'ts' , testFile : 'index.test.ts' } ,
49+ { template : 'lib-react-js' , sourceExtension : 'jsx' , testFile : 'index.test.jsx' } ,
50+ { template : 'lib-react-ts' , sourceExtension : 'tsx' , testFile : 'index.test.tsx' } ,
51+ { template : 'lib-vue-js' , sourceExtension : 'js' , testFile : 'index.test.js' } ,
52+ { template : 'lib-vue-ts' , sourceExtension : 'ts' , testFile : 'index.test.ts' } ,
53+ { template : 'lib-svelte-js' , sourceExtension : 'js' , testFile : 'index.test.js' } ,
54+ { template : 'lib-svelte-ts' , sourceExtension : 'ts' , testFile : 'index.test.ts' } ,
55+ { template : 'lib-solid-js' , sourceExtension : 'jsx' , testFile : 'index.test.jsx' } ,
56+ { template : 'lib-solid-ts' , sourceExtension : 'tsx' , testFile : 'index.test.tsx' } ,
57+ ] ;
58+
59+ const docTemplates = [
60+ {
61+ template : 'doc-basic' ,
62+ files : [
63+ 'README.md' ,
64+ '.gitignore' ,
65+ 'rstack.config.ts' ,
66+ 'docs/index.md' ,
67+ 'docs/guide/start/introduction.md' ,
68+ ] ,
69+ } ,
70+ {
71+ template : 'doc-i18n' ,
72+ files : [ 'rstack.config.ts' , 'docs/en/index.md' , 'docs/zh/index.md' ] ,
73+ } ,
74+ ] ;
75+
2176const getCheckScript = ( template : string , hasTypeScript : boolean ) : string =>
2277 hasTypeScript && ! templatesWithoutTypeCheck . has ( template ) ? tsCheckScript : jsCheckScript ;
2378
79+ const readProjectPackage = async ( projectDirectory : string ) : Promise < ProjectPackage > =>
80+ JSON . parse ( await readFile ( path . join ( projectDirectory , 'package.json' ) , 'utf8' ) ) as ProjectPackage ;
81+
82+ const expectFiles = async ( projectDirectory : string , files : string [ ] ) : Promise < void > => {
83+ for ( const file of files ) {
84+ await expect ( access ( path . join ( projectDirectory , file ) ) ) . resolves . toBeUndefined ( ) ;
85+ }
86+ } ;
87+
2488const expectStagedSetup = async (
2589 projectDirectory : string ,
2690 configExtension : string ,
@@ -49,6 +113,26 @@ const expectNoStagedSetup = async (
49113 ) . not . toContain ( 'define.staged({' ) ;
50114} ;
51115
116+ const expectProjectSetup = async (
117+ projectDirectory : string ,
118+ template : string ,
119+ configExtension : string ,
120+ hasTypeScript : boolean ,
121+ ) : Promise < void > => {
122+ const packageJson = await readProjectPackage ( projectDirectory ) ;
123+
124+ expect ( packageJson . name ) . toBe ( 'my-app' ) ;
125+ expect ( packageJson . scripts . check ) . toBe ( getCheckScript ( template , hasTypeScript ) ) ;
126+ await expectStagedSetup ( projectDirectory , configExtension , packageJson . scripts ) ;
127+
128+ const tsconfig = access ( path . join ( projectDirectory , 'tsconfig.json' ) ) ;
129+ if ( hasTypeScript ) {
130+ await expect ( tsconfig ) . resolves . toBeUndefined ( ) ;
131+ } else {
132+ await expect ( tsconfig ) . rejects . toThrow ( ) ;
133+ }
134+ } ;
135+
52136afterEach ( async ( ) => {
53137 await Promise . all (
54138 tempDirectories . splice ( 0 ) . map ( ( directory ) => rm ( directory , { recursive : true , force : true } ) ) ,
@@ -101,270 +185,35 @@ test.each([
101185 } ,
102186] ) ( 'omits staged setup when $scenario' , async ( { options } ) => {
103187 const projectDirectory = await createProject ( 'app-vanilla-ts' , options ) ;
104- const packageJson = JSON . parse (
105- await readFile ( path . join ( projectDirectory , 'package.json' ) , 'utf8' ) ,
106- ) ;
188+ const packageJson = await readProjectPackage ( projectDirectory ) ;
107189
108190 await expectNoStagedSetup ( projectDirectory , 'ts' , packageJson . scripts ) ;
109191} ) ;
110192
111- test . each ( [
112- {
113- template : 'app-vanilla-js' ,
114- configExtension : 'js' ,
115- sourceExtension : 'js' ,
116- testFile : 'dom.test.js' ,
117- hasTypeScript : false ,
118- } ,
119- {
120- template : 'app-vanilla-ts' ,
121- configExtension : 'ts' ,
122- sourceExtension : 'ts' ,
123- testFile : 'dom.test.ts' ,
124- hasTypeScript : true ,
125- } ,
126- {
127- template : 'app-react-js' ,
128- configExtension : 'js' ,
129- sourceExtension : 'jsx' ,
130- testFile : 'index.test.jsx' ,
131- hasTypeScript : false ,
132- } ,
133- {
134- template : 'app-react-ts' ,
135- configExtension : 'ts' ,
136- sourceExtension : 'tsx' ,
137- testFile : 'index.test.tsx' ,
138- hasTypeScript : true ,
139- } ,
140- {
141- template : 'app-preact-js' ,
142- configExtension : 'js' ,
143- sourceExtension : 'jsx' ,
144- testFile : 'index.test.jsx' ,
145- hasTypeScript : false ,
146- } ,
147- {
148- template : 'app-preact-ts' ,
149- configExtension : 'ts' ,
150- sourceExtension : 'tsx' ,
151- testFile : 'index.test.tsx' ,
152- hasTypeScript : true ,
153- } ,
154- {
155- template : 'app-vue-js' ,
156- configExtension : 'js' ,
157- sourceExtension : 'js' ,
158- testFile : 'index.test.js' ,
159- hasTypeScript : false ,
160- } ,
161- {
162- template : 'app-vue-ts' ,
163- configExtension : 'ts' ,
164- sourceExtension : 'ts' ,
165- testFile : 'index.test.ts' ,
166- hasTypeScript : true ,
167- } ,
168- {
169- template : 'app-lit-js' ,
170- configExtension : 'js' ,
171- sourceExtension : 'js' ,
172- testFile : 'index.test.js' ,
173- hasTypeScript : false ,
174- } ,
175- {
176- template : 'app-lit-ts' ,
177- configExtension : 'ts' ,
178- sourceExtension : 'ts' ,
179- testFile : 'index.test.ts' ,
180- hasTypeScript : true ,
181- } ,
182- {
183- template : 'app-svelte-js' ,
184- configExtension : 'js' ,
185- sourceExtension : 'js' ,
186- testFile : 'index.test.js' ,
187- hasTypeScript : false ,
188- } ,
189- {
190- template : 'app-svelte-ts' ,
191- configExtension : 'ts' ,
192- sourceExtension : 'ts' ,
193- testFile : 'index.test.ts' ,
194- hasTypeScript : true ,
195- } ,
196- {
197- template : 'app-solid-js' ,
198- configExtension : 'js' ,
199- sourceExtension : 'jsx' ,
200- testFile : 'index.test.jsx' ,
201- hasTypeScript : false ,
202- } ,
203- {
204- template : 'app-solid-ts' ,
205- configExtension : 'ts' ,
206- sourceExtension : 'tsx' ,
207- testFile : 'index.test.tsx' ,
208- hasTypeScript : true ,
209- } ,
210- ] ) (
193+ test . each ( sourceTemplates ) (
211194 'creates the $template template' ,
212- async ( { template, configExtension, sourceExtension, testFile, hasTypeScript } ) => {
195+ async ( { template, sourceExtension, testFile } ) => {
196+ const hasTypeScript = template . endsWith ( '-ts' ) ;
197+ const configExtension = hasTypeScript ? 'ts' : 'js' ;
213198 const projectDirectory = await createProject ( template ) ;
214- const packageJson = JSON . parse (
215- await readFile ( path . join ( projectDirectory , 'package.json' ) , 'utf8' ) ,
216- ) ;
217-
218- expect ( packageJson . name ) . toBe ( 'my-app' ) ;
219- expect ( packageJson . scripts . check ) . toBe ( getCheckScript ( template , hasTypeScript ) ) ;
220- await expectStagedSetup ( projectDirectory , configExtension , packageJson . scripts ) ;
221-
222- await expect ( access ( path . join ( projectDirectory , 'README.md' ) ) ) . resolves . toBeUndefined ( ) ;
223- await expect ( access ( path . join ( projectDirectory , '.gitignore' ) ) ) . resolves . toBeUndefined ( ) ;
224- await expect (
225- access ( path . join ( projectDirectory , `rstack.config.${ configExtension } ` ) ) ,
226- ) . resolves . toBeUndefined ( ) ;
227- await expect (
228- access ( path . join ( projectDirectory , `src/index.${ sourceExtension } ` ) ) ,
229- ) . resolves . toBeUndefined ( ) ;
230- await expect ( access ( path . join ( projectDirectory , 'tests' , testFile ) ) ) . resolves . toBeUndefined ( ) ;
231-
232- const tsconfigPath = path . join ( projectDirectory , 'tsconfig.json' ) ;
233- if ( hasTypeScript ) {
234- await expect ( access ( tsconfigPath ) ) . resolves . toBeUndefined ( ) ;
235- } else {
236- await expect ( access ( tsconfigPath ) ) . rejects . toThrow ( ) ;
199+ const files = [
200+ `rstack.config.${ configExtension } ` ,
201+ `src/index.${ sourceExtension } ` ,
202+ `tests/${ testFile } ` ,
203+ ] ;
204+
205+ if ( template . startsWith ( 'app-' ) ) {
206+ files . push ( 'README.md' , '.gitignore' ) ;
237207 }
208+
209+ await expectProjectSetup ( projectDirectory , template , configExtension , hasTypeScript ) ;
210+ await expectFiles ( projectDirectory , files ) ;
238211 } ,
239212) ;
240213
241- test ( 'creates the doc-basic template' , async ( ) => {
242- const projectDirectory = await createProject ( 'doc-basic' ) ;
243- const packageJson = JSON . parse (
244- await readFile ( path . join ( projectDirectory , 'package.json' ) , 'utf8' ) ,
245- ) ;
246-
247- expect ( packageJson . name ) . toBe ( 'my-app' ) ;
248- expect ( packageJson . scripts . check ) . toBe ( tsCheckScript ) ;
249- await expectStagedSetup ( projectDirectory , 'ts' , packageJson . scripts ) ;
250-
251- await expect ( access ( path . join ( projectDirectory , 'README.md' ) ) ) . resolves . toBeUndefined ( ) ;
252- await expect ( access ( path . join ( projectDirectory , '.gitignore' ) ) ) . resolves . toBeUndefined ( ) ;
253- await expect ( access ( path . join ( projectDirectory , 'rstack.config.ts' ) ) ) . resolves . toBeUndefined ( ) ;
254- await expect ( access ( path . join ( projectDirectory , 'tsconfig.json' ) ) ) . resolves . toBeUndefined ( ) ;
255- await expect ( access ( path . join ( projectDirectory , 'docs' , 'index.md' ) ) ) . resolves . toBeUndefined ( ) ;
256- await expect (
257- access ( path . join ( projectDirectory , 'docs' , 'guide' , 'start' , 'introduction.md' ) ) ,
258- ) . resolves . toBeUndefined ( ) ;
259- } ) ;
260-
261- test ( 'creates the doc-i18n template' , async ( ) => {
262- const projectDirectory = await createProject ( 'doc-i18n' ) ;
263- const packageJson = JSON . parse (
264- await readFile ( path . join ( projectDirectory , 'package.json' ) , 'utf8' ) ,
265- ) ;
266-
267- expect ( packageJson . name ) . toBe ( 'my-app' ) ;
268- expect ( packageJson . scripts . check ) . toBe ( tsCheckScript ) ;
269- await expectStagedSetup ( projectDirectory , 'ts' , packageJson . scripts ) ;
214+ test . each ( docTemplates ) ( 'creates the $template template' , async ( { template, files } ) => {
215+ const projectDirectory = await createProject ( template ) ;
270216
271- await expect ( access ( path . join ( projectDirectory , 'rstack.config.ts' ) ) ) . resolves . toBeUndefined ( ) ;
272- await expect (
273- access ( path . join ( projectDirectory , 'docs' , 'en' , 'index.md' ) ) ,
274- ) . resolves . toBeUndefined ( ) ;
275- await expect (
276- access ( path . join ( projectDirectory , 'docs' , 'zh' , 'index.md' ) ) ,
277- ) . resolves . toBeUndefined ( ) ;
217+ await expectProjectSetup ( projectDirectory , template , 'ts' , true ) ;
218+ await expectFiles ( projectDirectory , files ) ;
278219} ) ;
279-
280- test . each ( [
281- {
282- template : 'lib-node-js' ,
283- configExtension : 'js' ,
284- sourceExtension : 'js' ,
285- hasTypeScript : false ,
286- } ,
287- {
288- template : 'lib-node-ts' ,
289- configExtension : 'ts' ,
290- sourceExtension : 'ts' ,
291- hasTypeScript : true ,
292- } ,
293- {
294- template : 'lib-react-js' ,
295- configExtension : 'js' ,
296- sourceExtension : 'jsx' ,
297- hasTypeScript : false ,
298- } ,
299- {
300- template : 'lib-react-ts' ,
301- configExtension : 'ts' ,
302- sourceExtension : 'tsx' ,
303- hasTypeScript : true ,
304- } ,
305- {
306- template : 'lib-vue-js' ,
307- configExtension : 'js' ,
308- sourceExtension : 'js' ,
309- hasTypeScript : false ,
310- } ,
311- {
312- template : 'lib-vue-ts' ,
313- configExtension : 'ts' ,
314- sourceExtension : 'ts' ,
315- hasTypeScript : true ,
316- } ,
317- {
318- template : 'lib-svelte-js' ,
319- configExtension : 'js' ,
320- sourceExtension : 'js' ,
321- hasTypeScript : false ,
322- } ,
323- {
324- template : 'lib-svelte-ts' ,
325- configExtension : 'ts' ,
326- sourceExtension : 'ts' ,
327- hasTypeScript : true ,
328- } ,
329- {
330- template : 'lib-solid-js' ,
331- configExtension : 'js' ,
332- sourceExtension : 'jsx' ,
333- hasTypeScript : false ,
334- } ,
335- {
336- template : 'lib-solid-ts' ,
337- configExtension : 'ts' ,
338- sourceExtension : 'tsx' ,
339- hasTypeScript : true ,
340- } ,
341- ] ) (
342- 'creates the $template template' ,
343- async ( { template, configExtension, sourceExtension, hasTypeScript } ) => {
344- const projectDirectory = await createProject ( template ) ;
345- const packageJson = JSON . parse (
346- await readFile ( path . join ( projectDirectory , 'package.json' ) , 'utf8' ) ,
347- ) ;
348-
349- expect ( packageJson . name ) . toBe ( 'my-app' ) ;
350- expect ( packageJson . scripts . check ) . toBe ( getCheckScript ( template , hasTypeScript ) ) ;
351- await expectStagedSetup ( projectDirectory , configExtension , packageJson . scripts ) ;
352-
353- await expect (
354- access ( path . join ( projectDirectory , `rstack.config.${ configExtension } ` ) ) ,
355- ) . resolves . toBeUndefined ( ) ;
356- await expect (
357- access ( path . join ( projectDirectory , `src/index.${ sourceExtension } ` ) ) ,
358- ) . resolves . toBeUndefined ( ) ;
359- await expect (
360- access ( path . join ( projectDirectory , `tests/index.test.${ sourceExtension } ` ) ) ,
361- ) . resolves . toBeUndefined ( ) ;
362-
363- const tsconfigPath = path . join ( projectDirectory , 'tsconfig.json' ) ;
364- if ( hasTypeScript ) {
365- await expect ( access ( tsconfigPath ) ) . resolves . toBeUndefined ( ) ;
366- } else {
367- await expect ( access ( tsconfigPath ) ) . rejects . toThrow ( ) ;
368- }
369- } ,
370- ) ;
0 commit comments