from __future__ import annotations from typing import Any from unittest.mock import patch import subprocess from ai_reviewer.diff import run_git_diff def _completed(cmd: list[str], returncode: int, stdout: str = "", stderr: str = "") -> subprocess.CompletedProcess[Any]: return subprocess.CompletedProcess(cmd, returncode, stdout, stderr) def test_run_git_diff_prefers_direct_refs(): calls: list[list[str]] = [] def fake_run(cmd, check=False, capture_output=False, text=False): # type: ignore[override] calls.append(cmd) if cmd[3] == "diff": if cmd[4] == "base...head": return _completed(cmd, 0, stdout="ok") return _completed(cmd, 128, stderr="fatal") raise AssertionError("fetch should not run when refs exist locally") with patch("ai_reviewer.diff.subprocess.run", side_effect=fake_run): output = run_git_diff(".", "base", "head") assert output == "ok" # Only one diff attempt should be needed when local refs exist. assert len(calls) == 1 def test_run_git_diff_falls_back_to_origin_refs_after_fetch(): fetched = False diff_attempts: list[str] = [] def fake_run(cmd, check=False, capture_output=False, text=False): # type: ignore[override] nonlocal fetched if cmd[3] == "diff": diff_attempts.append(cmd[4]) spec = cmd[4] if spec == "origin/base...origin/head" and fetched: return _completed(cmd, 0, stdout="remote-ok") return _completed(cmd, 128, stderr="missing ref") if cmd[3] == "fetch": fetched = True return _completed(cmd, 0) raise AssertionError("unexpected git invocation") with patch("ai_reviewer.diff.subprocess.run", side_effect=fake_run): output = run_git_diff(".", "base", "head") assert output == "remote-ok" assert "origin/base...origin/head" in diff_attempts # Ensure the fallback only succeeds after fetch. assert diff_attempts.index("origin/base...origin/head") > diff_attempts.index("base...head")