# coding=utf-8 """Tests de la boite de dialogue, des traductions et de l'extension (pytest).""" import os import re import sys import xml.etree.ElementTree as ET import pytest ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") sys.path.insert(0, ROOT) INX = os.path.join(ROOT, "box_maker.inx") import box_core # noqa: E402 # -------------------------------------------------------------------------- # Traductions # -------------------------------------------------------------------------- def test_translations_up_to_date_and_complete(): """Chaque texte du .inx et des .py a sa traduction dans chaque catalogue.""" import gettext import i18n msgids = [msgid for msgid, _refs in i18n.extract()] assert "Finger-Joint Box" in msgids assert "Front" in msgids # noms des pieces, marques dans box_maker.py for language in i18n.LANGUAGES: entries = i18n.read_po(i18n.po_path(language)) missing = [m for m in msgids if not entries.get(m, ("", False))[0]] assert not missing, "{}.po incomplet : {}".format(language, missing) catalog = gettext.translation(i18n.DOMAIN, i18n.LOCALE_DIR, [language]) for msgid in msgids: assert catalog.gettext(msgid) == entries[msgid][0], \ "{} : .mo a recompiler (python i18n.py)".format(language) def test_french_error_message_keeps_placeholders(): """La traduction du message d'erreur garde les memes champs de format.""" import i18n fields = re.compile(r"\{\w+(?::[^}]*)?\}") for msgid, (msgstr, _fuzzy) in i18n.read_po(i18n.po_path("fr")).items(): assert sorted(fields.findall(msgid)) == sorted(fields.findall(msgstr)), msgid def test_po_roundtrip(tmp_path): import i18n messages = [("Simple", ["a"]), ('Quote "x" and \\ back', ["a"]), ("Two\nlines", ["a"]), ("Tab\tend\n", ["a"])] path = str(tmp_path / "xx.po") i18n.write_po(path, "fr", messages, {m: ("<" + m + ">", False) for m, _r in messages}) entries = i18n.read_po(path) for msgid, _refs in messages: assert entries[msgid] == ("<" + msgid + ">", False) # -------------------------------------------------------------------------- # Boite de dialogue # -------------------------------------------------------------------------- def test_inx_matches_arguments(): """Chaque du .inx a son add_argument, et inversement.""" root = ET.parse(INX).getroot() params = {elem.get("name") for elem in root.iter() if elem.tag.rsplit("}", 1)[-1] == "param"} with open(os.path.join(ROOT, "box_maker.py"), encoding="utf-8") as handle: arguments = set(re.findall(r'add_argument\("--(\w+)"', handle.read())) assert params == arguments def test_inx_images_exist(): """Les images de la boite de dialogue sont presentes (chemin relatif au .inx).""" root = ET.parse(INX).getroot() images = [elem.text.strip() for elem in root.iter() if elem.tag.rsplit("}", 1)[-1] == "image"] assert images for image in images: assert os.path.isfile(os.path.join(ROOT, image)), image def test_every_core_panel_has_a_translated_name(): inkex = pytest.importorskip("inkex") # noqa: F841 import box_maker names = {p.name for p in box_core.box_panels(100, 80, 50, 3)} assert names == set(box_maker.panel_names()) # -------------------------------------------------------------------------- # Bout en bout (avec inkex) # -------------------------------------------------------------------------- BLANK = ('' '') def _run(tmp_path, *args): pytest.importorskip("inkex") import box_maker source = tmp_path / "in.svg" source.write_text(BLANK, encoding="utf-8") output = tmp_path / "out.svg" box_maker.BoxMaker().run(list(args) + ["--output={}".format(output), str(source)]) return output.read_text(encoding="utf-8") if output.exists() else "" def test_end_to_end_closed_box_with_labels(tmp_path): svg = _run(tmp_path, "--labels=true") assert svg.count("{}<".format(name) in svg def test_end_to_end_too_small_reports_error(tmp_path, capsys): _run(tmp_path, "--length=10") err = capsys.readouterr().err assert "length" in err and "at least 15 mm" in err