import test from 'node:test'; import assert from 'node:assert/strict'; import jsQR from 'jsqr'; import { createPassengerQr, passengerLink } from '../src/lib/passenger.mjs'; test('rounded QR modules and finders remain decodable for multiple city and platform links', () => { for (const [cityId, stopId] of [[1, 1], [1, 107], [2, 123456]]) { const url = passengerLink('https://pwa.ridebus.by/', cityId, stopId), qr = createPassengerQr(url); const scale = 6, width = qr.size * scale, pixels = new Uint8ClampedArray(width * width * 4).fill(255); for (const rect of qr.rectangles) { for (let y = rect.y * scale; y < (rect.y + rect.height) * scale; y++) for (let x = rect.x * scale; x < (rect.x + rect.width) * scale; x++) { const px = (x + .5) / scale, py = (y + .5) / scale; const cx = Math.max(rect.x + rect.rx, Math.min(rect.x + rect.width - rect.rx, px)); const cy = Math.max(rect.y + rect.rx, Math.min(rect.y + rect.height - rect.rx, py)); if ((px - cx) ** 2 + (py - cy) ** 2 > rect.rx ** 2) continue; const index = (y * width + x) * 4, value = rect.fill === '#ffffff' ? 255 : 16; pixels[index] = pixels[index + 1] = pixels[index + 2] = value; } } assert.equal(jsQR(pixels, width, width)?.data, url); assert.ok(qr.rectangles.every(rect => rect.x >= 4 && rect.y >= 4 && rect.x + rect.width <= qr.size - 4 && rect.y + rect.height <= qr.size - 4)); } });