This commit is contained in:
2026-10-16 16:34:15 +08:00
parent 7a3769670b
commit ff366a4daf
80 changed files with 9961 additions and 888 deletions

View File

@@ -0,0 +1,59 @@
// P2-7(audit):app:open-config-dir 高频调用检测。
//
// 设计:main/audit-rate.js 提供 createAuditRateTracker({ windowMs, threshold, now })
// 返回 hit(key) → { count, exceeded }。滑动窗口按 key 计数:
// - 窗口内 count ≤ threshold → exceeded=false
// - 窗口内 count > threshold → exceeded=true(调用方据此 console.warn)
// - 超过 windowMs 的旧记录自动过期
//
// now 可注入(Date.now 默认),方便单测推进时间。
import { describe, it, expect } from 'vitest';
const { createAuditRateTracker } = require('../../main/audit-rate.js');
describe('createAuditRateTracker —— P2-7 高频调用检测', () => {
it('首次调用 count=1,不 exceeded', () => {
const t = createAuditRateTracker({ windowMs: 60_000, threshold: 5 });
expect(t.hit('k')).toEqual({ count: 1, exceeded: false });
});
it('窗口内累计到 threshold 不 exceeded,超过则 exceeded', () => {
let now = 1000;
const t = createAuditRateTracker({ windowMs: 60_000, threshold: 3, now: () => now });
expect(t.hit('k').exceeded).toBe(false); // 1
expect(t.hit('k').exceeded).toBe(false); // 2
expect(t.hit('k').exceeded).toBe(false); // 3
const fourth = t.hit('k'); // 4 > 3
expect(fourth.count).toBe(4);
expect(fourth.exceeded).toBe(true);
});
it('不同 key 独立计数', () => {
const t = createAuditRateTracker({ windowMs: 60_000, threshold: 1 });
t.hit('a');
expect(t.hit('b')).toEqual({ count: 1, exceeded: false });
});
it('超过 windowMs 的旧记录过期,重新计数', () => {
let now = 0;
const t = createAuditRateTracker({ windowMs: 1000, threshold: 2, now: () => now });
t.hit('k'); // t=0
t.hit('k'); // t=0, count=2
expect(t.hit('k').exceeded).toBe(true); // t=0, count=3
now = 1500; // 滑出窗口
expect(t.hit('k')).toEqual({ count: 1, exceeded: false });
});
it('边界:恰好 windowMs 的时间点视为过期([now-window, now) 语义)', () => {
let now = 0;
const t = createAuditRateTracker({ windowMs: 1000, threshold: 1, now: () => now });
t.hit('k'); // t=0
now = 1000; // 恰好 1000ms 后
expect(t.hit('k')).toEqual({ count: 1, exceeded: false });
});
it('默认 now=Date.now,不抛错', () => {
const t = createAuditRateTracker({ windowMs: 1000, threshold: 1 });
expect(() => t.hit('k')).not.toThrow();
});
});