useChapterListCollapse 用 localStorage 记忆折叠态(SSR 首帧恒展开避免 hydration 不一致);收起降为带展开按钮的窄轨、让宽给正文,展开时标题旁加收起按钮;三栏栅格据折叠态切列宽,章节列表/高亮/切章导航全保留。
65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
// @vitest-environment jsdom
|
||
import { act, renderHook } from "@testing-library/react";
|
||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||
|
||
import {
|
||
CHAPTER_LIST_COLLAPSE_KEY,
|
||
useChapterListCollapse,
|
||
} from "./useChapterListCollapse";
|
||
|
||
// 本仓库 jsdom 未提供可用的 Storage(setItem/clear 缺失),装一个内存版 localStorage。
|
||
function installMemoryStorage(): Storage {
|
||
const map = new Map<string, string>();
|
||
const storage: Storage = {
|
||
get length() {
|
||
return map.size;
|
||
},
|
||
clear: () => map.clear(),
|
||
getItem: (key) => (map.has(key) ? (map.get(key) ?? null) : null),
|
||
key: (index) => Array.from(map.keys())[index] ?? null,
|
||
removeItem: (key) => map.delete(key),
|
||
setItem: (key, value) => map.set(key, String(value)),
|
||
};
|
||
Object.defineProperty(window, "localStorage", {
|
||
value: storage,
|
||
configurable: true,
|
||
});
|
||
return storage;
|
||
}
|
||
|
||
describe("useChapterListCollapse", () => {
|
||
beforeEach(() => {
|
||
installMemoryStorage();
|
||
});
|
||
afterEach(() => {
|
||
window.localStorage.clear();
|
||
});
|
||
|
||
it("默认展开(无存档时 collapsed=false)", () => {
|
||
const { result } = renderHook(() => useChapterListCollapse());
|
||
expect(result.current.collapsed).toBe(false);
|
||
});
|
||
|
||
it("toggle 翻转并把状态写入 localStorage", () => {
|
||
const { result } = renderHook(() => useChapterListCollapse());
|
||
|
||
act(() => result.current.toggle());
|
||
|
||
expect(result.current.collapsed).toBe(true);
|
||
expect(window.localStorage.getItem(CHAPTER_LIST_COLLAPSE_KEY)).toBe("1");
|
||
|
||
act(() => result.current.toggle());
|
||
|
||
expect(result.current.collapsed).toBe(false);
|
||
expect(window.localStorage.getItem(CHAPTER_LIST_COLLAPSE_KEY)).toBe("0");
|
||
});
|
||
|
||
it("挂载时从 localStorage 恢复已收起状态", () => {
|
||
window.localStorage.setItem(CHAPTER_LIST_COLLAPSE_KEY, "1");
|
||
|
||
const { result } = renderHook(() => useChapterListCollapse());
|
||
|
||
expect(result.current.collapsed).toBe(true);
|
||
});
|
||
});
|