Skip to content

Commit c69bbb7

Browse files
committed
Try very hard to fix vitest
1 parent d42ad0e commit c69bbb7

File tree

17 files changed

+512
-210
lines changed

17 files changed

+512
-210
lines changed

devserver/vite.config.ts

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ import pathlib from 'path';
66
import react from '@vitejs/plugin-react';
77
import { nodePolyfills } from 'vite-plugin-node-polyfills';
88
import { loadEnv, defineConfig, type UserConfig } from 'vite'
9-
import { mergeConfig } from 'vitest/config';
9+
import { defineProject } from 'vitest/config';
1010
import type { BrowserCommand } from 'vitest/node';
11-
import rootConfig from '../vitest.config';
1211

1312
const setLocalStorage: BrowserCommand<[key: string, value: any]> = async (ctx, key, value) => {
1413
if (ctx.provider.name === 'playwright') {
@@ -72,26 +71,26 @@ export default defineConfig(({ mode }) => {
7271
},
7372
}
7473

75-
return mergeConfig(
76-
rootConfig, {
77-
...viteConfig,
78-
test: {
79-
name: 'Dev Server',
80-
include: [
81-
`${import.meta.dirname}/**/__tests__/**/*.ts*`
82-
],
83-
browser: {
84-
enabled: true,
85-
headless: true,
86-
provider: 'playwright',
87-
instances: [{
88-
browser: 'chromium'
89-
}],
90-
commands: {
91-
setLocalStorage
92-
}
74+
const testConfig = defineProject({
75+
test: {
76+
root: import.meta.dirname,
77+
name: 'Dev Server',
78+
include: ['**/__tests__/**/*.{ts,tsx}'],
79+
browser: {
80+
enabled: true,
81+
provider: 'playwright',
82+
instances: [{
83+
browser: 'chromium'
84+
}],
85+
commands: {
86+
setLocalStorage
9387
}
9488
}
9589
}
96-
);
90+
})
91+
92+
return {
93+
...viteConfig,
94+
...testConfig,
95+
}
9796
})

lib/buildtools/src/commands/main.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { getBuildCommand, getBuildHtmlCommand, getManifestCommand } from './buil
33
import { getListCommand } from './list.js';
44
import { getLintCommand, getLintGlobalCommand, getPrebuildAllCommand, getTscCommand } from './prebuild.js';
55
import getTemplateCommand from './template.js';
6-
import { getTestCommand } from './testing.js';
6+
import { getTestAllCommand, getTestCommand } from './testing.js';
77

88
const commands: (() => Command<any>)[] = [
99
getBuildCommand,
@@ -15,6 +15,7 @@ const commands: (() => Command<any>)[] = [
1515
getPrebuildAllCommand,
1616
getTemplateCommand,
1717
getTestCommand,
18+
getTestAllCommand,
1819
getTscCommand
1920
];
2021

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
import { resolve } from 'path';
22
import { Command, Option } from '@commander-js/extra-typings';
3+
import chalk from 'chalk';
34
import type { VitestRunMode } from 'vitest/node';
4-
import { resolveEitherBundleOrTab } from '../build/manifest.js';
5-
import { runIndividualVitest } from '../testing.js';
5+
import { runVitest } from '../testing/runner.js';
6+
import { getAllTestConfigurations, getTestConfiguration } from '../testing/utils.js';
67
import { logCommandErrorAndExit } from './commandUtils.js';
78

89
const vitestModeOption = new Option('--mode <mode>', 'Vitest Run Mode. See https://vitest.dev/guide/cli.html#mode')
910
.choices(['test', 'benchmark'] as VitestRunMode[])
1011
.default('test');
1112

1213
const watchOption = new Option('-w, --watch', 'Run tests in watch mode');
13-
1414
const updateOption = new Option('-u, --update', 'Update snapshots');
15-
1615
const coverageOption = new Option('--coverage');
1716

1817
export const getTestCommand = () => new Command('test')
@@ -24,15 +23,27 @@ export const getTestCommand = () => new Command('test')
2423
.argument('[directory]', 'Directory to search for tests. If no directory is specified, the current working directory is used')
2524
.action(async (directory, { mode, ...options }) => {
2625
const fullyResolved = resolve(directory ?? process.cwd());
27-
const resolveResult = await resolveEitherBundleOrTab(fullyResolved);
26+
const configResult = await getTestConfiguration(fullyResolved, !!options.watch);
2827

29-
if (resolveResult.severity === 'error') {
30-
if (resolveResult.errors.length === 0 ) {
31-
logCommandErrorAndExit(`No tab or bundle found at ${fullyResolved}`);
32-
}
28+
if (configResult.severity === 'error') {
29+
logCommandErrorAndExit(configResult);
30+
}
3331

34-
logCommandErrorAndExit(resolveResult);
32+
if (configResult.config === null) {
33+
console.log(chalk.yellowBright(`No tests found for in ${fullyResolved}`));
34+
return;
3535
}
3636

37-
await runIndividualVitest(mode, resolveResult.asset, options);
37+
await runVitest(mode, [fullyResolved], [configResult.config], options);
38+
});
39+
40+
export const getTestAllCommand = () => new Command('testall')
41+
.description('Run all tests based on the configuration of the root vitest file')
42+
.addOption(vitestModeOption)
43+
.addOption(watchOption)
44+
.addOption(updateOption)
45+
.addOption(coverageOption)
46+
.action(async ({ mode, ...options }) => {
47+
const configs = await getAllTestConfigurations(!!options.watch);
48+
await runVitest(mode, undefined, configs, options);
3849
});

lib/buildtools/src/testing.ts

Lines changed: 0 additions & 91 deletions
This file was deleted.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import pathlib from 'path';
2+
import react from '@vitejs/plugin-react';
3+
import { coverageConfigDefaults, defineConfig, defineProject, mergeConfig } from 'vitest/config';
4+
import { getGitRoot } from '../getGitRoot.js';
5+
6+
const gitRoot = await getGitRoot();
7+
8+
/**
9+
* A shared Vitest configuration object that can be combined with {@link mergeConfig}
10+
* to create custom Vitest configurations for each sub project
11+
*/
12+
export const sharedVitestConfiguration = defineConfig({
13+
resolve: {
14+
alias: [{
15+
find: /^js-slang\/context/,
16+
replacement: pathlib.join(gitRoot, 'src/__mocks__/context.ts')
17+
}]
18+
},
19+
test: {
20+
clearMocks: true,
21+
coverage: {
22+
provider: 'v8',
23+
exclude: [
24+
...coverageConfigDefaults.exclude,
25+
'./build/**',
26+
'**/__mocks__/**',
27+
'**/__test_mocks__/**',
28+
'**/bin/**',
29+
'**/build.js',
30+
'**/*.config.?(c)[jt]s',
31+
'**/dist.?(c)js',
32+
'./docs',
33+
'**/src/**/samples/**',
34+
'./lib/buildtools/src/build/docs/drawdown.ts'
35+
]
36+
},
37+
silent: 'passed-only',
38+
}
39+
});
40+
41+
/**
42+
* Vitest configuration specific to tabs
43+
*/
44+
export const sharedTabsConfig = mergeConfig(
45+
sharedVitestConfiguration,
46+
// @ts-expect-error help why are plugins weird
47+
defineProject({
48+
// @ts-expect-error help why are plugins weird
49+
plugins: [react()],
50+
optimizeDeps: {
51+
include: [
52+
'@blueprintjs/core',
53+
'@blueprintjs/icons',
54+
'gl-matrix',
55+
'js-slang',
56+
'lodash',
57+
'vitest-browser-react'
58+
]
59+
},
60+
test: {
61+
include: ['**/__tests__/*.{ts,tsx}'],
62+
environment: 'jsdom',
63+
browser: {
64+
provider: 'playwright',
65+
instances: [{
66+
browser: 'chromium',
67+
}]
68+
}
69+
}
70+
})
71+
);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { mergeConfig, type TestProjectInlineConfiguration } from 'vitest/config';
2+
import { startVitest, type VitestRunMode } from 'vitest/node';
3+
import { sharedVitestConfiguration } from './configs.js';
4+
import type { RunVitestBoolOptions } from './types.js';
5+
6+
/**
7+
* Create a new Vitest instance and run it. Refer to https://vitest.dev/advanced/api/#startvitest for more information.
8+
*/
9+
export async function runVitest(mode: VitestRunMode, filters: string[] | undefined, projects: TestProjectInlineConfiguration[], options: RunVitestBoolOptions) {
10+
try {
11+
const finalConfig = mergeConfig(
12+
sharedVitestConfiguration.test!,
13+
{
14+
config: false,
15+
projects,
16+
watch: !!options.watch,
17+
update: !!options.update,
18+
coverage: {
19+
// Coverage is always just blank so I can never seem to get
20+
// specific coverage reports only
21+
// include: filters?.map(each => `${each}/**/*.tsx`),
22+
enabled: !!options.coverage
23+
},
24+
}
25+
);
26+
const vitest = await startVitest(mode, filters, finalConfig);
27+
28+
if (vitest.shouldKeepServer()) {
29+
// If Vitest is called in watch mode, then we wait for the onClose hook
30+
// to be called to return instead
31+
// Refer to https://vitest.dev/advanced/api/vitest.html#shouldkeepserver
32+
await new Promise<void>(resolve => vitest.onClose(resolve));
33+
} else {
34+
await vitest.close();
35+
}
36+
} catch (error) {
37+
console.error(error);
38+
}
39+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface RunVitestBoolOptions {
2+
watch?: boolean
3+
coverage?: boolean
4+
update?: boolean
5+
}

0 commit comments

Comments
 (0)