-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
55cb4e4
commit 074b22e
Showing
4 changed files
with
155 additions
and
2 deletions.
There are no files selected for viewing
123 changes: 123 additions & 0 deletions
123
packages/container/libraries/core/src/metadata/decorators/injectFromBase.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import { afterAll, beforeAll, describe, expect, it, jest } from '@jest/globals'; | ||
|
||
jest.mock('@inversifyjs/prototype-utils'); | ||
|
||
import { Newable } from '@inversifyjs/common'; | ||
import { getBaseType } from '@inversifyjs/prototype-utils'; | ||
|
||
jest.mock('./injectFrom'); | ||
|
||
import { InversifyCoreError } from '../../error/models/InversifyCoreError'; | ||
import { InversifyCoreErrorKind } from '../../error/models/InversifyCoreErrorKind'; | ||
import { InjectFromBaseOptions } from '../models/InjectFromBaseOptions'; | ||
import { InjectFromOptions } from '../models/InjectFromOptions'; | ||
import { injectFrom } from './injectFrom'; | ||
import { injectFromBase } from './injectFromBase'; | ||
|
||
describe(injectFromBase.name, () => { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type | ||
let targetFixture: Function; | ||
|
||
beforeAll(() => { | ||
targetFixture = class {}; | ||
}); | ||
|
||
describe('when called, and getBaseType returns Newable', () => { | ||
let injectFromBaseOptionsFixture: InjectFromBaseOptions; | ||
|
||
let baseTypefixture: Newable; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type | ||
let injectFromResultMock: jest.Mock<(target: Function) => void>; | ||
|
||
let result: unknown; | ||
|
||
beforeAll(() => { | ||
injectFromBaseOptionsFixture = { | ||
extendConstructorArguments: true, | ||
extendProperties: true, | ||
}; | ||
baseTypefixture = class Base {}; | ||
injectFromResultMock = jest.fn().mockReturnValueOnce(undefined); | ||
|
||
(getBaseType as jest.Mock<typeof getBaseType>).mockReturnValueOnce( | ||
baseTypefixture, | ||
); | ||
|
||
(injectFrom as jest.Mock<typeof injectFrom>).mockReturnValueOnce( | ||
injectFromResultMock, | ||
); | ||
|
||
result = injectFromBase(injectFromBaseOptionsFixture)(targetFixture); | ||
}); | ||
|
||
afterAll(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should call getBaseType()', () => { | ||
expect(getBaseType).toHaveBeenCalledTimes(1); | ||
expect(getBaseType).toHaveBeenCalledWith(targetFixture); | ||
}); | ||
|
||
it('should call injectFrom()', () => { | ||
const expected: InjectFromOptions = { | ||
...injectFromBaseOptionsFixture, | ||
type: baseTypefixture, | ||
}; | ||
|
||
expect(injectFrom).toHaveBeenCalledTimes(1); | ||
expect(injectFrom).toHaveBeenCalledWith(expected); | ||
|
||
expect(injectFromResultMock).toHaveBeenCalledTimes(1); | ||
expect(injectFromResultMock).toHaveBeenCalledWith(targetFixture); | ||
}); | ||
|
||
it('should return undefined', () => { | ||
expect(result).toBeUndefined(); | ||
}); | ||
}); | ||
|
||
describe('when called, and getBaseType returns undefined', () => { | ||
let injectFromBaseOptionsFixture: InjectFromBaseOptions; | ||
|
||
let result: unknown; | ||
|
||
beforeAll(() => { | ||
injectFromBaseOptionsFixture = { | ||
extendConstructorArguments: true, | ||
extendProperties: true, | ||
}; | ||
|
||
(getBaseType as jest.Mock<typeof getBaseType>).mockReturnValueOnce( | ||
undefined, | ||
); | ||
|
||
try { | ||
injectFromBase(injectFromBaseOptionsFixture)(targetFixture); | ||
} catch (error: unknown) { | ||
result = error; | ||
} | ||
}); | ||
|
||
afterAll(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should call getBaseType()', () => { | ||
expect(getBaseType).toHaveBeenCalledTimes(1); | ||
expect(getBaseType).toHaveBeenCalledWith(targetFixture); | ||
}); | ||
|
||
it('should return undefined', () => { | ||
const expectedErrorProperties: Partial<InversifyCoreError> = { | ||
kind: InversifyCoreErrorKind.injectionDecoratorConflict, | ||
message: `Expected base type for type "${targetFixture.name}", none found.`, | ||
}; | ||
|
||
expect(result).toBeInstanceOf(InversifyCoreError); | ||
expect(result).toStrictEqual( | ||
expect.objectContaining(expectedErrorProperties), | ||
); | ||
}); | ||
}); | ||
}); |
26 changes: 26 additions & 0 deletions
26
packages/container/libraries/core/src/metadata/decorators/injectFromBase.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { Newable } from '@inversifyjs/common'; | ||
import { getBaseType } from '@inversifyjs/prototype-utils'; | ||
|
||
import { InversifyCoreError } from '../../error/models/InversifyCoreError'; | ||
import { InversifyCoreErrorKind } from '../../error/models/InversifyCoreErrorKind'; | ||
import { InjectFromBaseOptions } from '../models/InjectFromBaseOptions'; | ||
import { injectFrom } from './injectFrom'; | ||
|
||
export function injectFromBase(options: InjectFromBaseOptions): ClassDecorator { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type | ||
return (target: Function): void => { | ||
const baseType: Newable | undefined = getBaseType(target as Newable); | ||
|
||
if (baseType === undefined) { | ||
throw new InversifyCoreError( | ||
InversifyCoreErrorKind.injectionDecoratorConflict, | ||
`Expected base type for type "${target.name}", none found.`, | ||
); | ||
} | ||
|
||
injectFrom({ | ||
...options, | ||
type: baseType, | ||
})(target); | ||
}; | ||
} |
4 changes: 4 additions & 0 deletions
4
packages/container/libraries/core/src/metadata/models/InjectFromBaseOptions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export interface InjectFromBaseOptions { | ||
extendConstructorArguments?: boolean | undefined; | ||
extendProperties?: boolean | undefined; | ||
} |
4 changes: 2 additions & 2 deletions
4
packages/container/libraries/core/src/metadata/models/InjectFromOptions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import { Newable } from '@inversifyjs/common'; | ||
|
||
export interface InjectFromOptions { | ||
extendConstructorArguments?: boolean; | ||
extendProperties?: boolean; | ||
extendConstructorArguments?: boolean | undefined; | ||
extendProperties?: boolean | undefined; | ||
type: Newable; | ||
} |