This commit is contained in:
2026-10-21 14:42:59 +08:00
commit 954236d3f9
399 changed files with 85885 additions and 0 deletions

View File

@@ -0,0 +1,143 @@
// tests/unit/renderer/components/list-panel-width-policy.test.ts
//
// 守左侧列表面板(文献/笔记 Tab)的宽度策略(r175 起,r241 改默认值):
//
// 1) 数值本身:min=200、default=300、max=720。
// (r241:用户第二次说「左侧栏默认宽度可以稍微宽一些」⇒ default 280→300;
// min / max 不动 —— 拖宽天花板保留,最小宽度不动)
// 2) **storageKey 升版** —— 每次改默认值都必须换 key。原因:hook 的
// [width] effect 会把当前宽度(含首次挂载时的默认值)落盘到 localStorage
// ⇒ 「默认值」第一次运行后就被固化。只改常量不改 key ⇒ 存量用户永远
// 看不到新默认(r175 / r238 / r241 各踩过一次)。
// 3) **定向迁移** —— 升版的同时把旧 key 里「用户真拖过」的宽度搬到新 key;
// 等于旧默认(280)的那个值视为自动落盘,不迁移 ⇒ 新默认生效。
// 这比 r175 的「纯升版,手动偏好一起重置」更友好。
import { describe, expect, it, beforeEach, afterEach } from 'vitest';
import { renderHook, act, cleanup } from '@testing-library/react';
import {
LIST_PANEL_MIN,
LIST_PANEL_MAX,
LIST_PANEL_DEFAULT,
LIST_PANEL_WIDTH_KEY,
LEGACY_LIST_PANEL_WIDTH_KEY,
migrateLegacyListPanelWidth,
} from '../../../../src/renderer/src/components/layout/list-panel-width';
import { useResizablePanel } from '../../../../src/renderer/src/hooks/useResizablePanel';
function mountPanel(storageKey: string = LIST_PANEL_WIDTH_KEY) {
return renderHook(() =>
useResizablePanel({
storageKey,
defaultWidth: LIST_PANEL_DEFAULT,
min: LIST_PANEL_MIN,
max: LIST_PANEL_MAX,
side: 'left',
}),
);
}
describe('左侧列表面板宽度策略(r241)', () => {
beforeEach(() => {
localStorage.clear();
});
afterEach(() => {
cleanup();
localStorage.clear();
});
it('min / default / max 关系合法', () => {
expect(LIST_PANEL_MIN).toBeGreaterThan(0);
expect(LIST_PANEL_DEFAULT).toBeGreaterThanOrEqual(LIST_PANEL_MIN);
expect(LIST_PANEL_MAX).toBeGreaterThan(LIST_PANEL_DEFAULT);
});
it('默认宽度 = 300(r241:280→300),min 200 / max 720 不动', () => {
expect(LIST_PANEL_MIN).toBe(200);
expect(LIST_PANEL_DEFAULT).toBe(300);
expect(LIST_PANEL_MAX).toBe(720);
});
it('storageKey 已升版 —— v3 旧 key 不再被直接读取', () => {
expect(LIST_PANEL_WIDTH_KEY).not.toBe(LEGACY_LIST_PANEL_WIDTH_KEY);
expect(LIST_PANEL_WIDTH_KEY).toBe('workbench.listPanel.width.v4');
expect(LEGACY_LIST_PANEL_WIDTH_KEY).toBe('workbench.listPanel.width.v3');
});
it('无偏好时用默认宽度', () => {
const { result } = mountPanel();
expect(result.current.width).toBe(LIST_PANEL_DEFAULT);
});
it('新 key 里越界的旧值被丢弃 → 回落默认', () => {
localStorage.setItem(LIST_PANEL_WIDTH_KEY, '1500');
const { result } = mountPanel();
expect(result.current.width).toBe(LIST_PANEL_DEFAULT);
});
it('新 key 里的合法偏好被保留(手动拖过的宽度不丢)', () => {
localStorage.setItem(LIST_PANEL_WIDTH_KEY, '400');
const { result } = mountPanel();
expect(result.current.width).toBe(400);
});
it('setWidth 夹紧到 [min, max] —— 最小宽度真的生效', () => {
const { result } = mountPanel();
act(() => result.current.setWidth(10));
expect(result.current.width).toBe(LIST_PANEL_MIN);
act(() => result.current.setWidth(99999));
expect(result.current.width).toBe(LIST_PANEL_MAX);
});
});
describe('v3 → v4 定向迁移(r241)', () => {
beforeEach(() => {
localStorage.clear();
});
afterEach(() => {
cleanup();
localStorage.clear();
});
it('v3 里「用户真拖过」的宽度被搬到 v4', () => {
localStorage.setItem(LEGACY_LIST_PANEL_WIDTH_KEY, '400');
migrateLegacyListPanelWidth();
expect(localStorage.getItem(LIST_PANEL_WIDTH_KEY)).toBe('400');
});
it('v3 里等于旧默认 280 的值不迁移 ⇒ 新默认 300 生效', () => {
localStorage.setItem(LEGACY_LIST_PANEL_WIDTH_KEY, '280');
migrateLegacyListPanelWidth();
expect(localStorage.getItem(LIST_PANEL_WIDTH_KEY)).toBeNull();
const { result } = mountPanel();
expect(result.current.width).toBe(LIST_PANEL_DEFAULT);
});
it('v4 已有值时不覆盖(幂等 —— 不推翻新 key 下已有的偏好)', () => {
localStorage.setItem(LIST_PANEL_WIDTH_KEY, '360');
localStorage.setItem(LEGACY_LIST_PANEL_WIDTH_KEY, '400');
migrateLegacyListPanelWidth();
expect(localStorage.getItem(LIST_PANEL_WIDTH_KEY)).toBe('360');
});
it('v3 里越界的脏值不迁移', () => {
localStorage.setItem(LEGACY_LIST_PANEL_WIDTH_KEY, '1500');
migrateLegacyListPanelWidth();
expect(localStorage.getItem(LIST_PANEL_WIDTH_KEY)).toBeNull();
});
it('v3 缺失(全新安装)⇒ 不迁移,直接用新默认', () => {
migrateLegacyListPanelWidth();
expect(localStorage.getItem(LIST_PANEL_WIDTH_KEY)).toBeNull();
const { result } = mountPanel();
expect(result.current.width).toBe(LIST_PANEL_DEFAULT);
});
it('v2 及更早的 key 不再参与迁移(只认上一版 v3)', () => {
// v2 是 r238 之前的 key —— r241 的迁移源是 v3。
// 若实现误把 v2 也当来源,r238 时代「手动拖过 400」的老用户会在
// 两次升版后被重新当成有效偏好(本该在 r238 就处理完)。
localStorage.setItem('workbench.listPanel.width.v2', '400');
migrateLegacyListPanelWidth();
expect(localStorage.getItem(LIST_PANEL_WIDTH_KEY)).toBeNull();
});
});