from md2gost.latex.log import ( STRICT_KINDS, Diagnostic, format_diagnostics, parse_log, ) ERROR_LOG = """ This is XeTeX ! LaTeX Error: File `emblem' not found. See the LaTeX manual or LaTeX Companion for explanation. """ OVERFULL_LOG = r""" Overfull \hbox (56.70982pt too wide) in alignment at lines 220--220 [] Overfull \hbox (7.2pt too wide) detected at line 14 [] Overfull \hbox (0.4pt too wide) in paragraph at lines 30--31 """ UNDERFULL_LOG = r""" Underfull \hbox (badness 3000) in paragraph at lines 10--11 Underfull \hbox (badness 7000) in paragraph at lines 20--21 """ WARNING_LOG = """ LaTeX Warning: Reference `fig:1' on page 3 undefined on input line 42. LaTeX Warning: There were undefined references. """ def test_error_is_parsed() -> None: diags = parse_log(ERROR_LOG) assert len(diags) == 1 assert diags[0].kind == "error" assert "File `emblem' not found" in diags[0].message def test_overfull_amount_and_line() -> None: diags = [d for d in parse_log(OVERFULL_LOG) if d.kind == "overfull"] assert [d.amount for d in diags] == [56.70982, 7.2] assert [d.line for d in diags] == [220, 14] def test_overfull_below_threshold_is_dropped() -> None: """Вылеты в доли пункта не видны глазом и только зашумляют вывод.""" diags = parse_log(OVERFULL_LOG, overfull_threshold_pt=1.0) assert all(d.amount != 0.4 for d in diags if d.amount is not None) def test_underfull_threshold() -> None: diags = [d for d in parse_log(UNDERFULL_LOG, underfull_threshold=5000)] assert len(diags) == 1 assert diags[0].kind == "underfull" assert diags[0].amount == 7000 assert diags[0].line == 20 def test_warning_is_parsed() -> None: diags = parse_log(WARNING_LOG) assert [d.kind for d in diags] == ["warning", "warning"] assert "undefined" in diags[0].message def test_clean_log_gives_nothing() -> None: assert parse_log("This is XeTeX\nOutput written on a.pdf (3 pages).\n") == [] def test_format_sorts_overfull_by_amount() -> None: text = format_diagnostics(parse_log(OVERFULL_LOG)) first = text.index("56.7") second = text.index("7.2") assert first < second def test_format_is_empty_for_no_diagnostics() -> None: assert format_diagnostics([]) == "" def test_format_mentions_every_kind() -> None: diags = parse_log(ERROR_LOG + OVERFULL_LOG + UNDERFULL_LOG + WARNING_LOG) text = format_diagnostics(diags) for word in ("ошибк", "предупрежд", "за правое поле", "разрежен"): assert word in text def test_diagnostic_is_hashable() -> None: assert Diagnostic("error", "x", None, None) == Diagnostic("error", "x", None, None) NOISE_LOG = r""" Package unicode-math Warning: Using \overbracket and \underbracket from (unicode-math) `mathtools' package. LaTeX Warning: There were undefined references. """ def test_known_package_noise_is_suppressed() -> None: """Постоянный шум unicode-math заглушает собой полезные предупреждения.""" diags = parse_log(NOISE_LOG) assert len(diags) == 1 assert "undefined references" in diags[0].message def test_strict_ignores_underfull_and_warnings() -> None: """Разреженная строка бывает намеренной, выход за поле — никогда.""" assert "overfull" in STRICT_KINDS assert "error" in STRICT_KINDS assert "underfull" not in STRICT_KINDS assert "warning" not in STRICT_KINDS