Skip to content

Commit cbb9519

Browse files
authored
test: reduce duplicate test setup (#294)
1 parent 504b189 commit cbb9519

5 files changed

Lines changed: 183 additions & 340 deletions

File tree

packages/create-rstack/tests/create.test.ts

Lines changed: 104 additions & 255 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
2176
const 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+
2488
const 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+
52136
afterEach(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

Comments
 (0)