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