From 764bb495b9056ca6429867460584fe841817188b Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 10 Jul 2024 17:39:28 -0300 Subject: [PATCH] Add IN_LARGE_SEGMENT matcher --- src/dtos/types.ts | 8 +++++- .../__tests__/segment/client_side.spec.ts | 25 +++++++++++++++++++ src/evaluator/matchers/index.ts | 2 ++ src/evaluator/matchers/large_segment.ts | 18 +++++++++++++ src/evaluator/matchers/matcherTypes.ts | 1 + src/evaluator/matchersTransform/index.ts | 2 +- 6 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/evaluator/matchers/large_segment.ts diff --git a/src/dtos/types.ts b/src/dtos/types.ts index efbf0acc..351598cf 100644 --- a/src/dtos/types.ts +++ b/src/dtos/types.ts @@ -61,6 +61,11 @@ interface IInSegmentMatcher extends ISplitMatcherBase { userDefinedSegmentMatcherData: IInSegmentMatcherData } +interface IInLargeSegmentMatcher extends ISplitMatcherBase { + matcherType: 'IN_LARGE_SEGMENT', + userDefinedSegmentMatcherData: IInSegmentMatcherData +} + interface IWhitelistMatcher extends ISplitMatcherBase { matcherType: 'WHITELIST', whitelistMatcherData: IWhitelistMatcherData @@ -165,7 +170,8 @@ interface IInListSemverMatcher extends ISplitMatcherBase { export type ISplitMatcher = IAllKeysMatcher | IInSegmentMatcher | IWhitelistMatcher | IEqualToMatcher | IGreaterThanOrEqualToMatcher | ILessThanOrEqualToMatcher | IBetweenMatcher | IEqualToSetMatcher | IContainsAnyOfSetMatcher | IContainsAllOfSetMatcher | IPartOfSetMatcher | IStartsWithMatcher | IEndsWithMatcher | IContainsStringMatcher | IInSplitTreatmentMatcher | IEqualToBooleanMatcher | IMatchesStringMatcher | - IEqualToSemverMatcher | IGreaterThanOrEqualToSemverMatcher | ILessThanOrEqualToSemverMatcher | IBetweenSemverMatcher | IInListSemverMatcher + IEqualToSemverMatcher | IGreaterThanOrEqualToSemverMatcher | ILessThanOrEqualToSemverMatcher | IBetweenSemverMatcher | IInListSemverMatcher | + IInLargeSegmentMatcher /** Split object */ export interface ISplitPartition { diff --git a/src/evaluator/matchers/__tests__/segment/client_side.spec.ts b/src/evaluator/matchers/__tests__/segment/client_side.spec.ts index 3bace2ca..5e192829 100644 --- a/src/evaluator/matchers/__tests__/segment/client_side.spec.ts +++ b/src/evaluator/matchers/__tests__/segment/client_side.spec.ts @@ -32,3 +32,28 @@ test('MATCHER IN_SEGMENT / should return true ONLY when the segment is defined i expect(await matcherTrue()).toBe(true); // segment found in mySegments list expect(await matcherFalse()).toBe(false); // segment not found in mySegments list }); + +test('MATCHER IN_LARGE_SEGMENT / should return true ONLY when the segment is defined inside the segment storage', async function () { + const segment = 'employees'; + + const matcherTrue = matcherFactory(loggerMock, { + type: matcherTypes.IN_LARGE_SEGMENT, + value: segment + } as IMatcherDto, { + largeSegments: { + isInSegment(segmentName) { + return segment === segmentName; + } + } + } as IStorageSync) as IMatcher; + + const matcherFalse = matcherFactory(loggerMock, { + type: matcherTypes.IN_LARGE_SEGMENT, + value: segment + } as IMatcherDto, { + largeSegments: undefined + } as IStorageSync) as IMatcher; + + expect(await matcherTrue()).toBe(true); // large segment found in mySegments list + expect(await matcherFalse()).toBe(false); // large segment storage is not defined +}); diff --git a/src/evaluator/matchers/index.ts b/src/evaluator/matchers/index.ts index b110fc17..d50c38dd 100644 --- a/src/evaluator/matchers/index.ts +++ b/src/evaluator/matchers/index.ts @@ -1,5 +1,6 @@ import { allMatcherContext } from './all'; import { segmentMatcherContext } from './segment'; +import { largeSegmentMatcherContext } from './large_segment'; import { whitelistMatcherContext } from './whitelist'; import { equalToMatcherContext } from './eq'; import { greaterThanEqualMatcherContext } from './gte'; @@ -48,6 +49,7 @@ const matchers = [ lessThanEqualToSemverMatcherContext, // LESS_THAN_OR_EQUAL_TO_SEMVER: 20 betweenSemverMatcherContext, // BETWEEN_SEMVER: 21 inListSemverMatcherContext, // IN_LIST_SEMVER: 22 + largeSegmentMatcherContext, // IN_LARGE_SEGMENT: 23 ]; /** diff --git a/src/evaluator/matchers/large_segment.ts b/src/evaluator/matchers/large_segment.ts new file mode 100644 index 00000000..408fd5da --- /dev/null +++ b/src/evaluator/matchers/large_segment.ts @@ -0,0 +1,18 @@ +import { MaybeThenable } from '../../dtos/types'; +import { ISegmentsCacheBase } from '../../storages/types'; +import { thenable } from '../../utils/promise/thenable'; + +export function largeSegmentMatcherContext(largeSegmentName: string, storage: { largeSegments?: ISegmentsCacheBase }) { + + return function largeSegmentMatcher(key: string): MaybeThenable { + const isInLargeSegment = storage.largeSegments ? storage.largeSegments.isInSegment(largeSegmentName, key) : false; + + if (thenable(isInLargeSegment)) { + isInLargeSegment.then(result => { + return result; + }); + } + + return isInLargeSegment; + }; +} diff --git a/src/evaluator/matchers/matcherTypes.ts b/src/evaluator/matchers/matcherTypes.ts index 469c7a43..f09d50bf 100644 --- a/src/evaluator/matchers/matcherTypes.ts +++ b/src/evaluator/matchers/matcherTypes.ts @@ -22,6 +22,7 @@ export const matcherTypes: Record = { LESS_THAN_OR_EQUAL_TO_SEMVER: 20, BETWEEN_SEMVER: 21, IN_LIST_SEMVER: 22, + IN_LARGE_SEGMENT: 23, }; export const matcherDataTypes = { diff --git a/src/evaluator/matchersTransform/index.ts b/src/evaluator/matchersTransform/index.ts index 23c4d538..877f368d 100644 --- a/src/evaluator/matchersTransform/index.ts +++ b/src/evaluator/matchersTransform/index.ts @@ -33,7 +33,7 @@ export function matchersTransform(matchers: ISplitMatcher[]): IMatcherDto[] { let dataType = matcherDataTypes.STRING; let value = undefined; - if (type === matcherTypes.IN_SEGMENT) { + if (type === matcherTypes.IN_SEGMENT || type === matcherTypes.IN_LARGE_SEGMENT) { value = segmentTransform(userDefinedSegmentMatcherData as IInSegmentMatcherData); } else if (type === matcherTypes.EQUAL_TO) { value = numericTransform(unaryNumericMatcherData as IUnaryNumericMatcherData);