-
Notifications
You must be signed in to change notification settings - Fork 343
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(snakeCase): add snakeCase (#152)
* feat(snakeCase): Add caseSplitPattern RegExp const * feat(snakeCase): Add caseSplitPattern test code * feat(snakeCase): Add snakeCase function * feat(snakeCase): Add snakeCase test code * feat(snakeCase): Add snakeCase docs * feat(snakeCase): Add snakeCase benchmarks * chore: Add string export * fix(snakeCase): constants public api * Update docs/ko/reference/string/snakeCase.md * Update docs/ko/reference/string/snakeCase.md * Update docs/reference/string/snakeCase.md --------- Co-authored-by: Sojin Park <raon0211@gmail.com>
- Loading branch information
1 parent
883553b
commit d48900f
Showing
16 changed files
with
234 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { bench, describe } from 'vitest'; | ||
import { snakeCase as snakeCaseToolkit } from 'es-toolkit'; | ||
import { snakeCase as snakeCaseLodash } from 'lodash'; | ||
|
||
describe('snakeCase', () => { | ||
bench('es-toolkit/snakeCase', () => { | ||
const str = 'camleCase'; | ||
snakeCaseToolkit(str); | ||
}); | ||
|
||
bench('lodash/snakeCase', () => { | ||
const str = 'camelCase'; | ||
snakeCaseLodash(str); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# snakeCase | ||
|
||
문자열을 스네이크 표기법으로 변환해요. | ||
|
||
스네이크 표기법은 여러 단어로 구성된 식별자에서 각 단어를 소문자로 작성하고, 단어 사이를 밑줄(\_)로 연결하는 명명 규칙이에요. 예를 들어서, `snake_case` 처럼 작성해요. | ||
|
||
## 인터페이스 | ||
|
||
```typescript | ||
function snakeCase(str: string): string; | ||
``` | ||
|
||
### 파라미터 | ||
|
||
- `str` (`string`): 스네이크 케이스로 변환할 문자열이에요. | ||
|
||
### 반환 값 | ||
|
||
(`string`) 스네이크 케이스로 변환된 문자열이에요. | ||
|
||
## 예시 | ||
|
||
```typescript | ||
import { snakeCase } from 'es-toolkit/string'; | ||
|
||
snakeCase('camelCase'); // returns 'camel_case' | ||
snakeCase('some whitespace'); // returns 'some_whitespace' | ||
snakeCase('hyphen-text'); // returns 'hyphen_text' | ||
snakeCase('HTTPRequest'); // returns 'http_request' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# snakeCase | ||
|
||
Converts a string to snake case. | ||
|
||
Snake case is the naming convention in which each word is written in lowercase and separated by an underscore (\_) character. For example, `snake_case`. | ||
|
||
## Signature | ||
|
||
```typescript | ||
function snakeCase(str: string): string; | ||
``` | ||
|
||
### Parameters | ||
|
||
- `str` (`string`): The string that is to be changed to snake case. | ||
|
||
### Returns | ||
|
||
(`string`) The converted string to snake case. | ||
|
||
## Examples | ||
|
||
```typescript | ||
import { snakeCase } from 'es-toolkit/string'; | ||
|
||
snakeCase('camelCase'); // returns 'camel_case' | ||
snakeCase('some whitespace'); // returns 'some_whitespace' | ||
snakeCase('hyphen-text'); // returns 'hyphen_text' | ||
snakeCase('HTTPRequest'); // returns 'http_request' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { describe, expect, it } from 'vitest'; | ||
import { CASE_SPLIT_PATTERN } from './caseSplitPattern'; | ||
describe('caseSplitPattern', () => { | ||
it('should match camelCase', async () => { | ||
const str = 'camelCase'; | ||
const matches = str.match(CASE_SPLIT_PATTERN); | ||
expect(matches).toEqual(['camel', 'Case']); | ||
}); | ||
|
||
it('should match snake_case', async () => { | ||
const str = 'snake_case'; | ||
const matches = str.match(CASE_SPLIT_PATTERN); | ||
expect(matches).toEqual(['snake', 'case']); | ||
}); | ||
|
||
it('should match kebab-case', async () => { | ||
const str = 'kebab-case'; | ||
const matches = str.match(CASE_SPLIT_PATTERN); | ||
expect(matches).toEqual(['kebab', 'case']); | ||
}); | ||
|
||
it('should handle mixed formats', async () => { | ||
const str = 'camelCase_snake_case-kebabCase'; | ||
const matches = str.match(CASE_SPLIT_PATTERN); | ||
expect(matches).toEqual(['camel', 'Case', 'snake', 'case', 'kebab', 'Case']); | ||
}); | ||
|
||
it('should match acronyms', async () => { | ||
const str = 'HTTPRequest'; | ||
const matches = str.match(CASE_SPLIT_PATTERN); | ||
expect(matches).toEqual(['HTTP', 'Request']); | ||
}); | ||
|
||
it('should match special characters', async () => { | ||
const str = 'special_characters@123'; | ||
const matches = str.match(CASE_SPLIT_PATTERN); | ||
expect(matches).toEqual(['special', 'characters', '123']); | ||
}); | ||
|
||
it('should handle leading and trailing whitespace', async () => { | ||
const str = ' leading_and_trailing_whitespace '; | ||
const matches = str.match(CASE_SPLIT_PATTERN); | ||
expect(matches).toEqual(['leading', 'and', 'trailing', 'whitespace']); | ||
}); | ||
|
||
it('should handle underscores', async () => { | ||
const str = 'underscore_case_example'; | ||
const matches = str.match(CASE_SPLIT_PATTERN); | ||
expect(matches).toEqual(['underscore', 'case', 'example']); | ||
}); | ||
|
||
it('should handle single character words', async () => { | ||
const str = 'aB'; | ||
const matches = str.match(CASE_SPLIT_PATTERN); | ||
expect(matches).toEqual(['a', 'B']); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/** | ||
* Regular expression pattern to split strings into words for various case conversions | ||
* | ||
* This pattern matchs sequences of characters in a string, considering the following case: | ||
* - Sequences of two or more uppercase letters followed by an uppercase letter and lowercase letters or digits (for acronyms) | ||
* - Sequences of one uppercase letter optionally followed by lowercase letters and digits | ||
* - Single uppercase letters | ||
* - Sequences of digis | ||
* | ||
* The resulting match can be used to convert camelCase, snake_case, kebab-case, and other mixed formats into | ||
* a consistent format like snake case. | ||
* | ||
* @example | ||
* const matches = 'camelCaseHTTPRequest'.match(CASE_SPLIT_PATTERN); | ||
* // matchs: ['camel', 'Case', 'HTTP', 'Request'] | ||
*/ | ||
|
||
export const CASE_SPLIT_PATTERN = /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { CASE_SPLIT_PATTERN } from './caseSplitPattern'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { snakeCase } from './snakeCase.ts'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { describe, it, expect } from 'vitest'; | ||
import { snakeCase } from './snakeCase'; | ||
|
||
describe('snakeCase', () => { | ||
it('should change camel case to snake case', async () => { | ||
expect(snakeCase('camelCase')).toEqual('camel_case'); | ||
}); | ||
|
||
it('should change space to underscore', async () => { | ||
expect(snakeCase('some whitespace')).toEqual('some_whitespace'); | ||
}); | ||
|
||
it('should change hyphen to underscore', async () => { | ||
expect(snakeCase('hyphen-text')).toEqual('hyphen_text'); | ||
}); | ||
|
||
it('should change Acronyms to small letter', async () => { | ||
expect(snakeCase('HTTPRequest')).toEqual('http_request'); | ||
}); | ||
|
||
it('should handle leading and trailing whitepspace', async () => { | ||
expect(snakeCase(' leading and trailing whitespace')).toEqual('leading_and_trailing_whitespace'); | ||
}); | ||
|
||
it('should handle special characters correctly', async () => { | ||
expect(snakeCase('special@characters!')).toEqual('special_characters'); | ||
}); | ||
|
||
it('should handle strings that are already in snake_case', async () => { | ||
expect(snakeCase('snake_case')).toEqual('snake_case'); | ||
}); | ||
|
||
it('should work with an empty string', async () => { | ||
expect(snakeCase('')).toEqual(''); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { CASE_SPLIT_PATTERN } from '../constants'; | ||
|
||
/** | ||
* Converts a string to snake case. | ||
* | ||
* Snake case is the naming convention in which each word is written in lowercase and separated by an underscore (_) character. | ||
* | ||
* @param {string} str - The string that is to be changed to snake case. | ||
* @returns {string} - The converted string to snake case. | ||
* | ||
* @example | ||
* const convertedStr1 = snakeCase('camelCase') // returns 'camel_case' | ||
* const convertedStr2 = snakeCase('some whitespace') // returns 'some_whitespace' | ||
* const convertedStr3 = snakeCase('hyphen-text') // returns 'hyphen_text' | ||
* const convertedStr4 = snakeCase('HTTPRequest') // returns 'http_request' | ||
*/ | ||
|
||
export const snakeCase = (str: string): string => { | ||
const splitWords = str.match(CASE_SPLIT_PATTERN) || []; | ||
return splitWords.map(word => word.toLowerCase()).join('_'); | ||
}; |