// Tests for the document→layout glue (P0.5 step 10, automatable slice): // fit-to-width metrics built from a fake PageDocumentSource. No pdfium. import 'dart:ui' show Size; import 'package:flutter_test/flutter_test.dart'; import 'package:badnote/editor/layout/page_viewport.dart'; import 'package:badnote/editor/pdf/pdf_document_source.dart'; class _FakeSource implements PageDocumentSource { _FakeSource(this._sizes); final List _sizes; @override int get pageCount => _sizes.length; @override Size pageSize(int index) => _sizes[index]; } void main() { test('fit-to-width scales each page height by its aspect at the column width', () { // A4-ish portrait 600×800 and a square 500×500 at column width 300. final source = _FakeSource([const Size(600, 800), const Size(500, 500)]); final m = pageStackMetricsForWidth(source, 300); expect(m.pageCount, 2); expect(m.heightOf(0), closeTo(300 * 800 / 600, 1e-9)); // 400 expect(m.heightOf(1), closeTo(300.0, 1e-9)); // square → 300 expect(m.totalExtent, closeTo(700, 1e-9)); }); test('gap is threaded into the metrics', () { final source = _FakeSource([const Size(100, 100), const Size(100, 100)]); final m = pageStackMetricsForWidth(source, 100, gap: 25); expect(m.offsetOf(1), closeTo(125, 1e-9)); // 100 + 25 gap }); test('empty document yields empty metrics', () { final m = pageStackMetricsForWidth(_FakeSource(const []), 300); expect(m.pageCount, 0); expect(m.totalExtent, 0); }); test('non-positive page width is treated as zero height (no divide-by-zero)', () { final source = _FakeSource([const Size(0, 800), const Size(400, 200)]); final m = pageStackMetricsForWidth(source, 300); expect(m.heightOf(0), 0.0); expect(m.heightOf(1), closeTo(150, 1e-9)); // 300 * 200/400 }); test('windowing composes on top of the fit-to-width metrics', () { // 5 portrait pages 600×800 at width 300 → each 400 tall, total 2000. final source = _FakeSource(List.filled(5, const Size(600, 800))); final m = pageStackMetricsForWidth(source, 300); expect(m.totalExtent, closeTo(2000, 1e-9)); // viewport [350, 850) → page1 [400,800) and page2 [800,1200) just touched? // page0 [0,400), page1 [400,800), page2 [800,1200). window [350,850]: // first bottom>350 → page0 bottom 400>350 → 0; last top<850 → page2 top // 800<850 → 2. expect(m.visibleRange(350, 500), const PageWindow(0, 2)); }); }