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.
113 lines
3.3 KiB
113 lines
3.3 KiB
import type { WaitingProcess } from "../src/util/RequestBatcher.js";
|
|
import { RequestBatcher } from "../src/util/RequestBatcher.js";
|
|
import { describe, it, expect, vi } from "vitest";
|
|
|
|
describe("RequestBatcher", () => {
|
|
type ReadWaitingProcess = WaitingProcess<[string], string>;
|
|
|
|
it("Batches a request", async () => {
|
|
const requestBatcher = new RequestBatcher({ batchMillis: 500 });
|
|
const perform = async (input: string): Promise<string> => {
|
|
await wait(100);
|
|
return `Hello ${input}`;
|
|
};
|
|
const perform1 = vi.fn(perform);
|
|
const perform2 = vi.fn(perform);
|
|
const perform3 = vi.fn((input: string): Promise<string> => {
|
|
expect(requestBatcher.isLoading("read")).toBe(true);
|
|
return perform(input);
|
|
});
|
|
const perform4 = vi.fn(perform);
|
|
|
|
const modifyQueue = (queue, currentlyProcessing, input: [string]) => {
|
|
const last = queue[queue.length - 1];
|
|
if (last?.name === "read") {
|
|
(last as ReadWaitingProcess).args[0] += input;
|
|
return last;
|
|
}
|
|
return undefined;
|
|
};
|
|
|
|
let return1: string = "";
|
|
let return2: string = "";
|
|
let return3: string = "";
|
|
let return4: string = "";
|
|
|
|
expect(requestBatcher.isLoading("read")).toBe(false);
|
|
|
|
await Promise.all([
|
|
requestBatcher
|
|
.queueProcess<[string], string>({
|
|
name: "read",
|
|
args: ["a"],
|
|
perform: perform1,
|
|
modifyQueue,
|
|
})
|
|
.then((val) => (return1 = val)),
|
|
requestBatcher
|
|
.queueProcess<[string], string>({
|
|
name: "read",
|
|
args: ["b"],
|
|
perform: perform2,
|
|
modifyQueue,
|
|
})
|
|
.then((val) => (return2 = val)),
|
|
,
|
|
requestBatcher
|
|
.queueProcess<[string], string>({
|
|
name: "read",
|
|
args: ["c"],
|
|
perform: perform3,
|
|
modifyQueue,
|
|
})
|
|
.then((val) => (return3 = val)),
|
|
,
|
|
requestBatcher
|
|
.queueProcess<[string], string>({
|
|
name: "read",
|
|
args: ["d"],
|
|
perform: perform4,
|
|
modifyQueue,
|
|
})
|
|
.then((val) => (return4 = val)),
|
|
,
|
|
]);
|
|
|
|
expect(return1).toBe("Hello a");
|
|
expect(return2).toBe("Hello bcd");
|
|
expect(return3).toBe("Hello bcd");
|
|
expect(return4).toBe("Hello bcd");
|
|
|
|
expect(perform1).toHaveBeenCalledTimes(1);
|
|
expect(perform1).toHaveBeenCalledWith("a");
|
|
expect(perform2).toHaveBeenCalledTimes(1);
|
|
expect(perform2).toHaveBeenCalledWith("bcd");
|
|
expect(perform3).toHaveBeenCalledTimes(0);
|
|
expect(perform4).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it("sets a default batch millis", () => {
|
|
const requestBatcher = new RequestBatcher();
|
|
expect(requestBatcher.batchMillis).toBe(1000);
|
|
});
|
|
|
|
it("handles an error being thrown in the process", () => {
|
|
const requestBatcher = new RequestBatcher({ batchMillis: 500 });
|
|
const perform = async (_input: string): Promise<string> => {
|
|
throw new Error("Test Error");
|
|
};
|
|
const perform1 = vi.fn(perform);
|
|
expect(() =>
|
|
requestBatcher.queueProcess<[string], string>({
|
|
name: "read",
|
|
args: ["a"],
|
|
perform: perform1,
|
|
modifyQueue: () => undefined,
|
|
}),
|
|
).rejects.toThrowError("Test Error");
|
|
});
|
|
});
|
|
|
|
function wait(millis: number): Promise<void> {
|
|
return new Promise((resolve) => setTimeout(resolve, millis));
|
|
}
|
|
|