#!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys from pathlib import Path import pytest def _ensure_scripts_on_path() -> None: scripts_dir = Path(__file__).resolve().parents[2] if str(scripts_dir) not in sys.path: sys.path.insert(0, str(scripts_dir)) def _load_webnovel_module(): _ensure_scripts_on_path() import data_modules.webnovel as webnovel_module return webnovel_module def test_init_does_not_resolve_existing_project_root(monkeypatch): module = _load_webnovel_module() called = {} def _fake_run_script(script_name, argv): called["script_name"] = script_name called["argv"] = list(argv) return 0 def _fail_resolve(_explicit_project_root=None): raise AssertionError("init 子命令不应触发 project_root 解析") monkeypatch.setenv("WEBNOVEL_PROJECT_ROOT", r"D:\invalid\root") monkeypatch.setattr(module, "_run_script", _fake_run_script) monkeypatch.setattr(module, "_resolve_root", _fail_resolve) monkeypatch.setattr(sys, "argv", ["webnovel", "init", "proj-dir", "测试书", "修仙"]) with pytest.raises(SystemExit) as exc: module.main() assert int(exc.value.code or 0) == 0 assert called["script_name"] == "init_project.py" assert called["argv"] == ["proj-dir", "测试书", "修仙"] def test_extract_context_forwards_with_resolved_project_root(monkeypatch, tmp_path): module = _load_webnovel_module() book_root = (tmp_path / "book").resolve() called = {} def _fake_resolve(explicit_project_root=None): return book_root def _fake_run_script(script_name, argv): called["script_name"] = script_name called["argv"] = list(argv) return 0 monkeypatch.setattr(module, "_resolve_root", _fake_resolve) monkeypatch.setattr(module, "_run_script", _fake_run_script) monkeypatch.setattr( sys, "argv", [ "webnovel", "--project-root", str(tmp_path), "extract-context", "--chapter", "12", "--format", "json", ], ) with pytest.raises(SystemExit) as exc: module.main() assert int(exc.value.code or 0) == 0 assert called["script_name"] == "extract_chapter_context.py" assert called["argv"] == [ "--project-root", str(book_root), "--chapter", "12", "--format", "json", ] def test_quality_trend_report_writes_to_book_root_when_input_is_workspace_root(tmp_path, monkeypatch): _ensure_scripts_on_path() import quality_trend_report as quality_trend_report_module workspace_root = (tmp_path / "workspace").resolve() book_root = (workspace_root / "凡人资本论").resolve() (workspace_root / ".claude").mkdir(parents=True, exist_ok=True) (workspace_root / ".claude" / ".webnovel-current-project").write_text(str(book_root), encoding="utf-8") (book_root / ".webnovel").mkdir(parents=True, exist_ok=True) (book_root / ".webnovel" / "state.json").write_text("{}", encoding="utf-8") output_path = workspace_root / "report.md" monkeypatch.setattr( sys, "argv", [ "quality_trend_report", "--project-root", str(workspace_root), "--limit", "1", "--output", str(output_path), ], ) quality_trend_report_module.main() assert output_path.is_file() assert (book_root / ".webnovel" / "index.db").is_file() assert not (workspace_root / ".webnovel" / "index.db").exists()