import { describe, expect, it } from 'vitest'; import { canInsert, flatten, freeSlotsOf, insert, locate, neighbor, remove, withTrunk } from './tree'; describe('page tree', () => { it('flattens trunk top→bottom with left then right branches, closest→outward', () => { let t = withTrunk(['a', 'b']); t = insert(t, 'a', 'right', ['r1']); t = insert(t, 'r1', 'right', ['r2']); t = insert(t, 'a', 'left', ['l1']); t = insert(t, 'l1', 'left', ['l2']); t = insert(t, 'b', 'right', ['br']); expect(flatten(t)).toEqual(['a', 'l1', 'l2', 'r1', 'r2', 'b', 'br']); }); it('growing the trunk upward changes what comes first', () => { let t = withTrunk(['a']); t = insert(t, 'a', 'up', ['p1', 'p2']); expect(flatten(t)).toEqual(['p1', 'p2', 'a']); }); it('inserts an imported chain in reading order on every side', () => { let t = withTrunk(['a']); t = insert(t, 'a', 'left', ['x1', 'x2', 'x3']); expect(t.branches.a.left).toEqual(['x1', 'x2', 'x3']); t = insert(t, 'a', 'down', ['d1', 'd2']); expect(t.trunk).toEqual(['a', 'd1', 'd2']); }); it('forbids sub-branches off a branch', () => { let t = withTrunk(['a']); t = insert(t, 'a', 'right', ['r']); expect(canInsert(t, 'r', 'up')).toBe(false); expect(insert(t, 'r', 'down', ['z'])).toBe(t); expect(freeSlotsOf(t, 'r').map((s) => s.dir)).toEqual(['right']); }); it('inserting toward the trunk from a branch page goes between', () => { let t = withTrunk(['a']); t = insert(t, 'a', 'right', ['r1', 'r2']); t = insert(t, 'r2', 'left', ['mid']); expect(t.branches.a.right).toEqual(['r1', 'mid', 'r2']); }); it('navigates neighbours', () => { let t = withTrunk(['a', 'b']); t = insert(t, 'a', 'left', ['l1', 'l2']); expect(neighbor(t, 'a', 'down')).toBe('b'); expect(neighbor(t, 'a', 'left')).toBe('l1'); expect(neighbor(t, 'l1', 'left')).toBe('l2'); expect(neighbor(t, 'l1', 'right')).toBe('a'); expect(neighbor(t, 'l2', 'up')).toBe(null); }); it('removing a trunk page takes its branches with it', () => { let t = withTrunk(['a', 'b']); t = insert(t, 'a', 'right', ['r']); const { tree, removed } = remove(t, 'a'); expect(removed).toEqual(['a', 'r']); expect(flatten(tree)).toEqual(['b']); expect(locate(tree, 'r')).toBe(null); }); it('removing a branch page closes the gap', () => { let t = withTrunk(['a']); t = insert(t, 'a', 'right', ['r1', 'r2', 'r3']); expect(remove(t, 'r2').tree.branches.a.right).toEqual(['r1', 'r3']); }); });