"""End-to-end test of the P-touch print pipeline (no hardware required). Exercises config persistence, PDF generation, the "PDF" pseudo-printer path, and variable-length QR payloads, then verifies the output dimensions. IMPORTANT: this test writes to a temporary config file. It must never call save_config() with the default path, because that overwrites the operator's real settings in label_config.json. """ import os import sys import tempfile sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) os.chdir(os.path.dirname(os.path.abspath(__file__))) from PIL import Image, ImageDraw from reportlab.lib.units import mm from pypdf import PdfReader import label_config from print_label import print_ptouch_label from ptouch_label import LabelConfig, PtouchLabelRenderer, code_density_warning #: Isolated directory for config written by this test. TEMP_DIR = tempfile.mkdtemp(prefix="ptouch_test_") def make_test_logo(path): """Create a greyscale logo with transparency to exercise the flatten path.""" img = Image.new("RGBA", (400, 400), (255, 255, 255, 0)) draw = ImageDraw.Draw(img) draw.ellipse((20, 20, 380, 380), fill=(0, 0, 0, 255)) draw.rectangle((150, 150, 250, 250), fill=(255, 255, 255, 255)) img.save(path) return path def main(): base = os.path.dirname(os.path.abspath(__file__)) logo_path = os.path.join(TEMP_DIR, "test_logo.png") make_test_logo(logo_path) cfg = LabelConfig() cfg.logo_path = logo_path cfg.static_lines = ["MOTO ADV SRL", "Articol: CABLU", "Rev: 2026-09"] cfg.qr_prefix = "INV-" cfg.qr_suffix = "-A" cfg.qr_error_correction = "M" print("=" * 68) print("1. Config persistence round-trip (in a temp dir, real config untouched)") real_cfg_path = label_config.config_path() real_before = open(real_cfg_path).read() if os.path.exists(real_cfg_path) else None path = label_config.save_config(cfg, base_dir=TEMP_DIR) reloaded = label_config.load_config(base_dir=TEMP_DIR) print(f" saved to : {path}") print(f" logo preserved: {reloaded.logo_path == cfg.logo_path}") print(f" lines preserved: {reloaded.static_lines == cfg.static_lines}") print(f" prefix/suffix kept: " f"{reloaded.qr_prefix == cfg.qr_prefix and reloaded.qr_suffix == cfg.qr_suffix}") composed = reloaded.build_code_payload("1234") print(f" composed payload : {composed!r} " f"{'PASS' if composed == 'INV-1234-A' else 'FAIL'}") real_after = open(real_cfg_path).read() if os.path.exists(real_cfg_path) else None untouched = real_before == real_after print(f" real config untouched: {'PASS' if untouched else 'FAIL'}") print("\n2. Unknown/corrupt keys are tolerated") weird = LabelConfig.from_dict({"static_lines": "not-a-list", "bogus_key": 1}) print(f" static_lines fell back: {weird.static_lines == LabelConfig().static_lines}") print("\n3. Print pipeline via the 'PDF' pseudo-printer") success, pdf_path, warning = print_ptouch_label("INV-00042", "PDF", cfg) print(f" success : {success}") print(f" pdf : {pdf_path}") print(f" warning : {warning or 'none'}") page = PdfReader(pdf_path).pages[0] w_mm = float(page.mediabox.width) / mm h_mm = float(page.mediabox.height) / mm # With match_driver_media the page is the driver's media size and the label # content is centred inside it; otherwise page size == content size. want_w, want_h = cfg.page_size_mm exact = abs(w_mm - want_w) < 0.01 and abs(h_mm - want_h) < 0.01 print(f" page size : {w_mm:.2f} x {h_mm:.2f} mm {'PASS' if exact else 'FAIL'}") print(f" label content : {cfg.page_width_mm:.1f} x {cfg.page_height_mm:.1f} mm " f"at origin {cfg.origin_mm}") print("\n4. QR payload scaling with the inventory value") renderer = PtouchLabelRenderer(cfg) for value in ["A", "INV-00042", "MOTO-2026-0001234567"]: bitmap = renderer.code_bitmap(value) warn = code_density_warning(cfg, value) payload = cfg.build_code_payload(value) print( f" {value:<22} modules={bitmap.modules:>3} " f"size={bitmap.width_mm:5.2f}mm dots/mod={bitmap.dots_per_module:.1f} " f"{'OK' if not warn else 'WARN'}" ) print(f" payload: {payload!r}") if warn: print(f" -> {warn}") print("\n5. Oversized payload is reported, not silently misprinted") huge = "X" * 300 warn = code_density_warning(cfg, huge) print(f" warning present: {warn is not None}") print(f" -> {warn}") print("\n6. Preview render (what the GUI shows)") preview = renderer.render_preview("INV-00042", dpi=300) print(f" preview size : {preview.size} px @300dpi") preview.save(os.path.join(base, "test_ptouch_preview.png")) print(f" saved : test_ptouch_preview.png") # Tidy up the test artifacts for temp in (logo_path, pdf_path): try: if os.path.exists(temp): os.remove(temp) except OSError: pass print("\n" + "=" * 68) passed = exact and success and untouched print("RESULT:", "PASS" if passed else "FAIL") return 0 if passed else 1 if __name__ == "__main__": raise SystemExit(main())