Files
ss-tools/backend/tests/plugins/translate/test_preview_token_estimator.py

136 lines
5.2 KiB
Python

# #region Test.PreviewTokenEstimator [C:2] [TYPE Module] [SEMANTICS test, translate, token, cost, estimation]
# @BRIEF Tests for preview_token_estimator.py — TokenEstimator static methods.
# @RELATION BINDS_TO -> [TokenEstimator]
# @TEST_CONTRACT: TokenEstimator.estimate_prompt_tokens -> int | token estimate from string
# @TEST_CONTRACT: TokenEstimator.estimate_output_tokens -> int | output token estimate
# @TEST_CONTRACT: TokenEstimator.estimate_cost -> float | cost estimate from tokens
# @TEST_CONTRACT: TokenEstimator.check_cost_warning -> str | None | cost threshold warning
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent / "src"))
import os
os.environ.setdefault("SECRET_KEY", "test-secret-key-for-testing")
os.environ.setdefault("DATABASE_URL", "sqlite:///:memory:")
os.environ.setdefault("AUTH_DATABASE_URL", "sqlite:///:memory:")
import pytest
from src.plugins.translate.preview_token_estimator import TokenEstimator
class TestEstimatePromptTokens:
"""TokenEstimator.estimate_prompt_tokens — estimate tokens from string."""
def test_empty_string_returns_zero(self):
"""Empty string returns 0."""
assert TokenEstimator.estimate_prompt_tokens("") == 0
def test_short_string_returns_at_least_one(self):
"""Short string returns at least 1."""
assert TokenEstimator.estimate_prompt_tokens("a") == 1
def test_long_string_estimates(self):
"""Longer string produces token estimate."""
text = "hello world " * 100 # ~1300 chars
tokens = TokenEstimator.estimate_prompt_tokens(text)
assert tokens > 0
assert tokens <= len(text) # tokens shouldn't exceed chars
def test_empty_string_handled(self):
"""Empty string returns 0. Whitespace is truthy so gets min 1."""
assert TokenEstimator.estimate_prompt_tokens("") == 0
assert TokenEstimator.estimate_prompt_tokens(" ") == 1
class TestEstimateOutputTokens:
"""TokenEstimator.estimate_output_tokens — estimate output tokens."""
def test_zero_rows_returns_zero(self):
"""0 rows returns 0."""
assert TokenEstimator.estimate_output_tokens(0) == 0
def test_single_row_single_language(self):
"""1 row, 1 language gives output estimate."""
result = TokenEstimator.estimate_output_tokens(1, 1)
expected = int(1 * 1 * 120 * 1.2)
assert result == expected
def test_multi_row_single_language(self):
"""10 rows, 1 language."""
result = TokenEstimator.estimate_output_tokens(10, 1)
expected = int(10 * 1 * 120 * 1.2)
assert result == expected
def test_multi_row_multi_language(self):
"""5 rows, 3 languages."""
result = TokenEstimator.estimate_output_tokens(5, 3)
expected = int(5 * 3 * 120 * 1.2)
assert result == expected
def test_default_language(self):
"""Default num_languages is 1."""
result = TokenEstimator.estimate_output_tokens(2)
expected = int(2 * 1 * 120 * 1.2)
assert result == expected
class TestEstimateCost:
"""TokenEstimator.estimate_cost — cost from tokens."""
def test_zero_tokens_zero_cost(self):
"""0 tokens costs 0."""
assert TokenEstimator.estimate_cost(0) == 0.0
def test_default_rate(self):
"""1000 tokens at default rate."""
cost = TokenEstimator.estimate_cost(1000)
assert cost == pytest.approx(0.002, 0.000001)
def test_custom_rate(self):
"""Custom cost per 1k tokens."""
cost = TokenEstimator.estimate_cost(1000, 0.01)
assert cost == pytest.approx(0.01, 0.000001)
def test_large_token_count(self):
"""Large token count calculates correctly."""
cost = TokenEstimator.estimate_cost(100000)
assert cost == pytest.approx(0.2, 0.000001)
def test_rounding_precision(self):
"""Result is rounded to 6 decimal places."""
cost = TokenEstimator.estimate_cost(333)
assert isinstance(cost, float)
class TestCheckCostWarning:
"""TokenEstimator.check_cost_warning — cost threshold warning."""
def test_below_threshold_no_warning(self):
"""sample_size <= 30 returns None."""
assert TokenEstimator.check_cost_warning(10, 1, 100, 0.001) is None
assert TokenEstimator.check_cost_warning(30, 1, 100, 0.001) is None
def test_above_threshold_returns_warning(self):
"""sample_size > 30 returns warning string."""
warning = TokenEstimator.check_cost_warning(50, 2, 5000, 0.05)
assert warning is not None
assert "Large preview" in warning
assert "5000 tokens" in warning
assert "$0.0500" in warning
assert "2 languages" in warning
def test_warning_format_high_cost(self):
"""Warning includes formatted cost."""
warning = TokenEstimator.check_cost_warning(100, 1, 10000, 0.5)
assert warning is not None
assert "$0.5000" in warning
def test_single_language_format(self):
"""Warning for single language."""
warning = TokenEstimator.check_cost_warning(40, 1, 2000, 0.004)
assert warning is not None
assert "1 languages" in warning
# #endregion Test.PreviewTokenEstimator