124 lines
2.6 KiB
TypeScript
124 lines
2.6 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import "reflect-metadata";
|
|
import {
|
|
AlveoFactory,
|
|
Inject,
|
|
Injectable,
|
|
Module,
|
|
ProviderNotFoundError,
|
|
} from "../index";
|
|
|
|
describe("Alveo Injection", () => {
|
|
test("should resolve a simple singleton service", async () => {
|
|
@Injectable()
|
|
class SimpleService {
|
|
getValue() {
|
|
return "hello";
|
|
}
|
|
}
|
|
|
|
@Module({
|
|
providers: [SimpleService],
|
|
})
|
|
class RootModule {}
|
|
|
|
const app = await AlveoFactory.create(RootModule);
|
|
const service = await app.get(SimpleService);
|
|
|
|
expect(service).toBeInstanceOf(SimpleService);
|
|
expect(service.getValue()).toBe("hello");
|
|
});
|
|
|
|
test("should inject dependencies via constructor", async () => {
|
|
@Injectable()
|
|
class Dependency {
|
|
name = "dep";
|
|
}
|
|
|
|
@Injectable()
|
|
class MainService {
|
|
constructor(public readonly dep: Dependency) {}
|
|
}
|
|
|
|
@Module({
|
|
providers: [Dependency, MainService],
|
|
})
|
|
class RootModule {}
|
|
|
|
const app = await AlveoFactory.create(RootModule);
|
|
const main = await app.get(MainService);
|
|
|
|
expect(main.dep).toBeInstanceOf(Dependency);
|
|
expect(main.dep.name).toBe("dep");
|
|
});
|
|
|
|
test("should support Value Providers", async () => {
|
|
const TOKEN = Symbol("CONFIG");
|
|
|
|
@Injectable()
|
|
class Service {
|
|
constructor(
|
|
@Inject(TOKEN) public readonly config: { apiKey: string },
|
|
) {}
|
|
}
|
|
|
|
@Module({
|
|
providers: [
|
|
Service,
|
|
{ provide: TOKEN, useValue: { apiKey: "123" } },
|
|
],
|
|
})
|
|
class RootModule {}
|
|
|
|
const app = await AlveoFactory.create(RootModule);
|
|
const service = await app.get(Service);
|
|
|
|
expect(service.config.apiKey).toBe("123");
|
|
});
|
|
|
|
test("should support existing providers (aliases)", async () => {
|
|
const ALIAS = "ALIAS_TOKEN";
|
|
|
|
@Injectable()
|
|
class RealService {
|
|
ok() {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
@Module({
|
|
providers: [
|
|
RealService,
|
|
{ provide: ALIAS, useExisting: RealService },
|
|
],
|
|
})
|
|
class RootModule {}
|
|
|
|
const app = await AlveoFactory.create(RootModule);
|
|
const real = await app.get(RealService);
|
|
const aliased = await app.get(ALIAS);
|
|
|
|
expect(aliased).toBe(real);
|
|
expect((aliased as RealService).ok()).toBe(true);
|
|
});
|
|
|
|
test("should throw ProviderNotFoundError when dependency is missing", async () => {
|
|
@Injectable()
|
|
class MissingDep {}
|
|
|
|
@Injectable()
|
|
class Target {
|
|
constructor(_dep: MissingDep) {}
|
|
}
|
|
|
|
@Module({
|
|
providers: [Target],
|
|
})
|
|
class RootModule {}
|
|
|
|
expect(AlveoFactory.create(RootModule)).rejects.toThrow(
|
|
ProviderNotFoundError,
|
|
);
|
|
});
|
|
});
|