Files
tolaria/src/components/tldrawTextMeasurementGuard.test.ts

76 lines
2.4 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest'
import type { Editor } from 'tldraw'
import { installTldrawTextMeasurementGuard } from './tldrawTextMeasurementGuard'
type TextMeasure = Pick<Editor, 'textMeasure'>['textMeasure']
type MeasureElementTextNodeSpans = TextMeasure['measureElementTextNodeSpans']
function textMeasureHost(measureElementTextNodeSpans: MeasureElementTextNodeSpans) {
return {
textMeasure: {
measureElementTextNodeSpans,
},
}
}
function elementWithText(text: string): HTMLElement {
const element = document.createElement('div')
element.textContent = text
vi.spyOn(element, 'getBoundingClientRect').mockReturnValue(DOMRect.fromRect({
height: 24,
width: 88,
}))
return element
}
describe('tldraw text measurement guard', () => {
it('falls back to a whole-text span when Edge returns no range rect', () => {
const originalMeasure = vi.fn(() => {
throw new TypeError("Cannot read properties of undefined (reading 'top')")
})
const host = textMeasureHost(originalMeasure)
const cleanup = installTldrawTextMeasurementGuard(host)
expect(host.textMeasure.measureElementTextNodeSpans(elementWithText('Label'))).toEqual({
didTruncate: false,
spans: [{
box: { h: 24, w: 88, x: 0, y: 0 },
text: 'Label',
}],
})
cleanup()
expect(() => host.textMeasure.measureElementTextNodeSpans(elementWithText('Label'))).toThrow('top')
})
it('preserves first-line truncation for fallback measurements', () => {
const originalMeasure = vi.fn(() => {
throw new TypeError("Cannot read properties of undefined (reading 'top')")
})
const host = textMeasureHost(originalMeasure)
installTldrawTextMeasurementGuard(host)
expect(host.textMeasure.measureElementTextNodeSpans(
elementWithText('Title\nOverflow'),
{ shouldTruncateToFirstLine: true },
)).toEqual({
didTruncate: true,
spans: [{
box: { h: 24, w: 88, x: 0, y: 0 },
text: 'Title',
}],
})
})
it('rethrows unrelated measurement failures', () => {
const originalMeasure = vi.fn(() => {
throw new RangeError('bad measurement state')
})
const host = textMeasureHost(originalMeasure)
installTldrawTextMeasurementGuard(host)
expect(() => host.textMeasure.measureElementTextNodeSpans(elementWithText('Label')))
.toThrow('bad measurement state')
})
})