Files
2026-06-23 20:29:02 +08:00

169 lines
5.0 KiB
Python

#!/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_noma_module():
_ensure_scripts_on_path()
import data_modules.noma as noma_module
return noma_module
def test_init_does_not_resolve_existing_project_root(monkeypatch):
module = _load_noma_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", ["noma", "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_noma_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",
[
"noma",
"--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_preflight_succeeds_for_valid_project_root(monkeypatch, tmp_path, capsys):
module = _load_noma_module()
project_root = tmp_path / "book"
(project_root / ".noma").mkdir(parents=True, exist_ok=True)
(project_root / ".noma" / "state.json").write_text("{}", encoding="utf-8")
monkeypatch.setattr(sys, "argv", ["noma", "--project-root", str(project_root), "preflight"])
with pytest.raises(SystemExit) as exc:
module.main()
captured = capsys.readouterr()
assert int(exc.value.code or 0) == 0
assert "OK project_root" in captured.out
assert str(project_root.resolve()) in captured.out
def test_preflight_fails_when_required_scripts_are_missing(monkeypatch, tmp_path, capsys):
module = _load_noma_module()
project_root = tmp_path / "book"
(project_root / ".noma").mkdir(parents=True, exist_ok=True)
(project_root / ".noma" / "state.json").write_text("{}", encoding="utf-8")
fake_scripts_dir = tmp_path / "fake-scripts"
fake_scripts_dir.mkdir(parents=True, exist_ok=True)
monkeypatch.setattr(module, "_scripts_dir", lambda: fake_scripts_dir)
monkeypatch.setattr(sys, "argv", ["noma", "--project-root", str(project_root), "preflight", "--format", "json"])
with pytest.raises(SystemExit) as exc:
module.main()
captured = capsys.readouterr()
assert int(exc.value.code or 0) == 1
assert '"ok": false' in captured.out
assert '"name": "entry_script"' in captured.out
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" / ".noma-current-project").write_text(str(book_root), encoding="utf-8")
(book_root / ".noma").mkdir(parents=True, exist_ok=True)
(book_root / ".noma" / "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 / ".noma" / "index.db").is_file()
assert not (workspace_root / ".noma" / "index.db").exists()