"""Tests for the async dolt subprocess wrapper's failure handling.

Uses the Python interpreter as a stand-in subprocess (cross-platform, no dolt
needed) to prove a non-zero exit and a hung command both raise DoltError — the
latter is what stops a hung pull from pinning the import connection + advisory
lock forever.
"""

from __future__ import annotations

import sys
import time
from pathlib import Path

import pytest

from app.services import dolt_client
from app.services.dolt_client import DoltError


async def test_run_raises_on_nonzero_exit():
    with pytest.raises(DoltError) as exc:
        await dolt_client._run(
            sys.executable, ["-c", "import sys; sys.exit(3)"], cwd=Path.cwd(), timeout=30
        )
    assert "3" in str(exc.value)


async def test_run_times_out_and_kills():
    start = time.monotonic()
    with pytest.raises(DoltError) as exc:
        await dolt_client._run(
            sys.executable,
            ["-c", "import time; time.sleep(30)"],
            cwd=Path.cwd(),
            timeout=0.5,
        )
    elapsed = time.monotonic() - start
    assert "timed out" in str(exc.value)
    assert elapsed < 10  # killed promptly, not waited out


async def test_run_returns_stdout_on_success():
    out = await dolt_client._run(
        sys.executable, ["-c", "print('hello')"], cwd=Path.cwd(), timeout=30
    )
    assert out.strip() == "hello"
