@sigi/di
Version:
Dependencies injection library for sigi framework
70 lines (57 loc) • 2.02 kB
text/typescript
import { Injector } from './injector'
import { rootInjector } from './root-injector'
import { Type, InjectionToken, Provider, Token, ValueProvider } from './type'
export class Test<M extends AbstractTestModule> {
static createTestingModule<M extends AbstractTestModule>(overrideConfig?: {
TestModule?: Type<M>
providers?: Provider[]
}) {
return new Test<M>(
overrideConfig?.providers ? overrideConfig.providers : [],
overrideConfig?.TestModule ? overrideConfig.TestModule : (TestModule as any),
)
}
readonly providersMap = new Map<Token<unknown>, Provider>()
private constructor(
providers: Provider[],
private readonly TestModule: Type<M>,
) {
for (const provider of providers) {
this.providersMap.set((provider as ValueProvider<unknown>).provide ?? provider, provider)
}
}
overrideProvider<T>(token: Token<T>): MockProvider<T, M> {
return new MockProvider(this, token)
}
compile() {
const childInjector = rootInjector.createChild(Array.from(this.providersMap.values()))
return new this.TestModule(childInjector)
}
}
export class MockProvider<T, M extends AbstractTestModule> {
constructor(
private readonly test: Test<M>,
private readonly token: Type<T> | InjectionToken<T>,
) {}
useClass(value: Type<T>) {
this.test.providersMap.set(this.token, { provide: this.token, useClass: value })
return this.test
}
useValue(value: T) {
this.test.providersMap.set(this.token, { provide: this.token, useValue: value })
return this.test
}
useFactory(value: (...args: any[]) => any) {
this.test.providersMap.set(this.token, { provide: this.token, useFactory: value })
return this.test
}
}
export abstract class AbstractTestModule {
abstract getInstance<T>(provider: Provider<T>): T
}
export class TestModule implements AbstractTestModule {
constructor(private readonly injector: Injector) {}
getInstance<T>(token: Provider<T>): T {
return this.injector.getInstance(token)
}
}