Add test coverage config and badges

Configured Jest for improved test coverage reporting and threshold enforcement. Updated README with project time and test coverage badges. Added scripts to fix coverage report paths and generate badges. Updated dependencies to include necessary tools for coverage reporting. Bumped package version to 0.0.9.
This commit is contained in:
2024-08-16 12:01:45 +02:00
committed by Max P.
parent 187b39e7c5
commit 4a1229b344
6 changed files with 196 additions and 3 deletions

View File

@@ -1,3 +1,16 @@
### Project Time
![Time](https://waka.mpassarello.de/api/badge/MaxP/interval:any/project:TSinjex?label=Project%20time)
### Test Coverage
[Coverage Report..](https://pxammaxp.github.io/TSinjex/coverage/lcov-report/index.html)
| Statements | Branches | Functions | Lines |
| --------------------------- | ----------------------- | ------------------------- | ----------------- |
| ![Statements](https://pxammaxp.github.io/TSinjex/coverage/badges/badge-statements.svg) | ![Branches](https://pxammaxp.github.io/TSinjex/coverage/badges/badge-branches.svg) | ![Functions](https://pxammaxp.github.io/TSinjex/coverage/badges/badge-functions.svg) | ![Lines](https://pxammaxp.github.io/TSinjex/coverage/badges/badge-lines.svg) |
# TSinjex # TSinjex
## Configuration ## Configuration

28
jest.config.coverage.cjs Normal file
View File

@@ -0,0 +1,28 @@
module.exports = {
setupFilesAfterEnv: ['./scripts/jest.setup.js'],
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/__tests__/**/*.test.ts', '**/?(*.)+(test).ts'],
testPathIgnorePatterns: ['\\.spec\\.ts$', '\\.performance\\.test\\.ts$'],
moduleDirectories: ['node_modules', 'src'],
moduleNameMapper: {
'^src/(.*)$': '<rootDir>/src/$1',
},
collectCoverage: true,
coverageDirectory: '.locale/coverage',
coverageReporters: ['text', ['lcov', { projectRoot: '..' }], 'json-summary'],
collectCoverageFrom: [
'src/**/*.{ts,tsx}',
'!src/**/*.d.ts',
'!src/**/*.performance.test.ts',
'!src/auto-imports.ts'
],
coverageThreshold: {
global: {
branches: 70,
functions: 70,
lines: 70,
statements: 70,
},
},
};

52
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "ts-injex", "name": "ts-injex",
"version": "0.0.8", "version": "0.0.9",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ts-injex", "name": "ts-injex",
"version": "0.0.8", "version": "0.0.9",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"eslint-plugin-prettier": "^5.2.1", "eslint-plugin-prettier": "^5.2.1",
@@ -18,10 +18,12 @@
"@types/node": "^20.14.11", "@types/node": "^20.14.11",
"@typescript-eslint/eslint-plugin": "^8.1.0", "@typescript-eslint/eslint-plugin": "^8.1.0",
"@typescript-eslint/parser": "^8.1.0", "@typescript-eslint/parser": "^8.1.0",
"axios": "^1.7.2",
"eslint-plugin-deprecation": "^3.0.0", "eslint-plugin-deprecation": "^3.0.0",
"eslint-plugin-import": "^2.29.1", "eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsdoc": "^50.2.2", "eslint-plugin-jsdoc": "^50.2.2",
"eslint-plugin-override": "https://github.com/PxaMMaxP/eslint-plugin-override", "eslint-plugin-override": "https://github.com/PxaMMaxP/eslint-plugin-override",
"istanbul-badges-readme": "^1.9.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"ts-jest": "^29.2.3", "ts-jest": "^29.2.3",
"typedoc": "^0.26.5", "typedoc": "^0.26.5",
@@ -2023,6 +2025,17 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/axios": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
"integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
"dev": true,
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/babel-jest": { "node_modules/babel-jest": {
"version": "29.7.0", "version": "29.7.0",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz",
@@ -3592,6 +3605,26 @@
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
"peer": true "peer": true
}, },
"node_modules/follow-redirects": {
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"dev": true,
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/for-each": { "node_modules/for-each": {
"version": "0.3.3", "version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -4361,6 +4394,15 @@
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
}, },
"node_modules/istanbul-badges-readme": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/istanbul-badges-readme/-/istanbul-badges-readme-1.9.0.tgz",
"integrity": "sha512-sD9lTsFajcfK07euJReQ0C9dy0VmXViMDJk67EZseGRC+jv+esxt5I3Viqoi1b43m5in5ek5b+0rpxJi41bJVw==",
"dev": true,
"bin": {
"istanbul-badges-readme": "lib/index.js"
}
},
"node_modules/istanbul-lib-coverage": { "node_modules/istanbul-lib-coverage": {
"version": "3.2.2", "version": "3.2.2",
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
@@ -5843,6 +5885,12 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true
},
"node_modules/psl": { "node_modules/psl": {
"version": "1.9.0", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",

View File

@@ -11,6 +11,7 @@
"lint:fix": "eslint --fix --ext .ts .", "lint:fix": "eslint --fix --ext .ts .",
"test:file": "jest --watch --onlyChanged --coverage=true --verbose", "test:file": "jest --watch --onlyChanged --coverage=true --verbose",
"test:verbose": "jest --verbose", "test:verbose": "jest --verbose",
"test:coverage": "jest --config jest.config.coverage.cjs --coverage || true && node scripts/fix-coverage-paths.cjs && node scripts/generate-badge.cjs",
"version:show": "node -e \"console.log(require('./package.json').version)\"", "version:show": "node -e \"console.log(require('./package.json').version)\"",
"docs": "typedoc" "docs": "typedoc"
}, },
@@ -34,7 +35,9 @@
"eslint-plugin-override": "https://github.com/PxaMMaxP/eslint-plugin-override", "eslint-plugin-override": "https://github.com/PxaMMaxP/eslint-plugin-override",
"jest": "^29.7.0", "jest": "^29.7.0",
"ts-jest": "^29.2.3", "ts-jest": "^29.2.3",
"typedoc": "^0.26.5" "typedoc": "^0.26.5",
"istanbul-badges-readme": "^1.9.0",
"axios": "^1.7.2"
}, },
"dependencies": { "dependencies": {
"eslint-plugin-prettier": "^5.2.1", "eslint-plugin-prettier": "^5.2.1",

View File

@@ -0,0 +1,46 @@
const fs = require('fs');
const path = require('path');
const coverageDir = path.join(__dirname, '..', '.locale', 'coverage');
const typedocUrl = 'https://pxammaxp.github.io/TSinjex/';
const getAllFiles = (dir, files = []) => {
fs.readdirSync(dir).forEach(file => {
const fullPath = path.join(dir, file);
if (fs.statSync(fullPath).isDirectory()) {
getAllFiles(fullPath, files);
} else {
files.push(fullPath);
}
});
return files;
};
// Alle HTML-Dateien im coverage-Ordner finden
const htmlFiles = getAllFiles(coverageDir).filter(file => file.endsWith('.html'));
// Alle HTML-Dateien bearbeiten
htmlFiles.forEach(filePath => {
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) {
console.error(`Error reading file ${filePath}:`, err);
return;
}
// Relative Pfade anpassen
let fixedData = data.replace(/(src|href)="(?!\.)/g, '$1="./');
// Link zur TypeDoc-Dokumentation hinzufügen
const linkHtml = `<div style="position: fixed; bottom: 10px; right: 10px;"><a href="${typedocUrl}">Zur TypeDoc-Dokumentation</a></div>`;
fixedData = fixedData.replace('</body>', `${linkHtml}</body>`);
fs.writeFile(filePath, fixedData, 'utf8', (err) => {
if (err) {
console.error(`Error writing file ${filePath}:`, err);
return;
}
console.log(`Fixed paths and added link in ${filePath}`);
});
});
});

View File

@@ -0,0 +1,55 @@
const fs = require('fs');
const path = require('path');
const { exec } = require('child_process');
const axios = require('axios');
// Step 1: Create README.md in the coverage directory
const coverageReadmePath = path.join(__dirname, '..', '.locale', 'coverage', 'README.md');
const readmeContent = `
![Statements](#statements#)
![Branches](#branches#)
![Functions](#functions#)
![Lines](#lines#)
`;
fs.writeFileSync(coverageReadmePath, readmeContent, 'utf8');
// Step 2: Execute the istanbul-badges-readme tool
exec('npx istanbul-badges-readme --coverageDir=./.locale/coverage --readmeDir=./.locale/coverage', (err, stdout, stderr) => {
if (err) {
console.error(`Error executing istanbul-badges-readme: ${stderr}`);
return;
}
console.log('Badges generated successfully.');
// Step 3: Extract the badge links from README.md
const updatedReadmeContent = fs.readFileSync(coverageReadmePath, 'utf8');
const badgeLines = updatedReadmeContent.split('\n').filter(line => line.includes('https://img.shields.io'));
// Ensure the target directory exists
const badgesDir = path.join(__dirname, '..', '.locale', 'coverage', 'badges');
if (!fs.existsSync(badgesDir)) {
fs.mkdirSync(badgesDir, { recursive: true });
}
// Badge types and their order
const badgeTypes = ['statements', 'branches', 'functions', 'lines'];
// Save the badge images
badgeLines.forEach(async (line, index) => {
const match = line.match(/\((https:\/\/img\.shields\.io\/badge\/[^)]+)\)/);
if (match) {
const url = match[1];
const response = await axios.get(url, { responseType: 'arraybuffer' });
const buffer = Buffer.from(response.data, 'binary');
const fileName = `badge-${badgeTypes[index]}.svg`;
const filePath = path.join(badgesDir, fileName);
fs.writeFileSync(filePath, buffer);
console.log(`Saved ${fileName}`);
}
});
// Step 4: Delete the README.md file
fs.unlinkSync(coverageReadmePath);
console.log('README.md file deleted.');
});