Skip to content

Commit

Permalink
refactor(core): add buildMaybeClassElementMetadataFromMaybeClassEleme…
Browse files Browse the repository at this point in the history
…ntMetadata
  • Loading branch information
notaphplover committed Nov 16, 2024
1 parent 1434fb0 commit 4dfff5a
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { beforeAll, describe, expect, it } from '@jest/globals';

import { InversifyCoreError } from '../../error/models/InversifyCoreError';
import { InversifyCoreErrorKind } from '../../error/models/InversifyCoreErrorKind';
import { ClassElementMetadataKind } from '../models/ClassElementMetadataKind';
import { ManagedClassElementMetadata } from '../models/ManagedClassElementMetadata';
import { MaybeManagedClassElementMetadata } from '../models/MaybeManagedClassElementMetadata';
import { MetadataTag } from '../models/MetadataTag';
import { UnmanagedClassElementMetadata } from '../models/UnmanagedClassElementMetadata';
import { buildMaybeClassElementMetadataFromMaybeClassElementMetadata } from './buildMaybeClassElementMetadataFromMaybeClassElementMetadata';

describe(
buildMaybeClassElementMetadataFromMaybeClassElementMetadata.name,
() => {
describe('having unmanaged metadata', () => {
let metadataPartialFixture: Partial<MaybeManagedClassElementMetadata>;
let metadataFixture: UnmanagedClassElementMetadata;

beforeAll(() => {
metadataPartialFixture = {};
metadataFixture = {
kind: ClassElementMetadataKind.unmanaged,
};
});

describe('when called', () => {
let result: unknown;

beforeAll(() => {
try {
buildMaybeClassElementMetadataFromMaybeClassElementMetadata(
metadataPartialFixture,
)(metadataFixture);
} catch (error: unknown) {
result = error;
}
});

it('should throw an InversifyCoreError', () => {
const expectedErrorProperties: Partial<InversifyCoreError> = {
kind: InversifyCoreErrorKind.injectionDecoratorConflict,
message:
'Unexpected injection found. Found @unmanaged injection with additional @named, @optional, @tagged or @targetName injections',
};

expect(result).toBeInstanceOf(InversifyCoreError);
expect(result).toStrictEqual(
expect.objectContaining(expectedErrorProperties),
);
});
});
});

describe('having non unmanaged metadata', () => {
let metadataPartialFixture: Partial<MaybeManagedClassElementMetadata>;
let metadataFixture: ManagedClassElementMetadata;

beforeAll(() => {
metadataPartialFixture = {
name: 'name-fixture',
optional: true,
targetName: 'target-name-fixture',
};
metadataFixture = {
kind: ClassElementMetadataKind.singleInjection,
name: undefined,
optional: false,
tags: new Map([['foo', 'bar']]),
targetName: undefined,
value: 'service-identifier',
};
});

describe('when called', () => {
let result: unknown;

beforeAll(() => {
result = buildMaybeClassElementMetadataFromMaybeClassElementMetadata(
metadataPartialFixture,
)(metadataFixture);
});

it('should return ManagedClassElementMetadata', () => {
const expected:
| ManagedClassElementMetadata
| MaybeManagedClassElementMetadata = {
...metadataFixture,
...metadataPartialFixture,
};

expect(result).toStrictEqual(expected);
});
});
});

describe('having non unmanaged metadata and partial metadata with tags', () => {
let metadataPartialFixture: Partial<MaybeManagedClassElementMetadata>;
let metadataFixture: ManagedClassElementMetadata;

beforeAll(() => {
metadataPartialFixture = {
name: 'name-fixture',
optional: true,
tags: new Map([['bar', 'baz']]),
targetName: 'target-name-fixture',
};
metadataFixture = {
kind: ClassElementMetadataKind.singleInjection,
name: undefined,
optional: false,
tags: new Map([['foo', 'bar']]),
targetName: undefined,
value: 'service-identifier',
};
});

describe('when called', () => {
let result: unknown;

beforeAll(() => {
result = buildMaybeClassElementMetadataFromMaybeClassElementMetadata(
metadataPartialFixture,
)(metadataFixture);
});

it('should return ManagedClassElementMetadata', () => {
const expected:
| ManagedClassElementMetadata
| MaybeManagedClassElementMetadata = {
...metadataFixture,
...metadataPartialFixture,
tags: new Map([
...metadataFixture.tags,
...(metadataPartialFixture.tags as Map<MetadataTag, unknown>),
]),
};

expect(result).toStrictEqual(expected);
});
});
});
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { InversifyCoreError } from '../../error/models/InversifyCoreError';
import { InversifyCoreErrorKind } from '../../error/models/InversifyCoreErrorKind';
import { ClassElementMetadataKind } from '../models/ClassElementMetadataKind';
import { ManagedClassElementMetadata } from '../models/ManagedClassElementMetadata';
import { MaybeClassElementMetadata } from '../models/MaybeClassElementMetadata';
import { MaybeManagedClassElementMetadata } from '../models/MaybeManagedClassElementMetadata';
import { buildDefaultMaybeClassElementMetadata } from './buildDefaultMaybeClassElementMetadata';

export function buildMaybeClassElementMetadataFromMaybeClassElementMetadata(
metadataPartial: Partial<MaybeManagedClassElementMetadata>,
): (
metadata: MaybeClassElementMetadata | undefined,
) => ManagedClassElementMetadata | MaybeManagedClassElementMetadata {
return (
metadata: MaybeClassElementMetadata | undefined,
): ManagedClassElementMetadata | MaybeManagedClassElementMetadata => {
const definedMetadata: MaybeClassElementMetadata =
metadata ?? buildDefaultMaybeClassElementMetadata();

switch (definedMetadata.kind) {
case ClassElementMetadataKind.unmanaged:
throw new InversifyCoreError(
InversifyCoreErrorKind.injectionDecoratorConflict,
'Unexpected injection found. Found @unmanaged injection with additional @named, @optional, @tagged or @targetName injections',
);
default:
return buildMergedMetadata(definedMetadata, metadataPartial);
}
};
}

function buildMergedMetadata(
metadata: ManagedClassElementMetadata | MaybeManagedClassElementMetadata,
metadataPartial: Partial<MaybeManagedClassElementMetadata>,
): ManagedClassElementMetadata | MaybeManagedClassElementMetadata {
const mergedMetadata:
| ManagedClassElementMetadata
| MaybeManagedClassElementMetadata = {
...metadata,
...metadataPartial,
};

if (metadataPartial.tags !== undefined) {
mergedMetadata.tags = new Map([...metadata.tags, ...metadataPartial.tags]);
}

return mergedMetadata;
}

0 comments on commit 4dfff5a

Please sign in to comment.