2025-12-08 18:37:59 +01:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
import runpy
|
|
|
|
|
import sys
|
|
|
|
|
import unittest
|
|
|
|
|
from unittest.mock import patch
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestIntegrationBranchCommands(unittest.TestCase):
|
|
|
|
|
"""
|
2025-12-08 20:15:13 +01:00
|
|
|
Integration tests for the `pkgmgr branch` CLI wiring.
|
2025-12-08 18:37:59 +01:00
|
|
|
|
2025-12-08 20:15:13 +01:00
|
|
|
These tests execute the real entry point (main.py) and mock
|
2025-12-08 23:02:43 +01:00
|
|
|
the high-level helpers to ensure that argument parsing and
|
|
|
|
|
dispatch behave as expected.
|
2025-12-08 18:37:59 +01:00
|
|
|
"""
|
|
|
|
|
|
2025-12-08 20:15:13 +01:00
|
|
|
def _run_pkgmgr(self, extra_args: list[str]) -> None:
|
2025-12-08 18:37:59 +01:00
|
|
|
"""
|
2025-12-08 20:15:13 +01:00
|
|
|
Run the main entry point with the given extra args, as if called via:
|
|
|
|
|
|
|
|
|
|
pkgmgr <extra_args...>
|
|
|
|
|
|
|
|
|
|
We explicitly set sys.argv and execute main.py as __main__ using runpy.
|
2025-12-08 18:37:59 +01:00
|
|
|
"""
|
|
|
|
|
original_argv = list(sys.argv)
|
|
|
|
|
try:
|
2025-12-08 20:15:13 +01:00
|
|
|
# argv[0] is the program name; the rest are CLI arguments.
|
|
|
|
|
sys.argv = ["pkgmgr"] + list(extra_args)
|
|
|
|
|
runpy.run_module("main", run_name="__main__")
|
2025-12-08 18:37:59 +01:00
|
|
|
finally:
|
|
|
|
|
sys.argv = original_argv
|
|
|
|
|
|
2025-12-08 20:15:13 +01:00
|
|
|
@patch("pkgmgr.cli_core.commands.branch.open_branch")
|
2025-12-08 18:37:59 +01:00
|
|
|
def test_branch_open_with_name_and_base(self, mock_open_branch) -> None:
|
|
|
|
|
"""
|
2025-12-08 20:15:13 +01:00
|
|
|
`pkgmgr branch open feature/test --base develop` must forward
|
|
|
|
|
the name and base branch to open_branch() with cwd=".".
|
2025-12-08 18:37:59 +01:00
|
|
|
"""
|
|
|
|
|
self._run_pkgmgr(
|
2025-12-08 20:15:13 +01:00
|
|
|
["branch", "open", "feature/test", "--base", "develop"]
|
2025-12-08 18:37:59 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
mock_open_branch.assert_called_once()
|
|
|
|
|
_, kwargs = mock_open_branch.call_args
|
|
|
|
|
self.assertEqual(kwargs.get("name"), "feature/test")
|
|
|
|
|
self.assertEqual(kwargs.get("base_branch"), "develop")
|
|
|
|
|
self.assertEqual(kwargs.get("cwd"), ".")
|
|
|
|
|
|
2025-12-08 20:15:13 +01:00
|
|
|
@patch("pkgmgr.cli_core.commands.branch.open_branch")
|
|
|
|
|
def test_branch_open_without_name_uses_default_base(
|
|
|
|
|
self,
|
|
|
|
|
mock_open_branch,
|
|
|
|
|
) -> None:
|
2025-12-08 18:37:59 +01:00
|
|
|
"""
|
2025-12-08 20:15:13 +01:00
|
|
|
`pkgmgr branch open` without a name must still call open_branch(),
|
|
|
|
|
passing name=None and the default base branch 'main'.
|
2025-12-08 18:37:59 +01:00
|
|
|
"""
|
2025-12-08 20:15:13 +01:00
|
|
|
self._run_pkgmgr(["branch", "open"])
|
2025-12-08 18:37:59 +01:00
|
|
|
|
|
|
|
|
mock_open_branch.assert_called_once()
|
|
|
|
|
_, kwargs = mock_open_branch.call_args
|
|
|
|
|
self.assertIsNone(kwargs.get("name"))
|
|
|
|
|
self.assertEqual(kwargs.get("base_branch"), "main")
|
|
|
|
|
self.assertEqual(kwargs.get("cwd"), ".")
|
|
|
|
|
|
2025-12-08 23:02:43 +01:00
|
|
|
# ------------------------------------------------------------------
|
|
|
|
|
# close subcommand
|
|
|
|
|
# ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
@patch("pkgmgr.cli_core.commands.branch.close_branch")
|
|
|
|
|
def test_branch_close_with_name_and_base(self, mock_close_branch) -> None:
|
|
|
|
|
"""
|
|
|
|
|
`pkgmgr branch close feature/test --base develop` must forward
|
|
|
|
|
the name and base branch to close_branch() with cwd=".".
|
|
|
|
|
"""
|
|
|
|
|
self._run_pkgmgr(
|
|
|
|
|
["branch", "close", "feature/test", "--base", "develop"]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
mock_close_branch.assert_called_once()
|
|
|
|
|
_, kwargs = mock_close_branch.call_args
|
|
|
|
|
self.assertEqual(kwargs.get("name"), "feature/test")
|
|
|
|
|
self.assertEqual(kwargs.get("base_branch"), "develop")
|
|
|
|
|
self.assertEqual(kwargs.get("cwd"), ".")
|
|
|
|
|
|
|
|
|
|
@patch("pkgmgr.cli_core.commands.branch.close_branch")
|
|
|
|
|
def test_branch_close_without_name_uses_default_base(
|
|
|
|
|
self,
|
|
|
|
|
mock_close_branch,
|
|
|
|
|
) -> None:
|
|
|
|
|
"""
|
|
|
|
|
`pkgmgr branch close` without a name must still call close_branch(),
|
|
|
|
|
passing name=None and the default base branch 'main'.
|
|
|
|
|
|
|
|
|
|
The branch helper will then resolve the actual base (main/master)
|
|
|
|
|
internally.
|
|
|
|
|
"""
|
|
|
|
|
self._run_pkgmgr(["branch", "close"])
|
|
|
|
|
|
|
|
|
|
mock_close_branch.assert_called_once()
|
|
|
|
|
_, kwargs = mock_close_branch.call_args
|
|
|
|
|
self.assertIsNone(kwargs.get("name"))
|
|
|
|
|
self.assertEqual(kwargs.get("base_branch"), "main")
|
|
|
|
|
self.assertEqual(kwargs.get("cwd"), ".")
|
|
|
|
|
|
2025-12-08 18:37:59 +01:00
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
unittest.main()
|