@agentica/core
Version:
Agentic AI Library specialized in LLM Function Calling
172 lines • 9.17 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const __retry_1 = require("./__retry");
describe("__get_retry", () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe("success cases", () => {
it("should not retry when successful on first attempt", () => __awaiter(void 0, void 0, void 0, function* () {
const mockFn = vi.fn().mockResolvedValue("success");
const retryFn = (0, __retry_1.__get_retry)(3);
const result = yield retryFn(mockFn);
expect(result).toBe("success");
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenCalledWith(undefined);
}));
it("should call exactly 2 times when successful on second attempt", () => __awaiter(void 0, void 0, void 0, function* () {
const mockFn = vi.fn()
.mockRejectedValueOnce(new Error("First failure"))
.mockResolvedValue("success");
const retryFn = (0, __retry_1.__get_retry)(3);
const result = yield retryFn(mockFn);
expect(result).toBe("success");
expect(mockFn).toHaveBeenCalledTimes(2);
expect(mockFn).toHaveBeenNthCalledWith(1, undefined);
expect(mockFn).toHaveBeenNthCalledWith(2, new Error("First failure"));
}));
it("should call limit times when successful on last attempt", () => __awaiter(void 0, void 0, void 0, function* () {
const mockFn = vi.fn()
.mockRejectedValueOnce(new Error("First failure"))
.mockRejectedValueOnce(new Error("Second failure"))
.mockResolvedValue("success");
const retryFn = (0, __retry_1.__get_retry)(3);
const result = yield retryFn(mockFn);
expect(result).toBe("success");
expect(mockFn).toHaveBeenCalledTimes(3);
expect(mockFn).toHaveBeenNthCalledWith(1, undefined);
expect(mockFn).toHaveBeenNthCalledWith(2, new Error("First failure"));
expect(mockFn).toHaveBeenNthCalledWith(3, new Error("Second failure"));
}));
});
describe("failure cases", () => {
it("should throw last error after limit attempts", () => __awaiter(void 0, void 0, void 0, function* () {
const error1 = new Error("First failure");
const error2 = new Error("Second failure");
const error3 = new Error("Third failure");
const mockFn = vi.fn()
.mockRejectedValueOnce(error1)
.mockRejectedValueOnce(error2)
.mockRejectedValueOnce(error3);
const retryFn = (0, __retry_1.__get_retry)(3);
yield expect(retryFn(mockFn)).rejects.toThrow("Third failure");
expect(mockFn).toHaveBeenCalledTimes(3);
expect(mockFn).toHaveBeenNthCalledWith(1, undefined);
expect(mockFn).toHaveBeenNthCalledWith(2, error1);
expect(mockFn).toHaveBeenNthCalledWith(3, error2);
}));
it("should throw error immediately when limit is 1", () => __awaiter(void 0, void 0, void 0, function* () {
const error = new Error("Immediate failure");
const mockFn = vi.fn().mockRejectedValue(error);
const retryFn = (0, __retry_1.__get_retry)(1);
yield expect(retryFn(mockFn)).rejects.toThrow("Immediate failure");
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenCalledWith(undefined);
}));
});
describe("prevError propagation", () => {
it("should pass previous error as prevError correctly", () => __awaiter(void 0, void 0, void 0, function* () {
const error1 = new Error("First error");
const error2 = new Error("Second error");
const mockFn = vi.fn()
.mockRejectedValueOnce(error1)
.mockRejectedValueOnce(error2)
.mockResolvedValue("success");
const retryFn = (0, __retry_1.__get_retry)(3);
const result = yield retryFn(mockFn);
expect(result).toBe("success");
expect(mockFn).toHaveBeenCalledTimes(3);
expect(mockFn).toHaveBeenNthCalledWith(1, undefined);
expect(mockFn).toHaveBeenNthCalledWith(2, error1);
expect(mockFn).toHaveBeenNthCalledWith(3, error2);
}));
it("should use initial prevError in first call when provided", () => __awaiter(void 0, void 0, void 0, function* () {
const initialError = new Error("Initial error");
const mockFn = vi.fn().mockResolvedValue("success");
const retryFn = (0, __retry_1.__get_retry)(3);
const result = yield retryFn(mockFn, initialError);
expect(result).toBe("success");
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenCalledWith(initialError);
}));
});
describe("different error types", () => {
it("should handle string errors correctly", () => __awaiter(void 0, void 0, void 0, function* () {
const mockFn = vi.fn()
.mockRejectedValueOnce("String error")
.mockResolvedValue("success");
const retryFn = (0, __retry_1.__get_retry)(2);
const result = yield retryFn(mockFn);
expect(result).toBe("success");
expect(mockFn).toHaveBeenCalledTimes(2);
expect(mockFn).toHaveBeenNthCalledWith(2, "String error");
}));
it("should handle null errors correctly", () => __awaiter(void 0, void 0, void 0, function* () {
const mockFn = vi.fn()
.mockRejectedValueOnce(null)
.mockResolvedValue("success");
const retryFn = (0, __retry_1.__get_retry)(2);
const result = yield retryFn(mockFn);
expect(result).toBe("success");
expect(mockFn).toHaveBeenCalledTimes(2);
expect(mockFn).toHaveBeenNthCalledWith(2, null);
}));
it("should handle undefined errors correctly", () => __awaiter(void 0, void 0, void 0, function* () {
const mockFn = vi.fn()
.mockRejectedValueOnce(undefined)
.mockResolvedValue("success");
const retryFn = (0, __retry_1.__get_retry)(2);
const result = yield retryFn(mockFn);
expect(result).toBe("success");
expect(mockFn).toHaveBeenCalledTimes(2);
expect(mockFn).toHaveBeenNthCalledWith(2, undefined);
}));
});
describe("recursive call verification", () => {
it("should occur recursive calls in correct order", () => __awaiter(void 0, void 0, void 0, function* () {
const callOrder = [];
const mockFn = vi.fn()
.mockImplementationOnce(() => {
callOrder.push("first call");
throw new Error("First failure");
})
.mockImplementationOnce(() => {
callOrder.push("second call");
throw new Error("Second failure");
})
.mockImplementationOnce(() => __awaiter(void 0, void 0, void 0, function* () {
callOrder.push("third call");
return Promise.resolve("success");
}));
const retryFn = (0, __retry_1.__get_retry)(3);
const result = yield retryFn(mockFn);
expect(result).toBe("success");
expect(callOrder).toEqual(["first call", "second call", "third call"]);
expect(mockFn).toHaveBeenCalledTimes(3);
}));
});
describe("type safety", () => {
it("should handle different return types correctly", () => __awaiter(void 0, void 0, void 0, function* () {
const stringFn = vi.fn().mockResolvedValue("string result");
const numberFn = vi.fn().mockResolvedValue(42);
const objectFn = vi.fn().mockResolvedValue({ key: "value" });
const retryFn = (0, __retry_1.__get_retry)(3);
const stringResult = yield retryFn(stringFn);
const numberResult = yield retryFn(numberFn);
const objectResult = yield retryFn(objectFn);
expect(stringResult).toBe("string result");
expect(numberResult).toBe(42);
expect(objectResult).toEqual({ key: "value" });
}));
});
});
//# sourceMappingURL=__retry.spec.js.map