Some checks reported errors
continuous-integration/drone/push Build was killed
- 搭建 api、auth、utils 等逻辑模块 - 通过 tsc、eslint、vitest 测试验证 BREAKING CHANGE: 新镜像分支
160 lines
3.8 KiB
TypeScript
160 lines
3.8 KiB
TypeScript
/**
|
|
* 测试工具函数
|
|
* 提供测试中常用的辅助函数
|
|
*/
|
|
|
|
import { vi } from 'vitest';
|
|
|
|
// 等待指定时间(和await一起用)
|
|
export function sleep(ms: number): Promise<void> {
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
}
|
|
|
|
// 等待下一个事件循环(和await一起用)
|
|
export function nextTick(): Promise<void> {
|
|
return new Promise(resolve => setTimeout(resolve, 0));
|
|
}
|
|
|
|
// 创建一个可控制的Promise(将promise的控制权提取到外部)
|
|
export function createControlledPromise<T = any>() {
|
|
// 用闭包把内部函数暴露到外部
|
|
let resolve: (value: T) => void;
|
|
let reject: (reason?: any) => void;
|
|
const promise = new Promise<T>((res, rej) => {
|
|
resolve = res;
|
|
reject = rej;
|
|
});
|
|
|
|
return {
|
|
promise,
|
|
resolve: resolve!,
|
|
reject: reject!
|
|
};
|
|
}
|
|
|
|
// 模拟localStorage(闭包)
|
|
export function createMockLocalStorage() {
|
|
let store: Record<string, string> = {};
|
|
|
|
return {
|
|
getItem: vi.fn((key: string) => store[key] || null),
|
|
setItem: vi.fn((key: string, value: string) => {
|
|
store[key] = value;
|
|
}),
|
|
removeItem: vi.fn((key: string) => {
|
|
delete store[key];
|
|
}),
|
|
clear: vi.fn(() => {
|
|
store = {};
|
|
}),
|
|
get length() {
|
|
return Object.keys(store).length;
|
|
},
|
|
key: vi.fn((index: number) => {
|
|
const keys = Object.keys(store);
|
|
return keys[index] || null;
|
|
})
|
|
};
|
|
}
|
|
|
|
// 模拟sessionStorage
|
|
export function createMockSessionStorage() {
|
|
return createMockLocalStorage();
|
|
}
|
|
|
|
// 创建一个可读写的流
|
|
// 创建一个可读写的事件流
|
|
export function createMockStream() {
|
|
const listeners: Record<string, Function[]> = {};
|
|
|
|
// 先创建对象引用
|
|
const stream = {
|
|
on: vi.fn((event: string, callback: Function) => {
|
|
if (!listeners[event]) {
|
|
listeners[event] = [];
|
|
}
|
|
listeners[event].push(callback);
|
|
return stream; // 使用对象引用而不是 this
|
|
}),
|
|
|
|
emit: vi.fn((event: string, ...args: any[]) => {
|
|
if (listeners[event]) {
|
|
listeners[event].forEach(callback => callback(...args));
|
|
}
|
|
return stream; // 使用对象引用
|
|
}),
|
|
|
|
once: vi.fn((event: string, callback: Function) => {
|
|
const onceWrapper = (...args: any[]) => {
|
|
callback(...args);
|
|
// 移除监听器
|
|
if (listeners[event]) {
|
|
listeners[event] = listeners[event].filter(cb => cb !== onceWrapper);
|
|
}
|
|
};
|
|
return stream.on(event, onceWrapper); // 使用对象引用
|
|
}),
|
|
|
|
removeListener: vi.fn((event: string, callback: Function) => {
|
|
if (listeners[event]) {
|
|
listeners[event] = listeners[event].filter(cb => cb !== callback);
|
|
}
|
|
return stream; // 使用对象引用
|
|
}),
|
|
|
|
removeAllListeners: vi.fn((event?: string) => {
|
|
if (event) {
|
|
delete listeners[event];
|
|
} else {
|
|
Object.keys(listeners).forEach(key => {
|
|
delete listeners[key];
|
|
});
|
|
}
|
|
return stream; // 使用对象引用
|
|
})
|
|
};
|
|
|
|
return stream;
|
|
}
|
|
|
|
// 模拟IntersectionObserver
|
|
export function createMockIntersectionObserver() {
|
|
const callbacks: Function[] = [];
|
|
|
|
return {
|
|
observe: vi.fn(),
|
|
unobserve: vi.fn(),
|
|
disconnect: vi.fn(),
|
|
root: null,
|
|
rootMargin: '',
|
|
thresholds: [],
|
|
constructor: vi.fn((callback: Function) => {
|
|
callbacks.push(callback);
|
|
return {
|
|
observe: vi.fn(),
|
|
unobserve: vi.fn(),
|
|
disconnect: vi.fn()
|
|
};
|
|
})
|
|
};
|
|
}
|
|
|
|
// 模拟ResizeObserver
|
|
export function createMockResizeObserver() {
|
|
const callbacks: Function[] = [];
|
|
|
|
return {
|
|
observe: vi.fn(),
|
|
unobserve: vi.fn(),
|
|
disconnect: vi.fn(),
|
|
constructor: vi.fn((callback: Function) => {
|
|
callbacks.push(callback);
|
|
return {
|
|
observe: vi.fn(),
|
|
unobserve: vi.fn(),
|
|
disconnect: vi.fn()
|
|
};
|
|
})
|
|
};
|
|
}
|