Release version 0.7.0
This commit is contained in:
@@ -133,6 +133,36 @@ class TestIntegrationReleaseCommand(unittest.TestCase):
|
||||
"close must be True when --close is given",
|
||||
)
|
||||
|
||||
def test_release_help_runs_without_error(self) -> None:
|
||||
"""
|
||||
Running `pkgmgr release --help` should succeed without touching the
|
||||
release helper and print a usage message for the release subcommand.
|
||||
|
||||
This test intentionally does not mock anything to exercise the real
|
||||
CLI parser wiring in main.py.
|
||||
"""
|
||||
import io
|
||||
import contextlib
|
||||
|
||||
original_argv = list(sys.argv)
|
||||
buf = io.StringIO()
|
||||
|
||||
try:
|
||||
sys.argv = ["pkgmgr", "release", "--help"]
|
||||
# argparse will call sys.exit(), so we expect a SystemExit here.
|
||||
with contextlib.redirect_stdout(buf), contextlib.redirect_stderr(buf):
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
runpy.run_module("main", run_name="__main__")
|
||||
finally:
|
||||
sys.argv = original_argv
|
||||
|
||||
# Help exit code is usually 0 (or sometimes None, which also means "no error")
|
||||
self.assertIn(cm.exception.code, (0, None))
|
||||
|
||||
output = buf.getvalue()
|
||||
# Sanity checks: release help text should be present
|
||||
self.assertIn("usage:", output)
|
||||
self.assertIn("pkgmgr release", output)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
0
tests/unit/pkgmgr/actions/release/__init__.py
Normal file
0
tests/unit/pkgmgr/actions/release/__init__.py
Normal file
@@ -6,70 +6,16 @@ import textwrap
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from pkgmgr.core.version.semver import SemVer
|
||||
from pkgmgr.actions.release import (
|
||||
_determine_current_version,
|
||||
_bump_semver,
|
||||
from pkgmgr.actions.release.files import (
|
||||
update_pyproject_version,
|
||||
update_flake_version,
|
||||
update_pkgbuild_version,
|
||||
update_spec_version,
|
||||
update_changelog,
|
||||
update_debian_changelog,
|
||||
release,
|
||||
)
|
||||
|
||||
|
||||
class TestDetermineCurrentVersion(unittest.TestCase):
|
||||
@patch("pkgmgr.actions.release.get_tags", return_value=[])
|
||||
def test_determine_current_version_no_tags_returns_zero(
|
||||
self,
|
||||
mock_get_tags,
|
||||
) -> None:
|
||||
ver = _determine_current_version()
|
||||
self.assertIsInstance(ver, SemVer)
|
||||
self.assertEqual((ver.major, ver.minor, ver.patch), (0, 0, 0))
|
||||
mock_get_tags.assert_called_once()
|
||||
|
||||
@patch("pkgmgr.actions.release.find_latest_version")
|
||||
@patch("pkgmgr.actions.release.get_tags")
|
||||
def test_determine_current_version_uses_latest_semver_tag(
|
||||
self,
|
||||
mock_get_tags,
|
||||
mock_find_latest_version,
|
||||
) -> None:
|
||||
mock_get_tags.return_value = ["v0.1.0", "v1.2.3"]
|
||||
mock_find_latest_version.return_value = ("v1.2.3", SemVer(1, 2, 3))
|
||||
|
||||
ver = _determine_current_version()
|
||||
|
||||
self.assertEqual((ver.major, ver.minor, ver.patch), (1, 2, 3))
|
||||
mock_get_tags.assert_called_once()
|
||||
mock_find_latest_version.assert_called_once_with(["v0.1.0", "v1.2.3"])
|
||||
|
||||
|
||||
class TestBumpSemVer(unittest.TestCase):
|
||||
def test_bump_semver_major(self) -> None:
|
||||
base = SemVer(1, 2, 3)
|
||||
bumped = _bump_semver(base, "major")
|
||||
self.assertEqual((bumped.major, bumped.minor, bumped.patch), (2, 0, 0))
|
||||
|
||||
def test_bump_semver_minor(self) -> None:
|
||||
base = SemVer(1, 2, 3)
|
||||
bumped = _bump_semver(base, "minor")
|
||||
self.assertEqual((bumped.major, bumped.minor, bumped.patch), (1, 3, 0))
|
||||
|
||||
def test_bump_semver_patch(self) -> None:
|
||||
base = SemVer(1, 2, 3)
|
||||
bumped = _bump_semver(base, "patch")
|
||||
self.assertEqual((bumped.major, bumped.minor, bumped.patch), (1, 2, 4))
|
||||
|
||||
def test_bump_semver_invalid_type_raises(self) -> None:
|
||||
base = SemVer(1, 2, 3)
|
||||
with self.assertRaises(ValueError):
|
||||
_bump_semver(base, "invalid-type")
|
||||
|
||||
|
||||
class TestUpdatePyprojectVersion(unittest.TestCase):
|
||||
def test_update_pyproject_version_replaces_version_line(self) -> None:
|
||||
original = textwrap.dedent(
|
||||
@@ -364,151 +310,5 @@ class TestUpdateDebianChangelog(unittest.TestCase):
|
||||
self.assertEqual(content, original)
|
||||
|
||||
|
||||
class TestReleaseOrchestration(unittest.TestCase):
|
||||
@patch("pkgmgr.actions.release.sys.stdin.isatty", return_value=False)
|
||||
@patch("pkgmgr.actions.release._run_git_command")
|
||||
@patch("pkgmgr.actions.release.update_debian_changelog")
|
||||
@patch("pkgmgr.actions.release.update_spec_version")
|
||||
@patch("pkgmgr.actions.release.update_pkgbuild_version")
|
||||
@patch("pkgmgr.actions.release.update_flake_version")
|
||||
@patch("pkgmgr.actions.release.get_current_branch", return_value="develop")
|
||||
@patch("pkgmgr.actions.release.update_changelog")
|
||||
@patch("pkgmgr.actions.release.update_pyproject_version")
|
||||
@patch("pkgmgr.actions.release._bump_semver")
|
||||
@patch("pkgmgr.actions.release._determine_current_version")
|
||||
def test_release_happy_path_uses_helpers_and_git(
|
||||
self,
|
||||
mock_determine_current_version,
|
||||
mock_bump_semver,
|
||||
mock_update_pyproject,
|
||||
mock_update_changelog,
|
||||
mock_get_current_branch,
|
||||
mock_update_flake,
|
||||
mock_update_pkgbuild,
|
||||
mock_update_spec,
|
||||
mock_update_debian_changelog,
|
||||
mock_run_git_command,
|
||||
mock_isatty,
|
||||
) -> None:
|
||||
mock_determine_current_version.return_value = SemVer(1, 2, 3)
|
||||
mock_bump_semver.return_value = SemVer(1, 2, 4)
|
||||
|
||||
release(
|
||||
pyproject_path="pyproject.toml",
|
||||
changelog_path="CHANGELOG.md",
|
||||
release_type="patch",
|
||||
message="Test release",
|
||||
preview=False,
|
||||
)
|
||||
|
||||
# Current version + bump
|
||||
mock_determine_current_version.assert_called_once()
|
||||
mock_bump_semver.assert_called_once()
|
||||
args, kwargs = mock_bump_semver.call_args
|
||||
self.assertEqual(args[0], SemVer(1, 2, 3))
|
||||
self.assertEqual(args[1], "patch")
|
||||
self.assertEqual(kwargs, {})
|
||||
|
||||
# pyproject update
|
||||
mock_update_pyproject.assert_called_once()
|
||||
args, kwargs = mock_update_pyproject.call_args
|
||||
self.assertEqual(args[0], "pyproject.toml")
|
||||
self.assertEqual(args[1], "1.2.4")
|
||||
self.assertEqual(kwargs.get("preview"), False)
|
||||
|
||||
# changelog update
|
||||
mock_update_changelog.assert_called_once()
|
||||
args, kwargs = mock_update_changelog.call_args
|
||||
self.assertEqual(args[0], "CHANGELOG.md")
|
||||
self.assertEqual(args[1], "1.2.4")
|
||||
self.assertEqual(kwargs.get("message"), "Test release")
|
||||
self.assertEqual(kwargs.get("preview"), False)
|
||||
|
||||
# repo root is derived from pyproject path; we don't care about
|
||||
# exact paths here, only that helpers are called with preview=False.
|
||||
mock_update_flake.assert_called_once()
|
||||
self.assertEqual(mock_update_flake.call_args[1].get("preview"), False)
|
||||
|
||||
mock_update_pkgbuild.assert_called_once()
|
||||
self.assertEqual(mock_update_pkgbuild.call_args[1].get("preview"), False)
|
||||
|
||||
mock_update_spec.assert_called_once()
|
||||
self.assertEqual(mock_update_spec.call_args[1].get("preview"), False)
|
||||
|
||||
mock_update_debian_changelog.assert_called_once()
|
||||
self.assertEqual(
|
||||
mock_update_debian_changelog.call_args[1].get("preview"),
|
||||
False,
|
||||
)
|
||||
|
||||
# Git operations
|
||||
mock_get_current_branch.assert_called_once()
|
||||
self.assertEqual(mock_get_current_branch.return_value, "develop")
|
||||
|
||||
git_calls = [c.args[0] for c in mock_run_git_command.call_args_list]
|
||||
self.assertIn('git commit -am "Release version 1.2.4"', git_calls)
|
||||
self.assertIn('git tag -a v1.2.4 -m "Test release"', git_calls)
|
||||
self.assertIn("git push origin develop", git_calls)
|
||||
self.assertIn("git push origin --tags", git_calls)
|
||||
|
||||
@patch("pkgmgr.actions.release.sys.stdin.isatty", return_value=False)
|
||||
@patch("pkgmgr.actions.release._run_git_command")
|
||||
@patch("pkgmgr.actions.release.update_debian_changelog")
|
||||
@patch("pkgmgr.actions.release.update_spec_version")
|
||||
@patch("pkgmgr.actions.release.update_pkgbuild_version")
|
||||
@patch("pkgmgr.actions.release.update_flake_version")
|
||||
@patch("pkgmgr.actions.release.get_current_branch", return_value="develop")
|
||||
@patch("pkgmgr.actions.release.update_changelog")
|
||||
@patch("pkgmgr.actions.release.update_pyproject_version")
|
||||
@patch("pkgmgr.actions.release._bump_semver")
|
||||
@patch("pkgmgr.actions.release._determine_current_version")
|
||||
def test_release_preview_mode_skips_git_and_uses_preview_flag(
|
||||
self,
|
||||
mock_determine_current_version,
|
||||
mock_bump_semver,
|
||||
mock_update_pyproject,
|
||||
mock_update_changelog,
|
||||
mock_get_current_branch,
|
||||
mock_update_flake,
|
||||
mock_update_pkgbuild,
|
||||
mock_update_spec,
|
||||
mock_update_debian_changelog,
|
||||
mock_run_git_command,
|
||||
mock_isatty,
|
||||
) -> None:
|
||||
mock_determine_current_version.return_value = SemVer(1, 2, 3)
|
||||
mock_bump_semver.return_value = SemVer(1, 2, 4)
|
||||
|
||||
release(
|
||||
pyproject_path="pyproject.toml",
|
||||
changelog_path="CHANGELOG.md",
|
||||
release_type="patch",
|
||||
message="Preview release",
|
||||
preview=True,
|
||||
)
|
||||
|
||||
# All update helpers must be called with preview=True
|
||||
mock_update_pyproject.assert_called_once()
|
||||
self.assertTrue(mock_update_pyproject.call_args[1].get("preview"))
|
||||
|
||||
mock_update_changelog.assert_called_once()
|
||||
self.assertTrue(mock_update_changelog.call_args[1].get("preview"))
|
||||
|
||||
mock_update_flake.assert_called_once()
|
||||
self.assertTrue(mock_update_flake.call_args[1].get("preview"))
|
||||
|
||||
mock_update_pkgbuild.assert_called_once()
|
||||
self.assertTrue(mock_update_pkgbuild.call_args[1].get("preview"))
|
||||
|
||||
mock_update_spec.assert_called_once()
|
||||
self.assertTrue(mock_update_spec.call_args[1].get("preview"))
|
||||
|
||||
mock_update_debian_changelog.assert_called_once()
|
||||
self.assertTrue(mock_update_debian_changelog.call_args[1].get("preview"))
|
||||
|
||||
# In preview mode no git commands must be executed
|
||||
mock_run_git_command.assert_not_called()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
90
tests/unit/pkgmgr/actions/release/test_git_ops.py
Normal file
90
tests/unit/pkgmgr/actions/release/test_git_ops.py
Normal file
@@ -0,0 +1,90 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from pkgmgr.core.git import GitError
|
||||
from pkgmgr.actions.release.git_ops import (
|
||||
run_git_command,
|
||||
sync_branch_with_remote,
|
||||
update_latest_tag,
|
||||
)
|
||||
|
||||
|
||||
class TestRunGitCommand(unittest.TestCase):
|
||||
@patch("pkgmgr.actions.release.git_ops.subprocess.run")
|
||||
def test_run_git_command_success(self, mock_run) -> None:
|
||||
# No exception means success
|
||||
run_git_command("git status")
|
||||
mock_run.assert_called_once()
|
||||
args, kwargs = mock_run.call_args
|
||||
self.assertIn("git status", args[0])
|
||||
self.assertTrue(kwargs.get("check"))
|
||||
|
||||
@patch("pkgmgr.actions.release.git_ops.subprocess.run")
|
||||
def test_run_git_command_failure_raises_git_error(self, mock_run) -> None:
|
||||
from subprocess import CalledProcessError
|
||||
|
||||
mock_run.side_effect = CalledProcessError(
|
||||
returncode=1,
|
||||
cmd="git status",
|
||||
output="stdout",
|
||||
stderr="stderr",
|
||||
)
|
||||
|
||||
with self.assertRaises(GitError):
|
||||
run_git_command("git status")
|
||||
|
||||
|
||||
class TestSyncBranchWithRemote(unittest.TestCase):
|
||||
@patch("pkgmgr.actions.release.git_ops.run_git_command")
|
||||
def test_sync_branch_with_remote_skips_non_main_master(
|
||||
self,
|
||||
mock_run_git_command,
|
||||
) -> None:
|
||||
sync_branch_with_remote("feature/my-branch", preview=False)
|
||||
mock_run_git_command.assert_not_called()
|
||||
|
||||
@patch("pkgmgr.actions.release.git_ops.run_git_command")
|
||||
def test_sync_branch_with_remote_preview_on_main_does_not_run_git(
|
||||
self,
|
||||
mock_run_git_command,
|
||||
) -> None:
|
||||
sync_branch_with_remote("main", preview=True)
|
||||
mock_run_git_command.assert_not_called()
|
||||
|
||||
@patch("pkgmgr.actions.release.git_ops.run_git_command")
|
||||
def test_sync_branch_with_remote_main_runs_fetch_and_pull(
|
||||
self,
|
||||
mock_run_git_command,
|
||||
) -> None:
|
||||
sync_branch_with_remote("main", preview=False)
|
||||
|
||||
calls = [c.args[0] for c in mock_run_git_command.call_args_list]
|
||||
self.assertIn("git fetch origin", calls)
|
||||
self.assertIn("git pull origin main", calls)
|
||||
|
||||
|
||||
class TestUpdateLatestTag(unittest.TestCase):
|
||||
@patch("pkgmgr.actions.release.git_ops.run_git_command")
|
||||
def test_update_latest_tag_preview_does_not_call_git(
|
||||
self,
|
||||
mock_run_git_command,
|
||||
) -> None:
|
||||
update_latest_tag("v1.2.3", preview=True)
|
||||
mock_run_git_command.assert_not_called()
|
||||
|
||||
@patch("pkgmgr.actions.release.git_ops.run_git_command")
|
||||
def test_update_latest_tag_real_calls_git(
|
||||
self,
|
||||
mock_run_git_command,
|
||||
) -> None:
|
||||
update_latest_tag("v1.2.3", preview=False)
|
||||
|
||||
calls = [c.args[0] for c in mock_run_git_command.call_args_list]
|
||||
self.assertIn("git tag -f latest v1.2.3", calls)
|
||||
self.assertIn("git push origin latest --force", calls)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
142
tests/unit/pkgmgr/actions/release/test_release_orchestration.py
Normal file
142
tests/unit/pkgmgr/actions/release/test_release_orchestration.py
Normal file
@@ -0,0 +1,142 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from pkgmgr.core.version.semver import SemVer
|
||||
from pkgmgr.actions.release import release
|
||||
|
||||
|
||||
class TestReleaseOrchestration(unittest.TestCase):
|
||||
def test_release_happy_path_uses_helpers_and_git(self) -> None:
|
||||
with patch("pkgmgr.actions.release.sys.stdin.isatty", return_value=False), \
|
||||
patch("pkgmgr.actions.release.determine_current_version") as mock_determine_current_version, \
|
||||
patch("pkgmgr.actions.release.bump_semver") as mock_bump_semver, \
|
||||
patch("pkgmgr.actions.release.update_pyproject_version") as mock_update_pyproject, \
|
||||
patch("pkgmgr.actions.release.update_changelog") as mock_update_changelog, \
|
||||
patch("pkgmgr.actions.release.get_current_branch", return_value="develop") as mock_get_current_branch, \
|
||||
patch("pkgmgr.actions.release.update_flake_version") as mock_update_flake, \
|
||||
patch("pkgmgr.actions.release.update_pkgbuild_version") as mock_update_pkgbuild, \
|
||||
patch("pkgmgr.actions.release.update_spec_version") as mock_update_spec, \
|
||||
patch("pkgmgr.actions.release.update_debian_changelog") as mock_update_debian_changelog, \
|
||||
patch("pkgmgr.actions.release.run_git_command") as mock_run_git_command, \
|
||||
patch("pkgmgr.actions.release.sync_branch_with_remote") as mock_sync_branch, \
|
||||
patch("pkgmgr.actions.release.update_latest_tag") as mock_update_latest_tag:
|
||||
mock_determine_current_version.return_value = SemVer(1, 2, 3)
|
||||
mock_bump_semver.return_value = SemVer(1, 2, 4)
|
||||
|
||||
release(
|
||||
pyproject_path="pyproject.toml",
|
||||
changelog_path="CHANGELOG.md",
|
||||
release_type="patch",
|
||||
message="Test release",
|
||||
preview=False,
|
||||
)
|
||||
|
||||
# Current version + bump
|
||||
mock_determine_current_version.assert_called_once()
|
||||
mock_bump_semver.assert_called_once()
|
||||
args, kwargs = mock_bump_semver.call_args
|
||||
self.assertEqual(args[0], SemVer(1, 2, 3))
|
||||
self.assertEqual(args[1], "patch")
|
||||
self.assertEqual(kwargs, {})
|
||||
|
||||
# pyproject update
|
||||
mock_update_pyproject.assert_called_once()
|
||||
args, kwargs = mock_update_pyproject.call_args
|
||||
self.assertEqual(args[0], "pyproject.toml")
|
||||
self.assertEqual(args[1], "1.2.4")
|
||||
self.assertEqual(kwargs.get("preview"), False)
|
||||
|
||||
# changelog update
|
||||
mock_update_changelog.assert_called_once()
|
||||
args, kwargs = mock_update_changelog.call_args
|
||||
self.assertEqual(args[0], "CHANGELOG.md")
|
||||
self.assertEqual(args[1], "1.2.4")
|
||||
self.assertEqual(kwargs.get("message"), "Test release")
|
||||
self.assertEqual(kwargs.get("preview"), False)
|
||||
|
||||
# Additional packaging helpers called with preview=False
|
||||
mock_update_flake.assert_called_once()
|
||||
self.assertEqual(mock_update_flake.call_args[1].get("preview"), False)
|
||||
|
||||
mock_update_pkgbuild.assert_called_once()
|
||||
self.assertEqual(mock_update_pkgbuild.call_args[1].get("preview"), False)
|
||||
|
||||
mock_update_spec.assert_called_once()
|
||||
self.assertEqual(mock_update_spec.call_args[1].get("preview"), False)
|
||||
|
||||
mock_update_debian_changelog.assert_called_once()
|
||||
self.assertEqual(
|
||||
mock_update_debian_changelog.call_args[1].get("preview"),
|
||||
False,
|
||||
)
|
||||
|
||||
# Git operations
|
||||
mock_get_current_branch.assert_called_once()
|
||||
self.assertEqual(mock_get_current_branch.return_value, "develop")
|
||||
|
||||
git_calls = [c.args[0] for c in mock_run_git_command.call_args_list]
|
||||
self.assertIn('git commit -am "Release version 1.2.4"', git_calls)
|
||||
self.assertIn('git tag -a v1.2.4 -m "Test release"', git_calls)
|
||||
self.assertIn("git push origin develop", git_calls)
|
||||
self.assertIn("git push origin --tags", git_calls)
|
||||
|
||||
# Branch sync & latest tag update
|
||||
mock_sync_branch.assert_called_once_with("develop", preview=False)
|
||||
mock_update_latest_tag.assert_called_once_with("v1.2.4", preview=False)
|
||||
|
||||
def test_release_preview_mode_skips_git_and_uses_preview_flag(self) -> None:
|
||||
with patch("pkgmgr.actions.release.determine_current_version") as mock_determine_current_version, \
|
||||
patch("pkgmgr.actions.release.bump_semver") as mock_bump_semver, \
|
||||
patch("pkgmgr.actions.release.update_pyproject_version") as mock_update_pyproject, \
|
||||
patch("pkgmgr.actions.release.update_changelog") as mock_update_changelog, \
|
||||
patch("pkgmgr.actions.release.get_current_branch", return_value="develop") as mock_get_current_branch, \
|
||||
patch("pkgmgr.actions.release.update_flake_version") as mock_update_flake, \
|
||||
patch("pkgmgr.actions.release.update_pkgbuild_version") as mock_update_pkgbuild, \
|
||||
patch("pkgmgr.actions.release.update_spec_version") as mock_update_spec, \
|
||||
patch("pkgmgr.actions.release.update_debian_changelog") as mock_update_debian_changelog, \
|
||||
patch("pkgmgr.actions.release.run_git_command") as mock_run_git_command, \
|
||||
patch("pkgmgr.actions.release.sync_branch_with_remote") as mock_sync_branch, \
|
||||
patch("pkgmgr.actions.release.update_latest_tag") as mock_update_latest_tag:
|
||||
mock_determine_current_version.return_value = SemVer(1, 2, 3)
|
||||
mock_bump_semver.return_value = SemVer(1, 2, 4)
|
||||
|
||||
release(
|
||||
pyproject_path="pyproject.toml",
|
||||
changelog_path="CHANGELOG.md",
|
||||
release_type="patch",
|
||||
message="Preview release",
|
||||
preview=True,
|
||||
)
|
||||
|
||||
# All update helpers must be called with preview=True
|
||||
mock_update_pyproject.assert_called_once()
|
||||
self.assertTrue(mock_update_pyproject.call_args[1].get("preview"))
|
||||
|
||||
mock_update_changelog.assert_called_once()
|
||||
self.assertTrue(mock_update_changelog.call_args[1].get("preview"))
|
||||
|
||||
mock_update_flake.assert_called_once()
|
||||
self.assertTrue(mock_update_flake.call_args[1].get("preview"))
|
||||
|
||||
mock_update_pkgbuild.assert_called_once()
|
||||
self.assertTrue(mock_update_pkgbuild.call_args[1].get("preview"))
|
||||
|
||||
mock_update_spec.assert_called_once()
|
||||
self.assertTrue(mock_update_spec.call_args[1].get("preview"))
|
||||
|
||||
mock_update_debian_changelog.assert_called_once()
|
||||
self.assertTrue(mock_update_debian_changelog.call_args[1].get("preview"))
|
||||
|
||||
# In preview mode no real git commands must be executed
|
||||
mock_run_git_command.assert_not_called()
|
||||
|
||||
# Branch sync is still invoked (with preview=True internally),
|
||||
# and latest tag is only announced in preview mode
|
||||
mock_sync_branch.assert_called_once_with("develop", preview=True)
|
||||
mock_update_latest_tag.assert_called_once_with("v1.2.4", preview=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
64
tests/unit/pkgmgr/actions/release/test_versioning.py
Normal file
64
tests/unit/pkgmgr/actions/release/test_versioning.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from pkgmgr.core.version.semver import SemVer
|
||||
from pkgmgr.actions.release.versioning import (
|
||||
determine_current_version,
|
||||
bump_semver,
|
||||
)
|
||||
|
||||
|
||||
class TestDetermineCurrentVersion(unittest.TestCase):
|
||||
@patch("pkgmgr.actions.release.versioning.get_tags", return_value=[])
|
||||
def test_determine_current_version_no_tags_returns_zero(
|
||||
self,
|
||||
mock_get_tags,
|
||||
) -> None:
|
||||
ver = determine_current_version()
|
||||
self.assertIsInstance(ver, SemVer)
|
||||
self.assertEqual((ver.major, ver.minor, ver.patch), (0, 0, 0))
|
||||
mock_get_tags.assert_called_once()
|
||||
|
||||
@patch("pkgmgr.actions.release.versioning.find_latest_version")
|
||||
@patch("pkgmgr.actions.release.versioning.get_tags")
|
||||
def test_determine_current_version_uses_latest_semver_tag(
|
||||
self,
|
||||
mock_get_tags,
|
||||
mock_find_latest_version,
|
||||
) -> None:
|
||||
mock_get_tags.return_value = ["v0.1.0", "v1.2.3"]
|
||||
mock_find_latest_version.return_value = ("v1.2.3", SemVer(1, 2, 3))
|
||||
|
||||
ver = determine_current_version()
|
||||
|
||||
self.assertEqual((ver.major, ver.minor, ver.patch), (1, 2, 3))
|
||||
mock_get_tags.assert_called_once()
|
||||
mock_find_latest_version.assert_called_once_with(["v0.1.0", "v1.2.3"])
|
||||
|
||||
|
||||
class TestBumpSemVer(unittest.TestCase):
|
||||
def test_bump_semver_major(self) -> None:
|
||||
base = SemVer(1, 2, 3)
|
||||
bumped = bump_semver(base, "major")
|
||||
self.assertEqual((bumped.major, bumped.minor, bumped.patch), (2, 0, 0))
|
||||
|
||||
def test_bump_semver_minor(self) -> None:
|
||||
base = SemVer(1, 2, 3)
|
||||
bumped = bump_semver(base, "minor")
|
||||
self.assertEqual((bumped.major, bumped.minor, bumped.patch), (1, 3, 0))
|
||||
|
||||
def test_bump_semver_patch(self) -> None:
|
||||
base = SemVer(1, 2, 3)
|
||||
bumped = bump_semver(base, "patch")
|
||||
self.assertEqual((bumped.major, bumped.minor, bumped.patch), (1, 2, 4))
|
||||
|
||||
def test_bump_semver_invalid_type_raises(self) -> None:
|
||||
base = SemVer(1, 2, 3)
|
||||
with self.assertRaises(ValueError):
|
||||
bump_semver(base, "invalid-type")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user