74 lines
1.6 KiB
TypeScript
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");
|
|
});
|
|
});
|