test_db_units.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. """db 层纯逻辑单测(不触网/不触库的部分)。"""
  2. from __future__ import annotations
  3. import pytest
  4. from pbot.db.scanner import parse_open_times
  5. from pbot.db.scheduler import parse_progress_marks
  6. from pbot.db.seed import TASKS
  7. class TestParseOpenTimes:
  8. """serverlist 明文 JSON → {serverid: open_time}。"""
  9. def test_parses_nested_list(self) -> None:
  10. text = 'x({"serverData": [{"serverid": 14628306, "open_time": 1791043200, "state": 1}]})'
  11. out = parse_open_times(text)
  12. assert out == {14628306: 1791043200}
  13. def test_no_json_raises(self) -> None:
  14. from pbot.errors import PbotError
  15. with pytest.raises(PbotError):
  16. parse_open_times("plain text no json")
  17. def test_skips_missing_open_time(self) -> None:
  18. text = '{"a": [{"serverid": 1, "open_time": 100}, {"serverid": 2}]}'
  19. out = parse_open_times(text)
  20. assert out == {1: 100}
  21. class TestParseProgressMarks:
  22. """打勾文本 → (done, total)。"""
  23. def test_counts_done_and_fail(self) -> None:
  24. text = (
  25. "# header\n\n"
  26. "- 2026-10-04 00:15:33 ☑ **T1 开启喝药保护** — ok\n"
  27. "- 2026-10-04 00:22:10 ☑ **T2 开区挖矿(20分钟窗口)** — 851锄\n"
  28. "- 2026-10-04 00:30:00 ☒ **T3 比奇大城杀怪20** — 失败\n"
  29. )
  30. done, total, name = parse_progress_marks(text)
  31. assert (done, total) == (2, 3)
  32. assert name == ""
  33. def test_empty_text(self) -> None:
  34. done, total, _ = parse_progress_marks("")
  35. assert (done, total) == (0, 0)
  36. class TestSeedTasks:
  37. """种子任务清单与 run_pipeline 定案一致性。"""
  38. def test_order_t7_tail(self) -> None:
  39. codes = [str(t["code"]) for t in TASKS]
  40. assert codes.index("T07") == len(codes) - 2 # 倒数第二(队尾兜底, T10 最后)
  41. assert codes[-1] == "T10"
  42. def test_soft_set_matches_pipeline(self) -> None:
  43. soft = {str(t["code"]) for t in TASKS if t["soft"]}
  44. assert soft == {"T02", "T07", "T08", "T10"}
  45. def test_watch_only_t07(self) -> None:
  46. watch = [str(t["code"]) for t in TASKS if t["watch"]]
  47. assert watch == ["T07"]
  48. def test_modules_exist(self) -> None:
  49. import importlib
  50. for t in TASKS:
  51. mod = importlib.import_module(str(t["module"]))
  52. assert hasattr(mod, "run_task"), f"{t['module']} 缺 run_task"