test_webnovel_unified_cli.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import sys
  4. from pathlib import Path
  5. import pytest
  6. def _ensure_scripts_on_path() -> None:
  7. scripts_dir = Path(__file__).resolve().parents[2]
  8. if str(scripts_dir) not in sys.path:
  9. sys.path.insert(0, str(scripts_dir))
  10. def _load_webnovel_module():
  11. _ensure_scripts_on_path()
  12. import data_modules.webnovel as webnovel_module
  13. return webnovel_module
  14. def test_init_does_not_resolve_existing_project_root(monkeypatch):
  15. module = _load_webnovel_module()
  16. called = {}
  17. def _fake_run_script(script_name, argv):
  18. called["script_name"] = script_name
  19. called["argv"] = list(argv)
  20. return 0
  21. def _fail_resolve(_explicit_project_root=None):
  22. raise AssertionError("init 子命令不应触发 project_root 解析")
  23. monkeypatch.setenv("WEBNOVEL_PROJECT_ROOT", r"D:\invalid\root")
  24. monkeypatch.setattr(module, "_run_script", _fake_run_script)
  25. monkeypatch.setattr(module, "_resolve_root", _fail_resolve)
  26. monkeypatch.setattr(sys, "argv", ["webnovel", "init", "proj-dir", "测试书", "修仙"])
  27. with pytest.raises(SystemExit) as exc:
  28. module.main()
  29. assert int(exc.value.code or 0) == 0
  30. assert called["script_name"] == "init_project.py"
  31. assert called["argv"] == ["proj-dir", "测试书", "修仙"]
  32. def test_extract_context_forwards_with_resolved_project_root(monkeypatch, tmp_path):
  33. module = _load_webnovel_module()
  34. book_root = (tmp_path / "book").resolve()
  35. called = {}
  36. def _fake_resolve(explicit_project_root=None):
  37. return book_root
  38. def _fake_run_script(script_name, argv):
  39. called["script_name"] = script_name
  40. called["argv"] = list(argv)
  41. return 0
  42. monkeypatch.setattr(module, "_resolve_root", _fake_resolve)
  43. monkeypatch.setattr(module, "_run_script", _fake_run_script)
  44. monkeypatch.setattr(
  45. sys,
  46. "argv",
  47. [
  48. "webnovel",
  49. "--project-root",
  50. str(tmp_path),
  51. "extract-context",
  52. "--chapter",
  53. "12",
  54. "--format",
  55. "json",
  56. ],
  57. )
  58. with pytest.raises(SystemExit) as exc:
  59. module.main()
  60. assert int(exc.value.code or 0) == 0
  61. assert called["script_name"] == "extract_chapter_context.py"
  62. assert called["argv"] == [
  63. "--project-root",
  64. str(book_root),
  65. "--chapter",
  66. "12",
  67. "--format",
  68. "json",
  69. ]
  70. def test_quality_trend_report_writes_to_book_root_when_input_is_workspace_root(tmp_path, monkeypatch):
  71. _ensure_scripts_on_path()
  72. import quality_trend_report as quality_trend_report_module
  73. workspace_root = (tmp_path / "workspace").resolve()
  74. book_root = (workspace_root / "凡人资本论").resolve()
  75. (workspace_root / ".claude").mkdir(parents=True, exist_ok=True)
  76. (workspace_root / ".claude" / ".webnovel-current-project").write_text(str(book_root), encoding="utf-8")
  77. (book_root / ".webnovel").mkdir(parents=True, exist_ok=True)
  78. (book_root / ".webnovel" / "state.json").write_text("{}", encoding="utf-8")
  79. output_path = workspace_root / "report.md"
  80. monkeypatch.setattr(
  81. sys,
  82. "argv",
  83. [
  84. "quality_trend_report",
  85. "--project-root",
  86. str(workspace_root),
  87. "--limit",
  88. "1",
  89. "--output",
  90. str(output_path),
  91. ],
  92. )
  93. quality_trend_report_module.main()
  94. assert output_path.is_file()
  95. assert (book_root / ".webnovel" / "index.db").is_file()
  96. assert not (workspace_root / ".webnovel" / "index.db").exists()