Files
pkgmgr/tests/unit/pkgmgr/cli/commands/test_tools.py
Kevin Veen-Birkenbach b4e0594901 style: modernise typing and clean up lint findings
Repository-wide mechanical cleanup so `ruff check src tests` has a chance
of passing; no behavioural changes.

- Add `from __future__ import annotations` where PEP 604 unions are used.
  This has to come first: pyproject declares requires-python >= 3.9, where
  `X | None` is not evaluable at runtime unless annotations are stringified.
- Replace typing.List/Dict/Tuple/Set with the builtin generics and
  Optional[X] with X | None, then drop the imports that became unused.
  The four actions/*/__init__.py files needed this by hand because ruff
  leaves unused imports in __init__.py alone (possible re-exports).
- Strip shebangs from 72 importable modules. None of them are executable
  or invoked directly; the entry points are console_scripts and runpy.
- Flatten nested `with` blocks, collapse needless-bool returns, and apply
  the remaining mechanical ruff fixes (PIE810, FLY002, PERF102, FURB192,
  RUF059, I001).
- Pass check=False explicitly to the four subprocess.run() calls that
  inspect returncode themselves. That is the existing default.

Two rewrites are visible to mocks, so their tests move with them:
subprocess.run(stdout=PIPE, stderr=PIPE) became capture_output=True, and
open(path, "r", ...) lost the redundant mode.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 16:47:13 +02:00

89 lines
2.9 KiB
Python

from __future__ import annotations
import unittest
from types import SimpleNamespace
from typing import Any
from unittest.mock import call, patch
from pkgmgr.cli.commands.tools import handle_tools_command
Repository = dict[str, Any]
class _Args:
"""
Simple helper object to mimic argparse.Namespace for handle_tools_command.
"""
def __init__(self, command: str) -> None:
self.command = command
class TestHandleToolsCommand(unittest.TestCase):
"""
Unit tests for pkgmgr.cli.commands.tools.handle_tools_command.
We focus on:
- Correct path resolution and shell commands for 'explore' and 'terminal'.
- For 'code': delegation to pkgmgr.cli.tools.open_vscode_workspace.
"""
def setUp(self) -> None:
self.repos: list[Repository] = [
{"alias": "repo1", "directory": "/tmp/repo1"},
{"alias": "repo2", "directory": "/tmp/repo2"},
]
self.ctx = SimpleNamespace(
config_merged={"directories": {"workspaces": "~/Workspaces"}},
all_repositories=self.repos,
repositories_base_dir="/base/dir",
)
def _patch_run_command(self):
return patch("pkgmgr.cli.commands.tools.run_command")
# ------------------------------------------------------------------ #
# Tests for 'explore'
# ------------------------------------------------------------------ #
def test_explore_uses_directory_paths(self) -> None:
args = _Args(command="explore")
with self._patch_run_command() as mock_run_command:
handle_tools_command(args, self.ctx, self.repos)
expected_calls = [
call('nautilus "/tmp/repo1" & disown'),
call('nautilus "/tmp/repo2" & disown'),
]
self.assertEqual(mock_run_command.call_args_list, expected_calls)
# ------------------------------------------------------------------ #
# Tests for 'terminal'
# ------------------------------------------------------------------ #
def test_terminal_uses_directory_paths(self) -> None:
args = _Args(command="terminal")
with self._patch_run_command() as mock_run_command:
handle_tools_command(args, self.ctx, self.repos)
expected_calls = [
call('gnome-terminal --tab --working-directory="/tmp/repo1"'),
call('gnome-terminal --tab --working-directory="/tmp/repo2"'),
]
self.assertEqual(mock_run_command.call_args_list, expected_calls)
# ------------------------------------------------------------------ #
# Tests for 'code'
# ------------------------------------------------------------------ #
def test_code_delegates_to_open_vscode_workspace(self) -> None:
args = _Args(command="code")
with patch("pkgmgr.cli.commands.tools.open_vscode_workspace") as m:
handle_tools_command(args, self.ctx, self.repos)
m.assert_called_once_with(self.ctx, self.repos)