Skip to content

Commit 41bc93b

Browse files
committed
fix: improve entity name formatting
1 parent 0a6fff6 commit 41bc93b

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

src/utils/string-utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export function applyEntityNameCase(input: string, entityNameCase: EntityNameCas
2020
for (;;) {
2121
input = input
2222
.replace(/([a-z0-9])([A-Z][a-z]|[A-Z]{2,})/g, '$1 $2')
23+
.replace(/([a-z][0-9]+)([a-z])/g, '$1 $2')
2324
.replace(/([A-Z]{2,}[0-9]*)([A-Z][a-z])/g, '$1 $2');
2425
if (input === before) {
2526
break;
@@ -28,9 +29,15 @@ export function applyEntityNameCase(input: string, entityNameCase: EntityNameCas
2829
}
2930

3031
const bits = input
32+
.replace(/([a-z])([A-Z])/g, '$1 $2')
3133
.split(/[^a-zA-Z0-9]+/)
3234
.map((bit) => bit.toLowerCase())
3335
.filter((bit) => Boolean(bit));
36+
37+
if (bits.length === 0) {
38+
return '';
39+
}
40+
3441
if (entityNameCase === 'pascalCase') {
3542
return bits.map(ucFirst).join('');
3643
}

src/utils/test/string-utils.test.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import {applyEntityNameCase} from '../string-utils';
2+
3+
// Some of the test cases were taken from https://github.com/sindresorhus/camelcase/blob/main/test.js
4+
const camelCaseTestCases = {
5+
foo: 'foo',
6+
IDs: 'ids',
7+
FooIDs: 'fooIds',
8+
'foo-bar': 'fooBar',
9+
'foo-bar-baz': 'fooBarBaz',
10+
'foo--bar': 'fooBar',
11+
'--foo-bar': 'fooBar',
12+
'--foo--bar': 'fooBar',
13+
'FOO-BAR': 'fooBar',
14+
'-foo-bar-': 'fooBar',
15+
'--foo--bar--': 'fooBar',
16+
'foo-1': 'foo1',
17+
'foo.bar': 'fooBar',
18+
'foo..bar': 'fooBar',
19+
'..foo..bar..': 'fooBar',
20+
foo_bar: 'fooBar',
21+
__foo__bar__: 'fooBar',
22+
'foo bar': 'fooBar',
23+
' foo bar ': 'fooBar',
24+
'-': '',
25+
' - ': '',
26+
fooBar: 'fooBar',
27+
'fooBar-baz': 'fooBarBaz',
28+
'fooBarBaz-bazzy': 'fooBarBazBazzy',
29+
FBBazzy: 'fbBazzy',
30+
F: 'f',
31+
FooBar: 'fooBar',
32+
Foo: 'foo',
33+
FOO: 'foo',
34+
'--': '',
35+
'': '',
36+
_: '',
37+
' ': '',
38+
'.': '',
39+
'..': '',
40+
' ': '',
41+
__: '',
42+
'--__--_--_': '',
43+
XMLHttpRequest: 'xmlHttpRequest',
44+
AjaxXMLHttpRequest: 'ajaxXmlHttpRequest',
45+
'Ajax-XMLHttpRequest': 'ajaxXmlHttpRequest',
46+
'mGridCol6@md': 'mGridCol6Md',
47+
'A::a': 'aA',
48+
Hello1World: 'hello1World',
49+
Hello11World: 'hello11World',
50+
hello1world: 'hello1World',
51+
Hello1World11foo: 'hello1World11Foo',
52+
Hello1: 'hello1',
53+
hello1: 'hello1',
54+
h2w: 'h2W'
55+
};
56+
57+
describe('string-utils', () => {
58+
describe('applyEntityNameCase()', () => {
59+
it('should format a sentence', () => {
60+
expect(applyEntityNameCase('Hello World!', 'kebabCase')).toBe('hello-world');
61+
});
62+
it('should format a filename', () => {
63+
expect(applyEntityNameCase('filename-without-ext', 'snakeCase')).toBe('filename_without_ext');
64+
});
65+
it('should format a snake-case', () => {
66+
expect(applyEntityNameCase('CONST_NAME_EXAMPLE', 'pascalCase')).toBe('ConstNameExample');
67+
});
68+
it('should format a simple camel-case string', () => {
69+
expect(applyEntityNameCase('simpleCamelCaseString', 'kebabCase')).toBe('simple-camel-case-string');
70+
});
71+
it('should format a camel-case string with abbrev', () => {
72+
expect(applyEntityNameCase('openAPILibrary', 'kebabCase')).toBe('open-api-library');
73+
});
74+
it('should format a camel-case string with abbrev with numbers', () => {
75+
expect(applyEntityNameCase('publicV2Api', 'kebabCase')).toBe('public-v2-api');
76+
});
77+
it('should work for the specified camelCase testcases', () => {
78+
for (const [input, expected] of Object.entries(camelCaseTestCases)) {
79+
expect(applyEntityNameCase(input, 'camelCase')).toBe(expected);
80+
}
81+
});
82+
});
83+
});

0 commit comments

Comments
 (0)