From 819cabe5dc3526ec4abac48b2762e7fd6b687833 Mon Sep 17 00:00:00 2001 From: Vitalii Melnychuk Date: Thu, 31 Dec 2020 18:42:50 +0000 Subject: [PATCH] Enable Minimum code coverage check (#8) * use PR base ref branch * remove cache to simplify workflow * remove data folder use real coverage * rename to use base and compare branches * improve descriptions * check if minimum-coverage-ratio is no exist * use zero minimum-coverage-ratio * add log messages and tests for code coverage min Ration * fix minimum ratio feature enable condition * use toFixed(2) for diff * add log messages * comment tests to check coverage * refactor tests running * use another command for master * set workflow failed * uncomment tests --- .github/workflows/main.yml | 31 +-- .nycrc.json | 8 + .vscode/settings.json | 3 + action.yml | 6 +- data/head-lcov.info | 317 ------------------------ data/lcov.info | 317 ------------------------ dist/index.js | 55 ++-- package.json | 3 +- src/features/minCoverageRatio.js | 19 +- src/index.js | 34 +-- src/lcov.js | 2 +- tests/features/minCoverageRatio.test.js | 80 ++++++ tests/lcov.test.js | 23 +- tests/stubs/actionsCore.stub.js | 9 + 14 files changed, 199 insertions(+), 708 deletions(-) create mode 100644 .nycrc.json create mode 100644 .vscode/settings.json delete mode 100644 data/head-lcov.info delete mode 100644 data/lcov.info create mode 100644 tests/features/minCoverageRatio.test.js create mode 100644 tests/stubs/actionsCore.stub.js diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cd8fccc..0aaa631 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,31 +1,18 @@ name: Code Coverage -on: - push: - branches: - - master - pull_request: +on: [pull_request] jobs: base_branch_cov: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - #TODO: uncommend after merge to master - # with: - # ref: master + with: + ref: ${{ github.base_ref }} - name: Use Node.js 12.13.1 uses: actions/setup-node@v1 with: node-version: 12.13.1 - - name: Cache node modules - uses: actions/cache@v1 - with: - path: node_modules - key: node_modules-v1-${{ hashFiles('yarn.lock') }} - # loading an older version is fine here, since it will get an npm install - restore-keys: | - node_modules- - name: Install dependencies run: yarn @@ -48,14 +35,6 @@ jobs: uses: actions/setup-node@v1 with: node-version: 12.13.1 - - name: Cache node modules - uses: actions/cache@v1 - with: - path: node_modules - key: node_modules-v1-${{ hashFiles('yarn.lock') }} - # loading an older version is fine here, since it will get an npm install - restore-keys: | - node_modules- - name: Download math result for job 2 uses: actions/download-artifact@v2 @@ -66,7 +45,7 @@ jobs: run: yarn - name: Run test coverage - run: yarn coverage-lcov + run: yarn coverage # Testing beta of code coverage checks # This part can be removed or optimized once barecheck code coverage will be out of beta @@ -76,5 +55,5 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} lcov-file: './coverage/lcov.info' - head-lcov-file: './lcov.info' + base-lcov-file: './lcov.info' minimum-coverage-ratio: 0 diff --git a/.nycrc.json b/.nycrc.json new file mode 100644 index 0000000..647ebb9 --- /dev/null +++ b/.nycrc.json @@ -0,0 +1,8 @@ +{ + "check-coverage": false, + "extension": [".js"], + "include": ["src/**/*.js"], + "exclude": ["coverage/**", "node_modules/**", "**/*.test.js"], + "reporter": ["html", "text", "text-summary", "lcov"], + "all": true +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f9a4c68 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "javascript.validate.enable": false +} diff --git a/action.yml b/action.yml index 7702da0..8ec0dc9 100644 --- a/action.yml +++ b/action.yml @@ -8,11 +8,11 @@ inputs: description: Your GitHub secret token required: true lcov-file: - description: 'Path where code coverage artifacts located' + description: 'Compare code coverage report' required: true default: './coverage/lcov.info' - head-lcov-file: - description: 'Code coverage head branch report to compare with' + base-lcov-file: + description: 'Base code coverage report to generate percentage diff' required: true default: '' minimum-coverage-ratio: diff --git a/data/head-lcov.info b/data/head-lcov.info deleted file mode 100644 index ff2d33b..0000000 --- a/data/head-lcov.info +++ /dev/null @@ -1,317 +0,0 @@ -TN: -SF:src/config.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:4,1 -DA:6,1 -DA:8,1 -DA:10,1 -DA:12,1 -LF:7 -LH:7 -BRDA:4,0,0,1 -BRDA:4,0,1,1 -BRDA:8,1,0,1 -BRDA:8,1,1,0 -BRDA:10,2,0,1 -BRDA:10,2,1,1 -BRDA:12,3,0,1 -BRDA:12,3,1,0 -BRF:8 -BRH:6 -end_of_record -TN: -SF:src/mongoose.ts -FN:5,(anonymous_1) -FNF:1 -FNH:0 -FNDA:0,(anonymous_1) -DA:1,1 -DA:3,1 -DA:5,1 -DA:6,0 -DA:13,0 -DA:16,1 -LF:6 -LH:4 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/server.ts -FN:24,(anonymous_0) -FN:34,(anonymous_1) -FNF:2 -FNH:0 -FNDA:0,(anonymous_0) -FNDA:0,(anonymous_1) -DA:11,0 -DA:13,0 -DA:15,0 -DA:21,0 -DA:24,0 -DA:26,0 -DA:32,0 -DA:34,0 -DA:36,0 -LF:9 -LH:0 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/resolvers.ts -FNF:0 -FNH:0 -DA:3,1 -DA:5,1 -DA:7,1 -DA:11,1 -LF:4 -LH:4 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/types.ts -FN:30,(anonymous_0) -FNF:1 -FNH:1 -FNDA:1,(anonymous_0) -DA:30,1 -DA:31,1 -DA:32,1 -LF:3 -LH:3 -BRDA:30,0,0,1 -BRDA:30,0,1,1 -BRF:2 -BRH:2 -end_of_record -TN: -SF:src/graphql/utils.ts -FN:1,(anonymous_0) -FNF:1 -FNH:1 -FNDA:3,(anonymous_0) -DA:1,1 -DA:2,3 -DA:3,1 -DA:5,2 -LF:4 -LH:4 -BRDA:2,0,0,1 -BRDA:2,0,1,2 -BRDA:2,1,0,3 -BRDA:2,1,1,3 -BRF:4 -BRH:4 -end_of_record -TN: -SF:src/graphql/mutation/index.ts -FNF:0 -FNH:0 -DA:1,1 -DA:3,1 -LF:2 -LH:2 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/mutation/signInGoogle.ts -FN:14,(anonymous_7) -FN:17,(anonymous_8) -FNF:2 -FNH:0 -FNDA:0,(anonymous_7) -FNDA:0,(anonymous_8) -DA:1,1 -DA:2,1 -DA:3,1 -DA:5,1 -DA:14,1 -DA:17,0 -DA:18,0 -DA:23,0 -DA:25,0 -DA:27,0 -DA:33,0 -DA:35,0 -DA:37,0 -DA:39,0 -LF:14 -LH:5 -BRDA:25,0,0,0 -BRDA:25,0,1,0 -BRDA:35,1,0,0 -BRDA:35,1,1,0 -BRDA:35,2,0,0 -BRDA:35,2,1,0 -BRDA:35,3,0,0 -BRDA:35,3,1,0 -BRF:8 -BRH:0 -end_of_record -TN: -SF:src/graphql/query/currentUser.ts -FN:4,(anonymous_7) -FN:8,(anonymous_8) -FNF:2 -FNH:0 -FNDA:0,(anonymous_7) -FNDA:0,(anonymous_8) -DA:1,1 -DA:4,1 -DA:8,0 -DA:9,0 -DA:11,0 -DA:13,0 -LF:6 -LH:2 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/query/index.ts -FNF:0 -FNH:0 -DA:1,1 -DA:3,1 -DA:5,1 -LF:3 -LH:3 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/query/types/department.ts -FN:16,(anonymous_7) -FN:16,(anonymous_8) -FN:23,(anonymous_9) -FN:23,(anonymous_10) -FNF:4 -FNH:2 -FNDA:1,(anonymous_7) -FNDA:1,(anonymous_8) -FNDA:0,(anonymous_9) -FNDA:0,(anonymous_10) -DA:3,2 -DA:15,2 -DA:16,1 -DA:17,1 -DA:19,1 -DA:21,1 -DA:23,0 -DA:24,0 -DA:26,0 -DA:28,0 -LF:10 -LH:6 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/query/types/index.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:4,1 -LF:3 -LH:3 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/query/types/user.ts -FN:9,(anonymous_7) -FN:11,(anonymous_8) -FNF:2 -FNH:0 -FNDA:0,(anonymous_7) -FNDA:0,(anonymous_8) -DA:3,1 -DA:8,1 -DA:11,0 -DA:12,0 -DA:14,0 -DA:16,0 -LF:6 -LH:2 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/models/department.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:4,1 -DA:12,1 -DA:18,1 -DA:23,1 -LF:6 -LH:6 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/models/user.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:4,1 -DA:13,1 -DA:20,1 -DA:25,1 -LF:6 -LH:6 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/services/googleapis.ts -FN:3,(anonymous_7) -FN:5,(anonymous_8) -FNF:2 -FNH:0 -FNDA:0,(anonymous_7) -FNDA:0,(anonymous_8) -DA:1,1 -DA:3,1 -DA:5,0 -DA:6,0 -DA:8,0 -DA:9,0 -DA:11,0 -DA:15,0 -DA:17,0 -LF:9 -LH:2 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/services/jwt.ts -FN:8,(anonymous_1) -FN:11,(anonymous_2) -FNF:2 -FNH:0 -FNDA:0,(anonymous_1) -FNDA:0,(anonymous_2) -DA:1,1 -DA:2,1 -DA:8,1 -DA:9,0 -DA:11,1 -DA:12,0 -LF:6 -LH:4 -BRF:0 -BRH:0 -end_of_record diff --git a/data/lcov.info b/data/lcov.info deleted file mode 100644 index ff2d33b..0000000 --- a/data/lcov.info +++ /dev/null @@ -1,317 +0,0 @@ -TN: -SF:src/config.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:4,1 -DA:6,1 -DA:8,1 -DA:10,1 -DA:12,1 -LF:7 -LH:7 -BRDA:4,0,0,1 -BRDA:4,0,1,1 -BRDA:8,1,0,1 -BRDA:8,1,1,0 -BRDA:10,2,0,1 -BRDA:10,2,1,1 -BRDA:12,3,0,1 -BRDA:12,3,1,0 -BRF:8 -BRH:6 -end_of_record -TN: -SF:src/mongoose.ts -FN:5,(anonymous_1) -FNF:1 -FNH:0 -FNDA:0,(anonymous_1) -DA:1,1 -DA:3,1 -DA:5,1 -DA:6,0 -DA:13,0 -DA:16,1 -LF:6 -LH:4 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/server.ts -FN:24,(anonymous_0) -FN:34,(anonymous_1) -FNF:2 -FNH:0 -FNDA:0,(anonymous_0) -FNDA:0,(anonymous_1) -DA:11,0 -DA:13,0 -DA:15,0 -DA:21,0 -DA:24,0 -DA:26,0 -DA:32,0 -DA:34,0 -DA:36,0 -LF:9 -LH:0 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/resolvers.ts -FNF:0 -FNH:0 -DA:3,1 -DA:5,1 -DA:7,1 -DA:11,1 -LF:4 -LH:4 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/types.ts -FN:30,(anonymous_0) -FNF:1 -FNH:1 -FNDA:1,(anonymous_0) -DA:30,1 -DA:31,1 -DA:32,1 -LF:3 -LH:3 -BRDA:30,0,0,1 -BRDA:30,0,1,1 -BRF:2 -BRH:2 -end_of_record -TN: -SF:src/graphql/utils.ts -FN:1,(anonymous_0) -FNF:1 -FNH:1 -FNDA:3,(anonymous_0) -DA:1,1 -DA:2,3 -DA:3,1 -DA:5,2 -LF:4 -LH:4 -BRDA:2,0,0,1 -BRDA:2,0,1,2 -BRDA:2,1,0,3 -BRDA:2,1,1,3 -BRF:4 -BRH:4 -end_of_record -TN: -SF:src/graphql/mutation/index.ts -FNF:0 -FNH:0 -DA:1,1 -DA:3,1 -LF:2 -LH:2 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/mutation/signInGoogle.ts -FN:14,(anonymous_7) -FN:17,(anonymous_8) -FNF:2 -FNH:0 -FNDA:0,(anonymous_7) -FNDA:0,(anonymous_8) -DA:1,1 -DA:2,1 -DA:3,1 -DA:5,1 -DA:14,1 -DA:17,0 -DA:18,0 -DA:23,0 -DA:25,0 -DA:27,0 -DA:33,0 -DA:35,0 -DA:37,0 -DA:39,0 -LF:14 -LH:5 -BRDA:25,0,0,0 -BRDA:25,0,1,0 -BRDA:35,1,0,0 -BRDA:35,1,1,0 -BRDA:35,2,0,0 -BRDA:35,2,1,0 -BRDA:35,3,0,0 -BRDA:35,3,1,0 -BRF:8 -BRH:0 -end_of_record -TN: -SF:src/graphql/query/currentUser.ts -FN:4,(anonymous_7) -FN:8,(anonymous_8) -FNF:2 -FNH:0 -FNDA:0,(anonymous_7) -FNDA:0,(anonymous_8) -DA:1,1 -DA:4,1 -DA:8,0 -DA:9,0 -DA:11,0 -DA:13,0 -LF:6 -LH:2 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/query/index.ts -FNF:0 -FNH:0 -DA:1,1 -DA:3,1 -DA:5,1 -LF:3 -LH:3 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/query/types/department.ts -FN:16,(anonymous_7) -FN:16,(anonymous_8) -FN:23,(anonymous_9) -FN:23,(anonymous_10) -FNF:4 -FNH:2 -FNDA:1,(anonymous_7) -FNDA:1,(anonymous_8) -FNDA:0,(anonymous_9) -FNDA:0,(anonymous_10) -DA:3,2 -DA:15,2 -DA:16,1 -DA:17,1 -DA:19,1 -DA:21,1 -DA:23,0 -DA:24,0 -DA:26,0 -DA:28,0 -LF:10 -LH:6 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/query/types/index.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:4,1 -LF:3 -LH:3 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/graphql/query/types/user.ts -FN:9,(anonymous_7) -FN:11,(anonymous_8) -FNF:2 -FNH:0 -FNDA:0,(anonymous_7) -FNDA:0,(anonymous_8) -DA:3,1 -DA:8,1 -DA:11,0 -DA:12,0 -DA:14,0 -DA:16,0 -LF:6 -LH:2 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/models/department.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:4,1 -DA:12,1 -DA:18,1 -DA:23,1 -LF:6 -LH:6 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/models/user.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:4,1 -DA:13,1 -DA:20,1 -DA:25,1 -LF:6 -LH:6 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/services/googleapis.ts -FN:3,(anonymous_7) -FN:5,(anonymous_8) -FNF:2 -FNH:0 -FNDA:0,(anonymous_7) -FNDA:0,(anonymous_8) -DA:1,1 -DA:3,1 -DA:5,0 -DA:6,0 -DA:8,0 -DA:9,0 -DA:11,0 -DA:15,0 -DA:17,0 -LF:9 -LH:2 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/services/jwt.ts -FN:8,(anonymous_1) -FN:11,(anonymous_2) -FNF:2 -FNH:0 -FNDA:0,(anonymous_1) -FNDA:0,(anonymous_2) -DA:1,1 -DA:2,1 -DA:8,1 -DA:9,0 -DA:11,1 -DA:12,0 -LF:6 -LH:4 -BRF:0 -BRH:0 -end_of_record diff --git a/dist/index.js b/dist/index.js index c551d42..9fb99a5 100644 --- a/dist/index.js +++ b/dist/index.js @@ -5908,14 +5908,21 @@ function wrappy (fn, cb) { const core = __webpack_require__(186); const checkCoverageRation = (coverageDiff) => { - const minCoverageRatio = - parseInt(core.getInput('minimum-coverage-ratio'), 10) || 0; + const minCoverageRatio = parseInt( + core.getInput('minimum-coverage-ratio'), + 10 + ); - const coverageDiffAlert = coverageDiff + minCoverageRatio; + core.info(`minimum-coverage-ratio: ${minCoverageRatio}`); - if (coverageDiffAlert < 0) { - throw new Error(`Your coverage is ${coverageDiffAlert}%`); - } + if (minCoverageRatio >= 0) { + core.info(`minimum-coverage-ratio is enabled for this workflow`); + const coverageDiffAlert = coverageDiff + minCoverageRatio; + + if (coverageDiffAlert < 0) { + core.setFailed('Code coverage is less than minimum code coverage ratio'); + } + } else core.info(`minimum-coverage-ratio is disabled for this workflow`); }; module.exports = { @@ -5962,35 +5969,41 @@ const { checkCoverageRation } = __webpack_require__(880); async function main() { const token = core.getInput('github-token'); - const baseFile = core.getInput('lcov-file'); - const headFile = core.getInput('head-lcov-file'); + const compareFile = core.getInput('lcov-file'); + const baseFile = core.getInput('base-lcov-file'); + core.info(`lcov-file: ${compareFile}`); + core.info(`base-lcov-file: ${baseFile}`); - const baseFileRaw = fs.readFileSync(baseFile, 'utf8'); + const compareFileRaw = fs.readFileSync(compareFile, 'utf8'); - if (!baseFileRaw) { - console.log(`No coverage report found at '${baseFile}', exiting...`); + if (!compareFileRaw) { + core.info(`No coverage report found at '${compareFile}', exiting...`); return; } - const headFileRaw = fs.readFileSync(headFile, 'utf8'); + const baseFileRaw = fs.readFileSync(baseFile, 'utf8'); - if (!headFileRaw) { - console.log(`No coverage report found at '${headFileRaw}', exiting...`); + if (!baseFileRaw) { + core.info(`No coverage report found at '${baseFileRaw}', exiting...`); return; } - const headFileData = await lcov.parse(headFileRaw); const baseFileData = await lcov.parse(baseFileRaw); + const compareFileData = await lcov.parse(compareFileRaw); + + const comparePercentage = lcov.percentage(compareFileData); + core.info(`Compare branch code coverage: ${comparePercentage}%`); - const basePercentage = lcov.percentage(baseFileData).toFixed(2); - const headPercentage = lcov.percentage(headFileData).toFixed(2); + const basePercentage = lcov.percentage(baseFileData); + core.info(`Base branch code coverage: ${basePercentage}%`); - const diff = basePercentage - headPercentage; + const diff = (comparePercentage - basePercentage).toFixed(2); + core.info(`Code coverage diff: ${diff}%`); - sendComment(token, diff, basePercentage); + sendComment(token, diff, comparePercentage); checkCoverageRation(diff); - core.setOutput('percentage', basePercentage); + core.setOutput('percentage', comparePercentage); core.setOutput('diff', diff); } @@ -6029,7 +6042,7 @@ const percentage = (lcov) => { found += entry.lines.found; } - return (hit / found) * 100; + return ((hit / found) * 100).toFixed(2); }; module.exports = { diff --git a/package.json b/package.json index e6dd62a..fcd98f3 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,8 @@ "build": "ncc build src/index.js --license licenses.txt", "lint": "eslint --max-warnings=0 src", "format": "prettier --write src", - "test": "mocha tests", + "test": "mocha --recursive tests", "coverage": "nyc yarn test", - "coverage-lcov": "nyc --reporter=lcov yarn test", "format-check": "prettier --check src", "check-all": "yarn format-check && yarn lint" }, diff --git a/src/features/minCoverageRatio.js b/src/features/minCoverageRatio.js index 25b6564..9290e38 100644 --- a/src/features/minCoverageRatio.js +++ b/src/features/minCoverageRatio.js @@ -1,14 +1,21 @@ const core = require('@actions/core'); const checkCoverageRation = (coverageDiff) => { - const minCoverageRatio = - parseInt(core.getInput('minimum-coverage-ratio'), 10) || 0; + const minCoverageRatio = parseInt( + core.getInput('minimum-coverage-ratio'), + 10 + ); - const coverageDiffAlert = coverageDiff + minCoverageRatio; + core.info(`minimum-coverage-ratio: ${minCoverageRatio}`); - if (coverageDiffAlert < 0) { - throw new Error(`Your coverage is ${coverageDiffAlert}%`); - } + if (minCoverageRatio >= 0) { + core.info(`minimum-coverage-ratio is enabled for this workflow`); + const coverageDiffAlert = coverageDiff + minCoverageRatio; + + if (coverageDiffAlert < 0) { + core.setFailed('Code coverage is less than minimum code coverage ratio'); + } + } else core.info(`minimum-coverage-ratio is disabled for this workflow`); }; module.exports = { diff --git a/src/index.js b/src/index.js index f74146f..4fc0467 100644 --- a/src/index.js +++ b/src/index.js @@ -7,35 +7,41 @@ const { checkCoverageRation } = require('./features/minCoverageRatio'); async function main() { const token = core.getInput('github-token'); - const baseFile = core.getInput('lcov-file'); - const headFile = core.getInput('head-lcov-file'); + const compareFile = core.getInput('lcov-file'); + const baseFile = core.getInput('base-lcov-file'); + core.info(`lcov-file: ${compareFile}`); + core.info(`base-lcov-file: ${baseFile}`); - const baseFileRaw = fs.readFileSync(baseFile, 'utf8'); + const compareFileRaw = fs.readFileSync(compareFile, 'utf8'); - if (!baseFileRaw) { - console.log(`No coverage report found at '${baseFile}', exiting...`); + if (!compareFileRaw) { + core.info(`No coverage report found at '${compareFile}', exiting...`); return; } - const headFileRaw = fs.readFileSync(headFile, 'utf8'); + const baseFileRaw = fs.readFileSync(baseFile, 'utf8'); - if (!headFileRaw) { - console.log(`No coverage report found at '${headFileRaw}', exiting...`); + if (!baseFileRaw) { + core.info(`No coverage report found at '${baseFileRaw}', exiting...`); return; } - const headFileData = await lcov.parse(headFileRaw); const baseFileData = await lcov.parse(baseFileRaw); + const compareFileData = await lcov.parse(compareFileRaw); + + const comparePercentage = lcov.percentage(compareFileData); + core.info(`Compare branch code coverage: ${comparePercentage}%`); - const basePercentage = lcov.percentage(baseFileData).toFixed(2); - const headPercentage = lcov.percentage(headFileData).toFixed(2); + const basePercentage = lcov.percentage(baseFileData); + core.info(`Base branch code coverage: ${basePercentage}%`); - const diff = basePercentage - headPercentage; + const diff = (comparePercentage - basePercentage).toFixed(2); + core.info(`Code coverage diff: ${diff}%`); - sendComment(token, diff, basePercentage); + sendComment(token, diff, comparePercentage); checkCoverageRation(diff); - core.setOutput('percentage', basePercentage); + core.setOutput('percentage', comparePercentage); core.setOutput('diff', diff); } diff --git a/src/lcov.js b/src/lcov.js index 7daf562..337c9df 100644 --- a/src/lcov.js +++ b/src/lcov.js @@ -20,7 +20,7 @@ const percentage = (lcov) => { found += entry.lines.found; } - return (hit / found) * 100; + return ((hit / found) * 100).toFixed(2); }; module.exports = { diff --git a/tests/features/minCoverageRatio.test.js b/tests/features/minCoverageRatio.test.js new file mode 100644 index 0000000..4a5a4e9 --- /dev/null +++ b/tests/features/minCoverageRatio.test.js @@ -0,0 +1,80 @@ +const proxyquire = require('proxyquire'); +const sinon = require('sinon'); +const { assert } = require('chai'); + +const actionsCoreStub = require('../stubs/actionsCore.stub'); + +const defaultMocks = { + ...actionsCoreStub +}; + +const minCoverageRatioMock = (mocks) => { + const { getInput, info, setFailed } = { ...defaultMocks, ...mocks }; + return proxyquire('../../src/features/minCoverageRatio', { + '@actions/core': { getInput, info, setFailed } + }); +}; + +describe('eatures/minCoverageRatio', () => { + describe('checkCoverageRation', () => { + it("error shouldn't be thrown once feature is not enabled", () => { + const minCoverageRatio = NaN; + const coverageDiff = 0; + + const getInput = sinon + .stub() + .withArgs('minimum-coverage-ratio') + .returns(minCoverageRatio); + const setFailed = sinon.spy(); + + const { checkCoverageRation } = minCoverageRatioMock({ + getInput, + setFailed + }); + const res = checkCoverageRation(coverageDiff); + + assert.isUndefined(res); + assert.isFalse(setFailed.calledOnce); + }); + + it("error shouldn't be thrown once coverage diff is zero", () => { + const minCoverageRatio = 0; + const coverageDiff = 0; + + const getInput = sinon + .stub() + .withArgs('minimum-coverage-ratio') + .returns(minCoverageRatio); + const setFailed = sinon.spy(); + + const { checkCoverageRation } = minCoverageRatioMock({ + getInput, + setFailed + }); + const res = checkCoverageRation(coverageDiff); + + assert.isUndefined(res); + assert.isFalse(setFailed.calledOnce); + }); + + it('should call setFailed once coverage is less than minimum coverage ratio', () => { + const minCoverageRatio = 5; + const coverageDiff = -10; + + const getInput = sinon + .stub() + .withArgs('minimum-coverage-ratio') + .returns(minCoverageRatio); + const setFailed = sinon.spy(); + + const { checkCoverageRation } = minCoverageRatioMock({ + getInput, + setFailed + }); + const res = checkCoverageRation(coverageDiff); + + assert.isUndefined(res); + assert.isTrue(setFailed.calledOnce); + }); + }); +}); diff --git a/tests/lcov.test.js b/tests/lcov.test.js index d4d18d0..09d6951 100644 --- a/tests/lcov.test.js +++ b/tests/lcov.test.js @@ -27,7 +27,28 @@ describe('lcov', () => { const res = lcov.percentage(parsedLcovFile); - assert.deepEqual(res, 50); + assert.deepEqual(res, '50.00'); + }); + + it('result should be fixed to 2 symbols after comma', () => { + const parsedLcovFile = [ + { + lines: { + hit: 3, + found: 10 + } + }, + { + lines: { + hit: 23, + found: 51 + } + } + ]; + + const res = lcov.percentage(parsedLcovFile); + + assert.deepEqual(res, '42.62'); }); }); }); diff --git a/tests/stubs/actionsCore.stub.js b/tests/stubs/actionsCore.stub.js new file mode 100644 index 0000000..d1b21f8 --- /dev/null +++ b/tests/stubs/actionsCore.stub.js @@ -0,0 +1,9 @@ +const sinon = require('sinon'); + +const actionsCoreStub = { + info: sinon.spy(), + setFailed: sinon.spy(), + getInput: sinon.spy() +}; + +module.exports = actionsCoreStub;