Files
paseo/packages/app/src/git/diff-document/text-measurement.test.ts
T
Mohamed Boudra c7b103a2cd fix(app): stabilize canvas diff rendering
Keep diff headers and painted content on the same scroll clock while preserving native scrolling and independent per-file horizontal offsets.

Complete review, selection, typography, tree, and palette parity without returning line rendering to React.
2026-08-17 21:14:38 +02:00

54 lines
1.8 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
createFallbackAwareTextMeasurer,
requiresNativeParagraph,
type PrimaryTextFace,
} from "./text-measurement";
describe.each(["ios", "android"])("%s native text measurement", (platform) => {
it("routes CJK and emoji missing glyphs through the system fallback shaper", () => {
const fallbackInputs: string[] = [];
const measurer = createFallbackAwareTextMeasurer({
primary: primaryFaceWithout("中", "👨‍👩‍👧‍👦"),
measureWithSystemFallback(text) {
fallbackInputs.push(text);
return platform === "ios" ? 24 : 22;
},
});
expect(measurer.measure("中")).toBe(platform === "ios" ? 24 : 22);
expect(measurer.measure("👨‍👩‍👧‍👦")).toBe(platform === "ios" ? 24 : 22);
expect(fallbackInputs).toEqual(["中", "👨‍👩‍👧‍👦"]);
});
it("keeps combining graphemes intact when the primary face supports them", () => {
const measurer = createFallbackAwareTextMeasurer({
primary: primaryFaceWithout(),
measureWithSystemFallback: () => 99,
});
expect(measurer.measure("é")).toBe(20);
});
});
describe("native paragraph retention", () => {
it("keeps ordinary code on the allocation-free font path", () => {
expect(requiresNativeParagraph("const answer = value + 1;")).toBe(false);
});
it.each(["value => next", "中", "e\u0301", "👩‍💻", "مرحبا"])("retains shaping for %s", (text) => {
expect(requiresNativeParagraph(text)).toBe(true);
});
});
function primaryFaceWithout(...missing: string[]): PrimaryTextFace {
return {
glyphIds(text) {
const isMissing = missing.some((candidate) => text.includes(candidate));
return Array.from(text, () => (isMissing ? 0 : 1));
},
measure(text) {
return Array.from(text).length * 10;
},
};
}