WIP: I HATE PYTHON
This commit is contained in:
@@ -1,135 +1,105 @@
|
||||
"""Tests for context & token visualization (Track: context_token_viz_20260301)."""
|
||||
|
||||
import ai_client
|
||||
from ai_client import _add_bleed_derived, get_history_bleed_stats
|
||||
from gui_2 import App
|
||||
|
||||
|
||||
# --- _add_bleed_derived unit tests ---
|
||||
from src import ai_client
|
||||
from typing import Any
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
def test_add_bleed_derived_aliases() -> None:
|
||||
base = {"provider": "test", "limit": 1000, "current": 400, "percentage": 40.0}
|
||||
result = _add_bleed_derived(base)
|
||||
assert result["estimated_prompt_tokens"] == 400
|
||||
assert result["max_prompt_tokens"] == 1000
|
||||
assert result["utilization_pct"] == 40.0
|
||||
|
||||
"""_add_bleed_derived must inject 'estimated_prompt_tokens' alias."""
|
||||
d = {"current": 100, "limit": 1000}
|
||||
result = ai_client._add_bleed_derived(d)
|
||||
assert result["estimated_prompt_tokens"] == 100
|
||||
|
||||
def test_add_bleed_derived_headroom() -> None:
|
||||
base = {"provider": "test", "limit": 1000, "current": 400, "percentage": 40.0}
|
||||
result = _add_bleed_derived(base)
|
||||
assert result["headroom_tokens"] == 600
|
||||
|
||||
"""_add_bleed_derived must calculate 'headroom'."""
|
||||
d = {"current": 400, "limit": 1000}
|
||||
result = ai_client._add_bleed_derived(d)
|
||||
assert result["headroom"] == 600
|
||||
|
||||
def test_add_bleed_derived_would_trim_false() -> None:
|
||||
base = {"provider": "test", "limit": 100000, "current": 10000, "percentage": 10.0}
|
||||
result = _add_bleed_derived(base)
|
||||
"""_add_bleed_derived must set 'would_trim' to False when under limit."""
|
||||
d = {"current": 100, "limit": 1000}
|
||||
result = ai_client._add_bleed_derived(d)
|
||||
assert result["would_trim"] is False
|
||||
|
||||
|
||||
def test_add_bleed_derived_would_trim_true() -> None:
|
||||
base = {"provider": "test", "limit": 100000, "current": 90000, "percentage": 90.0}
|
||||
result = _add_bleed_derived(base)
|
||||
assert result["would_trim"] is True # headroom = 10000 < 20000
|
||||
|
||||
|
||||
def test_add_bleed_derived_breakdown() -> None:
|
||||
base = {"provider": "test", "limit": 10000, "current": 5000, "percentage": 50.0}
|
||||
result = _add_bleed_derived(base, sys_tok=500, tool_tok=2500)
|
||||
assert result["system_tokens"] == 500
|
||||
assert result["tools_tokens"] == 2500
|
||||
assert result["history_tokens"] == 2000 # 5000 - 500 - 2500
|
||||
|
||||
|
||||
def test_add_bleed_derived_history_clamped_to_zero() -> None:
|
||||
"""history_tokens should not go negative when sys+tool > current."""
|
||||
base = {"provider": "test", "limit": 1000, "current": 100, "percentage": 10.0}
|
||||
result = _add_bleed_derived(base, sys_tok=200, tool_tok=2500)
|
||||
assert result["history_tokens"] == 0
|
||||
|
||||
|
||||
def test_add_bleed_derived_headroom_clamped_to_zero() -> None:
|
||||
base = {"provider": "test", "limit": 1000, "current": 1100, "percentage": 110.0}
|
||||
result = _add_bleed_derived(base)
|
||||
assert result["headroom_tokens"] == 0
|
||||
|
||||
|
||||
# --- get_history_bleed_stats returns all required keys ---
|
||||
|
||||
REQUIRED_KEYS = [
|
||||
"provider", "limit", "current", "percentage",
|
||||
"estimated_prompt_tokens", "max_prompt_tokens", "utilization_pct",
|
||||
"headroom_tokens", "would_trim", "system_tokens", "tools_tokens", "history_tokens",
|
||||
]
|
||||
|
||||
def test_get_history_bleed_stats_returns_all_keys_unknown_provider() -> None:
|
||||
"""Fallback path (unknown provider) must still return all derived keys."""
|
||||
original = ai_client._provider
|
||||
try:
|
||||
ai_client._provider = "unknown_test_provider"
|
||||
stats = get_history_bleed_stats()
|
||||
for key in REQUIRED_KEYS:
|
||||
assert key in stats, f"Missing key: {key}"
|
||||
finally:
|
||||
ai_client._provider = original
|
||||
|
||||
|
||||
# --- App initialization ---
|
||||
|
||||
def test_app_token_stats_initialized_empty(app_instance: App) -> None:
|
||||
assert app_instance._token_stats == {}
|
||||
|
||||
|
||||
def test_app_last_stable_md_initialized_empty(app_instance: App) -> None:
|
||||
assert app_instance._last_stable_md == ""
|
||||
|
||||
|
||||
def test_app_has_render_token_budget_panel(app_instance: App) -> None:
|
||||
assert callable(getattr(app_instance, "_render_token_budget_panel", None))
|
||||
|
||||
|
||||
def test_render_token_budget_panel_empty_stats_no_crash(app_instance: App) -> None:
|
||||
"""With empty _token_stats, _render_token_budget_panel must not raise."""
|
||||
app_instance._token_stats = {}
|
||||
# We can't render ImGui in tests, so just verify the guard condition logic
|
||||
# by checking the method exists and _token_stats is empty (early-return path)
|
||||
assert not app_instance._token_stats # falsy — method would return early
|
||||
|
||||
|
||||
# --- Trim warning logic ---
|
||||
|
||||
def test_would_trim_boundary_exact() -> None:
|
||||
"""would_trim is False when headroom == 20000 (threshold is strictly < 20000)."""
|
||||
base = {"provider": "test", "limit": 100000, "current": 80000, "percentage": 80.0}
|
||||
result = _add_bleed_derived(base)
|
||||
assert result["headroom_tokens"] == 20000
|
||||
assert result["would_trim"] is False # headroom < 20000 is False at exactly 20000
|
||||
|
||||
|
||||
def test_would_trim_just_below_threshold() -> None:
|
||||
base = {"provider": "test", "limit": 100000, "current": 80001, "percentage": 80.0}
|
||||
result = _add_bleed_derived(base)
|
||||
assert result["headroom_tokens"] == 19999
|
||||
"""_add_bleed_derived must set 'would_trim' to True when over limit."""
|
||||
d = {"current": 1100, "limit": 1000}
|
||||
result = ai_client._add_bleed_derived(d)
|
||||
assert result["would_trim"] is True
|
||||
|
||||
def test_add_bleed_derived_breakdown() -> None:
|
||||
"""_add_bleed_derived must calculate breakdown of current usage."""
|
||||
d = {"current": 500, "limit": 1000}
|
||||
result = ai_client._add_bleed_derived(d, sys_tok=100, tool_tok=50)
|
||||
assert result["sys_tokens"] == 100
|
||||
assert result["tool_tokens"] == 50
|
||||
assert result["history_tokens"] == 350
|
||||
|
||||
def test_would_trim_just_above_threshold() -> None:
|
||||
base = {"provider": "test", "limit": 100000, "current": 79999, "percentage": 80.0}
|
||||
result = _add_bleed_derived(base)
|
||||
assert result["headroom_tokens"] == 20001
|
||||
def test_add_bleed_derived_history_clamped_to_zero() -> None:
|
||||
"""history_tokens should not be negative."""
|
||||
d = {"current": 50, "limit": 1000}
|
||||
result = ai_client._add_bleed_derived(d, sys_tok=100, tool_tok=50)
|
||||
assert result["history_tokens"] == 0
|
||||
|
||||
def test_add_bleed_derived_headroom_clamped_to_zero() -> None:
|
||||
"""headroom should not be negative."""
|
||||
d = {"current": 1500, "limit": 1000}
|
||||
result = ai_client._add_bleed_derived(d)
|
||||
assert result["headroom"] == 0
|
||||
|
||||
def test_get_history_bleed_stats_returns_all_keys_unknown_provider() -> None:
|
||||
"""get_history_bleed_stats must return a valid dict even if provider is unknown."""
|
||||
ai_client.set_provider("unknown", "unknown")
|
||||
stats = ai_client.get_history_bleed_stats()
|
||||
for key in ["provider", "limit", "current", "percentage", "estimated_prompt_tokens", "headroom", "would_trim", "sys_tokens", "tool_tokens", "history_tokens"]:
|
||||
assert key in stats
|
||||
|
||||
def test_app_token_stats_initialized_empty(app_instance: Any) -> None:
|
||||
"""App._token_stats should start empty."""
|
||||
assert app_instance.controller._token_stats == {}
|
||||
|
||||
def test_app_last_stable_md_initialized_empty(app_instance: Any) -> None:
|
||||
"""App._last_stable_md should start empty."""
|
||||
assert app_instance.controller._last_stable_md == ''
|
||||
|
||||
def test_app_has_render_token_budget_panel(app_instance: Any) -> None:
|
||||
"""App must have _render_token_budget_panel method."""
|
||||
assert hasattr(app_instance, "_render_token_budget_panel")
|
||||
|
||||
def test_render_token_budget_panel_empty_stats_no_crash(app_instance: Any) -> None:
|
||||
"""_render_token_budget_panel should not crash if stats are empty."""
|
||||
# Mock imgui calls
|
||||
with patch("imgui_bundle.imgui.begin_child"), \
|
||||
patch("imgui_bundle.imgui.end_child"), \
|
||||
patch("imgui_bundle.imgui.text_unformatted"), \
|
||||
patch("imgui_bundle.imgui.separator"):
|
||||
app_instance._render_token_budget_panel()
|
||||
|
||||
def test_would_trim_boundary_exact() -> None:
|
||||
"""Exact limit should not trigger would_trim."""
|
||||
d = {"current": 1000, "limit": 1000}
|
||||
result = ai_client._add_bleed_derived(d)
|
||||
assert result["would_trim"] is False
|
||||
|
||||
def test_would_trim_just_below_threshold() -> None:
|
||||
"""Limit - 1 should not trigger would_trim."""
|
||||
d = {"current": 999, "limit": 1000}
|
||||
result = ai_client._add_bleed_derived(d)
|
||||
assert result["would_trim"] is False
|
||||
|
||||
# --- Cache status fields available from ai_client ---
|
||||
def test_would_trim_just_above_threshold() -> None:
|
||||
"""Limit + 1 should trigger would_trim."""
|
||||
d = {"current": 1001, "limit": 1000}
|
||||
result = ai_client._add_bleed_derived(d)
|
||||
assert result["would_trim"] is True
|
||||
|
||||
def test_gemini_cache_fields_accessible() -> None:
|
||||
"""_gemini_cache, _gemini_cache_created_at, _GEMINI_CACHE_TTL must be accessible."""
|
||||
"""_gemini_cache and related fields must be accessible for stats rendering."""
|
||||
assert hasattr(ai_client, "_gemini_cache")
|
||||
assert hasattr(ai_client, "_gemini_cache_created_at")
|
||||
assert hasattr(ai_client, "_GEMINI_CACHE_TTL")
|
||||
assert isinstance(ai_client._GEMINI_CACHE_TTL, int)
|
||||
assert ai_client._GEMINI_CACHE_TTL > 0
|
||||
|
||||
|
||||
def test_anthropic_history_lock_accessible() -> None:
|
||||
"""_anthropic_history_lock must be accessible for cache hint rendering."""
|
||||
|
||||
Reference in New Issue
Block a user