Files
story/web/test/memoir-reading.test.mjs
T
Codex Local bf1233d5df
ci / verify (push) Canceled after 0s
feat: expand companion platform, device controls, and memoir workflows
Add customer and operator login, BLE provisioning, device fleet controls, call memory, memoir generation, and refreshed family and maintenance portals. Include API contracts, migrations, firmware sources, tests, assets, and deployment documentation.
2026-10-08 10:06:44 +08:00

40 lines
2.6 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { memoirTimeline, readMemoirMode, saveMemoirMode } from '../src/pages/memoir-reading.ts';
const chapter = (event_time, story_id) => ({ event_time, story_id, title: story_id, paragraphs: ['正文'], caption: '' });
test('timeline uses explicit years, keeps chapter indices and groups multiple stories without changing the book', () => {
const chapters = [chapter('1982年', 'a'), chapter('约1964年', 'b'), chapter('1968年夏天', 'c'), chapter('小时候', 'd')];
const original = structuredClone(chapters);
assert.deepEqual(memoirTimeline(chapters).map(group => [group.label, group.indices]), [['1960 年代', [1, 2]], ['1980 年代', [0]], ['时间未明确', [3]]]);
assert.deepEqual(chapters, original);
});
test('cross-decade ranges and unknown dates never become invented exact years or life stages', () => {
const groups = memoirTimeline([chapter('1968年至1982年', 'a'), chapter('年轻的时候', 'b'), chapter('', 'c'), chapter('1972—1976年', 'd')]);
assert.deepEqual(groups.map(group => [group.label, group.indices]), [['1970 年代', [3]], ['跨年代往事', [0]], ['时间未明确', [1, 2]]]);
assert.deepEqual(memoirTimeline([]), []);
});
test('mode preferences are scoped by elder and invalid stored values fall back to book', () => {
const previous = Object.getOwnPropertyDescriptor(globalThis, 'localStorage');
const values = new Map();
Object.defineProperty(globalThis, 'localStorage', { configurable: true, value: { getItem: key => values.get(key), setItem: (key, value) => values.set(key, value) } });
try {
saveMemoirMode('elder-a', 'timeline');
assert.equal(readMemoirMode('elder-a'), 'timeline');
assert.equal(readMemoirMode('elder-b'), 'book');
values.set('memoir-reading-mode:v1:elder-a', 'bad-mode');
assert.equal(readMemoirMode('elder-a'), 'book');
assert.deepEqual([...values.keys()], ['memoir-reading-mode:v1:elder-a']);
} finally { if (previous) Object.defineProperty(globalThis, 'localStorage', previous); else delete globalThis.localStorage; }
});
test('unavailable browser storage does not block reading or switching', () => {
const previous = Object.getOwnPropertyDescriptor(globalThis, 'localStorage');
Object.defineProperty(globalThis, 'localStorage', { configurable: true, get: () => { throw new Error('blocked'); } });
try { assert.equal(readMemoirMode('elder'), 'book'); assert.doesNotThrow(() => saveMemoirMode('elder', 'scroll')); }
finally { if (previous) Object.defineProperty(globalThis, 'localStorage', previous); else delete globalThis.localStorage; }
});