Files
core/test/circular-dependency.test.ts

74 lines
1.6 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import "reflect-metadata";
import {
AlveoFactory,
CircularDependencyError,
forwardRef,
Inject,
Injectable,
Module,
} from "../index";
describe("Alveo Circular Dependencies", () => {
test("should detect circular dependencies without forwardRef", async () => {
@Injectable()
class A {
constructor(_b: unknown) {}
}
@Injectable()
class B {
constructor(_a: A) {}
}
// Manually define metadata to simulate circular dep without forwardRef
Reflect.defineMetadata("design:paramtypes", [Object], A);
Reflect.defineMetadata("design:paramtypes", [A], B);
Reflect.defineMetadata("alveo:inject", [B], A);
@Module({
providers: [A, B],
})
class RootModule {}
expect(AlveoFactory.create(RootModule)).rejects.toThrow(
CircularDependencyError,
);
});
test("should resolve circular dependencies with forwardRef", async () => {
@Injectable()
class ServiceA {
constructor(
@Inject(forwardRef(() => ServiceB))
public readonly serviceB: { name: () => string },
) {}
name() {
return "A";
}
}
@Injectable()
class ServiceB {
constructor(
@Inject(forwardRef(() => ServiceA))
public readonly serviceA: { name: () => string },
) {}
name() {
return "B";
}
}
@Module({
providers: [ServiceA, ServiceB],
})
class RootModule {}
const app = await AlveoFactory.create(RootModule);
const a = await app.get(ServiceA);
const b = await app.get(ServiceB);
expect(a.serviceB.name()).toBe("B");
expect(b.serviceA.name()).toBe("A");
});
});