Papure/src/lib/model/tree.test.ts
2026-09-26 19:13:02 +02:00

68 lines
2.4 KiB
TypeScript

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']);
});
});