From 4a626ed1878dbd434c5a1f92f3e5598e1f90ef63 Mon Sep 17 00:00:00 2001 From: ethernet Date: Tue, 2 Jun 2026 18:18:38 -0400 Subject: [PATCH] fix(tests): add _patch_managed_uv autouse fixture to uv-dependent test files Production code now uses ensure_uv()/update_managed_uv() from managed_uv.py instead of shutil.which("uv") directly. Tests that patched shutil.which to control uv availability no longer controlled the actual code path, causing CI failures. Add an autouse _patch_managed_uv fixture to test_update_autostash.py and test_uv_tool_update.py (matching the existing fixture in test_cmd_update.py). The fixture makes managed_uv functions delegate to shutil.which so existing test patches flow through naturally. --- tests/hermes_cli/test_update_autostash.py | 36 +++++++++++++++++++++++ tests/hermes_cli/test_uv_tool_update.py | 36 +++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/tests/hermes_cli/test_update_autostash.py b/tests/hermes_cli/test_update_autostash.py index f7d90245a..5a255a052 100644 --- a/tests/hermes_cli/test_update_autostash.py +++ b/tests/hermes_cli/test_update_autostash.py @@ -1,6 +1,7 @@ from pathlib import Path from subprocess import CalledProcessError from types import SimpleNamespace +from unittest.mock import patch import pytest @@ -8,6 +9,41 @@ from hermes_cli import config as hermes_config from hermes_cli import main as hermes_main +# --------------------------------------------------------------------------- +# Managed-uv compatibility for tests that patch shutil.which +# --------------------------------------------------------------------------- +# The production code now uses ``ensure_uv()`` / ``update_managed_uv()`` +# instead of ``shutil.which("uv")``. Many tests in this file patch +# ``shutil.which`` to control whether uv is "available" — these autouse +# fixtures make the managed_uv functions delegate to the patched +# ``shutil.which`` so the existing test setup keeps working without +# per-test changes. +@pytest.fixture(autouse=True) +def _patch_managed_uv(request): + """Make managed_uv helpers follow shutil.which mocking in tests.""" + import shutil + + # resolve_uv delegates to shutil.which("uv") so that test patches + # on shutil.which flow through naturally. + def _fake_resolve_uv(): + return shutil.which("uv") + + def _fake_ensure_uv(): + path = shutil.which("uv") + return (path, False) # never freshly bootstrapped in tests + + def _fake_update_managed_uv(): + return None # never actually self-update in tests + + def _fake_rebuild_venv(*args, **kwargs): + return True # no-op in tests + + with patch("hermes_cli.managed_uv.resolve_uv", side_effect=_fake_resolve_uv), \ + patch("hermes_cli.managed_uv.ensure_uv", side_effect=_fake_ensure_uv), \ + patch("hermes_cli.managed_uv.update_managed_uv", side_effect=_fake_update_managed_uv), \ + patch("hermes_cli.managed_uv.rebuild_venv", side_effect=_fake_rebuild_venv): + yield + def test_stash_local_changes_if_needed_returns_none_when_tree_clean(monkeypatch, tmp_path): calls = [] diff --git a/tests/hermes_cli/test_uv_tool_update.py b/tests/hermes_cli/test_uv_tool_update.py index b5905c9b7..f1f2905ef 100644 --- a/tests/hermes_cli/test_uv_tool_update.py +++ b/tests/hermes_cli/test_uv_tool_update.py @@ -20,6 +20,42 @@ from unittest.mock import patch import pytest +# --------------------------------------------------------------------------- +# Managed-uv compatibility for tests that patch shutil.which +# --------------------------------------------------------------------------- +# The production code now uses ``ensure_uv()`` / ``update_managed_uv()`` +# instead of ``shutil.which("uv")``. Many tests in this file patch +# ``shutil.which`` to control whether uv is "available" — these autouse +# fixtures make the managed_uv functions delegate to the patched +# ``shutil.which`` so the existing test setup keeps working without +# per-test changes. +@pytest.fixture(autouse=True) +def _patch_managed_uv(request): + """Make managed_uv helpers follow shutil.which mocking in tests.""" + import shutil + + # resolve_uv delegates to shutil.which("uv") so that test patches + # on shutil.which flow through naturally. + def _fake_resolve_uv(): + return shutil.which("uv") + + def _fake_ensure_uv(): + path = shutil.which("uv") + return (path, False) # never freshly bootstrapped in tests + + def _fake_update_managed_uv(): + return None # never actually self-update in tests + + def _fake_rebuild_venv(*args, **kwargs): + return True # no-op in tests + + with patch("hermes_cli.managed_uv.resolve_uv", side_effect=_fake_resolve_uv), \ + patch("hermes_cli.managed_uv.ensure_uv", side_effect=_fake_ensure_uv), \ + patch("hermes_cli.managed_uv.update_managed_uv", side_effect=_fake_update_managed_uv), \ + patch("hermes_cli.managed_uv.rebuild_venv", side_effect=_fake_rebuild_venv): + yield + + # --------------------------------------------------------------------------- # is_uv_tool_install # ---------------------------------------------------------------------------