mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
[chore] remove all remaining type:ignore suppressions from tests/
Converts 115 `# type: ignore[...]` suppressions across 23 test files to no-suppression patterns (helper-return widening to Any, local Any aliases, cc:Any aliases, cast at narrow call sites, typed fixtures) so the hard no-type:ignore convention holds across tests/. No test logic or assertions changed — only mock-wiring mechanics and type annotations. Gate: ruff check tests/ clean; mypy tests/ (538 files) clean; 176 changed-file tests pass. Zero real suppressions remain (the 7 grep hits are 3 hygiene- checker string-literal test inputs and 4 prose mentions in comments).
This commit is contained in:
@@ -17,7 +17,7 @@ the session — while the happy path still adds + commits the savepoint.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
from typing import Any, cast
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
@@ -89,7 +89,7 @@ async def test_cache_put_tolerates_concurrent_duplicate_without_poisoning() -> N
|
||||
# a savepoint; _cache_put returns cleanly, the session is not poisoned, and
|
||||
# no full rollback undoes the outer task-create transaction.
|
||||
session = _FakeSession(duplicate=True)
|
||||
svc = ConventionsService(session=session) # type: ignore[arg-type]
|
||||
svc = ConventionsService(session=cast("Any", session))
|
||||
|
||||
await svc._cache_put(uuid4(), "deadbeef", _mapping(), "ok")
|
||||
|
||||
@@ -101,7 +101,7 @@ async def test_cache_put_tolerates_concurrent_duplicate_without_poisoning() -> N
|
||||
@pytest.mark.asyncio
|
||||
async def test_cache_put_happy_path_adds_and_releases_savepoint() -> None:
|
||||
session = _FakeSession(duplicate=False)
|
||||
svc = ConventionsService(session=session) # type: ignore[arg-type]
|
||||
svc = ConventionsService(session=cast("Any", session))
|
||||
|
||||
await svc._cache_put(uuid4(), "deadbeef", _mapping(), "ok")
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from types import SimpleNamespace
|
||||
from typing import TYPE_CHECKING, cast
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
from roboco.services.conventions import ConventionsService
|
||||
|
||||
@@ -33,7 +33,7 @@ def _git_repo(root: Path) -> str:
|
||||
|
||||
|
||||
def _svc() -> ConventionsService:
|
||||
return ConventionsService(session=None) # type: ignore[arg-type]
|
||||
return ConventionsService(session=cast("Any", None))
|
||||
|
||||
|
||||
def test_resolve_reads_clone_head_and_backfills(tmp_path: Path) -> None:
|
||||
|
||||
@@ -18,7 +18,7 @@ import pytest
|
||||
from roboco.services.git import GitService
|
||||
|
||||
|
||||
def _git_service() -> GitService:
|
||||
def _git_service() -> Any:
|
||||
return GitService.__new__(GitService)
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ def _git_service() -> GitService:
|
||||
async def test_resolve_diff_base_uses_parent_when_pushed() -> None:
|
||||
"""When origin/<parent> exists, use it (normal case)."""
|
||||
svc = _git_service()
|
||||
svc._run_git = AsyncMock() # type: ignore[method-assign]
|
||||
svc._ref_exists = AsyncMock(return_value=True) # type: ignore[method-assign]
|
||||
svc._run_git = AsyncMock()
|
||||
svc._ref_exists = AsyncMock(return_value=True)
|
||||
ws = Path("/tmp/ws")
|
||||
|
||||
base = await svc._resolve_diff_base(
|
||||
@@ -42,12 +42,10 @@ async def test_resolve_diff_base_falls_back_when_parent_absent() -> None:
|
||||
"""When origin/<parent> does NOT exist (cell-PM branch never pushed),
|
||||
fall back to the repo default branch via origin/HEAD."""
|
||||
svc = _git_service()
|
||||
svc._run_git = AsyncMock() # type: ignore[method-assign]
|
||||
svc._run_git = AsyncMock()
|
||||
# parent ref absent → _ref_exists False for the parent check.
|
||||
svc._ref_exists = AsyncMock(return_value=False) # type: ignore[method-assign]
|
||||
svc._default_branch_ref = AsyncMock( # type: ignore[method-assign]
|
||||
return_value="origin/master"
|
||||
)
|
||||
svc._ref_exists = AsyncMock(return_value=False)
|
||||
svc._default_branch_ref = AsyncMock(return_value="origin/master")
|
||||
ws = Path("/tmp/ws")
|
||||
|
||||
base = await svc._resolve_diff_base(
|
||||
@@ -84,7 +82,7 @@ async def test_default_branch_ref_fallback_when_no_head() -> None:
|
||||
# symbolic-ref fails; fetches succeed but ref never verifies.
|
||||
return type("R", (), {"returncode": 1, "stdout": ""})()
|
||||
|
||||
svc._ref_exists = AsyncMock(return_value=False) # type: ignore[method-assign]
|
||||
svc._ref_exists = AsyncMock(return_value=False)
|
||||
with patch.object(svc, "_run_git", new=fake_run):
|
||||
ref = await svc._default_branch_ref(Path("/tmp/ws"))
|
||||
assert ref == "origin/master"
|
||||
@@ -107,8 +105,8 @@ _BR = "feature/backend/root1234--cellpm56--dev78901"
|
||||
async def test_resolve_head_ref_prefers_local_branch_in_dev_clone() -> None:
|
||||
"""Dev's own clone has the local branch — use it unchanged."""
|
||||
svc = _git_service()
|
||||
svc._run_git = AsyncMock() # type: ignore[method-assign]
|
||||
svc._ref_exists = AsyncMock(return_value=True) # type: ignore[method-assign]
|
||||
svc._run_git = AsyncMock()
|
||||
svc._ref_exists = AsyncMock(return_value=True)
|
||||
|
||||
head = await svc._resolve_head_ref(Path("/tmp/ws"), _BR)
|
||||
assert head == _BR
|
||||
@@ -119,7 +117,7 @@ async def test_resolve_head_ref_falls_back_to_origin_in_foreign_clone() -> None:
|
||||
"""QA/doc/PM clone has no local branch but origin/<branch> exists
|
||||
(open_pr pushed it) — diff must target origin/<branch>."""
|
||||
svc = _git_service()
|
||||
svc._run_git = AsyncMock() # type: ignore[method-assign]
|
||||
svc._run_git = AsyncMock()
|
||||
|
||||
async def ref_exists(_ws: Any, ref: str) -> bool:
|
||||
# local branch absent; only the remote-tracking ref resolves.
|
||||
@@ -141,7 +139,7 @@ async def test_resolve_head_ref_fetches_branch_before_resolving() -> None:
|
||||
calls.append(args)
|
||||
return type("R", (), {"returncode": 0, "stdout": ""})()
|
||||
|
||||
svc._ref_exists = AsyncMock(return_value=True) # type: ignore[method-assign]
|
||||
svc._ref_exists = AsyncMock(return_value=True)
|
||||
with patch.object(svc, "_run_git", new=fake_run):
|
||||
await svc._resolve_head_ref(Path("/tmp/ws"), _BR)
|
||||
assert ["fetch", "origin", _BR] in calls
|
||||
@@ -153,18 +151,10 @@ async def test_diff_targets_origin_head_in_foreign_clone() -> None:
|
||||
base...origin/<branch>, not base...<bare-local-branch> (which is
|
||||
unresolvable there and silently produced an empty diff)."""
|
||||
svc = _git_service()
|
||||
svc._workspace_for_branch = AsyncMock( # type: ignore[method-assign]
|
||||
return_value=Path("/tmp/qa-ws")
|
||||
)
|
||||
svc._resolve_diff_base = AsyncMock( # type: ignore[method-assign]
|
||||
return_value="origin/master"
|
||||
)
|
||||
svc._resolve_head_ref = AsyncMock( # type: ignore[method-assign]
|
||||
return_value=f"origin/{_BR}"
|
||||
)
|
||||
svc._token_for_branch = AsyncMock( # type: ignore[method-assign]
|
||||
return_value="tok"
|
||||
)
|
||||
svc._workspace_for_branch = AsyncMock(return_value=Path("/tmp/qa-ws"))
|
||||
svc._resolve_diff_base = AsyncMock(return_value="origin/master")
|
||||
svc._resolve_head_ref = AsyncMock(return_value=f"origin/{_BR}")
|
||||
svc._token_for_branch = AsyncMock(return_value="tok")
|
||||
captured: list[list[str]] = []
|
||||
|
||||
async def fake_run(_ws: Any, args: list[str], **_kw: Any) -> Any:
|
||||
@@ -187,18 +177,10 @@ async def test_diff_targets_origin_head_in_foreign_clone() -> None:
|
||||
async def test_list_changed_files_targets_origin_head_in_foreign_clone() -> None:
|
||||
"""Same fix on the files_changed path (#154 evidence)."""
|
||||
svc = _git_service()
|
||||
svc._workspace_for_branch = AsyncMock( # type: ignore[method-assign]
|
||||
return_value=Path("/tmp/qa-ws")
|
||||
)
|
||||
svc._resolve_diff_base = AsyncMock( # type: ignore[method-assign]
|
||||
return_value="origin/master"
|
||||
)
|
||||
svc._resolve_head_ref = AsyncMock( # type: ignore[method-assign]
|
||||
return_value=f"origin/{_BR}"
|
||||
)
|
||||
svc._token_for_branch = AsyncMock( # type: ignore[method-assign]
|
||||
return_value="tok"
|
||||
)
|
||||
svc._workspace_for_branch = AsyncMock(return_value=Path("/tmp/qa-ws"))
|
||||
svc._resolve_diff_base = AsyncMock(return_value="origin/master")
|
||||
svc._resolve_head_ref = AsyncMock(return_value=f"origin/{_BR}")
|
||||
svc._token_for_branch = AsyncMock(return_value="tok")
|
||||
captured: list[list[str]] = []
|
||||
|
||||
async def fake_run(_ws: Any, args: list[str], **_kw: Any) -> Any:
|
||||
@@ -219,18 +201,10 @@ async def test_diff_honours_explicit_base_with_resolved_head() -> None:
|
||||
"""The incremental dev path (base=HEAD~1) still works: explicit base
|
||||
is preserved, head still goes through _resolve_head_ref."""
|
||||
svc = _git_service()
|
||||
svc._workspace_for_branch = AsyncMock( # type: ignore[method-assign]
|
||||
return_value=Path("/tmp/dev-ws")
|
||||
)
|
||||
svc._resolve_diff_base = AsyncMock( # type: ignore[method-assign]
|
||||
return_value="SHOULD_NOT_BE_USED"
|
||||
)
|
||||
svc._resolve_head_ref = AsyncMock( # type: ignore[method-assign]
|
||||
return_value=_BR
|
||||
)
|
||||
svc._token_for_branch = AsyncMock( # type: ignore[method-assign]
|
||||
return_value=None
|
||||
)
|
||||
svc._workspace_for_branch = AsyncMock(return_value=Path("/tmp/dev-ws"))
|
||||
svc._resolve_diff_base = AsyncMock(return_value="SHOULD_NOT_BE_USED")
|
||||
svc._resolve_head_ref = AsyncMock(return_value=_BR)
|
||||
svc._token_for_branch = AsyncMock(return_value=None)
|
||||
captured: list[list[str]] = []
|
||||
|
||||
async def fake_run(_ws: Any, args: list[str], **_kw: Any) -> Any:
|
||||
@@ -266,10 +240,8 @@ async def test_resolve_diff_base_refetches_default_branch_with_token() -> None:
|
||||
return type("R", (), {"returncode": 0, "stdout": ""})()
|
||||
|
||||
# parent ref never exists → fall back to default branch.
|
||||
svc._ref_exists = AsyncMock(return_value=False) # type: ignore[method-assign]
|
||||
svc._default_branch_ref = AsyncMock( # type: ignore[method-assign]
|
||||
return_value="origin/master"
|
||||
)
|
||||
svc._ref_exists = AsyncMock(return_value=False)
|
||||
svc._default_branch_ref = AsyncMock(return_value="origin/master")
|
||||
|
||||
with patch.object(svc, "_run_git", new=fake_run):
|
||||
base = await svc._resolve_diff_base(Path("/tmp/ws"), _BR, token="tok")
|
||||
@@ -291,7 +263,7 @@ async def test_resolve_head_ref_fetch_is_authenticated() -> None:
|
||||
seen.append((args, kw.get("token")))
|
||||
return type("R", (), {"returncode": 0, "stdout": ""})()
|
||||
|
||||
svc._ref_exists = AsyncMock(return_value=True) # type: ignore[method-assign]
|
||||
svc._ref_exists = AsyncMock(return_value=True)
|
||||
with patch.object(svc, "_run_git", new=fake_run):
|
||||
await svc._resolve_head_ref(Path("/tmp/ws"), _BR, token="tok")
|
||||
assert (["fetch", "origin", _BR], "tok") in seen
|
||||
@@ -302,5 +274,5 @@ async def test_token_for_branch_is_best_effort_none() -> None:
|
||||
"""Unresolvable branch/project must yield None (degrade to unauth),
|
||||
never raise inside the evidence-assembly path."""
|
||||
svc = _git_service()
|
||||
svc._task_for_branch = AsyncMock(return_value=None) # type: ignore[method-assign]
|
||||
svc._task_for_branch = AsyncMock(return_value=None)
|
||||
assert await svc._token_for_branch(_BR) is None
|
||||
|
||||
@@ -23,8 +23,8 @@ _BASE = "feature/backend/parent12345"
|
||||
_HEAD = "feature/backend/abc12345"
|
||||
|
||||
|
||||
def _git_service() -> GitService:
|
||||
svc = GitService.__new__(GitService)
|
||||
def _git_service() -> Any:
|
||||
svc: Any = GitService.__new__(GitService)
|
||||
svc.log = MagicMock()
|
||||
return svc
|
||||
|
||||
@@ -45,14 +45,14 @@ def _project() -> Any:
|
||||
return MagicMock(slug="roboco")
|
||||
|
||||
|
||||
async def _wire(svc: GitService, *, rev_list_stdout: str) -> AsyncMock:
|
||||
async def _wire(svc: Any, *, rev_list_stdout: str) -> AsyncMock:
|
||||
"""Stub the workspace/token resolution + _run_git; return the run mock."""
|
||||
svc._project_for_task = AsyncMock(return_value=_project()) # type: ignore[method-assign]
|
||||
svc._resolve_workspace_agent_id = MagicMock(return_value=uuid4()) # type: ignore[method-assign]
|
||||
svc.get_workspace = AsyncMock(return_value=_WORKSPACE) # type: ignore[method-assign]
|
||||
svc._get_project_token_or_raise = AsyncMock(return_value=_TOKEN) # type: ignore[method-assign]
|
||||
svc._project_for_task = AsyncMock(return_value=_project())
|
||||
svc._resolve_workspace_agent_id = MagicMock(return_value=uuid4())
|
||||
svc.get_workspace = AsyncMock(return_value=_WORKSPACE)
|
||||
svc._get_project_token_or_raise = AsyncMock(return_value=_TOKEN)
|
||||
run = AsyncMock(side_effect=[_result(), _result(stdout=rev_list_stdout)])
|
||||
svc._run_git = run # type: ignore[method-assign]
|
||||
svc._run_git = run
|
||||
return run
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ async def test_is_behind_base_requires_branch_name() -> None:
|
||||
@pytest.mark.asyncio
|
||||
async def test_is_behind_base_raises_when_project_missing() -> None:
|
||||
svc = _git_service()
|
||||
svc._project_for_task = AsyncMock(return_value=None) # type: ignore[method-assign]
|
||||
svc._project_for_task = AsyncMock(return_value=None)
|
||||
|
||||
with pytest.raises(NotFoundError):
|
||||
await svc.is_behind_base(_task(), base_branch=_BASE)
|
||||
|
||||
@@ -26,10 +26,10 @@ def _link(session_id: object, relationship_type: str) -> MagicMock:
|
||||
@pytest.mark.asyncio
|
||||
async def test_propagate_links_every_parent_session_to_subtask() -> None:
|
||||
"""Every link on the parent gets re-attached to the new subtask."""
|
||||
svc = MessagingService.__new__(MessagingService)
|
||||
svc: Any = MessagingService.__new__(MessagingService)
|
||||
parent_session = uuid4()
|
||||
review_session = uuid4()
|
||||
svc.get_sessions_for_task = AsyncMock( # type: ignore[method-assign]
|
||||
svc.get_sessions_for_task = AsyncMock(
|
||||
return_value=[
|
||||
_link(parent_session, "discussion"),
|
||||
_link(review_session, "review"),
|
||||
@@ -67,9 +67,9 @@ async def test_propagate_links_every_parent_session_to_subtask() -> None:
|
||||
@pytest.mark.asyncio
|
||||
async def test_propagate_no_parent_sessions_returns_empty() -> None:
|
||||
"""When the parent has no session links, propagation is a no-op."""
|
||||
svc = MessagingService.__new__(MessagingService)
|
||||
svc.get_sessions_for_task = AsyncMock(return_value=[]) # type: ignore[method-assign]
|
||||
svc.link_session_to_task = AsyncMock() # type: ignore[method-assign]
|
||||
svc: Any = MessagingService.__new__(MessagingService)
|
||||
svc.get_sessions_for_task = AsyncMock(return_value=[])
|
||||
svc.link_session_to_task = AsyncMock()
|
||||
|
||||
out = await svc.propagate_sessions_to_subtask(uuid4(), uuid4(), uuid4())
|
||||
assert out == []
|
||||
@@ -80,8 +80,8 @@ async def test_propagate_no_parent_sessions_returns_empty() -> None:
|
||||
async def test_propagate_unknown_relationship_type_defaults_to_discussion() -> None:
|
||||
"""Garbage relationship_type on the parent link doesn't crash; it
|
||||
defaults to DISCUSSION so the subtask is still linked."""
|
||||
svc = MessagingService.__new__(MessagingService)
|
||||
svc.get_sessions_for_task = AsyncMock( # type: ignore[method-assign]
|
||||
svc: Any = MessagingService.__new__(MessagingService)
|
||||
svc.get_sessions_for_task = AsyncMock(
|
||||
return_value=[_link(uuid4(), "definitely-not-a-real-type")]
|
||||
)
|
||||
calls: list[dict[str, Any]] = []
|
||||
|
||||
@@ -22,9 +22,9 @@ _PCT_NONE = 0
|
||||
_PCT_FALLBACK = 42
|
||||
|
||||
|
||||
def _svc_with_task(task: Any) -> TaskService:
|
||||
svc = TaskService.__new__(TaskService)
|
||||
svc.get = AsyncMock(return_value=task) # type: ignore[method-assign]
|
||||
def _svc_with_task(task: Any) -> Any:
|
||||
svc: Any = TaskService.__new__(TaskService)
|
||||
svc.get = AsyncMock(return_value=task)
|
||||
svc.session = MagicMock()
|
||||
svc.session.flush = AsyncMock()
|
||||
return svc
|
||||
@@ -119,6 +119,6 @@ async def test_no_checklist_falls_back_to_supplied_percentage() -> None:
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_missing_task_returns_none() -> None:
|
||||
svc = TaskService.__new__(TaskService)
|
||||
svc.get = AsyncMock(return_value=None) # type: ignore[method-assign]
|
||||
svc: Any = TaskService.__new__(TaskService)
|
||||
svc.get = AsyncMock(return_value=None)
|
||||
assert await svc.record_plan_progress(uuid4(), uuid4(), "x") is None
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, cast
|
||||
|
||||
import pytest
|
||||
from roboco.services.base import (
|
||||
BaseService,
|
||||
@@ -120,7 +122,7 @@ def test_base_service_binds_session_and_logger() -> None:
|
||||
service_name = "x"
|
||||
|
||||
fake_session = object()
|
||||
svc = _Svc(fake_session) # type: ignore[arg-type]
|
||||
svc = _Svc(cast("Any", fake_session))
|
||||
assert svc.session is fake_session
|
||||
assert svc.log is not None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user