diff --git a/.github/workflows/test-stack-reusable-workflow.yml b/.github/workflows/test-stack-reusable-workflow.yml index f2864680cef..29903c17151 100644 --- a/.github/workflows/test-stack-reusable-workflow.yml +++ b/.github/workflows/test-stack-reusable-workflow.yml @@ -64,14 +64,16 @@ jobs: echo "Running processes in docker..." docker ps - - name: Test built container with Pytest (generally as requests/plaintext fetching) + - name: Run Unit Tests run: | # Unit tests - echo "run test with unittest" docker run test-changedetectionio bash -c 'python3 -m unittest changedetectionio.tests.unit.test_notification_diff' docker run test-changedetectionio bash -c 'python3 -m unittest changedetectionio.tests.unit.test_watch_model' docker run test-changedetectionio bash -c 'python3 -m unittest changedetectionio.tests.unit.test_jinja2_security' - + docker run test-changedetectionio bash -c 'python3 -m unittest changedetectionio.tests.unit.test_semver' + + - name: Test built container with Pytest (generally as requests/plaintext fetching) + run: | # All tests echo "run test with pytest" # The default pytest logger_level is TRACE diff --git a/changedetectionio/__init__.py b/changedetectionio/__init__.py index 260690deaf1..f07204ff61c 100644 --- a/changedetectionio/__init__.py +++ b/changedetectionio/__init__.py @@ -24,6 +24,9 @@ app = None datastore = None +def get_version(): + return __version__ + # Parent wrapper or OS sends us a SIGTERM/SIGINT, do everything required for a clean shutdown def sigshutdown_handler(_signo, _stack_frame): global app diff --git a/changedetectionio/tests/unit/test_semver.py b/changedetectionio/tests/unit/test_semver.py new file mode 100644 index 00000000000..5ebfc95e7c2 --- /dev/null +++ b/changedetectionio/tests/unit/test_semver.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 + +# run from dir above changedetectionio/ dir +# python3 -m unittest changedetectionio.tests.unit.test_semver + +import re +import unittest + + +# The SEMVER regex +SEMVER_REGEX = r"^(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:-(?P(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$" + +# Compile the regex +semver_pattern = re.compile(SEMVER_REGEX) + +class TestSemver(unittest.TestCase): + def test_valid_versions(self): + """Test valid semantic version strings""" + valid_versions = [ + "1.0.0", + "0.1.0", + "0.0.1", + "1.0.0-alpha", + "1.0.0-alpha.1", + "1.0.0-0.3.7", + "1.0.0-x.7.z.92", + "1.0.0-alpha+001", + "1.0.0+20130313144700", + "1.0.0-beta+exp.sha.5114f85" + ] + for version in valid_versions: + with self.subTest(version=version): + self.assertIsNotNone(semver_pattern.match(version), f"Version {version} should be valid") + + def test_invalid_versions(self): + """Test invalid semantic version strings""" + invalid_versions = [ + "0.48.06", + "1.0", + "1.0.0-", +# Seems to pass the semver.org regex? +# "1.0.0-alpha-", + "1.0.0+", + "1.0.0-alpha+", + "1.0.0-", + "01.0.0", + "1.01.0", + "1.0.01", + ".1.0.0", + "1..0.0" + ] + for version in invalid_versions: + with self.subTest(version=version): + res = semver_pattern.match(version) + self.assertIsNone(res, f"Version '{version}' should be invalid") + + def test_our_version(self): + from changedetectionio import get_version + our_version = get_version() + self.assertIsNotNone(semver_pattern.match(our_version), f"Our version '{our_version}' should be a valid SEMVER string") + + +if __name__ == '__main__': + unittest.main()