Skip to content

Commit

Permalink
fix(#236): update titleCase to handle hyphens and parenthesis (#252)
Browse files Browse the repository at this point in the history
* chore: update titleCase

* chore: add more tests

* chore: refactor
  • Loading branch information
Benmuiruri authored Feb 11, 2025
1 parent 985d18d commit 926bc35
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 13 deletions.
34 changes: 28 additions & 6 deletions src/validation/validator-name.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,34 @@ export default class ValidatorName implements IValidator {
}

private titleCase(value: string): string {
const words = value.toLowerCase().split(' ');
const titleCase = (word: string) => word[0].toUpperCase() + word.slice(1);
const isRomanNumeral = /^[ivx]+$/ig;
const titleCased = words
if (!value) {
return '';
}

const titleCase = (word: string) => word[0]?.toUpperCase() + word.slice(1);

const isRomanNumeral = /^[ivx]+$/i;
const hasForwardSlash = /\//g;
const hasApostrophe = /\s*'\s*/g;
const hasParentheses = /\(([^)]+)\)/g;
const hasExtraSpaces = /\s+/g;

const splitAndProcess = (value: string, delimiter: string) => {
return value
.split(delimiter)
.map(word => word.match(isRomanNumeral) ? word.toUpperCase() : titleCase(word))
.join(delimiter);
};

return value.toLowerCase()
.replace(hasForwardSlash, ' / ')
.replace(hasApostrophe, '\'')
.replace(hasParentheses, match => `(${titleCase(match.slice(1, -1))})`)
.split(' ')
.filter(Boolean)
.map(word => word.match(isRomanNumeral) ? word.toUpperCase() : titleCase(word)).join(' ');
return titleCased.replace(/ '/g, '\'');
.map(word => splitAndProcess(word, '-'))
.join(' ')
.replace(hasExtraSpaces, ' ')
.trim();
}
}
4 changes: 2 additions & 2 deletions test/lib/credentials-file.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('lib/credentials-file.ts', () => {
expect(actual).to.deep.eq([{
filename: 'contacttype-name.csv',
content: `friendly replacement,friendly PARENT,friendly GRANDPARENT,friendly,name,phone,role,username,password
,Parent-name,,Place,contact,0712 344321,role,,
,Parent-Name,,Place,contact,0712 344321,role,,
`
}]);
});
Expand All @@ -61,7 +61,7 @@ describe('lib/credentials-file.ts', () => {
expect(actual).to.deep.eq([{
filename: 'contacttype-name.csv',
content: `friendly replacement,friendly PARENT,friendly GRANDPARENT,friendly,name,phone,role,username,password
,Parent-name,,Place,contact,,role,,
,Parent-Name,,Place,contact,,role,,
`
}]);
});
Expand Down
6 changes: 3 additions & 3 deletions test/lib/manage-hierarchy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('lib/manage-hierarchy.ts', () => {
const sessionCache = new SessionCache();

const jobParams = await ManageHierarchyLib.getJobDetails(formData, contactType, sessionCache, chtApiWithDocs());
expect(jobParams).to.have.property('jobName').that.equals('move_[From Sub.C-h-u]_to_[To Sub]');
expect(jobParams).to.have.property('jobName').that.equals('move_[From Sub.C-H-U]_to_[To Sub]');
expect(jobParams).to.have.property('jobData').that.deep.include({
action: 'move',
sourceId: 'from-chu-id',
Expand Down Expand Up @@ -113,7 +113,7 @@ describe('lib/manage-hierarchy.ts', () => {
const sessionCache = new SessionCache();

const jobParams = await ManageHierarchyLib.getJobDetails(formData, contactType, sessionCache, chtApiWithDocs());
expect(jobParams).to.have.property('jobName').that.equals('merge_[From Sub.C-h-u]_to_[To Sub.Destination]');
expect(jobParams).to.have.property('jobName').that.equals('merge_[From Sub.C-H-U]_to_[To Sub.Destination]');
expect(jobParams).to.have.property('jobData').that.deep.include({
action: 'merge',
sourceId: 'from-chu-id',
Expand All @@ -135,7 +135,7 @@ describe('lib/manage-hierarchy.ts', () => {
const sessionCache = new SessionCache();

const jobParams = await ManageHierarchyLib.getJobDetails(formData, contactType, sessionCache, chtApiWithDocs());
expect(jobParams).to.have.property('jobName').that.equals('delete_[From Sub.C-h-u]');
expect(jobParams).to.have.property('jobName').that.equals('delete_[From Sub.C-H-U]');
expect(jobParams).to.have.property('jobData').that.deep.include({
action: 'delete',
sourceId: 'from-chu-id',
Expand Down
7 changes: 5 additions & 2 deletions test/validation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,12 @@ const scenarios: Scenario[] = [
{ type: 'name', prop: undefined, isValid: false, error: 'Required' },
{ type: 'name', prop: 'abc', isValid: true, formatted: 'Abc' },
{ type: 'name', prop: 'a b c', isValid: true, formatted: 'A B C' },
{ type: 'name', prop: 'Mr. Sand(m-a-n)', isValid: true, formatted: 'Mr Sand(m-a-n)' },
{ type: 'name', prop: 'WELDON KO(E)CH \n', isValid: true, formatted: 'Weldon Ko(e)ch' },
{ type: 'name', prop: 'Mr. Sand(m-a-n)', isValid: true, formatted: 'Mr Sand(M-A-N)' },
{ type: 'name', prop: 'WELDON KO(E)CH \n', isValid: true, formatted: 'Weldon Ko(E)ch' },
{ type: 'name', prop: 'S \'am \'s', isValid: true, formatted: 'S\'am\'s' },
{ type: 'name', prop: 'this-is-(a-place)', isValid: true, formatted: 'This-Is-(A-Place)' },
{ type: 'name', prop: 'mr. chp-(per-son)', isValid: true, formatted: 'Mr Chp-(Per-Son)' },
{ type: 'name', prop: 'ma-#ma-(pa-pa)', isValid: true, formatted: 'Ma-Ma-(Pa-Pa)' },
{ type: 'name', prop: 'KYAMBOO/KALILUNI', isValid: true, formatted: 'Kyamboo / Kaliluni' },
{ type: 'name', prop: 'NZATANI / ILALAMBYU', isValid: true, formatted: 'Nzatani / Ilalambyu' },
{ type: 'name', prop: 'Sam\'s CHU', propertyParameter: ['CHU', 'Comm Unit'], isValid: true, formatted: 'Sam\'s' },
Expand Down

0 comments on commit 926bc35

Please sign in to comment.