diff --git a/docs/.vitepress/theme/utils/readingBookmark.test.js b/docs/.vitepress/theme/utils/readingBookmark.test.js index fd47186..1e0e15e 100644 --- a/docs/.vitepress/theme/utils/readingBookmark.test.js +++ b/docs/.vitepress/theme/utils/readingBookmark.test.js @@ -23,6 +23,23 @@ const createStorage = () => { } describe('reading bookmarks', () => { + it('uses root path defaults for missing path values', () => { + const storage = createStorage() + const bookmark = createReadingBookmark({ + title: ' Root page ', + section: ' Intro ' + }) + + assert.equal(bookmark.path, '/') + assert.equal(bookmark.title, 'Root page') + assert.equal(bookmark.section, 'Intro') + assert.equal(Number.isFinite(bookmark.updatedAt), true) + assert.equal(getReadingBookmarkKey(), 'ev-reading-bookmark:/') + + assert.equal(writeReadingBookmark(storage, bookmark), true) + assert.equal(readReadingBookmark(storage, undefined).path, '/') + }) + it('stores bookmarks by full path so each locale is independent', () => { const storage = createStorage() const zhBookmark = createReadingBookmark({ @@ -119,6 +136,26 @@ describe('reading bookmarks', () => { updatedAt: 1 } ) + + assert.deepEqual( + createReadingBookmark({ + path: '/easy-vibe/ja-jp/page/', + title: null, + section: null, + scrollY: Number.NaN, + progress: Number.NaN, + now: () => 2 + }), + { + version: 1, + path: '/easy-vibe/ja-jp/page/', + title: '', + section: '', + scrollY: 0, + progress: 0, + updatedAt: 2 + } + ) }) it('ignores malformed or mismatched stored values', () => { @@ -143,6 +180,33 @@ describe('reading bookmarks', () => { readReadingBookmark(storage, '/easy-vibe/ko-kr/page/', 1000), null ) + + storage.setItem( + getReadingBookmarkKey('/easy-vibe/ko-kr/page/'), + JSON.stringify(null) + ) + assert.equal( + readReadingBookmark(storage, '/easy-vibe/ko-kr/page/', 1000), + null + ) + + storage.setItem(getReadingBookmarkKey('/easy-vibe/ko-kr/page/'), '42') + assert.equal( + readReadingBookmark(storage, '/easy-vibe/ko-kr/page/', 1000), + null + ) + + storage.setItem( + getReadingBookmarkKey('/easy-vibe/ko-kr/page/'), + JSON.stringify({ + version: 2, + path: '/easy-vibe/ko-kr/page/' + }) + ) + assert.equal( + readReadingBookmark(storage, '/easy-vibe/ko-kr/page/', 1000), + null + ) }) it('clamps restored scroll position to current document height', () => { @@ -161,4 +225,62 @@ describe('reading bookmarks', () => { assert.equal(readReadingBookmark(storage, path, 640).scrollY, 640) }) + + it('normalizes sparse stored bookmark values', () => { + const storage = createStorage() + const path = '/easy-vibe/es-es/page/' + + storage.setItem( + getReadingBookmarkKey(path), + JSON.stringify({ + version: 1, + path, + scrollY: 20, + progress: -50 + }) + ) + + assert.deepEqual(readReadingBookmark(storage, path, -1), { + version: 1, + path, + title: '', + section: '', + scrollY: 0, + progress: 0, + updatedAt: 0 + }) + }) + + it('returns null when storage is missing, empty, or throws', () => { + assert.equal(readReadingBookmark(null, '/missing/'), null) + assert.equal(readReadingBookmark(createStorage(), '/missing/'), null) + assert.equal( + readReadingBookmark( + { + getItem() { + throw new Error('storage read failed') + } + }, + '/missing/' + ), + null + ) + }) + + it('returns false when bookmark cannot be written', () => { + assert.equal(writeReadingBookmark(null, { path: '/x/' }), false) + assert.equal(writeReadingBookmark(createStorage(), null), false) + assert.equal(writeReadingBookmark(createStorage(), { path: '' }), false) + assert.equal( + writeReadingBookmark( + { + setItem() { + throw new Error('storage write failed') + } + }, + createReadingBookmark({ path: '/x/' }) + ), + false + ) + }) }) diff --git a/package.json b/package.json index 33ff7ec..400425c 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,8 @@ "build": "npm run sitemap && vitepress build docs", "build:force": "npm run sitemap && vitepress build docs --force", "preview": "vitepress preview docs", + "test": "node --test $(find docs scripts -name '*.test.js' -print)", + "test:coverage": "node --test --experimental-test-coverage --test-coverage-lines=100 --test-coverage-branches=100 --test-coverage-functions=100 $(find docs scripts -name '*.test.js' -print)", "format": "prettier --write .", "verify": "bash scripts/verify.sh", "lint": "eslint docs/.vitepress/theme",