UNPKG

i18n-ai-translate

Version:

AI-powered localization CLI, Node library, and GitHub Action. Translate i18next JSON, Gettext PO, Java .properties, and iOS .strings with ChatGPT, Claude, Gemini, or local Ollama models.

72 lines 3.07 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const chat_pool_1 = __importDefault(require("../chat_pool")); const engine_1 = __importDefault(require("../enums/engine")); const rate_limiter_1 = __importDefault(require("../rate_limiter")); const mkPool = (concurrency) => chat_pool_1.default.create({ chatParams: {}, concurrency, engine: engine_1.default.ChatGPT, model: "gpt-4.1", rateLimiter: new rate_limiter_1.default(0, false), }); describe("ChatPool", () => { it("creates N triples and reports the correct size", () => { const pool = mkPool(3); expect(pool.size).toBe(3); expect(pool.all()).toHaveLength(3); }); it("each triple contains three distinct chat instances", () => { const pool = mkPool(2); for (const triple of pool.all()) { expect(triple.generateTranslationChat).toBeDefined(); expect(triple.verifyTranslationChat).toBeDefined(); expect(triple.verifyStylingChat).toBeDefined(); expect(triple.generateTranslationChat).not.toBe(triple.verifyTranslationChat); } }); it("different triples are distinct instances", () => { const pool = mkPool(3); const all = pool.all(); expect(all[0].generateTranslationChat).not.toBe(all[1].generateTranslationChat); expect(all[1].generateTranslationChat).not.toBe(all[2].generateTranslationChat); }); it("run() never hands the same triple to two concurrent tasks", async () => { const pool = mkPool(2); const inUse = new Set(); let maxConcurrent = 0; let active = 0; const task = () => pool.run(async (chats) => { expect(inUse.has(chats)).toBe(false); inUse.add(chats); active++; maxConcurrent = Math.max(maxConcurrent, active); // Yield once so other waiters get a chance to acquire. await Promise.resolve(); active--; inUse.delete(chats); }); await Promise.all([task(), task(), task(), task()]); expect(maxConcurrent).toBeLessThanOrEqual(2); }); it("serializes work beyond pool capacity", async () => { const pool = mkPool(1); const order = []; const task = (n) => pool.run(async () => { order.push(n); await Promise.resolve(); }); await Promise.all([task(1), task(2), task(3)]); expect(order).toEqual([1, 2, 3]); }); it("releases triples after errors so the pool does not deadlock", async () => { const pool = mkPool(1); await expect(pool.run(() => Promise.reject(new Error("boom")))).rejects.toThrow("boom"); // Should still be acquirable after the failed task. await expect(pool.run(() => Promise.resolve("ok"))).resolves.toBe("ok"); }); }); //# sourceMappingURL=chat_pool.spec.js.map