import json
import pytest
from ikat import __version__
from ikat.cli import main as cli_main
needs_mcp = pytest.mark.skipif(
__import__("importlib").util.find_spec("mcp.server.fastmcp") is None,
reason="mcp extra absent",
)
MD = "# Hi\n\n## 1. Sec\n\nBody text.\n"
def test_weave_stdout(tmp_path, capsys):
md = tmp_path / "d.md"
md.write_text(MD, encoding="utf-8")
assert cli_main(["weave", str(md)]) == 0
out = capsys.readouterr().out
assert "\\documentclass[conference]{IEEEtran}" in out
assert "\\section{Sec}" in out
def test_build_no_pdf(tmp_path, capsys):
md = tmp_path / "d.md"
md.write_text(MD, encoding="utf-8")
out = tmp_path / "out"
assert cli_main(["build", str(md), "--outdir", str(out), "--no-pdf"]) == 0
tex = (out / "d.tex").read_text(encoding="utf-8")
assert "\\maketitle" in tex
assert "tex:" in capsys.readouterr().out
def test_build_with_toml_and_spec(tmp_path):
(tmp_path / "ikat.toml").write_text('[template]\npreamble_append = ["% hi"]\n', encoding="utf-8")
md = tmp_path / "d.md"
md.write_text(MD, encoding="utf-8")
spec = tmp_path / "s.json"
spec.write_text(json.dumps({"bib_style": "plain", "bogus_key": 1}), encoding="utf-8")
out = tmp_path / "out"
assert cli_main(["build", str(md), "--toml", str(tmp_path / "ikat.toml"),
"--outdir", str(out), "--no-pdf"]) == 0
assert cli_main(["build", str(md), "--outdir", str(out), "--no-pdf",
"--spec", str(spec)]) == 0
assert "\\bibliographystyle{plain}" in (out / "d.tex").read_text(encoding="utf-8")
def test_check_reports_and_fails(tmp_path, capsys, monkeypatch):
from ikat import texenv
tex = tmp_path / "d.tex"
tex.write_text("\\documentclass{article}\\usepackage{pgfplots}\n", encoding="utf-8")
monkeypatch.setattr(texenv.shutil, "which", lambda _: None)
assert cli_main(["check", str(tex)]) == 1
rep = json.loads(capsys.readouterr().out)
assert rep["unprobed"] == ["pgfplots.sty", "article.cls"]
def test_templates_commands(tmp_path, capsys):
assert cli_main(["templates"]) == 0
names = capsys.readouterr().out.split()
assert len(names) == 9 and "arxiv" in names
assert cli_main(["template", "arxiv", "--show-preset"]) == 0
out = capsys.readouterr().out
assert "\\documentclass[11pt]{article}" in out
assert "bib_style=IEEEtran" in out
assert cli_main(["template", "nope"]) == 1
def test_flowchart_stdin(capsys, monkeypatch):
import sys
monkeypatch.setattr(sys, "stdin", __import__("io").StringIO("graph TD\na[x]-->b[y]\n"))
assert cli_main(["flowchart", "-"]) == 0
assert "\\begin{tikzpicture}" in capsys.readouterr().out
def test_skeleton_commands(capsys):
assert cli_main(["skeletons"]) == 0
assert "plain" in capsys.readouterr().out
assert cli_main(["skeleton", "skeleton-plain"]) == 0
assert "{{body}}" in capsys.readouterr().out
def test_plot_commands(tmp_path, capsys):
bar = tmp_path / "bar.json"
bar.write_text('{"title": "t", "ylabel": "y", "group_labels": ["a"],'
' "series_names": ["s"], "values": [[2.0]], "mins": [[2.0]],'
' "maxs": [[2.0]]}', encoding="utf-8")
assert cli_main(["barchart", str(bar), "--legend", "below"]) == 0
out = capsys.readouterr().out
assert "anchor=north,legend columns=-1" in out
line = tmp_path / "line.json"
line.write_text('{"title": "t", "xlabel": "x", "ylabel": "y", "xs": [1.0],'
' "names": ["s"], "yss": [[2.0]], "errs": [[0.0]]}', encoding="utf-8")
assert cli_main(["lineplot", str(line)]) == 0
assert "\\begin{tikzpicture}" in capsys.readouterr().out
def test_version(capsys):
assert cli_main(["version"]) == 0
assert capsys.readouterr().out.strip() == __version__
@needs_mcp
def test_mcp_tools_registered():
from ikat import mcp_server
import asyncio
names = sorted(t.name for t in asyncio.run(mcp_server.mcp.list_tools()))
assert names == ["barchart_to_tikz", "check_tex_packages", "ensure_tex_packages",
"float_packages", "flowchart_to_tikz", "get_skeleton", "get_template", "lineplot_to_tikz",
"list_skeletons", "list_templates", "version", "weave_document"]
@needs_mcp
def test_mcp_weave_and_template():
from ikat import mcp_server
r = mcp_server.weave_document(MD, "", '{"bib_style": "plain"}')
assert r["tex"].count("\\documentclass") == 1
assert "\\bibliographystyle{plain}" in r["tex"]
t = mcp_server.get_template("aps")
assert t["bib_style"] == "apsrev4-2"
assert "\\documentclass" in t["head"]
assert mcp_server.version() == __version__