diff --git a/.eslintrc.js b/.eslintrc.js index 5f18b7e..4fe3cba 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -68,6 +68,9 @@ module.exports = { // Allow properties in ctors, as it reduces code duplicates '@typescript-eslint/no-parameter-properties': ['error', { allows: ['private readonly', 'protected readonly', 'public readonly'] }], + // You know what you're doing when you force-unwrap (dammit operator) an optional field + '@typescript-eslint/no-non-null-assertion': 'off', + 'eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }], }, overrides: [ diff --git a/rollup.config.js b/rollup.config.js index 993023d..31126ea 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -67,7 +67,7 @@ function buildOutput() { /* esm */ { - file: `${ES5_BUNDLE_PATH}/index.esm${suffix}.js`, + file: `${ES5_BUNDLE_PATH}/index${suffix}.js`, format: 'es', sourcemap: true, plugins: [terser()], diff --git a/src/impl/container-impl.spec.ts b/src/impl/container-impl.spec.ts index b345943..08ad080 100644 --- a/src/impl/container-impl.spec.ts +++ b/src/impl/container-impl.spec.ts @@ -4,15 +4,19 @@ import * as assert from 'assert'; import { Container, DependencyInjectionError } from '../interfaces'; import { ContainerImpl } from './container-impl'; import { createModernFactoryRegistry } from './create-modern-factory-registry'; +import { createLegacyFactoryRegistry } from './create-legacy-factory-registry'; import { Cat, Dog, Fish, Meat, Milk, stringToken, symbolToken } from './container-types.spec'; -describe('ContainerImpl', () => { - // TODO: use legacyFactoryRegistry - describe('with ModernFactoryRegistry', () => { +const testBlocks = [ + { title: 'ContainerImpl with ModernFactoryRegistry', makeRegistry: createModernFactoryRegistry }, + { title: 'ContainerImpl with LegacyFactoryRegistry', makeRegistry: createLegacyFactoryRegistry }, +]; +testBlocks.forEach(({ title, makeRegistry }) => { + describe(title, () => { let container: Container; beforeEach(() => { - container = new ContainerImpl(createModernFactoryRegistry()); + container = new ContainerImpl(makeRegistry()); }); it('error path - no registration', () => { diff --git a/src/impl/create-legacy-factory-registry.ts b/src/impl/create-legacy-factory-registry.ts index 3da0c2c..636e84e 100644 --- a/src/impl/create-legacy-factory-registry.ts +++ b/src/impl/create-legacy-factory-registry.ts @@ -1,23 +1,28 @@ -import { FactoryRegistry } from '../interfaces'; +import { FactoryRegistry, ResolveFactoryFunction, Token } from '../interfaces'; export function createLegacyFactoryRegistry(): FactoryRegistry { - const factoryByToken = Object.create(null); + // cannot use `string | symbol` type here, see https://github.com/Microsoft/TypeScript/issues/24587 + const factoryByToken: Record> = Object.create(null); + // cannot iterate through symbols as keys in ES5 + const keys: Token[] = []; + + const toKey = (token: Token) => token as unknown as string; return { - getTokens: () => { - throw Error('not impl'); - }, - hasFactory: (token) => { - throw Error('not impl'); - }, - getFactory: (token) => { - throw Error('not impl'); - }, + getTokens: () => keys, + hasFactory: (token) => Object.prototype.hasOwnProperty.call(factoryByToken, toKey(token)), + getFactory: (token) => factoryByToken[toKey(token)], setFactory(token, factory) { - throw Error('not impl'); + if (!this.hasFactory(token)) { + keys.push(token); + } + factoryByToken[toKey(token)] = factory; }, forEach(callback) { - throw Error('not impl'); + keys.forEach((token) => { + const factory = this.getFactory(token)!; + callback(factory, token, this); + }); }, }; } diff --git a/src/interfaces/di-error.spec.ts b/src/interfaces/di-error.spec.ts index fab45cf..1488996 100644 --- a/src/interfaces/di-error.spec.ts +++ b/src/interfaces/di-error.spec.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import { describe, it } from 'mocha'; import * as assert from 'assert';