Skip to content

Commit 97ddc98

Browse files
chenglounice-hang
andcommitted
Cover documented layout helpers
Co-authored-by: Hang <HangWhy@outlook.com>
1 parent 43fa91d commit 97ddc98

1 file changed

Lines changed: 46 additions & 1 deletion

File tree

src/layout.test.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ let layout: LayoutModule['layout']
2121
let layoutWithLines: LayoutModule['layoutWithLines']
2222
let layoutNextLine: LayoutModule['layoutNextLine']
2323
let layoutNextLineRange: LayoutModule['layoutNextLineRange']
24+
let materializeLineRange: LayoutModule['materializeLineRange']
2425
let measureLineStats: LayoutModule['measureLineStats']
26+
let measureNaturalWidth: LayoutModule['measureNaturalWidth']
2527
let walkLineRanges: LayoutModule['walkLineRanges']
2628
let clearCache: LayoutModule['clearCache']
2729
let setLocale: LayoutModule['setLocale']
@@ -31,6 +33,7 @@ let stepPreparedLineGeometry: LineBreakModule['stepPreparedLineGeometry']
3133
let walkPreparedLines: LineBreakModule['walkPreparedLines']
3234
let getSegmentBreakableFitAdvances: MeasurementModule['getSegmentBreakableFitAdvances']
3335
let prepareRichInline: RichInlineModule['prepareRichInline']
36+
let layoutNextRichInlineLineRange: RichInlineModule['layoutNextRichInlineLineRange']
3437
let materializeRichInlineLineRange: RichInlineModule['materializeRichInlineLineRange']
3538
let measureRichInlineStats: RichInlineModule['measureRichInlineStats']
3639
let walkRichInlineLineRanges: RichInlineModule['walkRichInlineLineRanges']
@@ -280,14 +283,16 @@ beforeAll(async () => {
280283
layoutWithLines,
281284
layoutNextLine,
282285
layoutNextLineRange,
286+
materializeLineRange,
283287
measureLineStats,
288+
measureNaturalWidth,
284289
walkLineRanges,
285290
clearCache,
286291
setLocale,
287292
} = mod)
288293
;({ countPreparedLines, measurePreparedLineGeometry, stepPreparedLineGeometry, walkPreparedLines } = lineBreakMod)
289294
;({ getSegmentBreakableFitAdvances } = measurementMod)
290-
;({ prepareRichInline, materializeRichInlineLineRange, measureRichInlineStats, walkRichInlineLineRanges } = richInlineMod)
295+
;({ prepareRichInline, layoutNextRichInlineLineRange, materializeRichInlineLineRange, measureRichInlineStats, walkRichInlineLineRanges } = richInlineMod)
291296
})
292297

293298
beforeEach(() => {
@@ -747,6 +752,30 @@ describe('rich-inline invariants', () => {
747752
})
748753
})
749754

755+
test('layoutNextRichInlineLineRange streams the same ranges as the walker', () => {
756+
const prepared = prepareRichInline([
757+
{ text: 'Ship ', font: FONT },
758+
{ text: '@maya', font: '700 12px Test Sans', break: 'never', extraWidth: 18 },
759+
{ text: "'s rich note wraps cleanly", font: FONT },
760+
])
761+
const walked: Array<{ end: TestLayoutCursor & { itemIndex: number }, width: number }> = []
762+
walkRichInlineLineRanges(prepared, 120, line => {
763+
walked.push({ end: line.end, width: line.width })
764+
})
765+
766+
const streamed: typeof walked = []
767+
let cursor = { itemIndex: 0, segmentIndex: 0, graphemeIndex: 0 }
768+
while (true) {
769+
const line = layoutNextRichInlineLineRange(prepared, 120, cursor)
770+
if (line === null) break
771+
streamed.push({ end: line.end, width: line.width })
772+
cursor = line.end
773+
}
774+
775+
expect(streamed).toEqual(walked)
776+
expect(streamed.length).toBeGreaterThan(1)
777+
})
778+
750779
test('non-materializing range walker matches range materialization', () => {
751780
const prepared = prepareRichInline([
752781
{ text: 'Ship ', font: FONT },
@@ -1425,6 +1454,16 @@ describe('layout invariants', () => {
14251454
})))
14261455
})
14271456

1457+
test('materializeLineRange reproduces streamed layout lines', () => {
1458+
const prepared = prepareWithSegments('foo trans\u00ADatlantic said "hello" to 世界 and waved.', FONT)
1459+
const width = prepared.widths[0]! + prepared.widths[1]! + prepared.widths[2]! + prepared.breakableFitAdvances[4]![0]! + prepared.discretionaryHyphenWidth + 0.1
1460+
const expected = layoutWithLines(prepared, width, LINE_HEIGHT).lines[0]!
1461+
const range = layoutNextLineRange(prepared, { segmentIndex: 0, graphemeIndex: 0 }, width)
1462+
1463+
expect(range).not.toBeNull()
1464+
expect(materializeLineRange(prepared, range!)).toEqual(expected)
1465+
})
1466+
14281467
test('measureLineStats matches walked line count and widest line', () => {
14291468
const prepared = prepareWithSegments('foo trans\u00ADatlantic said "hello" to 世界 and waved.', FONT)
14301469
const width = prepared.widths[0]! + prepared.widths[1]! + prepared.widths[2]! + prepared.breakableFitAdvances[4]![0]! + prepared.discretionaryHyphenWidth + 0.1
@@ -1442,6 +1481,12 @@ describe('layout invariants', () => {
14421481
})
14431482
})
14441483

1484+
test('measureNaturalWidth returns the widest forced line', () => {
1485+
const prepared = prepareWithSegments('wide line\nfit\nmid', FONT, { whiteSpace: 'pre-wrap' })
1486+
1487+
expect(measureNaturalWidth(prepared)).toBe(measureWidth('wide line', FONT))
1488+
})
1489+
14451490
test('line-break geometry helpers stay aligned with streamed line ranges', () => {
14461491
const prepared = prepareWithSegments('foo trans\u00ADatlantic said "hello" to 世界 and waved.', FONT)
14471492
const widths = [48, 72, 120]

0 commit comments

Comments
 (0)