diff --git a/packages/ioc/package.json b/packages/ioc/package.json index d3ee3bb..c0f40f4 100644 --- a/packages/ioc/package.json +++ b/packages/ioc/package.json @@ -5,6 +5,7 @@ "main": "dist/index.js", "scripts": { "test": "vitest --run", + "tdd": "vitest", "build": "tsc" }, "devDependencies": { diff --git a/packages/ioc/src/container.ts b/packages/ioc/src/container.ts index 8c86bd1..b1ed407 100644 --- a/packages/ioc/src/container.ts +++ b/packages/ioc/src/container.ts @@ -1,6 +1,9 @@ - +/** + * A semi-generic container that provides error handling, emitter, and module store. + * For the handler to operate correctly, The only user provided dependency needs to be @sern/client + */ function hasCallableMethod(obj: object, name: PropertyKey) { - // object will always be defined + //@ts-ignore return typeof obj[name] == 'function'; } /** @@ -21,17 +24,18 @@ export class Container { this.hooks.get(name)!.push(callback); } private registerHooks(hookname: string, insert: object) { + if(hasCallableMethod(insert, hookname)) { - console.log(hookname) //@ts-ignore - this.addHook(hookname, async () => await insert[hookname]()) + this.addHook(hookname, () => insert[hookname]()) } } + addSingleton(key: string, insert: object) { if(typeof insert !== 'object') { throw Error("Inserted object must be an object"); } - if(!this.__singletons.has(key)){ + if(!this.__singletons.has(key)) { this.registerHooks('init', insert) this.registerHooks('dispose', insert) this.__singletons.set(key, insert); @@ -40,8 +44,8 @@ export class Container { return false; } - addWiredSingleton(key: string, fn: (c: Container) => object) { - const insert = fn(this); + addWiredSingleton(key: string, fn: (c: Record) => object) { + const insert = fn(this.deps()); return this.addSingleton(key, insert); } @@ -70,5 +74,16 @@ export class Container { await hookFunction(); } } -} + swap(key: string, swp: object) { + if (typeof swp !== 'object') { + throw Error("Inserted object must be an object"); + } + + const existing = this.__singletons.get(key); + if (!existing) { + throw Error("No existing key to swap for " + key); + } + this.__singletons.set(key, swp); + } +} diff --git a/packages/ioc/test/index.test.ts b/packages/ioc/test/index.test.ts index 207f242..632cb1b 100644 --- a/packages/ioc/test/index.test.ts +++ b/packages/ioc/test/index.test.ts @@ -1,12 +1,17 @@ import { Container } from '../src/container'; -import { describe, it, expect, beforeEach, vi } from 'vitest'; +import { describe, it, expect, beforeEach, vi, Mock } from 'vitest'; describe('CoreContainer Tests', () => { let coreContainer: Container; - + let singletonWInit: { init: Mock; value: string } beforeEach(() => { coreContainer = new Container({ autowire: false }); + singletonWInit = { + value: 'singletonWithInit', + init: vi.fn() + } + }); it('Adding and getting singletons', () => { @@ -99,22 +104,30 @@ describe('CoreContainer Tests', () => { expect(coreContainer.isReady()).toBe(true); }); it('Registering and executing hooks - init should be called once after ready', async () => { - let initCount = 0; - const singletonWithInit = { - value: 'singletonValueWithInit', - init: async () => { - initCount++; - } - }; - - coreContainer.addSingleton('singletonKeyWithInit', singletonWithInit); + coreContainer.addSingleton('singletonKeyWithInit', singletonWInit); // Call ready twice to ensure hooks are executed only once await coreContainer.ready(); await coreContainer.ready(); - expect(initCount).toBe(1); + expect(singletonWInit.init).toHaveBeenCalledOnce(); }); + it('should throw because not swapping anything', () => { + + expect(() => coreContainer.swap('singletonKeyWithInit', singletonWInit)).toThrow() + }) + it('should swap object with another', () => { + coreContainer.addSingleton('singleton', singletonWInit) + const singletonWithInit2 = { + value: 'singletonValueWithInit2', + init: vi.fn() + }; + coreContainer.swap('singleton', singletonWithInit2) + expect(coreContainer.get('singleton')).toBe(singletonWithInit2) + }) + it('should swap object, calling dispose hook', () => { + coreContainer.addSingleton('singleton', singletonWInit) + }) })