Files
UHD_Media_Tool/packages/adapters/src/sites/rate-limit.test.ts
T
rootandClaude Opus 5.5 d9f2af2f3c feat(adapters): port MoviePilot open site framework (7 spiders, 20 user parsers) + MovieClaw v0.27.0 site definitions + mp-sync tools (W1-3c)
- sites/spiders: Haidan/HDDolby/RousiPro/SunnyPT/TNode/TorrentLeech/Yema (+mTorrent wrapper), specialized SiteAdapter, indirect download resolved at download time
- sites/user-parsers: SiteParserBase + all 20 MP SiteSchema parsers (lxml XPath via xpath+xmldom), refreshSiteUserData with schema fallback
- sites/definitions: zod SiteDefinition schemas, 23 MovieClaw v0.27.0 (MIT) definitions via scripts/mp-sync/movieclaw-import.mjs, registry getSiteDefinition/listSiteDefinitions, NOTICE
- scripts/mp-sync: ledger.json (upstream sha256), check.mjs, build-ledger.mjs; docs/porting/mp-sync-ledger.md
- license-and-provenance: add copied-mit kind, re-anchor MovieClaw rows to v0.27.0

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 18:39:27 +08:00

51 lines
1.7 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { createSiteRateLimiter } from "./rate-limit.ts";
import { parseSizeMp as parseSize } from "./spider/spider.ts";
import { parseCount, parseSiteTime } from "./util.ts";
describe("站点令牌桶", () => {
it("burst 内不等待,之后按间隔补充;penalize 顺延;并发按顺序排队", async () => {
let clock = 0;
const sleeps: number[] = [];
const l = createSiteRateLimiter({
minIntervalMs: 1000,
burst: 2,
now: () => clock,
sleep: async (ms) => {
sleeps.push(ms);
clock += ms;
},
});
await Promise.all([l.acquire(), l.acquire(), l.acquire()]);
expect(sleeps).toEqual([1000]);
l.penalize(5000);
expect(l.tryAcquire()).toBe(false);
await l.acquire();
expect(sleeps.at(-1)).toBe(5000);
});
it("取消等待", async () => {
const l = createSiteRateLimiter({ minIntervalMs: 60_000 });
await l.acquire();
const ac = new AbortController();
const p = l.acquire(ac.signal);
ac.abort(new Error("cancelled"));
await expect(p).rejects.toThrow("cancelled");
});
});
describe("解析辅助", () => {
it("parseSize/parseCount/parseSiteTime", () => {
expect(parseSize("78.42 GB")).toBe(84202833838);
expect(parseSize("850 KB")).toBe(870400);
expect(parseSize("n/a")).toBe(0);
expect(parseSize("1,234.56 MiB")).toBe(1294529987);
expect(parseSize("2.1 TB")).toBe(2308974418330);
expect(parseCount("1,204")).toBe(1204);
expect(parseCount("532 / 3")).toBe(532);
expect(parseCount("--")).toBeNull();
expect(parseSiteTime("2026-09-26 21:14:03", "+08:00")).toBe("2026-09-26T13:14:03.000Z");
expect(parseSiteTime("3小时前", "+08:00")).toBeNull();
});
});