tests/test_context_budget.py
Rama master · réplica de lectura del repositorio original.
import datetime
import importlib.util
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
def load_script(name: str):
path = ROOT / "scripts" / f"{name}.py"
spec = importlib.util.spec_from_file_location(f"test_{name}", path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
SKILL_TEMPLATE = """---
name: {name}
description: {description}
---
# 标题
最后复核:{reviewed}
证据来源:测试夹具。
"""
class ContextBudgetTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.checker = load_script("check_context_budget")
def test_repository_context_files_pass(self):
problems, reviewed = self.checker.check_repo(ROOT)
self.assertEqual(problems, [], "\n".join(problems))
self.assertTrue(reviewed, "仓库应至少有一个带最后复核日期的技能")
def test_current_budgets_stay_under_ceiling(self):
self.assertEqual(self.checker.check_budget_history(), [])
for name, budget in self.checker.LINE_BUDGET.items():
self.assertLessEqual(budget, self.checker.MAX_EVER[name], name)
self.assertLessEqual(
self.checker.SKILL_MAX_LINES, self.checker.MAX_EVER["SKILL.md"]
)
self.assertLessEqual(
self.checker.DESCRIPTION_MAX_CHARS, self.checker.MAX_EVER["description"]
)
for name, budget in self.checker.BYTE_BUDGET.items():
self.assertLessEqual(budget, self.checker.MAX_EVER_BYTES[name], name)
self.assertLessEqual(
self.checker.SKILL_MAX_BYTES, self.checker.MAX_EVER_BYTES["SKILL.md"]
)
def test_raising_a_budget_without_a_reason_is_reported(self):
original = dict(self.checker.BUDGET_CHANGES)
try:
self.checker.BUDGET_CHANGES = {
"AGENTS.md": [(70, "2026-08-17", "初始值"), (80, "2026-08-18", "初始值")]
}
problems = self.checker.check_budget_history()
finally:
self.checker.BUDGET_CHANGES = original
self.assertTrue(any("是上调" in problem for problem in problems), problems)
def test_budget_above_ceiling_is_reported(self):
original = dict(self.checker.BUDGET_CHANGES)
try:
self.checker.BUDGET_CHANGES = {
"AGENTS.md": [(70, "2026-08-17", "初始值"), (300, "2026-08-18", "内容实在下沉不了")]
}
problems = self.checker.check_budget_history()
finally:
self.checker.BUDGET_CHANGES = original
self.assertTrue(any("越过天花板" in problem for problem in problems), problems)
def test_over_budget_entry_is_reported(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
budget = self.checker.LINE_BUDGET["AGENTS.md"]
(root / "AGENTS.md").write_text("行\n" * (budget + 1), encoding="utf-8")
problems = self.checker.check_line_budgets(root)
self.assertTrue(any("超出预算" in problem for problem in problems), problems)
def test_raising_a_byte_budget_without_a_reason_is_reported(self):
original = dict(self.checker.BYTE_BUDGET_CHANGES)
try:
self.checker.BYTE_BUDGET_CHANGES = {
"AGENTS.md": [(8 * 1024, "2026-09-03", "初始值"), (12 * 1024, "2026-09-04", "")]
}
problems = self.checker.check_budget_history()
finally:
self.checker.BYTE_BUDGET_CHANGES = original
self.assertTrue(any("字节预算" in problem for problem in problems), problems)
def test_byte_budget_above_ceiling_is_reported(self):
original = dict(self.checker.BYTE_BUDGET_CHANGES)
try:
self.checker.BYTE_BUDGET_CHANGES = {
"AGENTS.md": [(64 * 1024, "2026-09-03", "初始值")]
}
problems = self.checker.check_budget_history()
finally:
self.checker.BYTE_BUDGET_CHANGES = original
self.assertTrue(any("越过天花板" in problem for problem in problems), problems)
def test_a_file_within_the_line_budget_can_still_be_over_the_byte_budget(self):
"""行数合规不代表体积合规:这正是 STATUS.md 155 KB 那次没被拦住的原因。"""
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
budget = self.checker.BYTE_BUDGET["AGENTS.md"]
(root / "AGENTS.md").write_text("字" * budget, encoding="utf-8")
self.assertEqual(
self.checker.check_line_budgets(root),
["CLAUDE.md: 文件缺失"],
)
problems = self.checker.check_byte_budgets(root)
self.assertTrue(
any("AGENTS.md" in problem and "字节" in problem for problem in problems),
problems,
)
def test_over_long_line_is_reported(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
(root / "AGENTS.md").write_text(
"短行\n" + "长" * (self.checker.MAX_LINE_CHARS + 1) + "\n",
encoding="utf-8",
)
problems = self.checker.check_line_lengths(root)
self.assertEqual(len(problems), 1, problems)
self.assertIn("第 2 行", problems[0])
def test_skill_frontmatter_and_review_line_are_required(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
skill_dir = root / ".claude" / "skills" / "broken"
skill_dir.mkdir(parents=True)
(skill_dir / "SKILL.md").write_text("# 没有 frontmatter\n", encoding="utf-8")
named = root / ".claude" / "skills" / "mismatch"
named.mkdir(parents=True)
(named / "SKILL.md").write_text(
SKILL_TEMPLATE.format(
name="other", description="描述", reviewed="2026-01-01"
),
encoding="utf-8",
)
problems, reviewed = self.checker.check_skills(root)
self.assertTrue(any("frontmatter" in problem for problem in problems), problems)
self.assertTrue(any("不一致" in problem for problem in problems), problems)
self.assertEqual([rel for rel, _ in reviewed], [".claude/skills/mismatch/SKILL.md"])
def test_long_description_is_reported(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
skill_dir = root / ".claude" / "skills" / "verbose"
skill_dir.mkdir(parents=True)
(skill_dir / "SKILL.md").write_text(
SKILL_TEMPLATE.format(
name="verbose",
description="描" * (self.checker.DESCRIPTION_MAX_CHARS + 1),
reviewed="2026-01-01",
),
encoding="utf-8",
)
problems, _ = self.checker.check_skills(root)
self.assertTrue(any("description" in problem for problem in problems), problems)
def test_skill_utf8_bytes_are_checked_within_the_line_limit(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp).resolve()
skill_dir = root / ".claude" / "skills" / "sized"
skill_dir.mkdir(parents=True)
header = SKILL_TEMPLATE.format(
name="sized", description="描述", reviewed="2026-10-26"
)
limit = self.checker.SKILL_MAX_BYTES
row = "字" * 100 + "\n"
rows = (limit - len(header.encode("utf-8"))) // len(row.encode("utf-8"))
within = header + row * rows
path = skill_dir / "SKILL.md"
path.write_text(within, encoding="utf-8", newline="\n")
self.assertLess(len(within.splitlines()), self.checker.SKILL_MAX_LINES)
problems, _ = self.checker.check_skills(root)
self.assertEqual(problems, [])
path.write_text(within + row, encoding="utf-8", newline="\n")
problems, _ = self.checker.check_skills(root)
self.assertEqual(len(problems), 1, problems)
self.assertIn("字节", problems[0])
self.assertEqual(self.checker.check_line_lengths(root), [])
def test_skill_line_length_is_checked_independently_of_total_bytes(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp).resolve()
skill_dir = root / ".claude" / "skills" / "line"
skill_dir.mkdir(parents=True)
text = SKILL_TEMPLATE.format(
name="line", description="描述", reviewed="2026-10-26"
)
path = skill_dir / "SKILL.md"
path.write_text(text + "字" * self.checker.MAX_LINE_CHARS, encoding="utf-8")
self.assertEqual(self.checker.check_line_lengths(root), [])
path.write_text(text + "字" * (self.checker.MAX_LINE_CHARS + 1), encoding="utf-8")
self.assertLess(path.stat().st_size, self.checker.SKILL_MAX_BYTES)
problems = self.checker.check_line_lengths(root)
self.assertEqual(len(problems), 1, problems)
self.assertIn(".claude/skills/line/SKILL.md", problems[0])
def test_index_and_files_must_match(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
(root / "AGENTS.md").write_text(
"| 触发 | `.claude/skills/missing/SKILL.md` |\n", encoding="utf-8"
)
skill_dir = root / ".claude" / "skills" / "present"
skill_dir.mkdir(parents=True)
(skill_dir / "SKILL.md").write_text(
SKILL_TEMPLATE.format(
name="present", description="描述", reviewed="2026-01-01"
),
encoding="utf-8",
)
problems = self.checker.check_skill_index(root)
self.assertIn("AGENTS.md 索引指向不存在的技能:.claude/skills/missing/SKILL.md", problems)
self.assertIn("技能未登记进 AGENTS.md 索引:.claude/skills/present/SKILL.md", problems)
def test_stale_review_uses_fixed_today(self):
reviewed = [
("fresh", datetime.date(2026, 8, 1)),
("old", datetime.date(2025, 1, 1)),
]
stale = self.checker.stale_reviews(reviewed, datetime.date(2026, 8, 17))
self.assertEqual([rel for rel, _ in stale], ["old"])
if __name__ == "__main__":
unittest.main()