Files
shopdb-flask/frontend/src/utils/codes.spec.js

94 lines
3.5 KiB
JavaScript

// The arithmetic in codes.js decides whether a printed label scans, and it is
// the part no amount of looking at a screen will verify - a QR that is fine at
// 96 dpi on a monitor can be unreadable at 203 dpi on 0.5in stock.
import { describe, it, expect } from 'vitest'
import {
LABEL_PRESETS, BARCODE_DEFAULTS, qrModuleCount, qrFit, svgDataUri,
} from './codes'
describe('qrModuleCount', () => {
it('grows with the content', () => {
const short = qrModuleCount('AP-01')
const long = qrModuleCount('AP-01/'.repeat(20))
expect(short).toBeGreaterThan(0)
expect(long).toBeGreaterThan(short)
})
it('grows with error correction, because the redundancy is stored in modules', () => {
expect(qrModuleCount('WKSTN0042', 'H')).toBeGreaterThanOrEqual(
qrModuleCount('WKSTN0042', 'L'))
})
it('returns 0 rather than throwing on empty content', () => {
expect(qrModuleCount('')).toBe(0)
expect(qrModuleCount(null)).toBe(0)
})
})
describe('qrFit', () => {
it('calls a code too small when a module gets under two printer dots', () => {
// A long payload squeezed onto the 1.00 x 0.50in stock: the case the Tech
// Tools generator exists to warn about before 300 labels are printed.
const fit = qrFit('https://shopdb.example.net/assets/1234?from=label&sig=abcdef123456', {
sizeInches: 0.4286, dpi: 203, errorCorrection: 'H',
})
expect(fit.tooSmall).toBe(true)
expect(fit.dotsPerModule).toBeLessThan(2)
})
it('reports a whole number of dots per module as even', () => {
const modules = qrModuleCount('WKSTN0042', 'M')
// Choose the size that divides exactly at 4 dots per module.
const fit = qrFit('WKSTN0042', {
sizeInches: (modules * 4) / 203, dpi: 203, errorCorrection: 'M',
})
expect(fit.wholeDots).toBe(4)
expect(fit.even).toBe(true)
expect(fit.snapped).toBeCloseTo(fit.snapped, 5)
})
it('offers the nearest evenly-dividing size when the chosen one is uneven', () => {
const fit = qrFit('WKSTN0042', { sizeInches: 0.9, dpi: 203, errorCorrection: 'M' })
expect(fit.even).toBe(false)
expect(fit.snapped).toBeLessThanOrEqual(0.9)
expect(fit.snapped * 203 / fit.modules).toBeCloseTo(fit.wholeDots, 6)
})
it('is null when there is nothing to measure', () => {
expect(qrFit('', { sizeInches: 1 })).toBeNull()
expect(qrFit('WKSTN0042', {})).toBeNull()
})
})
describe('shared defaults', () => {
it('barcodes are CODE128 with no margin and no printed text', () => {
// The label draws its own caption, and the quiet zone is blank label. Both
// had drifted per-view before this module existed.
expect(BARCODE_DEFAULTS.format).toBe('CODE128')
expect(BARCODE_DEFAULTS.margin).toBe(0)
expect(BARCODE_DEFAULTS.displayValue).toBe(false)
})
it('every label preset is a complete, usable stock definition', () => {
expect(LABEL_PRESETS.length).toBeGreaterThan(0)
for (const preset of LABEL_PRESETS) {
expect(preset.id).toBeTruthy()
expect(preset.labelwidth).toBeGreaterThan(0)
expect(preset.labelheight).toBeGreaterThan(0)
// A code has to fit inside its label with its quiet zone on both sides.
expect(preset.codesize + 2 * preset.quiet).toBeLessThanOrEqual(preset.labelwidth)
}
})
})
describe('svgDataUri', () => {
it('escapes markup so the URI survives being put in a src attribute', () => {
const uri = svgDataUri('<svg><rect fill="#000"/></svg>')
expect(uri.startsWith('data:image/svg+xml;charset=utf-8,')).toBe(true)
expect(uri).not.toContain('<')
expect(uri).not.toContain('"')
})
})