mirror of
https://github.com/kmc7468/arkvault.git
synced 2026-11-04 08:10:28 +09:00
상위 디렉터리 및 카테고리의 소유권을 검증하지 않던 문제 등 버그 수정 및 Vitest 기반 테스트 추가
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
67989f4741
commit
ed732be999
31 files changed
+2057
-42
No files matched your search
@@ -0,0 +1,92 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { BoundedQueue, Scheduler } from "#lib/utils/concurrency/index.js";
|
||||
|
||||
const tick = () => new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
describe("BoundedQueue", () => {
|
||||
it("blocks producers while full", async () => {
|
||||
const queue = new BoundedQueue<number>(2);
|
||||
await queue.push(1);
|
||||
await queue.push(2);
|
||||
|
||||
let isPushed = false;
|
||||
const pushing = queue.push(3).then(() => (isPushed = true));
|
||||
await tick();
|
||||
expect(isPushed).toBe(false);
|
||||
|
||||
expect(await queue.pop()).toBe(1);
|
||||
await pushing;
|
||||
expect(isPushed).toBe(true);
|
||||
});
|
||||
|
||||
it("drains remaining items and then returns null after closing", async () => {
|
||||
const queue = new BoundedQueue<number>(2);
|
||||
await queue.push(1);
|
||||
queue.close();
|
||||
|
||||
expect(await queue.pop()).toBe(1);
|
||||
expect(await queue.pop()).toBeNull();
|
||||
await expect(queue.push(2)).rejects.toThrow("Queue closed");
|
||||
});
|
||||
|
||||
it("wakes up waiting consumers when closed", async () => {
|
||||
const queue = new BoundedQueue<number>(1);
|
||||
const popping = queue.pop();
|
||||
queue.close();
|
||||
expect(await popping).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Scheduler", () => {
|
||||
it("defers tasks while the memory limit is exceeded", async () => {
|
||||
const scheduler = new Scheduler<void>(100);
|
||||
const events: string[] = [];
|
||||
|
||||
let finishFirst!: () => void;
|
||||
const first = scheduler.schedule(100, async () => {
|
||||
events.push("first:start");
|
||||
await new Promise<void>((resolve) => (finishFirst = resolve));
|
||||
events.push("first:end");
|
||||
});
|
||||
const second = scheduler.schedule(10, async () => {
|
||||
events.push("second:start");
|
||||
});
|
||||
|
||||
await tick();
|
||||
expect(events).toEqual(["first:start"]);
|
||||
|
||||
finishFirst();
|
||||
await Promise.all([first, second]);
|
||||
expect(events).toEqual(["first:start", "first:end", "second:start"]);
|
||||
});
|
||||
|
||||
it("runs small tasks concurrently", async () => {
|
||||
const scheduler = new Scheduler<number>(100);
|
||||
let running = 0;
|
||||
let maxRunning = 0;
|
||||
|
||||
await Promise.all(
|
||||
[1, 2, 3].map((value) =>
|
||||
scheduler.schedule(10, async () => {
|
||||
maxRunning = Math.max(maxRunning, ++running);
|
||||
await tick();
|
||||
running--;
|
||||
return value;
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
expect(maxRunning).toBe(3);
|
||||
});
|
||||
|
||||
it("releases memory when a task fails", async () => {
|
||||
const scheduler = new Scheduler<void>(100);
|
||||
await expect(
|
||||
scheduler.schedule(100, async () => {
|
||||
throw new Error("Failed");
|
||||
}),
|
||||
).rejects.toThrow("Failed");
|
||||
|
||||
await expect(scheduler.schedule(100, async () => {})).resolves.toBeUndefined();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user