""" Pruebas del dibujo de códigos QR (cartera/qr.py). El generador se contrastó módulo a módulo con una biblioteca de referencia para las doce versiones y las ocho máscaras; aquí quedan fijadas unas huellas de aquel contraste, para que un cambio que rompa el dibujo se note, y las reglas que se pueden comprobar solas. python3 -m unittest discover -s pruebas -v """ from __future__ import annotations import hashlib import sys import unittest from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from cartera import qr # noqa: E402 def huella(texto: str, mascara: int) -> str: m = qr.matriz(texto, mascara) return hashlib.sha256("\n".join("".join("1" if v else "0" for v in f) for f in m).encode()).hexdigest()[:16] HUELLAS = { ('hola', 0): (21, '4fc02fa450493e1a'), ('caudal://enlazar?u=https://caudal.midominio.local:54013&c=ABCDE-FGHJK', 3): (37, 'b999eb98ad128ff2'), ('ñandú €', 5): (21, 'f0376ed7bb1bb4b8'), ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 7): (57, 'f4598565726ae33f'), ('yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy', 2): (65, '4c6b554ce57e4951'), } class TestQr(unittest.TestCase): def test_el_dibujo_no_ha_cambiado(self): for (texto, mascara), (lado, esperada) in HUELLAS.items(): with self.subTest(texto=texto[:20], mascara=mascara): self.assertEqual(len(qr.matriz(texto, mascara)), lado) self.assertEqual(huella(texto, mascara), esperada) def test_el_tamaño_crece_con_el_texto(self): self.assertEqual([len(qr.matriz("x" * n)) for n in (1, 14, 15, 26, 27, 287)], [21, 21, 25, 25, 29, 65]) def test_los_tres_ojos_y_el_modulo_fijo(self): m = qr.matriz("caudal") n = len(m) for x0, y0 in ((0, 0), (n - 7, 0), (0, n - 7)): ojo = ["".join("1" if m[y0 + y][x0 + x] else "0" for x in range(7)) for y in range(7)] self.assertEqual(ojo, ["1111111", "1000001", "1011101", "1011101", "1011101", "1000001", "1111111"]) self.assertTrue(m[n - 8][8]) def test_lo_que_no_cabe_se_dice(self): with self.assertRaises(qr.TextoDemasiadoLargo): qr.matriz("x" * 288) def test_filas_como_texto(self): filas = qr.filas("hola") self.assertEqual((len(filas), {len(f) for f in filas}, set("".join(filas))), (21, {21}, {"0", "1"})) if __name__ == "__main__": unittest.main()