Link another Caudal (phone, USB) with a code or a QR instead of the password, choosing the server's root certificate as a file; read Bitcoin straight from Bitcoin Core or Knots, without an Electrum server; Android app (beta) and a Windows build script. Fixed: Save did nothing for expenses, refunds and dividends entered by hand.
64 lines
2.8 KiB
Python
64 lines
2.8 KiB
Python
"""
|
|
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()
|