169 lines
5.0 KiB
Python
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()
|