From 351e30526c935895f6030169acdb2f1b17d4f493 Mon Sep 17 00:00:00 2001 From: Ulad Kasach Date: Fri, 12 Jul 2024 07:33:12 -0400 Subject: [PATCH] fix(rels): expose reference intuitive.via and support explicit reference prefix --- ...isPropertyNameAReferenceExplicitly.test.ts | 10 +++++++ .../isPropertyNameAReferenceExplicitly.ts | 13 ++++++++- ...sPropertyNameAReferenceIntuitively.test.ts | 28 ++++++++++--------- .../isPropertyNameAReferenceIntuitively.ts | 7 +++-- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceExplicitly.test.ts b/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceExplicitly.test.ts index 73b5788..e95b178 100644 --- a/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceExplicitly.test.ts +++ b/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceExplicitly.test.ts @@ -81,6 +81,16 @@ describe('isPropertyNameAReferenceExplicitly', () => { domainObjectName: 'LeadEngineer', expectedResult: false, }, + { + propertyName: 'leadEngineerRef', + domainObjectName: 'LeadEngineerRef', + expectedResult: true, + }, + { + propertyName: 'priceDue', + domainObjectName: 'Price', + expectedResult: true, + }, ]; cases.forEach((testCase) => { diff --git a/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceExplicitly.ts b/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceExplicitly.ts index 2a0d68f..4ec1ec2 100644 --- a/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceExplicitly.ts +++ b/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceExplicitly.ts @@ -3,6 +3,11 @@ import { camelCase, pascalCase } from 'change-case'; /** * determines whether property name is an intuitive reference to a domain object * + * options + * - entire match + * - prefix match + * - suffix match + * * for example: * - `address: Address` => true * - `homeAddress: Address` => true @@ -25,7 +30,7 @@ export const isPropertyNameAReferenceExplicitly = ({ propertyName: string; domainObjectName: string; }): boolean => { - // remove the potential `uuid` or `uuids` suffix of the property name (used in implicit uuid references) + // remove the potential `uuid(s)` suffix of the property name (used in implicit references) const propertyName = propertyNamePotentiallyWithIrrelevantSuffixes.replace( /Uuids?$/, '', @@ -43,6 +48,12 @@ export const isPropertyNameAReferenceExplicitly = ({ ).test(propertyName); // e.g., /Engineers?$/.test('leadEngineer'); if (namedAfterItAsASuffix) return true; + // check whether the property is named after it as a prefix + const namedAfterItAsAPrefix = new RegExp( + `^${camelCase(domainObjectName)}s?`, + ).test(propertyName); // e.g., /^Engineers?/.test('engineerLead'); + if (namedAfterItAsAPrefix) return true; + // otherwise, false return false; }; diff --git a/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceIntuitively.test.ts b/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceIntuitively.test.ts index 69bd28a..5abe56d 100644 --- a/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceIntuitively.test.ts +++ b/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceIntuitively.test.ts @@ -4,17 +4,17 @@ describe('isPropertyNameAReferenceIntuitively', () => { const cases: { propertyName: string; domainObjectName: string; - expectedResult: boolean; + expectedResult: false | { via: string }; }[] = [ { propertyName: 'address', domainObjectName: 'Address', - expectedResult: true, + expectedResult: { via: 'Address' }, }, { propertyName: 'homeAddress', domainObjectName: 'Address', - expectedResult: true, + expectedResult: { via: 'Address' }, }, { propertyName: 'home', @@ -24,32 +24,32 @@ describe('isPropertyNameAReferenceIntuitively', () => { { propertyName: 'engineer', domainObjectName: 'Engineer', - expectedResult: true, + expectedResult: { via: 'Engineer' }, }, { propertyName: 'engineers', domainObjectName: 'Engineer', - expectedResult: true, + expectedResult: { via: 'Engineer' }, }, { propertyName: 'engineerUuid', domainObjectName: 'Engineer', - expectedResult: true, + expectedResult: { via: 'Engineer' }, }, { propertyName: 'leadEngineerUuid', domainObjectName: 'Engineer', - expectedResult: true, + expectedResult: { via: 'Engineer' }, }, { propertyName: 'engineerUuids', domainObjectName: 'Engineer', - expectedResult: true, + expectedResult: { via: 'Engineer' }, }, { propertyName: 'assignedEngineerUuids', domainObjectName: 'Engineer', - expectedResult: true, + expectedResult: { via: 'Engineer' }, }, { propertyName: 'lead', @@ -69,22 +69,24 @@ describe('isPropertyNameAReferenceIntuitively', () => { { propertyName: 'leadEngineerUuid', domainObjectName: 'LeadEngineer', - expectedResult: true, + expectedResult: { via: 'LeadEngineer' }, }, { propertyName: 'headEngineerUuid', domainObjectName: 'LeadEngineer', - expectedResult: true, + expectedResult: { via: 'Engineer' }, }, { propertyName: 'engineerUuid', domainObjectName: 'LeadEngineer', - expectedResult: true, + expectedResult: { via: 'Engineer' }, }, ]; cases.forEach((testCase) => { - it(`should return ${testCase.expectedResult} for ${testCase.propertyName}: ${testCase.domainObjectName}`, () => { + it(`should return ${JSON.stringify(testCase.expectedResult)} for ${ + testCase.propertyName + }: ${testCase.domainObjectName}`, () => { expect( isPropertyNameAReferenceIntuitively({ propertyName: testCase.propertyName, diff --git a/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceIntuitively.ts b/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceIntuitively.ts index 6414a65..7890209 100644 --- a/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceIntuitively.ts +++ b/src/relationships/isPropertyNameAReference/isPropertyNameAReferenceIntuitively.ts @@ -4,6 +4,9 @@ import { isPropertyNameAReferenceExplicitly } from './isPropertyNameAReferenceEx /** * determines whether property name is an intuitive reference to a domain object * + * note + * - shares the qualifier-stripped dobj.name via which the reference became intuitive + * * for example: * - `address: Address` => true * - `homeAddress: Address` => true @@ -25,7 +28,7 @@ export const isPropertyNameAReferenceIntuitively = ({ }: { propertyName: string; domainObjectName: string; -}): boolean => { +}): false | { via: string } => { let qualifiersToDrop = 0; let iterationLimitExceeded = false; while (!iterationLimitExceeded) { @@ -46,7 +49,7 @@ export const isPropertyNameAReferenceIntuitively = ({ }); // if its an explicit reference now, then its an intuitive reference - if (isExplicitReferenceNow) return true; + if (isExplicitReferenceNow) return { via: domainObjectNameMinusQualifiers }; // otherwise, go another layer deeper and try again qualifiersToDrop += 1;