// Tests for the one-notebook-per-PDF logical page model (F6). import 'package:flutter_test/flutter_test.dart'; import 'package:badnote/editor/notebook/page_map.dart'; void main() { test('fromSource is the identity map (one source page per PDF page)', () { final m = PageMap.fromSource(3); expect(m.length, 3); expect(m.sourceCount, 3); expect(m.blankCount, 0); expect([m.sourceIndexAt(0), m.sourceIndexAt(1), m.sourceIndexAt(2)], [0, 1, 2]); }); test('fromSource(0) is empty', () { final m = PageMap.fromSource(0); expect(m.isEmpty, isTrue); expect(m.length, 0); }); test('insertBlankAt inserts a blank and shifts logical order, NOT source idx', () { final m = PageMap.fromSource(2).insertBlankAt(1); expect(m.length, 3); expect(m[0], const NotebookPage.source(0)); expect(m[1].isBlank, isTrue); expect(m[2], const NotebookPage.source(1)); // source index UNCHANGED expect(m.sourceIndexAt(1), isNull); expect(m.blankCount, 1); }); test('insertBlankAfter(-1) prepends; after(last) appends', () { final m = PageMap.fromSource(2); expect(m.insertBlankAfter(-1)[0].isBlank, isTrue); final appended = m.insertBlankAfter(1); expect(appended[2].isBlank, isTrue); expect(appended.length, 3); }); test('insertBlankAt at length appends (boundary)', () { final m = PageMap.fromSource(2).insertBlankAt(2); expect(m.length, 3); expect(m[2].isBlank, isTrue); }); test('removeAt drops the logical page', () { final m = PageMap.fromSource(3).removeAt(1); expect(m.length, 2); expect([m.sourceIndexAt(0), m.sourceIndexAt(1)], [0, 2]); }); test('move reorders (drag-reorder thumbnails)', () { final m = PageMap.fromSource(3).move(0, 2); // [1,2,0] expect([m.sourceIndexAt(0), m.sourceIndexAt(1), m.sourceIndexAt(2)], [1, 2, 0]); }); test('move to same index is a no-op (returns identical instance)', () { final m = PageMap.fromSource(3); expect(identical(m.move(1, 1), m), isTrue); }); test('out-of-range edits throw RangeError', () { final m = PageMap.fromSource(2); expect(() => m.insertBlankAt(3), throwsRangeError); expect(() => m.removeAt(2), throwsRangeError); expect(() => m.move(0, 5), throwsRangeError); expect(() => m.insertBlankAfter(2), throwsRangeError); }); test('value equality + immutability of the page list', () { expect(PageMap.fromSource(2), PageMap.fromSource(2)); expect(PageMap.fromSource(2).insertBlankAt(0) == PageMap.fromSource(2), isFalse); final m = PageMap.fromSource(1); expect(() => m.pages.add(const NotebookPage.blank()), throwsUnsupportedError); }); test('NotebookPage equality distinguishes kind + source index', () { expect(const NotebookPage.source(1), const NotebookPage.source(1)); expect(const NotebookPage.source(1) == const NotebookPage.source(2), isFalse); expect(const NotebookPage.blank() == const NotebookPage.source(0), isFalse); expect(const NotebookPage.blank(), const NotebookPage.blank()); }); }