feat: initial commit
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user