- 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]>
68 lines
2.0 KiB
TypeScript
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);
|
|
});
|
|
});
|
|
});
|