From 9a5defeb09629d429a451298b71f06a148ea281e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Randy=20D=C3=B6ring?= <30527984+radoering@users.noreply.github.com> Date: Sun, 30 Apr 2023 13:37:33 +0200 Subject: [PATCH] tests: sort tests and increase coverage --- src/poetry/core/version/pep440/version.py | 4 +- tests/version/pep440/test_version.py | 369 ++++++++++++++++------ 2 files changed, 272 insertions(+), 101 deletions(-) diff --git a/src/poetry/core/version/pep440/version.py b/src/poetry/core/version/pep440/version.py index 17a9fe3d9..b9326ec3f 100644 --- a/src/poetry/core/version/pep440/version.py +++ b/src/poetry/core/version/pep440/version.py @@ -328,7 +328,9 @@ def without_local(self: T) -> T: return self.replace(local=None) def without_postrelease(self: T) -> T: - return self.replace(post=None, dev=None) + if self.is_postrelease(): + return self.replace(post=None, dev=None) + return self def without_devrelease(self: T) -> T: return self.replace(dev=None) diff --git a/tests/version/pep440/test_version.py b/tests/version/pep440/test_version.py index b60e2db5a..c262d53a9 100644 --- a/tests/version/pep440/test_version.py +++ b/tests/version/pep440/test_version.py @@ -1,5 +1,7 @@ from __future__ import annotations +from typing import TYPE_CHECKING + import pytest from poetry.core.version.exceptions import InvalidVersion @@ -8,6 +10,10 @@ from poetry.core.version.pep440 import ReleaseTag +if TYPE_CHECKING: + from collections.abc import Sequence + + @pytest.mark.parametrize( "text,result", [ @@ -112,6 +118,189 @@ def test_pep440_parse_text_invalid_versions(text: str) -> None: PEP440Version.parse(text) +@pytest.mark.parametrize( + ("version", "major", "minor", "patch", "non_semver_parts", "parts"), + [ + ("1", 1, None, None, (), (1,)), + ("1.2", 1, 2, None, (), (1, 2)), + ("1.2.3", 1, 2, 3, (), (1, 2, 3)), + ("1.2.3.4", 1, 2, 3, (4,), (1, 2, 3, 4)), + ("1.2.3.4.5", 1, 2, 3, (4, 5), (1, 2, 3, 4, 5)), + ("9!1.2.3.4.5a6.post7.dev8", 1, 2, 3, (4, 5), (1, 2, 3, 4, 5)), + ], +) +def test_properties( + version: str, + major: int, + minor: int | None, + patch: int | None, + non_semver_parts: Sequence[int], + parts: Sequence[int], +) -> None: + v = PEP440Version.parse(version) + assert v.major == major + assert v.minor == minor + assert v.patch == patch + assert v.non_semver_parts == non_semver_parts + assert v.parts == parts + + +@pytest.mark.parametrize( + "version, expected", + [ + ("1", False), + ("1.dev0", False), + ("1.a0", True), + ("1.b1", True), + ("1.rc3", True), + ("1.a0.dev0", True), + ("9!1.2.3a1.post2.dev3", True), + ], +) +def test_is_prerelease(version: str, expected: bool) -> None: + v = PEP440Version.parse(version) + assert v.is_prerelease() is expected + + +@pytest.mark.parametrize( + "version, expected", + [ + ("1", False), + ("1.post1", True), + ("9!1.2.3a1.post2.dev3", True), + ], +) +def test_is_postrelease(version: str, expected: bool) -> None: + v = PEP440Version.parse(version) + assert v.is_postrelease() is expected + + +@pytest.mark.parametrize( + "version, expected", + [ + ("1", False), + ("1.dev0", True), + ("1.a0.dev0", True), + ("9!1.2.3a1.post2.dev3", True), + ], +) +def test_is_devrelease(version: str, expected: bool) -> None: + v = PEP440Version.parse(version) + assert v.is_devrelease() is expected + + +@pytest.mark.parametrize( + "version, expected", + [ + ("1", False), + ("1+local", True), + ("1+local.dev0", True), + ("9!1.2.3a1.post2.dev3+local", True), + ], +) +def test_is_local(version: str, expected: bool) -> None: + v = PEP440Version.parse(version) + assert v.is_local() is expected + + +@pytest.mark.parametrize( + "version, expected", + [ + ("1", True), + ("1.2", True), + ("1+local", True), + ("1.dev0", False), + ("1a0", False), + ("1.post0", False), + ], +) +def test_is_no_suffix_release(version: str, expected: bool) -> None: + v = PEP440Version.parse(version) + assert v.is_no_suffix_release() is expected + + +@pytest.mark.parametrize( + "version, expected", + [ + ("1", True), + ("1.2", True), + ("1.2.3", True), + ("2!1.2.3", True), + ("1.2.3+local", True), + ("1.2.3.4", True), + ("1.dev0", False), + ("1.2dev0", False), + ("1.2.3dev0", False), + ("1.2.3.4dev0", False), + ("1.post1", True), + ("1.2.post1", True), + ("1.2.3.post1", True), + ("1.post1.dev0", False), + ("1.2.post1.dev0", False), + ("1.2.3.post1.dev0", False), + ("1.a1", False), + ("1.2a1", False), + ("1.2.3a1", False), + ("1.2.3.4a1", False), + ("1.a1.post2", False), + ("1.2a1.post2", False), + ("1.2.3a1.post2", False), + ("1.2.3.4a1.post2", False), + ("1.a1.post2.dev0", False), + ("1.2a1.post2.dev0", False), + ("1.2.3a1.post2.dev0", False), + ("1.2.3.4a1.post2.dev0", False), + ], +) +def test_is_stable(version: str, expected: bool) -> None: + subject = PEP440Version.parse(version) + + assert subject.is_stable() is expected + assert subject.is_unstable() is not expected + + +@pytest.mark.parametrize( + "version, expected", + [ + ("0", True), + ("0.2", True), + ("0.2.3", True), + ("2!0.2.3", True), + ("0.2.3+local", True), + ("0.2.3.4", True), + ("0.dev0", False), + ("0.2dev0", False), + ("0.2.3dev0", False), + ("0.2.3.4dev0", False), + ("0.post1", True), + ("0.2.post1", True), + ("0.2.3.post1", True), + ("0.post1.dev0", False), + ("0.2.post1.dev0", False), + ("0.2.3.post1.dev0", False), + ("0.a1", False), + ("0.2a1", False), + ("0.2.3a1", False), + ("0.2.3.4a1", False), + ("0.a1.post2", False), + ("0.2a1.post2", False), + ("0.2.3a1.post2", False), + ("0.2.3.4a1.post2", False), + ("0.a1.post2.dev0", False), + ("0.2a1.post2.dev0", False), + ("0.2.3a1.post2.dev0", False), + ("0.2.3.4a1.post2.dev0", False), + ], +) +def test_is_stable_all_major_0_versions_are_treated_as_normal_versions( + version: str, expected: bool +) -> None: + subject = PEP440Version.parse(version) + + assert subject.is_stable() is expected + assert subject.is_unstable() is not expected + + @pytest.mark.parametrize( "version, expected", [ @@ -211,6 +400,24 @@ def test_next_patch(version: str, expected: str) -> None: assert v.next_patch().text == expected +@pytest.mark.parametrize( + ("version", "expected"), + [ + # simple versions (only "release" attribute) are tested in test_segments + # via Release.next() + ("1", "2"), + ("2!1", "2!2"), + ("1+local", "2+local"), + ("1.post4", "2"), + ("1.dev4", "1"), + ("1.a4", "1"), + ], +) +def test_next_stable(version: str, expected: str) -> None: + v = PEP440Version.parse(version) + assert v.next_stable().text == expected + + @pytest.mark.parametrize( "version, expected", [ @@ -229,133 +436,95 @@ def test_next_prerelease(version: str, expected: str) -> None: @pytest.mark.parametrize( "version, expected", [ - ("1", True), - ("1.2", True), - ("1.2.3", True), - ("2!1.2.3", True), - ("1.2.3+local", True), - ("1.2.3.4", True), - ("1.dev0", False), - ("1.2dev0", False), - ("1.2.3dev0", False), - ("1.2.3.4dev0", False), - ("1.post1", True), - ("1.2.post1", True), - ("1.2.3.post1", True), - ("1.post1.dev0", False), - ("1.2.post1.dev0", False), - ("1.2.3.post1.dev0", False), - ("1.a1", False), - ("1.2a1", False), - ("1.2.3a1", False), - ("1.2.3.4a1", False), - ("1.a1.post2", False), - ("1.2a1.post2", False), - ("1.2.3a1.post2", False), - ("1.2.3.4a1.post2", False), - ("1.a1.post2.dev0", False), - ("1.2a1.post2.dev0", False), - ("1.2.3a1.post2.dev0", False), - ("1.2.3.4a1.post2.dev0", False), + ("1", "1.post0"), + ("1.post1", "1.post2"), + ("9!1.2.3.4", "9!1.2.3.4.post0"), + ("9!1.2.3.4.post2", "9!1.2.3.4.post3"), + ("1.dev0", "1.post0"), + ("1.post1.dev0", "1.post1"), + ("1a1", "1a1.post0"), + ("1a1.dev0", "1a1.post0"), + ("1a1.post2", "1a1.post3"), + ("1a1.post2.dev0", "1a1.post2"), ], ) -def test_is_stable(version: str, expected: bool) -> None: - subject = PEP440Version.parse(version) - - assert subject.is_stable() == expected - assert subject.is_unstable() == (not expected) +def test_next_postrelease(version: str, expected: str) -> None: + v = PEP440Version.parse(version) + assert v.next_postrelease().text == expected @pytest.mark.parametrize( "version, expected", [ - ("0", True), - ("0.2", True), - ("0.2.3", True), - ("2!0.2.3", True), - ("0.2.3+local", True), - ("0.2.3.4", True), - ("0.dev0", False), - ("0.2dev0", False), - ("0.2.3dev0", False), - ("0.2.3.4dev0", False), - ("0.post1", True), - ("0.2.post1", True), - ("0.2.3.post1", True), - ("0.post1.dev0", False), - ("0.2.post1.dev0", False), - ("0.2.3.post1.dev0", False), - ("0.a1", False), - ("0.2a1", False), - ("0.2.3a1", False), - ("0.2.3.4a1", False), - ("0.a1.post2", False), - ("0.2a1.post2", False), - ("0.2.3a1.post2", False), - ("0.2.3.4a1.post2", False), - ("0.a1.post2.dev0", False), - ("0.2a1.post2.dev0", False), - ("0.2.3a1.post2.dev0", False), - ("0.2.3.4a1.post2.dev0", False), + ("0.dev0", "0.dev1"), + ("9!1.2.3a1.post2.dev3", "9!1.2.3a1.post2.dev4"), ], ) -def test_is_stable_all_major_0_versions_are_treated_as_normal_versions( - version: str, expected: bool -) -> None: - subject = PEP440Version.parse(version) - - assert subject.is_stable() == expected - assert subject.is_unstable() == (not expected) +def test_next_devrelease(version: str, expected: str) -> None: + v = PEP440Version.parse(version) + assert v.next_devrelease().text == expected @pytest.mark.parametrize( "version, expected", [ - ("1", "1.post0"), - ("1.post1", "1.post2"), - ("9!1.2.3.4", "9!1.2.3.4.post0"), - ("9!1.2.3.4.post2", "9!1.2.3.4.post3"), - ("1.dev0", "1.post0"), - ("1.post1.dev0", "1.post1"), - ("1a1", "1a1.post0"), - ("1a1.dev0", "1a1.post0"), - ("1a1.post2", "1a1.post3"), - ("1a1.post2.dev0", "1a1.post2"), + ("1", "1a0"), + ("9!1.2.3a1.post2.dev3", "9!1.2.3a0"), ], ) -def test_next_postrelease(version: str, expected: str) -> None: +def test_first_prerelease(version: str, expected: str) -> None: v = PEP440Version.parse(version) - assert v.next_postrelease().text == expected + assert v.first_prerelease().text == expected -def test_next_devrelease() -> None: - v = PEP440Version.parse("9!1.2.3a1.post2.dev3") - assert v.next_devrelease().text == "9!1.2.3a1.post2.dev4" +@pytest.mark.parametrize( + "version, expected", + [ + ("1", "1.dev0"), + ("1a1", "1a1.dev0"), + ("1.post2", "1.post2.dev0"), + ("9!1.2.3a1.post2.dev3", "9!1.2.3a1.post2.dev0"), + ], +) +def test_first_devrelease(version: str, expected: str) -> None: + v = PEP440Version.parse(version) + assert v.first_devrelease().text == expected -def test_first_prerelease() -> None: - v = PEP440Version.parse("9!1.2.3a1.post2.dev3") - assert v.first_prerelease().text == "9!1.2.3a0" +@pytest.mark.parametrize( + "version, expected", + [ + ("1", "1"), + ("1+local.dev0", "1"), + ("9!1.2.3a1.post2.dev3+local", "9!1.2.3a1.post2.dev3"), + ], +) +def test_without_local(version: str, expected: str) -> None: + v = PEP440Version.parse(version) + assert v.without_local().text == expected -def test_first_devrelease() -> None: - v = PEP440Version.parse("9!1.2.3a1.post2.dev3") - assert v.first_devrelease().text == "9!1.2.3a1.post2.dev0" +@pytest.mark.parametrize( + "version, expected", + [ + ("1", "1"), + ("1.dev0", "1.dev0"), + ("9!1.2.3a1.post2.dev3", "9!1.2.3a1"), + ], +) +def test_without_postrelease(version: str, expected: str) -> None: + v = PEP440Version.parse(version) + assert v.without_postrelease().text == expected @pytest.mark.parametrize( - ("version", "expected"), + "version, expected", [ - # simple versions (only "release" attribute) are tested in test_segments - # via Release.next() - ("1", "2"), - ("2!1", "2!2"), - ("1+local", "2+local"), - ("1.post4", "2"), - ("1.dev4", "1"), - ("1.a4", "1"), + ("1", "1"), + ("1.dev0", "1"), + ("9!1.2.3a1.post2.dev3", "9!1.2.3a1.post2"), ], ) -def test_next_stable(version: str, expected: str) -> None: +def test_without_devrelease(version: str, expected: str) -> None: v = PEP440Version.parse(version) - assert v.next_stable().text == expected + assert v.without_devrelease().text == expected