UNPKG

alepha

Version:

Easy-to-use modern TypeScript framework for building many kind of applications.

194 lines (163 loc) 5.53 kB
import { $pipeline, Alepha } from "alepha"; import { describe, test } from "vitest"; import { $timeout } from "../primitives/$timeout.ts"; import { DateTimeProvider } from "../providers/DateTimeProvider.ts"; // ----------------------------------------------------------------------------------------------------------------- // $timeout — core behavior // ----------------------------------------------------------------------------------------------------------------- describe("$timeout", () => { test("handler that completes before deadline returns normally", async ({ expect, }) => { const alepha = Alepha.create(); class TestService { fn = $pipeline({ use: [$timeout([1, "seconds"])], handler: async () => "ok", }); } const svc = alepha.inject(TestService); expect(await svc.fn()).toBe("ok"); }); test("handler that exceeds deadline rejects", async ({ expect }) => { const alepha = Alepha.create(); const dt = alepha.inject(DateTimeProvider); class TestService { fn = $pipeline({ use: [$timeout([50, "milliseconds"])], handler: async () => { await dt.wait([200, "milliseconds"]); return "too late"; }, }); } const svc = alepha.inject(TestService); await expect(svc.fn()).rejects.toThrowError( "$timeout: handler exceeded deadline", ); }); test("handler return value is preserved", async ({ expect }) => { const alepha = Alepha.create(); class TestService { fn = $pipeline({ use: [$timeout([1, "seconds"])], handler: async () => ({ data: [1, 2, 3] }), }); } const svc = alepha.inject(TestService); expect(await svc.fn()).toEqual({ data: [1, 2, 3] }); }); test("handler arguments are passed through", async ({ expect }) => { const alepha = Alepha.create(); class TestService { fn = $pipeline({ use: [$timeout([1, "seconds"])], handler: async (a: number, b: number) => a + b, }); } const svc = alepha.inject(TestService); expect(await svc.fn(3, 4)).toBe(7); }); test("handler errors propagate (not masked by timeout)", async ({ expect, }) => { const alepha = Alepha.create(); class TestService { fn = $pipeline({ use: [$timeout([1, "seconds"])], handler: async () => { throw new Error("Handler failed"); }, }); } const svc = alepha.inject(TestService); await expect(svc.fn()).rejects.toThrowError("Handler failed"); }); test("accepts number (milliseconds) as duration", async ({ expect }) => { const alepha = Alepha.create(); class TestService { fn = $pipeline({ use: [$timeout(1000)], handler: async () => "ok", }); } const svc = alepha.inject(TestService); expect(await svc.fn()).toBe("ok"); }); }); // ----------------------------------------------------------------------------------------------------------------- // $timeout — metadata // ----------------------------------------------------------------------------------------------------------------- describe("$timeout metadata", () => { test("has middleware metadata with name and options", ({ expect }) => { const alepha = Alepha.create(); class TestService { fn = $pipeline({ use: [$timeout([30, "seconds"])], handler: async () => "ok", }); } const svc = alepha.inject(TestService); const meta = svc.fn.middlewares; expect(meta).toHaveLength(1); expect(meta[0]).toEqual({ name: "$timeout", options: { duration: [30, "seconds"] }, }); }); }); // ----------------------------------------------------------------------------------------------------------------- // $timeout — composition // ----------------------------------------------------------------------------------------------------------------- describe("$timeout composition", () => { test("composes with other middleware", async ({ expect }) => { const calls: string[] = []; const alepha = Alepha.create(); class TestService { fn = $pipeline({ use: [ $timeout([1, "seconds"]), // Inline logging middleware ((handler: any) => async (...args: any[]) => { calls.push("log:before"); const result = await handler(...args); calls.push("log:after"); return result; }) as any, ], handler: async () => { calls.push("handler"); return "ok"; }, }); } const svc = alepha.inject(TestService); await svc.fn(); expect(calls).toEqual(["log:before", "handler", "log:after"]); }); test("timeout fires even when inner middleware is slow", async ({ expect, }) => { const alepha = Alepha.create(); const dt = alepha.inject(DateTimeProvider); class TestService { fn = $pipeline({ use: [ $timeout([50, "milliseconds"]), // Slow middleware that delays before calling handler ((handler: any) => async (...args: any[]) => { await dt.wait([200, "milliseconds"]); return handler(...args); }) as any, ], handler: async () => "ok", }); } const svc = alepha.inject(TestService); await expect(svc.fn()).rejects.toThrowError( "$timeout: handler exceeded deadline", ); }); });