- 新增布局管理器支持拖拽调整面板宽度 - 新增状态管理器实现布局持久化 - 重构前端页面结构优化四栏式布局 - 新增 Jest 测试框架和完整测试用例 - 完善项目文档(PRD/FD/TDD/TODO/LOG) - 清理 Python 缓存文件并更新 .gitignore Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
114 lines
2.2 KiB
JavaScript
114 lines
2.2 KiB
JavaScript
/**
|
|
* Jest 测试环境设置
|
|
* 模拟浏览器 API 和 DOM 环境
|
|
*/
|
|
|
|
// 模拟 localStorage
|
|
class LocalStorageMock {
|
|
constructor() {
|
|
this.store = {};
|
|
}
|
|
|
|
clear() {
|
|
this.store = {};
|
|
}
|
|
|
|
getItem(key) {
|
|
return this.store[key] || null;
|
|
}
|
|
|
|
setItem(key, value) {
|
|
this.store[key] = String(value);
|
|
}
|
|
|
|
removeItem(key) {
|
|
delete this.store[key];
|
|
}
|
|
|
|
get length() {
|
|
return Object.keys(this.store).length;
|
|
}
|
|
|
|
key(index) {
|
|
const keys = Object.keys(this.store);
|
|
return keys[index] || null;
|
|
}
|
|
}
|
|
|
|
global.localStorage = new LocalStorageMock();
|
|
// jsdom 环境下 window.localStorage 可能是独立实例;这里统一指向 mock,避免跨用例污染
|
|
try {
|
|
if (typeof window !== 'undefined') {
|
|
Object.defineProperty(window, 'localStorage', {
|
|
configurable: true,
|
|
value: global.localStorage
|
|
});
|
|
}
|
|
} catch (_) {
|
|
// ignore
|
|
}
|
|
|
|
// 模拟主应用的 toast(避免 LayoutManager.notify() 退化到 window.alert,触发 jsdom 的 not implemented 报错)
|
|
global.showToast = () => {};
|
|
try {
|
|
if (typeof window !== 'undefined') {
|
|
window.showToast = global.showToast;
|
|
}
|
|
} catch (_) {
|
|
// ignore
|
|
}
|
|
|
|
// 模拟 requestAnimationFrame
|
|
global.requestAnimationFrame = (callback) => {
|
|
return setTimeout(callback, 16);
|
|
};
|
|
|
|
global.cancelAnimationFrame = (id) => {
|
|
clearTimeout(id);
|
|
};
|
|
|
|
// 模拟 performance.now
|
|
if (!global.performance) {
|
|
global.performance = {};
|
|
}
|
|
global.performance.now = () => Date.now();
|
|
|
|
// 模拟 CSS.supports
|
|
if (!global.CSS) {
|
|
global.CSS = {};
|
|
}
|
|
global.CSS.supports = (property, value) => {
|
|
// 简单模拟,假设支持所有现代 CSS 特性
|
|
return true;
|
|
};
|
|
|
|
// 模拟 getComputedStyle
|
|
global.getComputedStyle = (element) => {
|
|
return {
|
|
getPropertyValue: (prop) => {
|
|
if (
|
|
element &&
|
|
element.style &&
|
|
typeof element.style.getPropertyValue === 'function'
|
|
) {
|
|
return element.style.getPropertyValue(prop) || '';
|
|
}
|
|
return '';
|
|
}
|
|
};
|
|
};
|
|
|
|
// 清理函数
|
|
afterEach(() => {
|
|
// 清空 localStorage
|
|
localStorage.clear();
|
|
|
|
// 清空 document.body
|
|
document.body.innerHTML = '';
|
|
|
|
// 重置 CSS 变量
|
|
if (document.documentElement.style) {
|
|
document.documentElement.style.cssText = '';
|
|
}
|
|
});
|