Something went wrong. Try again.
A local-first note taking app
Something went wrong. Try again.
4.8 kB · 158 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159import { describe, expect, it } from 'vitest';
import type { TilingNode } from '../../tiling/model';import type { OpenDocRequest } from '../workspace';import type { TileTabsMap } from './tabsModel';import { buildInitialTileTabs, maxIdSuffix, serializeLayout,} from './tilingPersistence';
function req(entryId: string): OpenDocRequest { return { providerId: 'fs', entryId, title: entryId };}
function splitRow( id: string, first: TilingNode, second: TilingNode,): TilingNode { return { kind: 'split', id, orientation: 'row', ratio: 0.5, first, second };}
describe('serializeLayout', () => { it('captures each tile’s documents and active index, skipping empty tabs', () => { const tree = splitRow( 'split-1', { kind: 'tile', id: 'tile-1' }, { kind: 'tile', id: 'tile-2' }, ); const tileTabs: TileTabsMap = { 'tile-1': { tabs: [ { tabId: 'tab-a', slot: { kind: 'loading', request: req('a') }, mode: 'edit', }, { tabId: 'tab-b', slot: { kind: 'loading', request: req('b') }, mode: 'view', }, ], activeTabId: 'tab-b', }, 'tile-2': { tabs: [{ tabId: 'tab-empty', slot: { kind: 'empty' }, mode: 'edit' }], activeTabId: 'tab-empty', }, };
const layout = serializeLayout(tree, 'tile-2', tileTabs); expect(layout.version).toBe(2); expect(layout.activeTileId).toBe('tile-2'); expect(layout.tree).toEqual(tree); // Per-tab mode is persisted alongside each document request. expect(layout.tiles).toEqual([ { tileId: 'tile-1', tabs: [ { request: req('a'), mode: 'edit' }, { request: req('b'), mode: 'view' }, ], activeIndex: 1, }, { tileId: 'tile-2', tabs: [], activeIndex: -1 }, ]); });});
describe('buildInitialTileTabs', () => { it('falls back to a single empty tile when there is nothing persisted', () => { const result = buildInitialTileTabs(null, 'tile-1'); expect(result.pending).toEqual([]); expect(result.map['tile-1'].tabs).toHaveLength(1); expect(result.map['tile-1'].tabs[0].slot).toEqual({ kind: 'empty' }); });
it('builds loading tabs and pending opens from persisted tiles', () => { const result = buildInitialTileTabs( [ { tileId: 'tile-1', tabs: [ { request: req('a'), mode: 'edit' }, { request: req('b'), mode: 'view' }, ], activeIndex: 1, }, { tileId: 'tile-2', tabs: [], activeIndex: -1 }, ], 'tile-1', );
// Two documents to open, all on tile-1. expect(result.pending.map((p) => p.request)).toEqual([req('a'), req('b')]); expect(result.pending.every((p) => p.tileId === 'tile-1')).toBe(true);
const tile1 = result.map['tile-1']; expect(tile1.tabs.map((t) => t.slot.kind)).toEqual(['loading', 'loading']); // Persisted per-tab mode is restored. expect(tile1.tabs.map((t) => t.mode)).toEqual(['edit', 'view']); // active index 1 -> second tab active. expect(tile1.activeTabId).toBe(tile1.tabs[1].tabId);
// Empty persisted tile becomes a fresh empty tile. expect(result.map['tile-2'].tabs[0].slot).toEqual({ kind: 'empty' });
// Counter advanced past every minted id (3 tabs total). expect(result.nextTabCounter).toBe(4); });
it('upgrades a v1 persisted tile (bare requests) to edit mode', () => { // v1 stored tabs as bare OpenDocRequests, with no mode field. const v1Tiles = [ { tileId: 'tile-1', tabs: [req('a')], activeIndex: 0 }, ] as unknown as Parameters<typeof buildInitialTileTabs>[0]; const result = buildInitialTileTabs(v1Tiles, 'tile-1'); expect(result.map['tile-1'].tabs.map((t) => t.mode)).toEqual(['edit']); expect(result.pending.map((p) => p.request)).toEqual([req('a')]); });
it('clamps an out-of-range active index', () => { const result = buildInitialTileTabs( [ { tileId: 'tile-1', tabs: [{ request: req('a'), mode: 'edit' }], activeIndex: 9, }, ], 'tile-1', ); expect(result.map['tile-1'].activeTabId).toBe( result.map['tile-1'].tabs[0].tabId, ); });});
describe('maxIdSuffix', () => { it('finds the largest numeric suffix across tile and split ids', () => { const tree = splitRow( 'split-7', { kind: 'tile', id: 'tile-2' }, splitRow( 'split-3', { kind: 'tile', id: 'tile-9' }, { kind: 'tile', id: 'tile-4' }, ), ); expect(maxIdSuffix(tree)).toBe(9); });
it('returns the suffix of a lone tile', () => { expect(maxIdSuffix({ kind: 'tile', id: 'tile-1' })).toBe(1); });});