102 lines
3.2 KiB
TypeScript
102 lines
3.2 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest';
|
|
|
|
import type { MeasureWidthImpl } from '../types';
|
|
import { MissingFontSpecError } from '../errors';
|
|
import { buildFontSpecKey } from '../fontSpecKey';
|
|
import { measureSliceWidthCached } from '../measureSliceWidthCached';
|
|
import { measureWidthCached } from '../measureWidthCached';
|
|
|
|
describe('textWrap width-measurement', () => {
|
|
it('buildFontSpecKey: 缺字段必须报错(简体中文)', () => {
|
|
expect(() => buildFontSpecKey({ fontFamily: 'PingFangSC-Regular', fontWeight: '400' } as any)).toThrow(
|
|
MissingFontSpecError
|
|
);
|
|
});
|
|
|
|
it('measureWidthCached: 未提供测量能力 -> approx + WIDTH_UNKNOWN', async () => {
|
|
const res = await measureWidthCached({
|
|
text: 'hello',
|
|
context: 'WIDGET',
|
|
contextProfile: 'WIDGET',
|
|
fontSpec: null,
|
|
measureWidthImpl: undefined,
|
|
});
|
|
expect(res.width).toBeNull();
|
|
expect(res.meta).toEqual({ isApprox: true, reason: 'WIDTH_UNKNOWN' });
|
|
});
|
|
|
|
it('measureWidthCached: 同 key 命中缓存(不会重复调用底层测量)', async () => {
|
|
const impl: MeasureWidthImpl = vi.fn(async ({ text }) => text.length);
|
|
|
|
const a = await measureWidthCached({
|
|
text: 'abc',
|
|
context: 'APP',
|
|
contextProfile: 'APP|ios',
|
|
fontSpec: { fontFamily: 'PingFangSC-Regular', fontWeight: '400', fontSize: 16 },
|
|
measureWidthImpl: impl,
|
|
});
|
|
const b = await measureWidthCached({
|
|
text: 'abc',
|
|
context: 'APP',
|
|
contextProfile: 'APP|ios',
|
|
fontSpec: { fontFamily: 'PingFangSC-Regular', fontWeight: '400', fontSize: 16 },
|
|
measureWidthImpl: impl,
|
|
});
|
|
|
|
expect(a.width).toBe(3);
|
|
expect(b.width).toBe(3);
|
|
expect(impl).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('measureWidthCached: 测量抛错 -> approx + MEASURE_FAILED', async () => {
|
|
const impl: MeasureWidthImpl = vi.fn(async () => {
|
|
throw new Error('boom');
|
|
});
|
|
|
|
const res = await measureWidthCached({
|
|
text: 'abc',
|
|
context: 'APP',
|
|
contextProfile: 'APP|ios|throw',
|
|
fontSpec: { fontFamily: 'PingFangSC-Regular', fontWeight: '400', fontSize: 16 },
|
|
measureWidthImpl: impl,
|
|
});
|
|
|
|
expect(res.width).toBeNull();
|
|
expect(res.meta).toEqual({ isApprox: true, reason: 'MEASURE_FAILED' });
|
|
});
|
|
|
|
it('measureSliceWidthCached: 同 sliceKey 命中缓存', async () => {
|
|
const impl: MeasureWidthImpl = vi.fn(async ({ text }) => text.length);
|
|
|
|
const tokens = [
|
|
{ text: 'I', start: 0, end: 1 },
|
|
{ text: 'am', start: 2, end: 4 },
|
|
{ text: 'tired', start: 5, end: 10 },
|
|
];
|
|
|
|
const a = await measureSliceWidthCached({
|
|
tokens: tokens as any,
|
|
start: 0,
|
|
end: 2,
|
|
context: 'APP',
|
|
contextProfile: 'APP|ios',
|
|
fontSpec: { fontFamily: 'PingFangSC-Regular', fontWeight: '400', fontSize: 16 },
|
|
measureWidthImpl: impl,
|
|
});
|
|
const b = await measureSliceWidthCached({
|
|
tokens: tokens as any,
|
|
start: 0,
|
|
end: 2,
|
|
context: 'APP',
|
|
contextProfile: 'APP|ios',
|
|
fontSpec: { fontFamily: 'PingFangSC-Regular', fontWeight: '400', fontSize: 16 },
|
|
measureWidthImpl: impl,
|
|
});
|
|
|
|
expect(a.width).toBe('I am'.length);
|
|
expect(b.width).toBe('I am'.length);
|
|
expect(impl).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
|