diff --git a/tools/build-helpers/package.json b/tools/build-helpers/package.json index 8daa385f1..94229efa6 100644 --- a/tools/build-helpers/package.json +++ b/tools/build-helpers/package.json @@ -5,6 +5,9 @@ "description": "A internal used package with helpers.", "main": "helpers.ts", "types": "helpers.ts", + "scripts": { + "test": "vitest run" + }, "author": "", "license": "ISC", "type": "module", diff --git a/tools/build-helpers/src/toCamelCase.spec.ts b/tools/build-helpers/src/toCamelCase.spec.ts new file mode 100644 index 000000000..c382160ab --- /dev/null +++ b/tools/build-helpers/src/toCamelCase.spec.ts @@ -0,0 +1,42 @@ +import { describe, expect, it } from 'vitest'; +import { toCamelCase } from './toCamelCase.ts'; + +describe('toCamelCase', () => { + it('converts kebab-case icon names', () => { + expect(toCamelCase('arrow-up')).toBe('arrowUp'); + expect(toCamelCase('circle-arrow-out-down-left')).toBe('circleArrowOutDownLeft'); + expect(toCamelCase('arrow-up-0-1')).toBe('arrowUp01'); + }); + + it('treats whitespace, hyphens and underscores as separators', () => { + expect(toCamelCase('foo_bar')).toBe('fooBar'); + expect(toCamelCase('foo bar')).toBe('fooBar'); + expect(toCamelCase('foo\tbar')).toBe('fooBar'); + expect(toCamelCase('foo - _\tbar')).toBe('fooBar'); + expect(toCamelCase('-foo')).toBe('Foo'); + }); + + it('lowercases only a leading capital letter', () => { + expect(toCamelCase('Foo-bar')).toBe('fooBar'); + expect(toCamelCase('FooBar')).toBe('fooBar'); + expect(toCamelCase('alreadyCamelCase')).toBe('alreadyCamelCase'); + }); + + it('keeps separators that are not followed by a word character', () => { + expect(toCamelCase('foo-')).toBe('foo-'); + expect(toCamelCase('foo__')).toBe('foo__'); + expect(toCamelCase('foo\t!')).toBe('foo\t!'); + expect(toCamelCase('')).toBe(''); + }); + + it('handles long runs of tabs in linear time', () => { + const input = `a${'\t'.repeat(100_000)}!`; + + const start = performance.now(); + const result = toCamelCase(input); + const duration = performance.now() - start; + + expect(result).toBe(input); + expect(duration).toBeLessThan(100); + }); +}); diff --git a/tools/build-helpers/src/toCamelCase.ts b/tools/build-helpers/src/toCamelCase.ts index 4b049144e..3e25202bd 100644 --- a/tools/build-helpers/src/toCamelCase.ts +++ b/tools/build-helpers/src/toCamelCase.ts @@ -5,6 +5,6 @@ * @returns {string} A camelized string */ export const toCamelCase = (string: string): string => - string.replace(/^([A-Z])|[\s-_]+(\w)/g, (match, p1, p2) => - p2 ? p2.toUpperCase() : p1.toLowerCase(), + string.replace(/^([A-Z])|[\s-_]+(\w)?/g, (match, p1, p2) => + p1 ? p1.toLowerCase() : p2 ? p2.toUpperCase() : match, );