Files
obelisk/tests/session-reader-state.test.mjs
T

89 lines
2.9 KiB
JavaScript
Raw Normal View History

import { test } from 'node:test';
import assert from 'node:assert/strict';
import { createSessionReaderStateCache } from '../app/src/renderer/src/session-reader-state.mjs';
import { resolveReaderAnchorIndex } from '../app/src/renderer/src/session-timeline-viewport.mjs';
test('reader state cache stores only semantic state in independent session snapshots', () => {
const cache = createSessionReaderStateCache({ maxEntries: 4 });
cache.set('session-a', {
mode: 'anchor',
anchor: {
itemKey: 'message:a-120',
messageUuid: 'a-120',
offset: 18,
fallbackIndex: 120,
},
disclosures: [{ key: 'tool:a-call', messageUuid: 'a-120', open: true, raw: false }],
expandedMessageIds: ['a-120'],
scrollTop: 98_000,
currentMsgIdx: 120,
});
const restored = cache.get('session-a');
assert.deepEqual(restored, {
mode: 'anchor',
anchor: {
itemKey: 'message:a-120',
messageUuid: 'a-120',
offset: 18,
fallbackIndex: 120,
},
disclosures: [{ key: 'tool:a-call', messageUuid: 'a-120', open: true, raw: false }],
expandedMessageIds: ['a-120'],
});
assert.equal(cache.get('session-b'), null);
restored.anchor.offset = 999;
restored.disclosures[0].open = false;
restored.expandedMessageIds.push('mutated');
assert.equal(cache.get('session-a').anchor.offset, 18);
assert.equal(cache.get('session-a').disclosures[0].open, true);
assert.deepEqual(cache.get('session-a').expandedMessageIds, ['a-120']);
});
test('reader state cache evicts the least recently used session', () => {
const cache = createSessionReaderStateCache({ maxEntries: 2 });
const state = messageUuid => ({
mode: 'anchor',
anchor: { itemKey: `message:${messageUuid}`, messageUuid, offset: 0, fallbackIndex: 0 },
});
cache.set('session-a', state('a'));
cache.set('session-b', state('b'));
cache.get('session-a');
cache.set('session-c', state('c'));
assert.equal(cache.get('session-b'), null);
assert.equal(cache.get('session-a').anchor.messageUuid, 'a');
assert.equal(cache.get('session-c').anchor.messageUuid, 'c');
});
test('reader anchors resolve by stable identity before falling back to position', () => {
const items = [
{ key: 'message:first', messageUuid: 'first' },
{ key: 'workflow:shared', messageUuid: 'shared' },
{ key: 'message:shared', messageUuid: 'shared' },
{ key: 'message:last', messageUuid: 'last' },
];
assert.equal(resolveReaderAnchorIndex({
itemKey: 'message:shared',
messageUuid: 'shared',
fallbackIndex: 0,
}, items), 2);
assert.equal(resolveReaderAnchorIndex({
itemKey: 'missing',
messageUuid: 'shared',
fallbackIndex: 0,
}, items), 1);
assert.equal(resolveReaderAnchorIndex({
itemKey: 'missing',
messageUuid: 'missing',
fallbackIndex: 99,
}, items), 3);
assert.equal(resolveReaderAnchorIndex(null, items), 0);
assert.equal(resolveReaderAnchorIndex(null, []), null);
});