From 4b046a7d147d171c9448f9f590929e62d6695f46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E5=B0=8F=E5=A2=A8?= <2291200076@qq.com> Date: Tue, 2 Apr 2024 21:21:47 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=96=E5=86=99=E6=B5=8B=E8=AF=95=E7=94=A8?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main-code/text-conversion.ts | 18 +- .../{text-split.ts => text-transform.ts} | 112 ++--- src/test/extension.test.ts | 31 ++ src/test/test-case.ts | 434 +++++++++++------- .../{support-case.ts => support-case-type.ts} | 164 +++---- src/type-definition/test-case-type.ts | 15 + 6 files changed, 450 insertions(+), 324 deletions(-) rename src/main-code/{text-split.ts => text-transform.ts} (95%) rename src/type-definition/{support-case.ts => support-case-type.ts} (95%) create mode 100644 src/type-definition/test-case-type.ts diff --git a/src/main-code/text-conversion.ts b/src/main-code/text-conversion.ts index 32483ec..eb69305 100644 --- a/src/main-code/text-conversion.ts +++ b/src/main-code/text-conversion.ts @@ -1,10 +1,10 @@ -import { transformText } from './text-split'; +import { transformText } from './text-transform'; /** * 转小驼峰 to Camel Case - * + * * @param {string} str user selection - * @returns + * @returns * @since 2024-03-28 */ export function toCamelCase(str: string): string { @@ -19,9 +19,9 @@ export function toCamelCase(str: string): string { /** * 转大驼峰 to Pascal Case - * + * * @param {string} str user selection - * @returns + * @returns * @since 2024-03-28 */ export function toPascalCase(str: string): string { @@ -30,9 +30,9 @@ export function toPascalCase(str: string): string { /** * 转大写 to Upper Case - * + * * @param {string} str user selection - * @returns + * @returns * @since 2024-03-28 */ export function toUpperCase(str: string): string { @@ -41,9 +41,9 @@ export function toUpperCase(str: string): string { /** * 转小写 to Lower Case - * + * * @param {string} str user selection - * @returns + * @returns * @since 2024-03-28 */ export function toLowerCase(str: string): string { diff --git a/src/main-code/text-split.ts b/src/main-code/text-transform.ts similarity index 95% rename from src/main-code/text-split.ts rename to src/main-code/text-transform.ts index 53fd2cd..862de42 100644 --- a/src/main-code/text-split.ts +++ b/src/main-code/text-transform.ts @@ -1,56 +1,56 @@ - -const logDebugInfo = false; - -/** - * 分词 - * - * @param str - * @since 2024-04-02 - */ -export function transformText(input: string): string { - logDebugInfo && console.log('input ', '->' + input + '<-'); - - // 记录首尾空格 - const leadingSpaces = input.match(/^ +/); - const trailingSpaces = input.match(/ +$/); - - // 去除首尾空格 - input = input.trim(); - - // 使用正则表达式匹配中英文字母、连字符、下划线和空格 - let result = input.replace(/([A-Za-z\-_ ]+)/g, (match: string) => { - - // 替换连字符为 '|' (如有多个则合并) - match = match.replace(/[-_ ]+/g, '|'); - - // 拆分连续的小写字母和大写字母为多个单词 - match = match.replace(/([a-z])([A-Z])/g, '$1|$2'); - - // 分割 - let words = match.split('|'); - - // 处理特殊情况,如 'ENFADADO' 不应该被拆分 - words = words.map(word => { - if (word.toUpperCase() === word && word.length > 1) { - return word.toLowerCase(); - } - return word.replace(/([A-Z])/g, '|$1').toLowerCase(); - }); - - // 重新组合单词 - return '|' + words.join('|') + '|'; - }); - - // 如果有多个 | 将其合并 - result = result.replace(/[\|]+/g, '|'); - - // 如果首尾有 | 将其替换掉 - result = result.replace(/(^[\|]+|[\|]+$)/g, ''); - - // 还原首尾空格 - // result = (leadingSpaces ? (leadingSpaces[0] + '|') : '') + result + (trailingSpaces ? ('|' + trailingSpaces[0]) : ''); - result = (leadingSpaces ? leadingSpaces[0] : '') + result + (trailingSpaces ? trailingSpaces[0] : ''); - - logDebugInfo && console.log('output ', '->' + result + '<-'); - return result; -} + +const logDebugInfo = false; + +/** + * 分词 + * + * @param str + * @since 2024-04-02 + */ +export function transformText(input: string): string { + logDebugInfo && console.log('input ', '->' + input + '<-'); + + // 记录首尾空格 + const leadingSpaces = input.match(/^ +/); + const trailingSpaces = input.match(/ +$/); + + // 去除首尾空格 + input = input.trim(); + + // 使用正则表达式匹配中英文字母、连字符、下划线和空格 + let result = input.replace(/([A-Za-z\-_ ]+)/g, (match: string) => { + + // 替换连字符为 '|' (如有多个则合并) + match = match.replace(/[-_ ]+/g, '|'); + + // 拆分连续的小写字母和大写字母为多个单词 + match = match.replace(/([a-z])([A-Z])/g, '$1|$2'); + + // 分割 + let words = match.split('|'); + + // 处理特殊情况,如 'ENFADADO' 不应该被拆分 + words = words.map(word => { + if (word.toUpperCase() === word && word.length > 1) { + return word.toLowerCase(); + } + return word.replace(/([A-Z])/g, '|$1').toLowerCase(); + }); + + // 重新组合单词 + return '|' + words.join('|') + '|'; + }); + + // 如果有多个 | 将其合并 + result = result.replace(/[\|]+/g, '|'); + + // 如果首尾有 | 将其替换掉 + result = result.replace(/(^[\|]+|[\|]+$)/g, ''); + + // 还原首尾空格 + // result = (leadingSpaces ? (leadingSpaces[0] + '|') : '') + result + (trailingSpaces ? ('|' + trailingSpaces[0]) : ''); + result = (leadingSpaces ? leadingSpaces[0] : '') + result + (trailingSpaces ? trailingSpaces[0] : ''); + + logDebugInfo && console.log('output ', '->' + result + '<-'); + return result; +} diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index 4ca0ab4..400299c 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -3,8 +3,13 @@ import * as assert from 'assert'; // You can import and use all API from the 'vscode' module // as well as import your extension to test it import * as vscode from 'vscode'; +import testGroups from './test-case'; +import { TestCase, TestCaseGroup } from '../type-definition/test-case-type'; +import { transformText } from '../main-code/text-transform'; +import { toCamelCase, toPascalCase } from '../main-code/text-conversion'; // import * as myExtension from '../../extension'; +/* suite('Extension Test Suite', () => { vscode.window.showInformationMessage('Start all tests.'); @@ -13,3 +18,29 @@ suite('Extension Test Suite', () => { assert.strictEqual(-1, [1, 2, 3].indexOf(0)); }); }); + */ + +suite('Extension Test: run test case', () => { + vscode.window.showInformationMessage('Start all tests.'); + + // transform to camel case + + + const groups: Array = testGroups; + for (const testGroup of groups) { + const testTitle = testGroup.testTitle; + const testCases: Array = testGroup.cases; + for (const testCase of testCases) { + test(testTitle + ' - ' + testCase.title, () => { + const inputList = Array.isArray(testCase.input) ? testCase.input : [testCase.input]; + for (const input of inputList) { + // 验证 transformText + assert.strictEqual(testCase.transformText, transformText(input)); + // 验证转换 + assert.strictEqual(testCase.output.camelCase, toCamelCase(input)); + assert.strictEqual(testCase.output.pascalCase, toPascalCase(input)); + } + }); + } + } +}); diff --git a/src/test/test-case.ts b/src/test/test-case.ts index 1c9560c..2f4d7f8 100644 --- a/src/test/test-case.ts +++ b/src/test/test-case.ts @@ -1,183 +1,263 @@ +import { TestCaseGroup } from "../type-definition/test-case-type"; +const testGroups: Array = [ + { + group: 'Input validation', + testTitle: 'Input validation (输入有效性验证)', + cases: [ + // 输入为空 + { + title: 'empty input', + input: '', + transformText: '', + output: { + camelCase: '', + pascalCase: '', + }, + }, + { + title: 'empty input (contains space)', + input: ' ', + transformText: ' ', + output: { + camelCase: ' ', + pascalCase: ' ', + }, + }, + // 输入长文本 + { + title: 'long text input', + input: + `China's factory activity expanded in March after five consecutive months of contraction, an official survey revealed on Sunday, adding to a run of indicators that suggest the stabilization of the world's second-largest economy.` + , + transformText: '', + output: { + camelCase: '', + pascalCase: '', + }, + }, + // 输入包含换行 + { + title: 'enter input', + input: + `How do you\bdo? + How do you\tdo! + ` + , + transformText: '', + output: { + camelCase: '', + pascalCase: '', + }, + }, + // 非英文字符,特殊字符 + { + title: 'Chinese input', + input: + '今天是星期日' + , + transformText: '', + output: { + camelCase: '今天是星期日', + pascalCase: '今天是星期日', + }, + }, + { + title: 'Special character with emoji input', + input: + '🥰 a-cup/_of Coffee🍻,-_please!. ' + , + transformText: '', + output: { + camelCase: '', + pascalCase: '', + }, + }, + { + title: 'Random input', + input: + ' NHDAs--+90-usz&* ' + , + transformText: '', + output: { + camelCase: '', + pascalCase: '', + }, + }, + { + title: 'Mixed input 1', + input: + '--担心你鸿dAf_=coffee—_— ' + , + transformText: '', + output: { + camelCase: '', + pascalCase: '', + }, + }, + { + title: 'Mixed input 2', + input: + 'fsdi_sdacsaf+desd' + , + transformText: '', + output: { + camelCase: '', + pascalCase: '', + }, + }, + // add more cases... + ], + }, + { + group: 'Functional verification', + testTitle: 'Functional verification (功能验证)', + cases: [ + // 正常输入 + { + title: 'Normal input (foo-bar)', + input: [ + 'foo--bar', + '-foo -bar', + '__foo - _bar-__', + ], + transformText: 'foo|bar', + output: { + camelCase: 'fooBar', + pascalCase: 'FooBar', + }, + }, + { + title: 'Normal input (test-case)', + input: [ + 'test case', + 'test_case', + 'test-case', + 'testCase', + 'TestCase', + 'TEST_CASE', + ], + transformText: 'test|case', + output: { + camelCase: 'testCase', + pascalCase: 'TestCase', + }, + }, + { + title: 'Normal input (pine-apple)', + input: [ + 'pineApple', + ], + transformText: 'pine|apple', + output: { + camelCase: 'pineApple', + pascalCase: 'PineApple', + }, + }, + { + title: 'Normal input (have-a-nice-day!)', + input: [ + 'Have a nice day!', + 'have a nice day!', + 'Have-a-nice-day!', + 'have-a-nice-day!', + 'HAVE-A-NICE-DAY!', + 'Have_a_nice_day!', + 'have_a_nice_day!', + 'HAVE_A_NICE_DAY!', + 'HaveANiceDay!', + 'haveANiceDay!', + ], + transformText: 'have|a|nice|day|!', + output: { + camelCase: 'haveANiceDay!', + pascalCase: 'HaveANiceDay!', + }, + }, + { + title: 'Normal input (a-nice-day!)', + input: [ + ' A nice day! ', + ' a_nice_day! ', + ' ANiceDay! ', + ' A_NICE_DAY! ', + ' A_Nice_DaY! ', + ' A-NiCe_Day! ', + ' A----NiCe_Day_-_!-- ', + ], + transformText: ' a|nice|day|! ', + output: { + camelCase: ' aNiceDay! ', + pascalCase: ' ANiceDay! ', + }, + }, + { + title: 'Normal input (a-nice-day)', + input: [ + ' A niCe-Day-', + ' A niceDay', + ], + transformText: ' a|nice|day', + output: { + camelCase: ' a niceDay', + pascalCase: ' A NiceDay', + }, + }, + { + title: 'Normal input (Julius-Caesar, William-Shakespeare, ...)', + input: + ' Julius_Caesar, William_Shakespeare, Albert_Einstein, Marie_Curie, WolfgangAmadeusMozart, Vincent-van-Gogh. ' + , + transformText: ' julius|caesar|,|william|shakespeare|,|albert|einstein|,|marie|curie|,|wolfgang|amadeus|mozart|,|vincent|van|gogh|. ', + output: { + camelCase: '', + pascalCase: '', + }, + }, + { + title: 'Normal input ("You" (or "Your") ...)', + input: + [ + ` "You" (or "Your") shall mean an individual or Legal Entity`, + ` exercising permissions granted by this License.` + ].join('\n') + , + transformText: ' &|quot|;|you|&|quot|;|(|or|&|quot|;|your|&|quot|;)|shall|mean|an|individual|or|legal|entity|\n|exercising|permissions|granted|by|this|license|.', + output: { + camelCase: ' "You" (or "Your") shall mean an individual or Legal Entity\n exercising permissions granted by this License.', + pascalCase: ' "You" (or "Your") shall mean an individual or Legal Entity\n exercising permissions granted by this License.', + }, + }, + // add more cases... + ], + }, + { + group: 'Extreme case verification', + testTitle: 'Extreme case verification (极端情况验证)', + cases: [ + // 极端情况 -enum SkipReason { - /** 空字符串 */ - EMPTY_STRING, - /** 字符串过长 */ - STRING_TOO_LONG, - /** 不包含英文字母 */ - NOT_CONTAIN_LETTERS, -} - -type TestSkipCase = { - /** 当 input 不是规范的输入时,isSkip 为 true */ - isSkip: true - skipReason: SkipReason -}; -type TestReplaceCase = { - isSkip: false - splitResult: Array - output: { - camelCase: string - pascalCase: string - } -}; -type TestCase = (TestSkipCase | TestReplaceCase) & { - input: string | Array -}; - -/* -Have a nice day! -foo--bar -foo -bar -pineApple -*/ -const testCase: Array = [ - { - input: - '' - , - isSkip: true, - skipReason: SkipReason.EMPTY_STRING - }, - { - input: - `China's factory activity expanded in March after five consecutive months of contraction, an official survey revealed on Sunday, adding to a run of indicators that suggest the stabilization of the world's second-largest economy.` - , - isSkip: true, - skipReason: SkipReason.STRING_TOO_LONG - }, - { - input: - '今天是星期日' - , - isSkip: true, - skipReason: SkipReason.NOT_CONTAIN_LETTERS - }, - { - input: [ - 'test case', - 'test_case', - 'test-case', - 'testCase', - 'TestCase', - 'TEST_CASE', + // add more cases... ], - isSkip: false, - splitResult: [ - '' + }, + { + group: 'Xxxx verification', + testTitle: 'Xxxx verification (xxx验证)', + cases: [ + // Description + // { + // title: 'Normal input ( ...)', + // input: '', + // transformText: '', + // output: { + // camelCase: '', + // pascalCase: '' + // } + // }, + // add more cases... ], - output: { - camelCase: 'testCase', - pascalCase: 'TestCase', - } - }, - { - input: [ - ' A nice day! ', - ' a_nice_day! ', - ' ANiceDay! ', - ' A_NICE_DAY! ', - ' A_Nice_DaY ', - ' A-NiCe_Day ', - ' A----NiCe_Day_-_-- ', - ], - isSkip: false, - splitResult: [ - '' - ], - output: { - camelCase: ' aNiceDay! ', - pascalCase: ' ANiceDay! ', - } - }, - { - input: [ - ' A niCe-Day-', - ' A niceDay', - ], - isSkip: false, - splitResult: [ - '' - ], - output: { - camelCase: ' a niceDay', - pascalCase: ' A NiceDay', - } - }, - { - input: [ - 'Have a nice day!', - 'have a nice day!', - 'Have-a-nice-day!', - 'have-a-nice-day!', - 'HAVE-A-NICE-DAY!', - 'Have_a_nice_day!', - 'have_a_nice_day!', - 'HAVE_A_NICE_DAY!', - 'HaveANiceDay!', - 'haveANiceDay!', - ], - isSkip: false, - splitResult: ['have', 'a', 'nice', 'day', '!'], - output: { - camelCase: ' a niceDay', - pascalCase: ' A NiceDay', - } - }, - { - input: - ' Julius_Caesar, William_Shakespeare, Albert_Einstein, Marie_Curie, WolfgangAmadeusMozart, Vincent-van-Gogh. ' - , - isSkip: false, - splitResult: [], - output: { - camelCase: '', - pascalCase: '', - } - }, - { - input: - '🥰 a-cup/_of Coffee🍻,-_please!. ' - , - isSkip: false, - splitResult: [], - output: { - camelCase: '', - pascalCase: '', - } - }, - { - input: - ' NHDAs--+90-usz&* ' - , - isSkip: false, - splitResult: [], - output: { - camelCase: '', - pascalCase: '', - } - }, - { - input: - '--担心你鸿dAf_=coffee—_— ' - , - isSkip: false, - splitResult: [], - output: { - camelCase: '', - pascalCase: '', - } - }, - { - input: - 'fsdi_sdacsaf+desd' - , - isSkip: false, - splitResult: [], - output: { - camelCase: '', - pascalCase: '', - } }, + // add more cases... ]; + +export default testGroups; \ No newline at end of file diff --git a/src/type-definition/support-case.ts b/src/type-definition/support-case-type.ts similarity index 95% rename from src/type-definition/support-case.ts rename to src/type-definition/support-case-type.ts index 92b7b64..2ee6259 100644 --- a/src/type-definition/support-case.ts +++ b/src/type-definition/support-case-type.ts @@ -1,82 +1,82 @@ -export enum SupportCase { - /** - * 小驼峰 / 驼峰命名 - * Camel Case - * e.g. fooBar - * - * @alias: camelCase / CamelCase / camel_case / CAMEL_CASE - * @since 2024-04-02 - */ - CAMEL_CASE, - - /** - * 大驼峰 / 帕斯卡命名 - * Pascal Case - * e.g. FooBar - * - * @alias: pascalCase / PascalCase / pascal_case / PASCAL_CASE - * @since 2024-04-02 - */ - PASCAL_CASE, - - /** - * 连字符 / 脊柱式命名 - * Kebab Case / Spinal Case - * e.g. foo-bar - * - * @alias: kebabCase / KebabCase / kebab_case / KEBAB_CASE - * spinalCase / SpinalCase / spinal_case / SPINAL_CASE - * @since 2024-04-02 - */ - KEBAB_CASE, - - /** - * 下划线 / 蛇形命名 - * Snake Case - * e.g. foo_bar - * - * @alias: snakeCase / SnakeCase / snake_case / SNAKE_CASE - * @since 2024-04-02 - */ - SNAKE_CASE, - - /** - * 下划线大写 - * Snake Upper Case - * e.g. FOO_BAR - * - * @alias: snakeUpperCase / SnakeUpperCase / snake_upper_case / SNAKE_UPPER_CASE - * @since 2024-04-02 - */ - SNAKE_UPPER_CASE, - - /** - * 全大写 - * Upper Case - * e.g. FOO_BAR / FOOBAR - * - * @alias: upperCase / UpperCase / upper_case / UPPER_CASE - * @since 2024-04-02 - */ - UPPER_CASE, - - /** - * 全小写 - * Lower Case - * e.g. foo_bar / foobar - * - * @alias: lowerCase / LowerCase / lower_case / LOWER_CASE - * @since 2024-04-02 - */ - LOWER_CASE, - - /** - * 驼峰蛇形命名 - * Camel Snake Case - * e.g. Foo_Bar - * - * @alias: camelSnakeCase / CamelSnakeCase / camel_snake_case / CAMEL_SNAKE_CASE - * @since 2024-04-02 - */ - CAMEL_SNAKE_CASE, -} +export enum SupportCase { + /** + * 小驼峰 / 驼峰命名 + * Camel Case + * e.g. fooBar + * + * @alias: camelCase / CamelCase / camel_case / CAMEL_CASE + * @since 2024-04-02 + */ + CAMEL_CASE, + + /** + * 大驼峰 / 帕斯卡命名 + * Pascal Case + * e.g. FooBar + * + * @alias: pascalCase / PascalCase / pascal_case / PASCAL_CASE + * @since 2024-04-02 + */ + PASCAL_CASE, + + /** + * 连字符 / 脊柱式命名 + * Kebab Case / Spinal Case + * e.g. foo-bar + * + * @alias: kebabCase / KebabCase / kebab_case / KEBAB_CASE + * spinalCase / SpinalCase / spinal_case / SPINAL_CASE + * @since 2024-04-02 + */ + KEBAB_CASE, + + /** + * 下划线 / 蛇形命名 + * Snake Case + * e.g. foo_bar + * + * @alias: snakeCase / SnakeCase / snake_case / SNAKE_CASE + * @since 2024-04-02 + */ + SNAKE_CASE, + + /** + * 下划线大写 + * Snake Upper Case + * e.g. FOO_BAR + * + * @alias: snakeUpperCase / SnakeUpperCase / snake_upper_case / SNAKE_UPPER_CASE + * @since 2024-04-02 + */ + SNAKE_UPPER_CASE, + + /** + * 全大写 + * Upper Case + * e.g. FOO_BAR / FOOBAR + * + * @alias: upperCase / UpperCase / upper_case / UPPER_CASE + * @since 2024-04-02 + */ + UPPER_CASE, + + /** + * 全小写 + * Lower Case + * e.g. foo_bar / foobar + * + * @alias: lowerCase / LowerCase / lower_case / LOWER_CASE + * @since 2024-04-02 + */ + LOWER_CASE, + + /** + * 驼峰蛇形命名 + * Camel Snake Case + * e.g. Foo_Bar + * + * @alias: camelSnakeCase / CamelSnakeCase / camel_snake_case / CAMEL_SNAKE_CASE + * @since 2024-04-02 + */ + CAMEL_SNAKE_CASE, +} diff --git a/src/type-definition/test-case-type.ts b/src/type-definition/test-case-type.ts new file mode 100644 index 0000000..2df4b51 --- /dev/null +++ b/src/type-definition/test-case-type.ts @@ -0,0 +1,15 @@ +export type TestCaseGroup = { + group: string + testTitle: string + cases: Array +}; + +export type TestCase = { + title: string + input: string | Array + transformText: string + output: { + camelCase: string + pascalCase: string + } +};