feat(camelCase): implement camelCase in compat layer (#507)
Some checks are pending
CI / codecov (push) Waiting to run
Release / release (push) Waiting to run

* feat(camelCase): implement `camelCase` in compat layer

* A bench

* Change normalize way
This commit is contained in:
Dayong Lee 2024-09-10 21:05:04 +09:00 committed by GitHub
parent 1d15d7414d
commit 9c7218330e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 101 additions and 0 deletions

View File

@ -1,5 +1,6 @@
import { bench, describe } from 'vitest';
import { camelCase as camelCaseToolkit } from 'es-toolkit';
import { camelCase as camelCaseToolkitCompat } from 'es-toolkit/compat';
import { camelCase as camelCaseLodash } from 'lodash';
describe('camelCase', () => {
@ -8,6 +9,11 @@ describe('camelCase', () => {
camelCaseToolkit(str);
});
bench('es-toolkit/compat/camelCase', () => {
const str = 'kebab-case';
camelCaseToolkitCompat(str);
});
bench('lodash/camelCase', () => {
const str = 'kebab-case';
camelCaseLodash(str);

View File

@ -0,0 +1,9 @@
export function normalizeForCase(str: string | object): string {
if (typeof str === 'object') {
str = str.toString();
}
// Remove constraction apostrophes
str = str.replace(/['\u2019]/g, '');
return str;
}

View File

@ -78,6 +78,7 @@ export { isWeakSet } from './predicate/isWeakSet.ts';
export { conforms } from './predicate/conforms.ts';
export { conformsTo } from './predicate/conformsTo.ts';
export { camelCase } from './string/camelCase.ts';
export { startsWith } from './string/startsWith.ts';
export { endsWith } from './string/endsWith.ts';
export { padStart } from './string/padStart.ts';

View File

@ -0,0 +1,63 @@
import { describe, it, expect } from 'vitest';
import { camelCase } from './camelCase';
describe('camelCase', () => {
it('should work with numbers', () => {
expect(camelCase('12 feet')).toBe('12Feet');
expect(camelCase('enable 6h format')).toBe('enable6HFormat');
expect(camelCase('enable 24H format')).toBe('enable24HFormat');
expect(camelCase('too legit 2 quit')).toBe('tooLegit2Quit');
expect(camelCase('walk 500 miles')).toBe('walk500Miles');
expect(camelCase('xhr2 request')).toBe('xhr2Request');
});
it('should handle acronyms', () => {
expect(camelCase('safe HTML')).toBe('safeHtml');
expect(camelCase('safeHTML')).toBe('safeHtml');
expect(camelCase('escape HTML entities')).toBe('escapeHtmlEntities');
expect(camelCase('escapeHTMLEntities')).toBe('escapeHtmlEntities');
expect(camelCase('XMLHttpRequest')).toBe('xmlHttpRequest');
expect(camelCase('XmlHTTPRequest')).toBe('xmlHttpRequest');
// As Lodash test codes, it should be 'ids'. But real lodash returns 'iDs'.
expect(camelCase('IDs')).toBe('iDs');
// As Lodash test codes, it should be 'productXmls'. But real lodash returns 'productXmLs'.
expect(camelCase('Product XMLs')).toBe('productXmLs');
});
const strings = ['foo bar', 'Foo bar', 'foo Bar', 'Foo Bar', 'FOO BAR', 'fooBar', '--foo-bar--', '__foo_bar__'];
it('should convert string to camel case', () => {
const actual = strings.map(camelCase);
const expected = actual.map(() => 'fooBar');
expect(actual).toEqual(expected);
});
it('should handle double-converting strings', () => {
const actual = strings.map(str => camelCase(camelCase(str)));
const expected = actual.map(() => 'fooBar');
expect(actual).toEqual(expected);
});
it('should remove constraction apostrophes', () => {
const apostrophes = ["'", '\u2019'];
const postfixes = ['d', 'll', 'm', 're', 's', 't', 've'];
const actual = apostrophes.map(apostrophe => postfixes.map(postfix => camelCase(`a b${apostrophe}${postfix} c`)));
const expected = apostrophes.map(() => postfixes.map(postfixes => `aB${postfixes}C`));
expect(actual).toEqual(expected);
});
it('should remove remove Latin mathematical operators', () => {
expect(camelCase('\xd7')).toBe('');
expect(camelCase('\xf7')).toBe('');
});
it('should coerce string to a string', () => {
expect(camelCase(Object('foo bar'))).toBe('fooBar');
expect(camelCase({ toString: () => 'foo bar' })).toBe('fooBar');
});
});

View File

@ -0,0 +1,22 @@
import { camelCase as camelCaseToolkit } from '../../string/camelCase';
import { normalizeForCase } from '../_internal/normalizeForCase';
/**
* Converts a string to camel case.
*
* Camel case is the naming convention in which the first word is written in lowercase and
* each subsequent word begins with a capital letter, concatenated without any separator characters.
*
* @param {string | object} str - The string that is to be changed to camel case.
* @returns {string} - The converted string to camel case.
*
* @example
* const convertedStr1 = camelCase('camelCase') // returns 'camelCase'
* const convertedStr2 = camelCase('some whitespace') // returns 'someWhitespace'
* const convertedStr3 = camelCase('hyphen-text') // returns 'hyphenText'
* const convertedStr4 = camelCase('HTTPRequest') // returns 'httpRequest'
*/
export function camelCase(str: string | object): string {
return camelCaseToolkit(normalizeForCase(str));
}