"""Test the package's version identifier. This packaged version identifier must adhere to PEP440 and a strict subset of semantic versioning: - version identifiers must follow the x.y.z format where x.y.z are non-negative integers - non-final versions are only allowed with a .devN suffix where N is also a non-negative integer """ import re import pytest from packaging import version as pkg_version import urban_meal_delivery class TestPEP404Compliance: """Packaged version identifier is PEP440 compliant.""" @pytest.fixture def parsed_version(self) -> str: """The packaged version.""" return pkg_version.Version(urban_meal_delivery.__version__) # noqa:WPS609 def test_parsed_version_has_no_epoch(self, parsed_version): """PEP440 compliant subset of semantic versioning: no epoch.""" assert parsed_version.epoch == 0 def test_parsed_version_is_non_local(self, parsed_version): """PEP440 compliant subset of semantic versioning: no local version.""" assert parsed_version.local is None def test_parsed_version_is_no_post_release(self, parsed_version): """PEP440 compliant subset of semantic versioning: no post releases.""" assert parsed_version.is_postrelease is False def test_parsed_version_is_all_public(self, parsed_version): """PEP440 compliant subset of semantic versioning: all public parts.""" assert parsed_version.public == urban_meal_delivery.__version__ # noqa:WPS609 class TestSemanticVersioning: """Packaged version follows a strict subset of semantic versioning.""" version_pattern = re.compile( r'^(0|([1-9]\d*))\.(0|([1-9]\d*))\.(0|([1-9]\d*))(\.dev(0|([1-9]\d*)))?$', ) def test_version_is_semantic(self): """Packaged version follows semantic versioning.""" result = self.version_pattern.fullmatch( urban_meal_delivery.__version__, # noqa:WPS609 ) assert result is not None # The next two test cases are sanity checks to validate the version_pattern. @pytest.mark.parametrize( 'version', [ '0.1.0', '1.0.0', '1.2.3', '1.23.456', '123.4.56', '10.11.12', '1.2.3.dev0', '1.2.3.dev1', '1.2.3.dev10', ], ) def test_valid_semantic_versioning(self, version): """Versions follow the x.y.z or x.y.z.devN format.""" result = self.version_pattern.fullmatch(version) assert result is not None @pytest.mark.parametrize( 'version', [ '1', '1.2', '-1.2.3', '01.2.3', '1.02.3', '1.2.03', '1.2.3.4', '1.2.3.abc', '1.2.3-dev0', '1.2.3+dev0', '1.2.3.d0', '1.2.3.develop0', '1.2.3.dev-1', '1.2.3.dev01', '1.2.3..dev0', '1-2-3', '1,2,3', '1..2.3', '1.2..3', ], ) def test_invalid_semantic_versioning(self, version): """Versions follow the x.y.z or x.y.z.devN format.""" result = self.version_pattern.fullmatch(version) assert result is None