mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-21 06:51:01 +00:00
test: tighten retry helper coverage
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { retryAsync } from "./retry.js";
|
||||
import { resolveRetryConfig, retryAsync } from "./retry.js";
|
||||
|
||||
async function runRetryAfterCase(params: {
|
||||
minDelayMs: number;
|
||||
@@ -48,22 +48,34 @@ describe("retryAsync", () => {
|
||||
});
|
||||
|
||||
it("stops when shouldRetry returns false", async () => {
|
||||
const fn = vi.fn().mockRejectedValue(new Error("boom"));
|
||||
await expect(retryAsync(fn, { attempts: 3, shouldRetry: () => false })).rejects.toThrow("boom");
|
||||
const err = new Error("boom");
|
||||
const fn = vi.fn().mockRejectedValue(err);
|
||||
const shouldRetry = vi.fn(() => false);
|
||||
await expect(retryAsync(fn, { attempts: 3, shouldRetry })).rejects.toThrow("boom");
|
||||
expect(fn).toHaveBeenCalledTimes(1);
|
||||
expect(shouldRetry).toHaveBeenCalledWith(err, 1);
|
||||
});
|
||||
|
||||
it("calls onRetry before retrying", async () => {
|
||||
const fn = vi.fn().mockRejectedValueOnce(new Error("boom")).mockResolvedValueOnce("ok");
|
||||
it("calls onRetry with retry metadata before retrying", async () => {
|
||||
const err = new Error("boom");
|
||||
const fn = vi.fn().mockRejectedValueOnce(err).mockResolvedValueOnce("ok");
|
||||
const onRetry = vi.fn();
|
||||
const res = await retryAsync(fn, {
|
||||
attempts: 2,
|
||||
minDelayMs: 0,
|
||||
maxDelayMs: 0,
|
||||
label: "telegram",
|
||||
onRetry,
|
||||
});
|
||||
expect(res).toBe("ok");
|
||||
expect(onRetry).toHaveBeenCalledWith(expect.objectContaining({ attempt: 1, maxAttempts: 2 }));
|
||||
expect(onRetry).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
attempt: 1,
|
||||
maxAttempts: 2,
|
||||
err,
|
||||
label: "telegram",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("clamps attempts to at least 1", async () => {
|
||||
@@ -89,3 +101,30 @@ describe("retryAsync", () => {
|
||||
expect(delays[0]).toBe(250);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveRetryConfig", () => {
|
||||
it.each([
|
||||
{
|
||||
name: "rounds attempts and delays",
|
||||
overrides: { attempts: 2.6, minDelayMs: 10.4, maxDelayMs: 99.8, jitter: 0.4 },
|
||||
expected: { attempts: 3, minDelayMs: 10, maxDelayMs: 100, jitter: 0.4 },
|
||||
},
|
||||
{
|
||||
name: "clamps attempts to at least one and maxDelayMs to minDelayMs",
|
||||
overrides: { attempts: 0, minDelayMs: 250, maxDelayMs: 100, jitter: -1 },
|
||||
expected: { attempts: 1, minDelayMs: 250, maxDelayMs: 250, jitter: 0 },
|
||||
},
|
||||
{
|
||||
name: "falls back for non-finite overrides and caps jitter at one",
|
||||
overrides: {
|
||||
attempts: Number.NaN,
|
||||
minDelayMs: Number.POSITIVE_INFINITY,
|
||||
maxDelayMs: Number.NaN,
|
||||
jitter: 2,
|
||||
},
|
||||
expected: { attempts: 3, minDelayMs: 300, maxDelayMs: 30000, jitter: 1 },
|
||||
},
|
||||
])("$name", ({ overrides, expected }) => {
|
||||
expect(resolveRetryConfig(undefined, overrides)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user