# 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