qalmsw / tests /test_cli.py
pebaryan
Improve open source project readiness
3183da7
Raw
History Blame Contribute Delete
3.95 kB
"""Tests for CLI batch mode and retrieval backend switching."""
import json
from pathlib import Path
from typer.testing import CliRunner
from qalmsw.cli import app
from qalmsw.retrieval import search_by_title, set_backend
from qalmsw.retrieval.scholar import search_by_title as gs_search
from qalmsw.retrieval.semantic_scholar import search_by_title as ss_search
runner = CliRunner()
def test_default_backend_is_semantic_scholar():
"""Module-level search_by_title should point to Semantic Scholar by default."""
assert search_by_title is ss_search
def test_set_backend_google_scholar():
"""Switching to google-scholar patches the module-level function."""
import qalmsw.retrieval as mod
original = mod.search_by_title
set_backend("google-scholar")
try:
assert mod.search_by_title is gs_search
finally:
# Restore
set_backend("semantic-scholar")
assert mod.search_by_title is original
def test_set_backend_semantic_scholar():
"""Switching back to semantic-scholar restores the original."""
import qalmsw.retrieval as mod
set_backend("google-scholar")
set_backend("semantic-scholar")
assert mod.search_by_title is ss_search
def test_set_backend_unknown_raises():
"""Unknown backend name raises ValueError."""
import pytest
with pytest.raises(ValueError, match="Unknown retrieval backend"):
set_backend("bing")
def test_resolve_files_single(tmp_path: Path):
"""Single existing .tex file is returned as-is."""
tex = tmp_path / "paper.tex"
tex.write_text(r"\documentclass{article}\begin{document}hello\end{document}")
from qalmsw.cli import _resolve_files
resolved = _resolve_files([tex])
assert len(resolved) == 1
assert resolved[0] == tex
def test_resolve_files_glob(tmp_path: Path):
"""Glob pattern expands to matching .tex files."""
(tmp_path / "ch1.tex").write_text("chapter 1")
(tmp_path / "ch2.tex").write_text("chapter 2")
(tmp_path / "notes.txt").write_text("not a tex file")
from qalmsw.cli import _resolve_files
resolved = _resolve_files([tmp_path / "ch*.tex"])
assert len(resolved) == 2
names = {f.name for f in resolved}
assert names == {"ch1.tex", "ch2.tex"}
def test_resolve_files_no_match(tmp_path: Path):
"""Glob with no matches returns empty list."""
from qalmsw.cli import _resolve_files
resolved = _resolve_files([tmp_path / "nonexistent*.tex"])
assert resolved == []
def test_json_output_is_parseable_without_status_lines(tmp_path: Path):
"""--json should emit only JSON so CI tools can parse stdout."""
tex = tmp_path / "paper.tex"
tex.write_text(r"\documentclass{article}\begin{document}Plain text.\end{document}")
result = runner.invoke(
app,
[
"check",
"--skip-grammar",
"--skip-math",
"--skip-reviewer",
"--json",
str(tex),
],
)
assert result.exit_code == 0
payload = json.loads(result.stdout)
assert payload["file"] == str(tex)
assert payload["findings"] == []
def test_json_output_batches_multiple_files(tmp_path: Path):
"""Multi-file --json should still be one parseable JSON document."""
tex1 = tmp_path / "a.tex"
tex2 = tmp_path / "b.tex"
tex1.write_text(r"\documentclass{article}\begin{document}A.\end{document}")
tex2.write_text(r"\documentclass{article}\begin{document}B.\end{document}")
result = runner.invoke(
app,
[
"check",
"--skip-grammar",
"--skip-math",
"--skip-reviewer",
"--json",
str(tex1),
str(tex2),
],
)
assert result.exit_code == 0
payload = json.loads(result.stdout)
assert payload["total_files"] == 2
assert [file_payload["file"] for file_payload in payload["files"]] == [
str(tex1),
str(tex2),
]