"""Tests for title page generation (```title, info_conv.yaml, template fill).""" from __future__ import annotations from pathlib import Path from docx import Document from md2gost.title_page import ( TitleMeta, build_title_docx, load_info_conv, merge_title_meta, parse_and_strip_title_fence, parse_kv_text, should_generate_title, ) from md2gost.user_profile import UserProfile, load_user_profile, save_user_profile def test_parse_title_fence_and_strip(): md = ( "```title\n" "number: 3\n" "year: 2025\n" "discipline: Тестовая дисциплина\n" "```\n" "\n" "# *ВВЕДЕНИЕ\n" "\n" "Text.\n" ) fields, body = parse_and_strip_title_fence(md) assert fields["number"] == "3" assert fields["year"] == "2025" assert fields["discipline"] == "Тестовая дисциплина" assert "# *ВВЕДЕНИЕ" in body assert "```title" not in body def test_parse_kv_russian_aliases_and_typos(): raw = ( "Инститиут: ИИТ\n" "Кафедра: ЦТ\n" "Дисциплина: ПАЦО\n" "Преподователь: Иванов И. И.\n" "Должность: старший преподаватель\n" ) y = parse_kv_text(raw) assert y["institute"] == "ИИТ" assert y["department"] == "ЦТ" assert y["discipline"] == "ПАЦО" assert y["teacher"] == "Иванов И. И." assert y["teacher_position"] == "старший преподаватель" def test_merge_fence_overrides_yaml(): yaml_f = {"institute": "ИИТ", "discipline": "Из yaml"} fence = {"discipline": "Из fence", "number": "2"} meta = merge_title_meta( yaml_fields=yaml_f, fence_fields=fence, student="Петров П. П.", group="ИНБО-01-20", ) assert meta.institute == "ИИТ" assert meta.discipline == "Из fence" assert meta.number == "2" assert meta.student == "Петров П. П." assert meta.group == "ИНБО-01-20" # student/group ignored from yaml/fence meta2 = merge_title_meta( yaml_fields={"student": "X", "group": "Y", "institute": "Z"}, student="A", group="B", ) assert meta2.student == "A" and meta2.group == "B" assert meta2.institute == "Z" def test_load_info_conv(tmp_path: Path): p = tmp_path / "info_conv.yaml" p.write_text( "Институт: Институт информационных технологий (ИИТ)\n" "Кафедра: Кафедра ЦТ\n" "Преподаватель: Сидоров\n" "Должность: ассистент\n", encoding="utf-8", ) data = load_info_conv(tmp_path) assert "ИИТ" in data["institute"] assert data["teacher"] == "Сидоров" def test_should_generate_title(tmp_path: Path): assert should_generate_title( explicit_title="ready.docx", fence_fields={"number": "1"}, md_dir=tmp_path, enabled=True, ) is False assert should_generate_title( explicit_title=None, fence_fields={"number": "1"}, md_dir=tmp_path, enabled=False, ) is False assert should_generate_title( explicit_title=None, fence_fields={"number": "1"}, md_dir=tmp_path, enabled=True, ) is True assert should_generate_title( explicit_title=None, fence_fields={}, md_dir=tmp_path, enabled=True, ) is False (tmp_path / "info_conv.yaml").write_text("Институт: X\n", encoding="utf-8") assert should_generate_title( explicit_title=None, fence_fields={}, md_dir=tmp_path, enabled=True, ) is True assert should_generate_title( explicit_title=None, fence_fields={}, md_dir=tmp_path, enabled=False, ) is False def test_user_profile_roundtrip(tmp_path: Path): save_user_profile(UserProfile(student="А А А", group="ГР-1"), base=tmp_path) loaded = load_user_profile(base=tmp_path) assert loaded.student == "А А А" assert loaded.group == "ГР-1" assert loaded.is_complete() def test_build_title_docx_fills_red_slots(tmp_path: Path): meta = TitleMeta( institute="Институт ИИТ", department="Кафедра ЦТ", discipline="Дисциплина X", number="7", group="ИНБО-99-99", student="Тестов Тест Тестович", teacher_position="доцент, кафедра ЦТ", teacher="Преподов П. П.", year="2024", ) out = tmp_path / "title.docx" build_title_docx(meta, out) doc = Document(str(out)) texts = [p.text for p in doc.paragraphs] assert "Институт ИИТ" in texts[0] assert "Кафедра ЦТ" in texts[1] assert "Дисциплина X" in texts[5] assert "7" in texts[8] assert "ИНБО-99-99" in texts[13] assert "Тестов Тест Тестович" in texts[15] assert "доцент" in texts[19] assert "Преподов" in texts[21] assert "2024" in texts[28] # prefixes kept assert texts[13].startswith("студент группы") assert "по дисциплине" in texts[5] assert "Москва" in texts[28] def test_pipeline_generates_title(tmp_path: Path, monkeypatch): from md2gost.pipeline import ConvertRequest, convert from md2gost import user_profile as up monkeypatch.setattr(up, "app_dir", lambda: tmp_path) save_user_profile( UserProfile(student="Конвейев К. К.", group="ИНБО-00-00"), base=tmp_path, ) (tmp_path / "info_conv.yaml").write_text( "Институт: ИИТ тест\n" "Кафедра: Каф тест\n" "Дисциплина: Дисц тест\n" "Преподаватель: Преп П. П.\n" "Должность: ст. преподаватель\n", encoding="utf-8", ) md = tmp_path / "report.md" md.write_text( "```title\n" "number: 2\n" "year: 2026\n" "```\n" "\n" "# *СОДЕРЖАНИЕ\n" "\n" "[TOC]\n" "\n" "# *ВВЕДЕНИЕ\n" "\n" "Текст введения.\n" "\n" "# *ЗАКЛЮЧЕНИЕ\n" "\n" "Вывод.\n" "\n" "# *СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ\n" "\n" "[1]: Книга. — М., 2024.\n", encoding="utf-8", ) out = tmp_path / "report.docx" result = convert( ConvertRequest( filename=str(md), output=str(out), table_continuation="off", listing_continuation="off", auto_title=True, open_when_done=False, ), log=lambda _m: None, ) assert result.ok, result.message assert out.is_file() doc = Document(str(out)) blob = "\n".join(p.text for p in doc.paragraphs) assert "Конвейев" in blob assert "ИНБО-00-00" in blob assert "ИИТ тест" in blob assert "Дисц тест" in blob assert "Преп П. П." in blob def test_pipeline_skips_title_by_default(tmp_path: Path, monkeypatch): from md2gost.pipeline import ConvertRequest, convert from md2gost import user_profile as up monkeypatch.setattr(up, "app_dir", lambda: tmp_path) save_user_profile( UserProfile(student="Конвейев К. К.", group="ИНБО-00-00"), base=tmp_path, ) (tmp_path / "info_conv.yaml").write_text( "Институт: ИИТ тест\n" "Кафедра: Каф тест\n" "Дисциплина: Дисц тест\n" "Преподаватель: Преп П. П.\n" "Должность: ст. преподаватель\n", encoding="utf-8", ) md = tmp_path / "report.md" md.write_text( "```title\n" "number: 2\n" "year: 2026\n" "```\n" "\n" "# *ВВЕДЕНИЕ\n" "\n" "Текст введения.\n" "\n" "# *ЗАКЛЮЧЕНИЕ\n" "\n" "Вывод.\n" "\n" "# *СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ\n" "\n" "[1]: Книга. — М., 2024.\n", encoding="utf-8", ) out = tmp_path / "report.docx" result = convert( ConvertRequest( filename=str(md), output=str(out), table_continuation="off", listing_continuation="off", open_when_done=False, ), log=lambda _m: None, ) assert result.ok, result.message doc = Document(str(out)) blob = "\n".join(p.text for p in doc.paragraphs) assert "Конвейев" not in blob assert "ИИТ тест" not in blob assert "Текст введения" in blob