import { describe, expect, test } from "bun:test"; import "reflect-metadata"; import { AlveoFactory, Container, Module } from "../index"; describe("Alveo Providers", () => { test("should support Factory Providers", async () => { const TOKEN = "FACTORY"; @Module({ providers: [ { provide: TOKEN, useFactory: () => "dynamic_value", }, ], }) class RootModule {} const app = await AlveoFactory.create(RootModule); const value = await app.get(TOKEN); expect(value).toBe("dynamic_value"); }); test("should support Asynchronous Factory Providers", async () => { const TOKEN = "ASYNC_FACTORY"; @Module({ providers: [ { provide: TOKEN, useFactory: async () => { await new Promise((resolve) => setTimeout(resolve, 10)); return "async_value"; }, }, ], }) class RootModule {} const app = await AlveoFactory.create(RootModule); const value = await app.get(TOKEN); expect(value).toBe("async_value"); }); test("should handle concurrent resolution of the same async provider", async () => { const TOKEN = "CONCURRENT_ASYNC"; let callCount = 0; @Module({ providers: [ { provide: TOKEN, useFactory: async () => { callCount++; await new Promise((resolve) => setTimeout(resolve, 20)); return { id: Math.random() }; }, }, ], }) class RootModule {} // We use a fresh container to test concurrent resolution // bypassing the sequential resolveAll() of AlveoFactory.create() const container = new Container(); await container.registerRootModule(RootModule); const [val1, val2] = await Promise.all([ container.get(TOKEN), container.get(TOKEN), ]); expect(val1).toBe(val2); expect(callCount).toBe(1); }); });