89 lines
2.8 KiB
TypeScript
89 lines
2.8 KiB
TypeScript
import { BinaryFontPacker } from "@suaveplan/font-compress";
|
|
import type { TypefaceFont } from "@suaveplan/font-convert";
|
|
import { describe, it } from "@suaveplan/testing/runner";
|
|
import fc from "fast-check";
|
|
import { BinaryFontUnpacker } from "../src/index.js";
|
|
|
|
const packer = new BinaryFontPacker();
|
|
const unpacker = new BinaryFontUnpacker();
|
|
|
|
// Restrict coordinates to Int16 range (BTF dict uses Int16Array)
|
|
const coordArb = fc.integer({ min: -32768, max: 32767 });
|
|
|
|
const glyphArb = fc.record({
|
|
ha: coordArb,
|
|
x_min: coordArb,
|
|
x_max: coordArb,
|
|
o: fc.constant("m 0 0 z "),
|
|
});
|
|
|
|
const fontArb: fc.Arbitrary<TypefaceFont> = fc.record({
|
|
familyName: fc.string({ minLength: 1, maxLength: 30 }),
|
|
cssFontWeight: fc.constantFrom("100", "400", "700", "bold", "normal"),
|
|
cssFontStyle: fc.constantFrom("normal", "italic", "oblique"),
|
|
reversed: fc.boolean(),
|
|
ascender: coordArb,
|
|
descender: coordArb,
|
|
underlinePosition: coordArb,
|
|
underlineThickness: coordArb,
|
|
resolution: coordArb,
|
|
boundingBox: fc.record({
|
|
yMin: coordArb,
|
|
xMin: coordArb,
|
|
yMax: coordArb,
|
|
xMax: coordArb,
|
|
}),
|
|
original_font_information: fc.constant({}),
|
|
glyphs: fc.dictionary(
|
|
fc
|
|
.string({ minLength: 1, maxLength: 1 })
|
|
.filter((s) => s.charCodeAt(0) < 65536),
|
|
glyphArb,
|
|
{ minKeys: 0, maxKeys: 20 }
|
|
),
|
|
});
|
|
|
|
describe("property tests: pack/unpack roundtrip", () => {
|
|
it("familyName round-trips for all valid inputs", {
|
|
timeout: 30000,
|
|
}, () => {
|
|
fc.assert(
|
|
fc.property(fontArb, (font) => {
|
|
const result = unpacker.unpack(packer.pack(font));
|
|
return result.familyName === font.familyName;
|
|
}),
|
|
{ numRuns: 100 }
|
|
);
|
|
});
|
|
|
|
it("metrics round-trip for all valid inputs", { timeout: 30000 }, () => {
|
|
fc.assert(
|
|
fc.property(fontArb, (font) => {
|
|
const result = unpacker.unpack(packer.pack(font));
|
|
return (
|
|
result.ascender === font.ascender &&
|
|
result.descender === font.descender &&
|
|
result.resolution === font.resolution &&
|
|
result.reversed === font.reversed
|
|
);
|
|
}),
|
|
{ numRuns: 100 }
|
|
);
|
|
});
|
|
|
|
it("glyph count round-trips for all valid inputs", {
|
|
timeout: 30000,
|
|
}, () => {
|
|
fc.assert(
|
|
fc.property(fontArb, (font) => {
|
|
const result = unpacker.unpack(packer.pack(font));
|
|
return (
|
|
Object.keys(result.glyphs).length ===
|
|
Object.keys(font.glyphs).length
|
|
);
|
|
}),
|
|
{ numRuns: 100 }
|
|
);
|
|
});
|
|
});
|