mirror of
https://github.com/sern-handler/handler
synced 2026-06-06 01:16:55 +00:00
114 lines
3.6 KiB
TypeScript
114 lines
3.6 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { CoreContainer } from '../../src/core/ioc/container';
|
|
import { EventEmitter } from 'events';
|
|
import { DefaultLogging, Disposable, Emitter, Init, Logging } from '../../src/core';
|
|
import { CoreDependencies } from '../../src/types/ioc';
|
|
|
|
describe('ioc container', () => {
|
|
let container: CoreContainer<{}> = new CoreContainer();
|
|
let dependency: Logging & Init & Disposable;
|
|
let dependency2: Emitter
|
|
beforeEach(() => {
|
|
dependency = {
|
|
init: vi.fn(),
|
|
error(): void {},
|
|
warning(): void {},
|
|
info(): void {},
|
|
debug(): void {},
|
|
dispose: vi.fn()
|
|
};
|
|
dependency2 = {
|
|
addListener: vi.fn(),
|
|
removeListener: vi.fn(),
|
|
emit: vi.fn()
|
|
};
|
|
container = new CoreContainer();
|
|
});
|
|
const wait = (seconds: number) => new Promise((resolve) => setTimeout(resolve, seconds));
|
|
class DB implements Init, Disposable {
|
|
public connected = false
|
|
constructor() {}
|
|
async init() {
|
|
this.connected = true
|
|
await wait(10)
|
|
}
|
|
async dispose() {
|
|
await wait(20)
|
|
this.connected = false
|
|
}
|
|
}
|
|
it('should be ready after calling container.ready()', () => {
|
|
container.ready();
|
|
expect(container.isReady()).toBe(true);
|
|
});
|
|
it('should container all core dependencies', async () => {
|
|
const keys = [
|
|
'@sern/modules',
|
|
'@sern/emitter',
|
|
'@sern/logger',
|
|
'@sern/errors',
|
|
] satisfies (keyof CoreDependencies)[];
|
|
container.add({
|
|
'@sern/logger': () => new DefaultLogging(),
|
|
'@sern/client': () => new EventEmitter(),
|
|
});
|
|
for (const k of keys) {
|
|
//@ts-expect-error typings for iti are strict
|
|
expect(() => container.get(k)).not.toThrow();
|
|
}
|
|
});
|
|
it('should init modules', () => {
|
|
container.upsert({ '@sern/logger': dependency });
|
|
container.ready();
|
|
expect(dependency.init).to.toHaveBeenCalledOnce();
|
|
});
|
|
it('should dispose modules', async () => {
|
|
|
|
container.upsert({ '@sern/logger': dependency })
|
|
|
|
container.ready();
|
|
// We need to access the dependency at least once to be able to dispose of it.
|
|
container.get('@sern/logger' as never);
|
|
await container.disposeAll();
|
|
expect(dependency.dispose).toHaveBeenCalledOnce();
|
|
});
|
|
|
|
it('should init and dispose', async () => {
|
|
container.add({ db: new DB() })
|
|
container.ready()
|
|
const db = container.get('db' as never) as DB
|
|
expect(db.connected).toBeTruthy()
|
|
|
|
await container.disposeAll();
|
|
|
|
expect(db.connected).toBeFalsy()
|
|
})
|
|
|
|
it('should not lazy module', () => {
|
|
container.upsert({ '@sern/logger': () => dependency });
|
|
container.ready();
|
|
expect(dependency.init).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('should init dependency depending on something else', () => {
|
|
container.add({ '@sern/client': dependency2 });
|
|
container.upsert((cntr) => ({
|
|
'@sern/logger': dependency
|
|
}));
|
|
container.ready();
|
|
expect(dependency.init).toHaveBeenCalledTimes(1);
|
|
})
|
|
|
|
it('should detect a key already exists', () => {
|
|
container.add({ '@sern/client': dependency2 });
|
|
expect(container.hasKey('@sern/client')).toBeTruthy()
|
|
})
|
|
|
|
|
|
it('should detect a key already exists', () => {
|
|
container.add({ '@sern/client': () => dependency2 });
|
|
expect(container.hasKey('@sern/client')).toBeTruthy()
|
|
})
|
|
|
|
});
|