refactor: remove verified dead code

This commit is contained in:
chengyongru
2026-08-08 21:10:34 +08:00
committed by chengyongru
parent 4e063f5695
commit 113e8d67ad
40 changed files with 76 additions and 716 deletions
-13
View File
@@ -169,19 +169,6 @@ class TestDiffCommits:
assert git_ready.diff_commits("deadbeef", "cafebabe") == ""
class TestFindCommit:
def test_finds_by_prefix(self, git_ready):
ws = git_ready._workspace
(ws / "SOUL.md").write_text("v2", encoding="utf-8")
sha = git_ready.auto_commit("v2")
found = git_ready.find_commit(sha[:4])
assert found is not None
assert found.sha == sha
def test_returns_none_for_unknown(self, git_ready):
assert git_ready.find_commit("deadbeef") is None
class TestShowCommitDiff:
def test_returns_commit_with_diff(self, git_ready):
ws = git_ready._workspace
+11 -2
View File
@@ -9,6 +9,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from agent.runner_helpers import make_run_spec
from nanobot.agent.automation_turns import publish_next_deferred_turn
from nanobot.config.schema import AgentDefaults
from nanobot.providers.base import LLMResponse, ToolCallRequest
@@ -1047,7 +1048,11 @@ async def test_cron_turn_deferred_while_session_active(tmp_path):
assert loop._cron_turns.deferred_queues[session_key] == [msg]
assert loop.pending_cron_job_ids_for_session(session_key) == {"job-1"}
await loop._cron_turns.publish_next_deferred(session_key)
await publish_next_deferred_turn(
deferred_queues=loop._cron_turns.deferred_queues,
publish_inbound=loop.bus.publish_inbound,
session_key=session_key,
)
queued = await asyncio.wait_for(loop.bus.consume_inbound(), timeout=0.5)
assert queued is msg
assert session_key not in loop._cron_turns.deferred_queues
@@ -1097,7 +1102,11 @@ async def test_local_trigger_turn_deferred_while_session_active(tmp_path):
assert loop._local_trigger_turns.deferred_queues[session_key] == [msg]
assert loop.pending_local_trigger_ids_for_session(session_key) == {"trg_123"}
assert await loop._local_trigger_turns.publish_next_deferred(session_key) is True
assert await publish_next_deferred_turn(
deferred_queues=loop._local_trigger_turns.deferred_queues,
publish_inbound=loop.bus.publish_inbound,
session_key=session_key,
) is True
queued = await asyncio.wait_for(loop.bus.consume_inbound(), timeout=0.5)
assert queued is msg
assert session_key not in loop._local_trigger_turns.deferred_queues
+13 -16
View File
@@ -1,9 +1,7 @@
"""Tests for CLI Apps loop helpers."""
from types import SimpleNamespace
from nanobot.apps.cli.service import CliAppManager
from nanobot.apps.cli.utils import runtime_lines, session_extra
from nanobot.apps.cli.utils import runtime_lines_for_request, session_extra
def test_session_extra_returns_cli_apps_only_when_present() -> None:
@@ -30,8 +28,9 @@ def test_cli_app_mentions_inject_runtime_metadata(tmp_path, monkeypatch):
}
)
lines = runtime_lines(
SimpleNamespace(content="please use @zoom tonight; ignore @krita?", metadata={}),
lines = runtime_lines_for_request(
"please use @zoom tonight; ignore @krita?",
{},
tmp_path,
)
@@ -43,17 +42,15 @@ def test_cli_app_mentions_inject_runtime_metadata(tmp_path, monkeypatch):
def test_structured_cli_app_attachment_injects_runtime_metadata(tmp_path):
lines = runtime_lines(
SimpleNamespace(
content="please use @zoom tonight",
metadata={
"cli_apps": [{
"name": "zoom",
"entry_point": "cli-anything-zoom",
"display_name": "Zoom",
}],
},
),
lines = runtime_lines_for_request(
"please use @zoom tonight",
{
"cli_apps": [{
"name": "zoom",
"entry_point": "cli-anything-zoom",
"display_name": "Zoom",
}],
},
tmp_path,
)
-26
View File
@@ -6,7 +6,6 @@ from zipfile import ZipFile
import pytest
from nanobot.utils.document import (
SUPPORTED_EXTENSIONS,
PdfSafetyError,
_is_text_extension,
extract_pdf_pages,
@@ -14,31 +13,6 @@ from nanobot.utils.document import (
)
class TestSupportedExtensions:
"""Test the SUPPORTED_EXTENSIONS constant."""
def test_supported_extensions_include_common_formats(self):
"""Test that common document formats are included."""
# Document formats
assert ".pdf" in SUPPORTED_EXTENSIONS
assert ".docx" in SUPPORTED_EXTENSIONS
assert ".xlsx" in SUPPORTED_EXTENSIONS
assert ".pptx" in SUPPORTED_EXTENSIONS
# Text formats
assert ".txt" in SUPPORTED_EXTENSIONS
assert ".md" in SUPPORTED_EXTENSIONS
assert ".csv" in SUPPORTED_EXTENSIONS
assert ".json" in SUPPORTED_EXTENSIONS
assert ".yaml" in SUPPORTED_EXTENSIONS
assert ".yml" in SUPPORTED_EXTENSIONS
# Image formats
assert ".png" in SUPPORTED_EXTENSIONS
assert ".jpg" in SUPPORTED_EXTENSIONS
assert ".jpeg" in SUPPORTED_EXTENSIONS
class TestExtractText:
"""Test the extract_text function."""
+1 -36
View File
@@ -13,7 +13,7 @@ import os
import pytest
from nanobot.agent.tools import file_state
from nanobot.agent.tools.filesystem import EditFileTool, ReadFileTool, _find_match
from nanobot.agent.tools.filesystem import EditFileTool, ReadFileTool
@pytest.fixture(autouse=True)
@@ -68,41 +68,6 @@ class TestDeleteLineCleanup:
# ---------------------------------------------------------------------------
class TestSmartQuoteNormalization:
"""_find_match should handle curly ↔ straight quote fallback."""
def test_curly_double_quotes_match_straight(self):
content = 'She said \u201chello\u201d to him'
old_text = 'She said "hello" to him'
match, count = _find_match(content, old_text)
assert match is not None
assert count == 1
# Returned match should be the ORIGINAL content with curly quotes
assert "\u201c" in match
def test_curly_single_quotes_match_straight(self):
content = "it\u2019s a test"
old_text = "it's a test"
match, count = _find_match(content, old_text)
assert match is not None
assert count == 1
assert "\u2019" in match
def test_straight_matches_curly_in_old_text(self):
content = 'x = "hello"'
old_text = 'x = \u201chello\u201d'
match, count = _find_match(content, old_text)
assert match is not None
assert count == 1
def test_exact_match_still_preferred_over_quote_normalization(self):
content = 'x = "hello"'
old_text = 'x = "hello"'
match, count = _find_match(content, old_text)
assert match == old_text
assert count == 1
class TestQuoteStylePreservation:
"""When quote-normalized matching occurs, replacement should preserve actual quote style."""
-47
View File
@@ -7,7 +7,6 @@ from nanobot.agent.tools.filesystem import (
ListDirTool,
ReadFileTool,
WriteFileTool,
_find_match,
)
# ---------------------------------------------------------------------------
@@ -116,52 +115,6 @@ class TestReadFileTool:
assert "Maximum is 100 MiB" in result
# ---------------------------------------------------------------------------
# _find_match (unit tests for the helper)
# ---------------------------------------------------------------------------
class TestFindMatch:
def test_exact_match(self):
match, count = _find_match("hello world", "world")
assert match == "world"
assert count == 1
def test_exact_no_match(self):
match, count = _find_match("hello world", "xyz")
assert match is None
assert count == 0
def test_crlf_normalisation(self):
# Caller normalises CRLF before calling _find_match, so test with
# pre-normalised content to verify exact match still works.
content = "line1\nline2\nline3"
old_text = "line1\nline2\nline3"
match, count = _find_match(content, old_text)
assert match is not None
assert count == 1
def test_line_trim_fallback(self):
content = " def foo():\n pass\n"
old_text = "def foo():\n pass"
match, count = _find_match(content, old_text)
assert match is not None
assert count == 1
# The returned match should be the *original* indented text
assert " def foo():" in match
def test_line_trim_multiple_candidates(self):
content = " a\n b\n a\n b\n"
old_text = "a\nb"
match, count = _find_match(content, old_text)
assert count == 2
def test_empty_old_text(self):
match, count = _find_match("hello", "")
# Empty string is always "in" any string via exact match
assert match == ""
# ---------------------------------------------------------------------------
# EditFileTool
# ---------------------------------------------------------------------------
+11 -16
View File
@@ -9,7 +9,6 @@ from nanobot.utils.file_edit_events import (
build_file_edit_start_event,
build_unified_diff_payload,
line_diff_stats,
prepare_file_edit_tracker,
prepare_file_edit_trackers,
read_file_snapshot,
)
@@ -44,15 +43,14 @@ def test_write_file_start_tracks_snapshot_and_end_emits_exact_diff(tmp_path: Pat
target = tmp_path / "notes.txt"
target.write_text("old\nkeep\n", encoding="utf-8")
params = {"path": "notes.txt", "content": "new\nkeep\nextra\n"}
tracker = prepare_file_edit_tracker(
trackers = prepare_file_edit_trackers(
call_id="call-write",
tool_name="write_file",
tool=_write_tool(tmp_path),
workspace=tmp_path,
params=params,
)
assert tracker is not None
[tracker] = trackers
start = build_file_edit_start_event(tracker)
assert start == {
"version": 1,
@@ -103,15 +101,14 @@ def test_unified_diff_payload_truncates_large_diffs() -> None:
def test_binary_file_is_reported_but_not_counted(tmp_path: Path) -> None:
target = tmp_path / "data.bin"
target.write_bytes(b"\x00\x01before")
tracker = prepare_file_edit_tracker(
trackers = prepare_file_edit_trackers(
call_id="call-bin",
tool_name="edit_file",
tool=_edit_tool(tmp_path),
workspace=tmp_path,
params={"path": "data.bin", "old_text": "before", "new_text": "after"},
)
assert tracker is not None
[tracker] = trackers
assert not read_file_snapshot(target).countable
target.write_bytes(b"\x00\x01after")
event = build_file_edit_end_event(tracker)
@@ -123,15 +120,14 @@ def test_binary_file_is_reported_but_not_counted(tmp_path: Path) -> None:
def test_binary_before_file_is_reported_but_not_counted(tmp_path: Path) -> None:
target = tmp_path / "data.bin"
target.write_bytes(b"\x00\x01before")
tracker = prepare_file_edit_tracker(
trackers = prepare_file_edit_trackers(
call_id="call-bin",
tool_name="write_file",
tool=_write_tool(tmp_path),
workspace=tmp_path,
params={"path": "data.bin", "content": "after\n"},
)
assert tracker is not None
[tracker] = trackers
target.write_text("after\n", encoding="utf-8")
event = build_file_edit_end_event(tracker)
assert event["binary"] is True
@@ -215,15 +211,14 @@ def test_apply_patch_dry_run_does_not_prepare_file_edit_trackers(tmp_path: Path)
def test_oversized_file_is_reported_but_not_counted(tmp_path: Path) -> None:
target = tmp_path / "large.txt"
params = {"path": "large.txt", "content": "x"}
tracker = prepare_file_edit_tracker(
trackers = prepare_file_edit_trackers(
call_id="call-large",
tool_name="write_file",
tool=_write_tool(tmp_path),
workspace=tmp_path,
params=params,
)
assert tracker is not None
[tracker] = trackers
target.write_text("x" * (2 * 1024 * 1024 + 1), encoding="utf-8")
event = build_file_edit_end_event(tracker)
assert event["binary"] is True
@@ -232,11 +227,11 @@ def test_oversized_file_is_reported_but_not_counted(tmp_path: Path) -> None:
assert "diff" not in event
def test_untracked_tools_do_not_prepare_file_edit_tracker(tmp_path: Path) -> None:
assert prepare_file_edit_tracker(
def test_untracked_tools_do_not_prepare_file_edit_trackers(tmp_path: Path) -> None:
assert prepare_file_edit_trackers(
call_id="call-exec",
tool_name="exec",
tool=None,
workspace=tmp_path,
params={"path": "created-by-shell.txt"},
) is None
) == []
+2 -86
View File
@@ -1,13 +1,12 @@
"""Tests for GitStore — line_ages() and core git operations."""
"""Tests for GitStore core operations."""
import subprocess
from datetime import datetime, timedelta, timezone
from pathlib import Path
from unittest.mock import patch
import pytest
from nanobot.utils.gitstore import GitStore, GitStoreError
from nanobot.utils.gitstore import GitStore
@pytest.fixture
@@ -18,89 +17,6 @@ def git(tmp_path):
return g
class TestLineAges:
def test_returns_empty_when_not_initialized(self, tmp_path):
"""line_ages should return [] if the git repo is not initialized."""
git = GitStore(tmp_path, tracked_files=["MEMORY.md"])
assert git.line_ages("MEMORY.md") == []
def test_returns_empty_for_missing_file(self, git):
"""line_ages should return [] for a file that doesn't exist."""
assert git.line_ages("SOUL.md") == []
def test_returns_empty_for_empty_file(self, git, tmp_path):
"""line_ages should return [] for an empty tracked file."""
(tmp_path / "SOUL.md").write_text("", encoding="utf-8")
git.auto_commit("empty soul")
assert git.line_ages("SOUL.md") == []
def test_one_age_per_line(self, git, tmp_path):
"""line_ages should return one entry per line in the file."""
content = "# Memory\n\n## Section A\n- item 1\n"
(tmp_path / "MEMORY.md").write_text(content, encoding="utf-8")
git.auto_commit("initial")
ages = git.line_ages("MEMORY.md")
assert len(ages) == len(content.splitlines())
def test_fresh_lines_have_age_zero(self, git, tmp_path):
"""Lines committed today should have age_days=0."""
(tmp_path / "MEMORY.md").write_text("## A\n- x\n", encoding="utf-8")
git.auto_commit("initial")
ages = git.line_ages("MEMORY.md")
assert all(a.age_days == 0 for a in ages)
def test_age_differentiates_across_days(self, git, tmp_path):
"""Lines committed today should show correct age when 'now' is mocked forward."""
(tmp_path / "MEMORY.md").write_text("## A\n- x\n", encoding="utf-8")
git.auto_commit("initial")
future_now = datetime.now(tz=timezone.utc) + timedelta(days=30)
with patch("nanobot.utils.gitstore.datetime") as mock_dt:
mock_dt.now.return_value = future_now
mock_dt.fromtimestamp = datetime.fromtimestamp
ages = git.line_ages("MEMORY.md")
assert len(ages) == 2
assert all(a.age_days == 30 for a in ages)
def test_annotate_failure_is_explicit(self, git, tmp_path):
(tmp_path / "MEMORY.md").write_text("important\n", encoding="utf-8")
git.auto_commit("initial")
with patch("dulwich.porcelain.annotate", side_effect=OSError("broken repo")):
with pytest.raises(GitStoreError, match="annotation failed"):
git.line_ages("MEMORY.md")
def test_partial_edit_only_updates_changed_lines(self, git, tmp_path):
"""Only modified lines should reflect the new commit's timestamp."""
now = datetime(2026, 5, 1, tzinfo=timezone.utc)
old = now - timedelta(days=30)
(tmp_path / "MEMORY.md").write_text(
"# Memory\n\n## A\n- old\n\n## B\n- keep\n", encoding="utf-8"
)
with patch("dulwich.worktree.time.time", return_value=old.timestamp()):
git.auto_commit("commit1")
# Only modify section A
(tmp_path / "MEMORY.md").write_text(
"# Memory\n\n## A\n- new\n\n## B\n- keep\n", encoding="utf-8"
)
with patch("dulwich.worktree.time.time", return_value=now.timestamp()):
git.auto_commit("commit2")
with patch("nanobot.utils.gitstore.datetime") as mock_dt:
mock_dt.now.return_value = now
mock_dt.fromtimestamp = datetime.fromtimestamp
ages = git.line_ages("MEMORY.md")
lines = (tmp_path / "MEMORY.md").read_text(encoding="utf-8").splitlines()
assert len(ages) == len(lines)
age_by_line = {line: age.age_days for line, age in zip(lines, ages, strict=True)}
assert age_by_line["- new"] == 0
assert age_by_line["- keep"] == 30
class TestSummarizeWorkingTree:
"""Ground-truth diff summary used to keep Dream audit records honest."""
-8
View File
@@ -1,14 +1,11 @@
from pathlib import Path
from zoneinfo import ZoneInfoNotFoundError
import pytest
import tiktoken
from nanobot.utils import helpers
from nanobot.utils.helpers import (
_write_text_atomic,
content_with_media_breadcrumbs,
current_time_str,
split_message,
truncate_text_to_tokens,
)
@@ -51,11 +48,6 @@ def test_truncate_text_to_tokens_non_positive_budget_returns_text():
assert truncate_text_to_tokens(text, 0) == text
def test_current_time_str_rejects_unknown_timezone():
with pytest.raises(ZoneInfoNotFoundError):
current_time_str("Not/AZone")
def test_content_with_media_breadcrumbs_preserves_valid_paths():
assert content_with_media_breadcrumbs(
"user",