claude-code-best/src/utils/__tests__/sequential.test.ts
claude-code-best a14d3dc8f0 fix(types): clean type fixes across 92 files
Apply proper TypeScript type corrections without any unsafe casts:
- Fix unknown/never/{} types from decompilation
- Correct function signatures and parameter types
- Add missing type declarations and interfaces
- Fix Ink component prop types
- Update API client/provider type annotations

Test files with mock data casts are included as-is (acceptable pattern).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 23:45:56 +08:00

100 lines
3.0 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import { sequential } from "../sequential";
describe("sequential", () => {
test("wraps async function, returns same result", async () => {
const fn = sequential(async (x: number) => x * 2);
expect(await fn(5)).toBe(10);
});
test("single call resolves normally", async () => {
const fn = sequential(async () => "ok");
expect(await fn()).toBe("ok");
});
test("concurrent calls execute sequentially (FIFO order)", async () => {
const order: number[] = [];
const fn = sequential(async (n: number) => {
order.push(n);
await new Promise(r => setTimeout(r, 10));
return n;
});
const results = await Promise.all([fn(1), fn(2), fn(3)]);
expect(results).toEqual([1, 2, 3]);
expect(order).toEqual([1, 2, 3]);
});
test("preserves arguments correctly", async () => {
const fn = sequential(async (a: number, b: string) => `${a}-${b}`);
expect(await fn(42, "test")).toBe("42-test");
});
test("error in first call does not block subsequent calls", async () => {
let callCount = 0;
const fn = sequential(async () => {
callCount++;
if (callCount === 1) throw new Error("first fail");
return "ok";
});
await expect(fn()).rejects.toThrow("first fail");
expect(await fn()).toBe("ok");
});
test("preserves rejection reason", async () => {
const fn = sequential(async () => {
throw new Error("specific error");
});
await expect(fn()).rejects.toThrow("specific error");
});
test("multiple args passed correctly", async () => {
const fn = sequential(async (a: number, b: number, c: number) => a + b + c);
expect(await fn(1, 2, 3)).toBe(6);
});
test("returns different wrapper for each call to sequential", () => {
const fn1 = sequential(async () => 1);
const fn2 = sequential(async () => 2);
expect(fn1).not.toBe(fn2);
});
test("handles rapid concurrent calls", async () => {
const order: number[] = [];
const fn = sequential(async (n: number) => {
order.push(n);
return n;
});
const promises = Array.from({ length: 10 }, (_, i) => fn(i));
const results = await Promise.all(promises);
expect(results).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
expect(order).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
});
test("execution order matches call order", async () => {
const log: string[] = [];
const fn = sequential(async (label: string) => {
log.push(`start:${label}`);
await new Promise(r => setTimeout(r, 5));
log.push(`end:${label}`);
return label;
});
await Promise.all([fn("a"), fn("b")]);
expect(log[0]).toBe("start:a");
expect(log[1]).toBe("end:a");
expect(log[2]).toBe("start:b");
expect(log[3]).toBe("end:b");
});
test("works with functions returning different types", async () => {
const fn = sequential(async (x: number): Promise<string | number> => {
return x > 0 ? "positive" : x;
});
expect(await fn(5)).toBe("positive");
expect(await fn(-1)).toBe(-1);
});
});