Skip to content

Commit

Permalink
feat: Permit override of single injectable using injection token
Browse files Browse the repository at this point in the history
  • Loading branch information
Iku-turso committed Nov 22, 2022
1 parent abf402a commit f6ae117
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,25 @@ export default containerId => {
},

override: (alias, instantiateStub) => {
const originalInjectable = injectableMap.get(alias.id);
const relatedInjectables = getRelatedInjectables(alias);

if (relatedInjectables.length > 1) {
throw new Error(
`Tried to override single implementation of injection token "${
alias.id
}", but found multiple registered implementations: "${relatedInjectables
.map(x => x.id)
.join('", "')}".`,
);
}

if (relatedInjectables.length === 0) {
if (alias.aliasType === 'injection-token') {
throw new Error(
`Tried to override single implementation of injection token "${alias.id}", but found no registered implementations.`,
);
}

if (!originalInjectable) {
throw new Error(
`Tried to override "${alias.id}" which is not registered.`,
);
Expand All @@ -252,6 +268,8 @@ export default containerId => {
);
}

const originalInjectable = relatedInjectables[0];

overridingInjectables.set(originalInjectable.id, {
...originalInjectable,
causesSideEffects: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,90 @@ describe('createContainer.override', () => {

expect(actual).toEqual(['some-override']);
});

it('given single registered injectable with injection token, and the injection token is overridden, when the injection token is inject-singled, injects the overridden instance', () => {
const di = createContainer('some-container');

const someInjectionToken = getInjectionToken({
id: 'some-injection-token',
});

const injectable = getInjectable({
id: 'some-injectable',
instantiate: () => 'irrelevant',
injectionToken: someInjectionToken,
});

di.register(injectable);

di.override(someInjectionToken, () => 'some-override');

const actual = di.inject(someInjectionToken);

expect(actual).toBe('some-override');
});

it('given single registered injectable with injection token, and the injection token is overridden, when the injection token is inject-many, injects the overridden instance', () => {
const di = createContainer('some-container');

const someInjectionToken = getInjectionToken({
id: 'some-injection-token',
});

const injectable = getInjectable({
id: 'some-injectable',
instantiate: () => 'irrelevant',
injectionToken: someInjectionToken,
});

di.register(injectable);

di.override(someInjectionToken, () => 'some-override');

const actual = di.injectMany(someInjectionToken);

expect(actual).toEqual(['some-override']);
});

it('given multiple registered injectables with injection token, and the injection token is overridden, throws', () => {
const di = createContainer('some-container');

const someInjectionToken = getInjectionToken({
id: 'some-injection-token',
});

const injectable1 = getInjectable({
id: 'some-injectable-1',
instantiate: () => 'irrelevant',
injectionToken: someInjectionToken,
});

const injectable2 = getInjectable({
id: 'some-injectable-2',
instantiate: () => 'irrelevant',
injectionToken: someInjectionToken,
});

di.register(injectable1, injectable2);

expect(() => {
di.override(someInjectionToken, () => 'some-override');
}).toThrow(
'Tried to override single implementation of injection token "some-injection-token", but found multiple registered implementations: "some-injectable-1", "some-injectable-2".',
);
});

it('given no registered injectable with injection token, when the injection token is overridden, throws', () => {
const di = createContainer('some-container');

const someInjectionToken = getInjectionToken({
id: 'some-injection-token',
});

expect(() => {
di.override(someInjectionToken, () => 'some-override');
}).toThrow(
'Tried to override single implementation of injection token "some-injection-token", but found no registered implementations.',
);
});
});

0 comments on commit f6ae117

Please sign in to comment.