Skip to content

Commit

Permalink
feat: run vitest with coverage (nocobase#3802)
Browse files Browse the repository at this point in the history
* chore: vitest coverage

* chore: vitest coverage config

* chore: vitest coverage config

* chore: vitest coverage config

* chore: report storage dir

* chore: exclude lib dir

* chore: coverage report dir

* fix: client and server coverage

* fix: bug

* fix: coverage storage dir

---------

Co-authored-by: dream2023 <[email protected]>
  • Loading branch information
chareice and dream2023 authored Mar 31, 2024
1 parent 19c6695 commit 6bbaea2
Show file tree
Hide file tree
Showing 21 changed files with 488 additions and 80 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ tsconfig.paths.json
ncc-cache/
yarn--**
v8-compile-cache-**
vitest.config.mts.timestamp-*
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
"tar": "nocobase tar",
"test": "nocobase test",
"test:server": "nocobase test:server",
"test:server-coverage": "nocobase test-coverage:server",
"test:client": "nocobase test:client",
"test:client-coverage": "nocobase test-coverage:client",
"e2e": "nocobase e2e",
"ts": "nocobase test:server",
"tc": "nocobase test:client",
Expand Down
1 change: 1 addition & 0 deletions packages/core/cli/src/commands/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = (cli) => {
require('./doc')(cli);
require('./pm2')(cli);
require('./test')(cli);
require('./test-coverage')(cli);
require('./umi')(cli);
require('./upgrade')(cli);
require('./postinstall')(cli);
Expand Down
44 changes: 44 additions & 0 deletions packages/core/cli/src/commands/test-coverage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const { run } = require('../util');
const fg = require('fast-glob');

const coreClientPackages = ['packages/core/client', 'packages/core/sdk'];
const isCore = (dir) => dir.startsWith('packages/core');

const getPackagesDir = (isClient) => {
if (process.argv.length > 3 && !process.argv[3].startsWith('-')) {
return [process.argv[3]];
}

const allPackageJson = fg.sync(['packages/*/*/package.json', 'packages/*/*/*/package.json'], {
cwd: process.cwd(),
onlyFiles: true,
});
const res = allPackageJson.map((pkg) => pkg.replace('/package.json', ''));
return isClient
? res.filter((dir) => (isCore(dir) ? coreClientPackages.includes(dir) : true))
: res.filter((dir) => (isCore(dir) ? !coreClientPackages.includes(dir) : true));
};

module.exports = (cli) => {
cli.command('test-coverage:server').action(async () => {
const packageRoots = getPackagesDir(false);
for (const dir of packageRoots) {
try {
await run('yarn', ['test:server', '--coverage', dir]);
} catch (e) {
continue;
}
}
});

cli.command('test-coverage:client').action(async () => {
const packageRoots = getPackagesDir(true);
for (const dir of packageRoots) {
try {
await run('yarn', ['test:client', '--coverage', dir]);
} catch (e) {
continue;
}
}
});
};
10 changes: 10 additions & 0 deletions packages/core/cli/src/commands/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ function addTestCommand(name, cli) {
.option('--run')
.option('--allowOnly')
.option('--bail')
.option('--coverage')
.option('-h, --help')
.option('--single-thread [singleThread]')
.arguments('[paths...]')
Expand All @@ -29,14 +30,18 @@ function addTestCommand(name, cli) {
process.env.TEST_ENV = 'server-side';
process.argv.splice(process.argv.indexOf('--server'), 1);
}

if (opts.client) {
process.env.TEST_ENV = 'client-side';
process.argv.splice(process.argv.indexOf('--client'), 1);
}

process.env.NODE_ENV = 'test';

if (!opts.watch && !opts.run) {
process.argv.push('--run');
}

const first = paths?.[0];
if (!process.env.TEST_ENV && first) {
const key = first.split(path.sep).join('/');
Expand All @@ -46,17 +51,22 @@ function addTestCommand(name, cli) {
process.env.TEST_ENV = 'server-side';
}
}

if (process.env.TEST_ENV === 'server-side' && opts.singleThread !== 'false') {
process.argv.push('--poolOptions.threads.singleThread=true');
}

if (opts.singleThread === 'false') {
process.argv.splice(process.argv.indexOf('--single-thread=false'), 1);
}

const cliArgs = ['--max_old_space_size=14096', './node_modules/.bin/vitest', ...process.argv.slice(3)];

if (process.argv.includes('-h') || process.argv.includes('--help')) {
await run('node', cliArgs);
return;
}

if (process.env.TEST_ENV) {
console.log('process.env.TEST_ENV', process.env.TEST_ENV, cliArgs);
await run('node', cliArgs);
Expand Down
3 changes: 3 additions & 0 deletions packages/core/test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
"supertest": "^6.1.6",
"vite": "^5.0.0",
"vitest": "^1.4.0",
"@vitest/coverage-v8": "^1.4.0",
"@vitest/coverage-istanbul": "^1.4.0",
"vitest-dom": "^0.1.1",
"ws": "^8.13.0"
},
"gitHead": "d0b4efe4be55f8c79a98a331d99d9f8cf99021a1"
Expand Down
229 changes: 158 additions & 71 deletions packages/core/test/vitest.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
/// <reference types="vitest" />

import react from '@vitejs/plugin-react';
import fs from 'fs';
import path, { resolve } from 'path';
import { URL } from 'url';
import { defineConfig as vitestConfig } from 'vitest/config';
import { mergeConfig, defineConfig as vitestConfig } from 'vitest/config';

const CORE_CLIENT_PACKAGES = ['sdk', 'client'];

const __dirname = new URL('.', import.meta.url).pathname;

Expand Down Expand Up @@ -44,75 +48,158 @@ function tsConfigPathsToAlias() {
];
}

export const defineConfig = (config = {}) => {
return vitestConfig(
process.env.TEST_ENV === 'server-side'
? {
root: process.cwd(),
resolve: {
mainFields: ['module'],
},
test: {
globals: true,
setupFiles: resolve(__dirname, './setup/server.ts'),
alias: tsConfigPathsToAlias(),
include: ['packages/**/__tests__/**/*.test.ts'],
exclude: [
'**/node_modules/**',
'**/dist/**',
'**/lib/**',
'**/es/**',
'**/e2e/**',
'**/__e2e__/**',
'**/{vitest,commitlint}.config.*',
'packages/**/{dumi-theme-nocobase,sdk,client}/**/__tests__/**/*.{test,spec}.{ts,tsx}',
],
testTimeout: 300000,
hookTimeout: 300000,
// bail: 1,
// 在 GitHub Actions 中不输出日志
silent: !!process.env.GITHUB_ACTIONS,
// poolOptions: {
// threads: {
// singleThread: process.env.SINGLE_THREAD == 'false' ? false : true,
// },
// },
},
}
: {
plugins: [react()],
resolve: {
mainFields: ['module'],
},
define: {
'process.env.__TEST__': true,
'process.env.__E2E__': false,
},
test: {
globals: true,
setupFiles: resolve(__dirname, './setup/client.ts'),
environment: 'jsdom',
css: false,
alias: tsConfigPathsToAlias(),
include: ['packages/**/{dumi-theme-nocobase,sdk,client}/**/__tests__/**/*.{test,spec}.{ts,tsx}'],
exclude: [
'**/node_modules/**',
'**/dist/**',
'**/lib/**',
'**/es/**',
'**/e2e/**',
'**/__e2e__/**',
'**/{vitest,commitlint}.config.*',
],
testTimeout: 300000,
// 在 GitHub Actions 中不输出日志
silent: !!process.env.GITHUB_ACTIONS,
server: {
deps: {
inline: ['@juggle/resize-observer', 'clsx'],
},
},
},
const defineCommonConfig = () => {
return vitestConfig({
root: process.cwd(),
resolve: {
mainFields: ['module'],
},
test: {
globals: true,
alias: tsConfigPathsToAlias(),
testTimeout: 300000,
hookTimeout: 300000,
silent: !!process.env.GITHUB_ACTIONS,
include: [
'packages/**/src/**/__tests__/**/*.test.ts',
],
exclude: [
'**/node_modules/**',
'**/dist/**',
'**/lib/**',
'**/es/**',
'**/.dumi/**',
'**/e2e/**',
'**/__e2e__/**',
'**/{vitest,commitlint}.config.*',
],
watchExclude: [
'**/node_modules/**',
'**/dist/**',
'**/lib/**',
'**/es/**',
'**/.dumi/**',
'**/e2e/**',
'**/__e2e__/**',
'**/{vitest,commitlint}.config.*',
],
coverage: {
provider: 'istanbul',
include: [
'packages/**/src/**/*.{ts,tsx}',
],
exclude: ['**/swagger/**', '**/.dumi/**', '**/.umi/**', '**/.plugins/**', '**/lib/**', '**/__tests__/**', '**/e2e/**', '**/client.js', '**/server.js', '**/*.d.ts']
}
}
})
}

function getExclude(isServer) {
return [
`packages/core/${isServer ? '' : '!'}(${CORE_CLIENT_PACKAGES.join('|')})/**/*`,
`packages/**/src/${isServer ? 'client' : 'server'}/**/*`,
]
}

const defineServerConfig = () => {
return vitestConfig({
test: {
setupFiles: resolve(__dirname, './setup/server.ts'),
exclude: getExclude(true)
},
coverage: {
exclude: getExclude(true)
}
})
}

const defineClientConfig = () => {
return vitestConfig({
plugins: [react()],
define: {
'process.env.__TEST__': true,
'process.env.__E2E__': false,
},
test: {
environment: 'jsdom',
css: false,
setupFiles: resolve(__dirname, './setup/client.ts'),
server: {
deps: {
inline: ['@juggle/resize-observer', 'clsx'],
},
);
},
exclude: getExclude(false),
coverage: {
exclude: getExclude(false)
}
}
})
}

export const getFilterInclude = (isServer, isCoverage) => {
let filterFileOrDir = process.argv.slice(2).find(arg => !arg.startsWith('-'));
if (!filterFileOrDir) return;
const absPath = path.join(process.cwd(), filterFileOrDir);
const isDir = fs.existsSync(absPath) && fs.statSync(absPath).isDirectory();
// 如果是文件,则只测试当前文件
if (!isDir) {
return [filterFileOrDir];
}

const suffix = isCoverage ? `**/*.{ts,tsx}` : `**/__tests__/**/*.{test,spec}.{ts,tsx}`

// 判断是否为包目录,如果不是包目录,则只测试当前目录
const isPackage = fs.existsSync(path.join(absPath, 'package.json'));
if (!isPackage) {
return [`${filterFileOrDir}/${suffix}`];
}

// 判断是否为 core 包目录,不分 client 和 server
const isCore = absPath.includes('packages/core');
if (isCore) {
return [`${filterFileOrDir}/src/${suffix}`];
}

// 插件目录,区分 client 和 server
return [`${filterFileOrDir}/src/${isServer ? 'server' : 'client'}/${suffix}`];
}

export const getReportsDirectory = (isServer) => {
let filterFileOrDir = process.argv.slice(2).find(arg => !arg.startsWith('-'));
if (!filterFileOrDir) return;
const isPackage = fs.existsSync(path.join(process.cwd(), filterFileOrDir, 'package.json'));
if (isPackage) {
let reportsDirectory = `./storage/coverage/${filterFileOrDir.replace('packages/', '')}`;

const isCore = filterFileOrDir.includes('packages/core');

if (!isCore) {
reportsDirectory = `${reportsDirectory}/${isServer ? 'server' : 'client'}`;
}

return reportsDirectory;
}
}

export const defineConfig = () => {
const isServer = process.env.TEST_ENV === 'server-side';
const config = vitestConfig(mergeConfig(defineCommonConfig(), isServer ? defineServerConfig() : defineClientConfig()));

const filterInclude = getFilterInclude(isServer);
if (filterInclude) {
config.test.include = getFilterInclude(isServer);
}
const isCoverage = process.argv.includes('--coverage');
if (!isCoverage) {
return config;
}

config.test.coverage.include = getFilterInclude(isServer, true);
const reportsDirectory = getReportsDirectory(isServer);
if (reportsDirectory) {
config.test.coverage.reportsDirectory = reportsDirectory;
}

return config;
};
Loading

0 comments on commit 6bbaea2

Please sign in to comment.