UNPKG

@agentica/core

Version:

Agentic AI Library specialized in LLM Function Calling

277 lines (210 loc) 7.89 kB
import { MPSC } from "./MPSC"; describe("the MPSC", () => { describe("basic functionality", () => { it("basic MPSC functionality test", async () => { const mpsc = new MPSC<number>(); const reader = mpsc.consumer.getReader(); // Produce values mpsc.produce(10); mpsc.produce(20); mpsc.produce(30); const read1 = await reader.read(); const read2 = await reader.read(); const read3 = await reader.read(); expect(read1.value).toBe(10); expect(read1.done).toBe(false); expect(read2.value).toBe(20); expect(read2.done).toBe(false); expect(read3.value).toBe(30); expect(read3.done).toBe(false); }); it("close functionality test", async () => { const mpsc = new MPSC<number>(); const reader = mpsc.consumer.getReader(); mpsc.produce(10); mpsc.close(); await reader.read(); expect(mpsc.done()).toBe(true); }); it("multiple producers scenario test", async () => { const multiMpsc = new MPSC<string>(); const multiReader = multiMpsc.consumer.getReader(); // Simulate multiple producers for (let i = 1; i <= 5; i++) { multiMpsc.produce(`producer-${i}`); } // Read all values const multiResults: string[] = []; for (let i = 0; i < 5; i++) { const { value } = await multiReader.read(); if (value != null) { multiResults.push(value); } } expect(multiResults.length).toBe(5); expect(multiResults).toContain("producer-1"); expect(multiResults).toContain("producer-2"); expect(multiResults).toContain("producer-3"); expect(multiResults).toContain("producer-4"); expect(multiResults).toContain("producer-5"); multiMpsc.close(); const multiAfterClose = await multiReader.read(); expect(multiAfterClose.done).toBe(true); }); it("reading before producing test", async () => { const delayMpsc = new MPSC<number>(); const delayReader = delayMpsc.consumer.getReader(); // Start reading before producing const readPromise = delayReader.read(); // Produce after a small delay setTimeout(() => { delayMpsc.produce(42); }, 10); const delayResult = await readPromise; expect(delayResult.value).toBe(42); expect(delayResult.done).toBe(false); delayMpsc.close(); }); it("producer-first, then consumer test", async () => { const laterMpsc = new MPSC<string>(); // Produce values first laterMpsc.produce("first"); laterMpsc.produce("second"); laterMpsc.produce("third"); // Then get reader and read const laterReader = laterMpsc.consumer.getReader(); const laterResult1 = await laterReader.read(); const laterResult2 = await laterReader.read(); const laterResult3 = await laterReader.read(); expect(laterResult1.value).toBe("first"); expect(laterResult1.done).toBe(false); expect(laterResult2.value).toBe("second"); expect(laterResult2.done).toBe(false); expect(laterResult3.value).toBe("third"); expect(laterResult3.done).toBe(false); laterMpsc.close(); }); }); describe("waitClosed functionality", () => { it("basic waitClosed functionality test", async () => { const mpsc = new MPSC<string>(); const reader = mpsc.consumer.getReader(); mpsc.produce("message"); const readResult = await reader.read(); expect(readResult.value).toBe("message"); expect(readResult.done).toBe(false); // Call waitClose then execute close const closePromise = mpsc.waitClosed(); mpsc.close(); await closePromise; // Should resolve when closed const afterClose = await reader.read(); expect(afterClose.done).toBe(true); }); it("call waitClose on already closed queue test", async () => { const mpsc2 = new MPSC<number>(); mpsc2.close(); // Close first const alreadyClosedPromise = mpsc2.waitClosed(); // Should resolve immediately since already closed await alreadyClosedPromise; }); it("multiple waitClose calls test", async () => { const mpsc3 = new MPSC<number>(); // Create multiple waitClose promises const waitPromises = [mpsc3.waitClosed(), mpsc3.waitClosed(), mpsc3.waitClosed()]; // All promises should resolve mpsc3.close(); await Promise.all(waitPromises); }); it("verify waitClose doesn't block other operations", async () => { const mpsc4 = new MPSC<string>(); const reader4 = mpsc4.consumer.getReader(); // Call waitClose const waitPromise4 = mpsc4.waitClosed(); // Check if value production and consumption still work mpsc4.produce("first"); mpsc4.produce("second"); const read1 = await reader4.read(); const read2 = await reader4.read(); expect(read1.value).toBe("first"); expect(read1.done).toBe(false); expect(read2.value).toBe("second"); expect(read2.done).toBe(false); mpsc4.close(); await waitPromise4; const afterClose4 = await reader4.read(); expect(afterClose4.done).toBe(true); }); it("waitClose resolution after async close test", async () => { const mpsc5 = new MPSC<number>(); const reader5 = mpsc5.consumer.getReader(); mpsc5.produce(100); // Call waitClose const waitPromise5 = mpsc5.waitClosed(); // Perform async close setTimeout(() => { mpsc5.close(); }, 50); // Wait for waitClose to resolve await waitPromise5; await reader5.read(); const afterClose5 = await reader5.read(); expect(afterClose5.done).toBe(true); }); }); describe("waitUntilEmpty functionality", () => { it("waitUntilEmpty test when queue is empty", async () => { const mpsc = new MPSC<number>(); const reader = mpsc.consumer.getReader(); // Should resolve immediately since queue is empty await mpsc.waitUntilEmpty(); mpsc.produce(1); const readResult = await reader.read(); expect(readResult.value).toBe(1); expect(readResult.done).toBe(false); mpsc.close(); }); it("waitUntilEmpty test when queue is not empty", async () => { const mpsc = new MPSC<number>(); const reader = mpsc.consumer.getReader(); mpsc.produce(1); mpsc.produce(2); // waitUntilEmpty should not resolve since queue is not empty const waitPromise = mpsc.waitUntilEmpty(); // Read first value const read1 = await reader.read(); expect(read1.value).toBe(1); // Read second value const read2 = await reader.read(); expect(read2.value).toBe(2); mpsc.close(); const read3 = await reader.read(); expect(read3.done).toBe(true); // Now queue is empty, waitUntilEmpty should resolve await waitPromise; }); it("waitUntilEmpty test on closed queue", async () => { const mpsc = new MPSC<number>(); const reader = mpsc.consumer.getReader(); mpsc.produce(1); mpsc.close(); // waitUntilEmpty should resolve since queue is closed await mpsc.waitUntilEmpty(); const readResult = await reader.read(); expect(readResult.value).toBe(1); expect(readResult.done).toBe(false); const afterClose = await reader.read(); expect(afterClose.done).toBe(true); }); }); describe("done functionality", () => { it("done test on unclosed queue", async () => { const mpsc = new MPSC<number>(); expect(mpsc.done()).toBe(false); mpsc.produce(1); expect(mpsc.done()).toBe(false); mpsc.close(); await mpsc.consumer.getReader().read(); expect(mpsc.done()).toBe(true); }); }); });