diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index df5f3e6..42960d4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,9 +8,12 @@ on: jobs: - build: + unit-test: runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 @@ -18,10 +21,54 @@ jobs: - name: Setup Python uses: actions/setup-python@v4 with: - python-version: '3.12' + python-version: ${{ matrix.python-version }} - name: Run Python unit tests - run: python3 -u -m unittest tests/tests.py + run: python3 -u -B -m unittest tests/tests.py + + + cli-mode-tests: + + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + + steps: + - uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Integration test of CLI use-case + id: integrationCLI + run: | + export PYTHONPATH=$PWD/src + echo $PYTHONPATH + python3 -B -m jacoco_badge_generator --jacoco-csv-file tests/jacoco.csv --badges-directory tests/cli/badges --generate-branches-badge true + python3 -B -m jacoco_badge_generator --jacoco-csv-file tests/multi1.csv tests/multi2.csv --badges-directory tests/cli/badges --generate-branches-badge true --coverage-badge-filename coverageMulti.svg --branches-badge-filename branchesMulti.svg + python3 -B -m jacoco_badge_generator --jacoco-csv-file tests/jacoco.csv --badges-directory tests/cli/badgesJSON --generate-coverage-badge false --generate-coverage-endpoint true --generate-branches-endpoint true + python3 -B -m jacoco_badge_generator --jacoco-csv-file tests/summaryReportTest.csv --badges-directory tests/cli/summary --generate-coverage-badge false --generate-summary true + python3 -B -m jacoco_badge_generator --jacoco-csv-file tests/jacoco.csv --badges-directory tests/cli/badges --generate-branches-badge true --generate-coverage-endpoint true --generate-branches-endpoint true --coverage-badge-filename customCoverage.svg --branches-badge-filename customBranches.svg --coverage-endpoint-filename customCoverage.json --branches-endpoint-filename customBranches.json --coverage-label "custom coverage label one" --branches-label "custom coverage label two" + python3 -B -m jacoco_badge_generator --jacoco-csv-file **/multi*.csv --badges-directory tests/glob/badges --generate-branches-badge true --coverage-badge-filename coverageMultiCLI.svg --branches-badge-filename branchesMultiCLI.svg + + - name: Verify integration test results + run: python3 -u -B -m unittest tests/integration-cli-mode.py + + + actions-mode-tests: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.12' - name: Verify that the Docker image for the action builds run: docker build . --file Dockerfile @@ -130,20 +177,9 @@ jobs: echo "coverage = ${{ steps.integration6.outputs.coverage }}" echo "branch coverage = ${{ steps.integration6.outputs.branches }}" - - name: Integration test of CLI use-case - id: integrationCLI - run: | - export PYTHONPATH=$PWD/src - echo $PYTHONPATH - python3 -B -m jacoco_badge_generator --jacoco-csv-file tests/jacoco.csv --badges-directory tests/cli/badges --generate-branches-badge true - python3 -B -m jacoco_badge_generator --jacoco-csv-file tests/multi1.csv tests/multi2.csv --badges-directory tests/cli/badges --generate-branches-badge true --coverage-badge-filename coverageMulti.svg --branches-badge-filename branchesMulti.svg - python3 -B -m jacoco_badge_generator --jacoco-csv-file tests/jacoco.csv --badges-directory tests/cli/badgesJSON --generate-coverage-badge false --generate-coverage-endpoint true --generate-branches-endpoint true - python3 -B -m jacoco_badge_generator --jacoco-csv-file tests/summaryReportTest.csv --badges-directory tests/cli/summary --generate-coverage-badge false --generate-summary true - python3 -B -m jacoco_badge_generator --jacoco-csv-file tests/jacoco.csv --badges-directory tests/cli/badges --generate-branches-badge true --generate-coverage-endpoint true --generate-branches-endpoint true --coverage-badge-filename customCoverage.svg --branches-badge-filename customBranches.svg --coverage-endpoint-filename customCoverage.json --branches-endpoint-filename customBranches.json --coverage-label "custom coverage label one" --branches-label "custom coverage label two" - python3 -B -m jacoco_badge_generator --jacoco-csv-file **/multi*.csv --badges-directory tests/glob/badges --generate-branches-badge true --coverage-badge-filename coverageMultiCLI.svg --branches-badge-filename branchesMultiCLI.svg - - name: Verify integration test results - run: python3 -u -m unittest tests/integration.py + run: python3 -u -B -m unittest tests/integration-actions-mode.py + # This test can be used to test failing the workflow run on decrease. # Uncomment to use. Success is if this fails the workflow. diff --git a/CHANGELOG.md b/CHANGELOG.md index 61e2f7e..8293695 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### CI/CD * Bump Python to 3.12 in CI/CD workflows when running unit tests. +* Matrix testing for Python versions 3.8 through 3.12 for unit tests. +* Matrix testing the CLI mode for Python versions 3.8 through 3.12. ## [2.11.0] - 2023-09-15 diff --git a/tests/integration-actions-mode.py b/tests/integration-actions-mode.py new file mode 100644 index 0000000..f6cdfe5 --- /dev/null +++ b/tests/integration-actions-mode.py @@ -0,0 +1,103 @@ +# jacoco-badge-generator: Github action for generating a jacoco coverage +# percentage badge. +# +# Copyright (c) 2020-2023 Vincent A Cicirello +# https://www.cicirello.org/ +# +# MIT License +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# + +import unittest +import json + +import sys +sys.path.insert(0,'src') +import jacoco_badge_generator.coverage_badges as jbg + +class IntegrationTest(unittest.TestCase) : + + def testGLOBIntegrationMultiJacocoReportsCase(self) : + with open("tests/78.svg","r") as expected : + with open("tests/glob/badges/coverageMulti.svg","r") as generated : + self.assertEqual(expected.read(), generated.read()) + with open("tests/87b.svg","r") as expected : + with open("tests/glob/badges/branchesMulti.svg","r") as generated : + self.assertEqual(expected.read(), generated.read()) + + def testIntegrationCustomCoverageLabel(self) : + with open("tests/custom1.svg","r") as expected : + with open("tests/badges/customCoverage.svg","r") as generated : + self.assertEqual(expected.read(), generated.read()) + + def testIntegrationCustomBranchesLabel(self) : + with open("tests/custom2.svg","r") as expected : + with open("tests/badges/customBranches.svg","r") as generated : + self.assertEqual(expected.read(), generated.read()) + + def testIntegrationCustomCoverageLabelJSON(self) : + with open("tests/custom1.json","r") as expected : + with open("tests/badges/customCoverage.json","r") as generated : + self.assertEqual(expected.read(), generated.read()) + + def testIntegrationCustomBranchesLabelJSON(self) : + with open("tests/custom2.json","r") as expected : + with open("tests/badges/customBranches.json","r") as generated : + self.assertEqual(expected.read(), generated.read()) + + def testIntegrationInstructionsBadge(self) : + with open("tests/100.svg","r") as expected : + with open("tests/badges/jacoco.svg","r") as generated : + self.assertEqual(expected.read(), generated.read()) + + def testIntegrationBranchesBadge(self) : + with open("tests/90b.svg","r") as expected : + with open("tests/badges/branches.svg","r") as generated : + self.assertEqual(expected.read(), generated.read()) + + def testIntegrationMultiJacocoReportsCase(self) : + with open("tests/78.svg","r") as expected : + with open("tests/badges/coverageMulti.svg","r") as generated : + self.assertEqual(expected.read(), generated.read()) + with open("tests/87b.svg","r") as expected : + with open("tests/badges/branchesMulti.svg","r") as generated : + self.assertEqual(expected.read(), generated.read()) + + def testIntegrationSummaryReport(self) : + with open("tests/summary/coverage-summary.json", "r") as f : + d = json.load(f) + self.assertAlmostEqual(72.72727272727272, d["coverage"]) + self.assertAlmostEqual(77.77777777777777, d["branches"]) + + def testIntegrationInstructionsJSON(self) : + with open("tests/endpoints/jacoco.json", "r") as f : + d = json.load(f) + self.assertEqual(1, d["schemaVersion"]) + self.assertEqual("coverage", d["label"]) + self.assertEqual("100%", d["message"]) + self.assertEqual(jbg.defaultColors[0], d["color"]) + + def testIntegrationBranchesJSON(self) : + with open("tests/endpoints/branches.json", "r") as f : + d = json.load(f) + self.assertEqual(1, d["schemaVersion"]) + self.assertEqual("branches", d["label"]) + self.assertEqual("90%", d["message"]) + self.assertEqual(jbg.defaultColors[1], d["color"]) diff --git a/tests/integration.py b/tests/integration-cli-mode.py similarity index 59% rename from tests/integration.py rename to tests/integration-cli-mode.py index 4e665fe..5a4e269 100644 --- a/tests/integration.py +++ b/tests/integration-cli-mode.py @@ -42,14 +42,6 @@ def testCLIGLOBIntegrationMultiJacocoReportsCase(self) : with open("tests/glob/badges/branchesMultiCLI.svg","r") as generated : self.assertEqual(expected.read(), generated.read()) - def testGLOBIntegrationMultiJacocoReportsCase(self) : - with open("tests/78.svg","r") as expected : - with open("tests/glob/badges/coverageMulti.svg","r") as generated : - self.assertEqual(expected.read(), generated.read()) - with open("tests/87b.svg","r") as expected : - with open("tests/glob/badges/branchesMulti.svg","r") as generated : - self.assertEqual(expected.read(), generated.read()) - def testCLIIntegrationCustomCoverageLabel(self) : with open("tests/custom1.svg","r") as expected : with open("tests/cli/badges/customCoverage.svg","r") as generated : @@ -70,26 +62,6 @@ def testCLIIntegrationCustomBranchesLabelJSON(self) : with open("tests/cli/badges/customBranches.json","r") as generated : self.assertEqual(expected.read(), generated.read()) - def testIntegrationCustomCoverageLabel(self) : - with open("tests/custom1.svg","r") as expected : - with open("tests/badges/customCoverage.svg","r") as generated : - self.assertEqual(expected.read(), generated.read()) - - def testIntegrationCustomBranchesLabel(self) : - with open("tests/custom2.svg","r") as expected : - with open("tests/badges/customBranches.svg","r") as generated : - self.assertEqual(expected.read(), generated.read()) - - def testIntegrationCustomCoverageLabelJSON(self) : - with open("tests/custom1.json","r") as expected : - with open("tests/badges/customCoverage.json","r") as generated : - self.assertEqual(expected.read(), generated.read()) - - def testIntegrationCustomBranchesLabelJSON(self) : - with open("tests/custom2.json","r") as expected : - with open("tests/badges/customBranches.json","r") as generated : - self.assertEqual(expected.read(), generated.read()) - def testCLIIntegrationInstructionsBadge(self) : with open("tests/100.svg","r") as expected : with open("tests/cli/badges/jacoco.svg","r") as generated : @@ -108,52 +80,12 @@ def testCLIIntegrationMultiJacocoReportsCase(self) : with open("tests/cli/badges/branchesMulti.svg","r") as generated : self.assertEqual(expected.read(), generated.read()) - def testIntegrationInstructionsBadge(self) : - with open("tests/100.svg","r") as expected : - with open("tests/badges/jacoco.svg","r") as generated : - self.assertEqual(expected.read(), generated.read()) - - def testIntegrationBranchesBadge(self) : - with open("tests/90b.svg","r") as expected : - with open("tests/badges/branches.svg","r") as generated : - self.assertEqual(expected.read(), generated.read()) - - def testIntegrationMultiJacocoReportsCase(self) : - with open("tests/78.svg","r") as expected : - with open("tests/badges/coverageMulti.svg","r") as generated : - self.assertEqual(expected.read(), generated.read()) - with open("tests/87b.svg","r") as expected : - with open("tests/badges/branchesMulti.svg","r") as generated : - self.assertEqual(expected.read(), generated.read()) - - def testIntegrationSummaryReport(self) : - with open("tests/summary/coverage-summary.json", "r") as f : - d = json.load(f) - self.assertAlmostEqual(72.72727272727272, d["coverage"]) - self.assertAlmostEqual(77.77777777777777, d["branches"]) - def testCLIIntegrationSummaryReport(self) : with open("tests/cli/summary/coverage-summary.json", "r") as f : d = json.load(f) self.assertAlmostEqual(72.72727272727272, d["coverage"]) self.assertAlmostEqual(77.77777777777777, d["branches"]) - def testIntegrationInstructionsJSON(self) : - with open("tests/endpoints/jacoco.json", "r") as f : - d = json.load(f) - self.assertEqual(1, d["schemaVersion"]) - self.assertEqual("coverage", d["label"]) - self.assertEqual("100%", d["message"]) - self.assertEqual(jbg.defaultColors[0], d["color"]) - - def testIntegrationBranchesJSON(self) : - with open("tests/endpoints/branches.json", "r") as f : - d = json.load(f) - self.assertEqual(1, d["schemaVersion"]) - self.assertEqual("branches", d["label"]) - self.assertEqual("90%", d["message"]) - self.assertEqual(jbg.defaultColors[1], d["color"]) - def testCLIIntegrationInstructionsJSON(self) : with open("tests/cli/badgesJSON/jacoco.json", "r") as f : d = json.load(f)