Files
ApiCore/ApiCore-Backend/src/label-templates/font-metrics.spec.ts
T
Nick SzaunigandClaude Opus 5.5 c18860c75c
Backend Image / build-and-push (push) Successful in 6m34s
Frontend Image / build-and-push (push) Successful in 10m17s
feat: T6 wave 2 – medicine book, document rights, label particulars, herd events
- Veterinary medicine catalogue, lots and append-only movement ledger
  (rest always computed; corrections as counter-bookings; inactive
  medicines take no new stock; unit must match on lot moves).
- Documents of medicine lots, authority notices and restrictions need the
  domain right on top of documents:* (403 before any lookup).
- Label particulars: pure checkLabel with six mandatory gaps and four
  warnings, AFM font metrics, Berlin-day dates, geometric reading order
  for split addresses, new master-data fields with row-locked updates.
- Herd events ColonyCreated, ColonyMoved, ApiaryChanged and
  TskReferenceDayReached (ids only, never forwarded to webhooks); CSV
  import emits ColonyCreated with audit.
- ARCHITECTURE.md §12 Compliance (T6), Annahmen 59–70.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-15 13:43:44 +02:00

68 lines
2.0 KiB
TypeScript

import { fontMetricsOf, heightMm, pdfTextMeasurer } from './font-metrics';
import { LabelTextElement } from './label-element.types';
describe('font metrics', () => {
// Guards against a pdfkit update that changes or hides the AFM values.
it('Helvetica metrics are x-height 523 and cap height 718', () => {
expect(fontMetricsOf('sans', false, false)).toEqual({
xHeight: 523,
capHeight: 718,
});
});
it('Times and Courier return their own AFM values', () => {
expect(fontMetricsOf('serif', false, false)).toEqual({
xHeight: 450,
capHeight: 662,
});
expect(fontMetricsOf('serif', true, true)).toEqual({
xHeight: 462,
capHeight: 669,
});
expect(fontMetricsOf('mono', false, false)).toEqual({
xHeight: 426,
capHeight: 562,
});
});
it('reads the style variants of a family', () => {
expect(fontMetricsOf('sans', true, false).xHeight).toBe(532);
});
it('converts a size and a metric to millimetres', () => {
expect(heightMm(6, 523)).toBeCloseTo(1.107, 3);
expect(heightMm(7, 523)).toBeCloseTo(1.2915, 3);
expect(heightMm(72, 1000)).toBeCloseTo(25.4, 9);
});
describe('pdfTextMeasurer', () => {
const element: LabelTextElement = {
id: 'e',
type: 'text',
x: 0,
y: 0,
width: 20,
height: 10,
text: '',
fontSize: 10,
fontFamily: 'sans',
bold: false,
italic: false,
color: '#000000',
align: 'left',
};
it('measures more lines for a narrower box', () => {
const measurer = pdfTextMeasurer();
const text = 'Mindestens haltbar bis 05.03.2028 und noch mehr Text';
const wide = measurer.heightOfStringPt(text, { ...element, width: 120 });
const narrow = measurer.heightOfStringPt(text, { ...element, width: 20 });
expect(narrow).toBeGreaterThan(wide);
});
it('measures nothing for an empty text', () => {
expect(pdfTextMeasurer().heightOfStringPt('', element)).toBe(0);
});
});
});