diff --git a/README.md b/README.md index 580509f..1da8f0d 100644 --- a/README.md +++ b/README.md @@ -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 ## Configuration diff --git a/jest.config.coverage.cjs b/jest.config.coverage.cjs new file mode 100644 index 0000000..df0c2a9 --- /dev/null +++ b/jest.config.coverage.cjs @@ -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/(.*)$': '/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, + }, + }, +}; diff --git a/package-lock.json b/package-lock.json index 2b843f7..747f529 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ts-injex", - "version": "0.0.8", + "version": "0.0.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ts-injex", - "version": "0.0.8", + "version": "0.0.9", "license": "MIT", "dependencies": { "eslint-plugin-prettier": "^5.2.1", @@ -18,10 +18,12 @@ "@types/node": "^20.14.11", "@typescript-eslint/eslint-plugin": "^8.1.0", "@typescript-eslint/parser": "^8.1.0", + "axios": "^1.7.2", "eslint-plugin-deprecation": "^3.0.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsdoc": "^50.2.2", "eslint-plugin-override": "https://github.com/PxaMMaxP/eslint-plugin-override", + "istanbul-badges-readme": "^1.9.0", "jest": "^29.7.0", "ts-jest": "^29.2.3", "typedoc": "^0.26.5", @@ -2023,6 +2025,17 @@ "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": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -3592,6 +3605,26 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "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": { "version": "0.3.3", "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", "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": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -5843,6 +5885,12 @@ "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": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", diff --git a/package.json b/package.json index 197a864..f0d38f3 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "lint:fix": "eslint --fix --ext .ts .", "test:file": "jest --watch --onlyChanged --coverage=true --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)\"", "docs": "typedoc" }, @@ -34,7 +35,9 @@ "eslint-plugin-override": "https://github.com/PxaMMaxP/eslint-plugin-override", "jest": "^29.7.0", "ts-jest": "^29.2.3", - "typedoc": "^0.26.5" + "typedoc": "^0.26.5", + "istanbul-badges-readme": "^1.9.0", + "axios": "^1.7.2" }, "dependencies": { "eslint-plugin-prettier": "^5.2.1", diff --git a/scripts/fix-coverage-paths.cjs b/scripts/fix-coverage-paths.cjs new file mode 100644 index 0000000..090f4c4 --- /dev/null +++ b/scripts/fix-coverage-paths.cjs @@ -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 = `
Zur TypeDoc-Dokumentation
`; + fixedData = fixedData.replace('', `${linkHtml}`); + + 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}`); + }); + }); +}); diff --git a/scripts/generate-badge.cjs b/scripts/generate-badge.cjs new file mode 100644 index 0000000..f307d4c --- /dev/null +++ b/scripts/generate-badge.cjs @@ -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.'); +});