本地 RAG 知识库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

86 lines
2.1 KiB

/**
* utils.ts 工具函数单元测试
*/
import { describe, it, expect, vi } from 'vitest';
import { escapeHtml, debounce, formatTime, uuid, shortUuid } from '../src/utils';
describe('escapeHtml', () => {
it('转义 HTML 特殊字符', () => {
expect(escapeHtml('<script>alert("xss")</script>')).toBe(
'&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;'
);
});
it('转义所有五种危险字符', () => {
expect(escapeHtml('&<>"\'')).toBe('&amp;&lt;&gt;&quot;&#x27;');
});
it('不修改安全文本', () => {
expect(escapeHtml('Hello World 你好世界')).toBe('Hello World 你好世界');
});
it('空字符串返回空字符串', () => {
expect(escapeHtml('')).toBe('');
});
});
describe('uuid', () => {
it('生成符合 UUID v4 格式的字符串', () => {
const id = uuid();
expect(id).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/);
});
it('两次生成不同的值', () => {
expect(uuid()).not.toBe(uuid());
});
});
describe('shortUuid', () => {
it('生成长度为 8 的字符串', () => {
expect(shortUuid()).toHaveLength(8);
});
});
describe('formatTime', () => {
it('格式化为 HH:mm', () => {
// 2026-01-15 14:30:00 UTC
const ts = new Date(2026, 0, 15, 14, 30, 0).getTime();
expect(formatTime(ts)).toBe('14:30');
});
it('补零处理', () => {
const ts = new Date(2026, 0, 1, 9, 5, 0).getTime();
expect(formatTime(ts)).toBe('09:05');
});
});
describe('debounce', () => {
it('延迟执行函数', async () => {
vi.useFakeTimers();
const fn = vi.fn();
const debounced = debounce(fn, 100);
debounced();
expect(fn).not.toHaveBeenCalled();
vi.advanceTimersByTime(100);
expect(fn).toHaveBeenCalledTimes(1);
vi.useRealTimers();
});
it('连续调用只执行最后一次', async () => {
vi.useFakeTimers();
const fn = vi.fn();
const debounced = debounce(fn, 100);
debounced();
debounced();
debounced();
vi.advanceTimersByTime(100);
expect(fn).toHaveBeenCalledTimes(1);
vi.useRealTimers();
});
});