diff --git a/src/main/java/com/lanyuanxiaoyao/service/template/Helper.java b/src/main/java/com/lanyuanxiaoyao/service/template/Helper.java index 1c5f10d..cb5d9ee 100644 --- a/src/main/java/com/lanyuanxiaoyao/service/template/Helper.java +++ b/src/main/java/com/lanyuanxiaoyao/service/template/Helper.java @@ -216,7 +216,7 @@ public class Helper { return camelCase; } - StringBuilder result = new StringBuilder(); + StringBuilder result = new StringBuilder(camelCase.length() * 2); // 预分配更多空间以避免重新分配 // 处理第一个字符,直接转为小写 result.append(Character.toLowerCase(camelCase.charAt(0))); @@ -224,12 +224,16 @@ public class Helper { for (int i = 1; i < camelCase.length(); i++) { char currentChar = camelCase.charAt(i); - // 如果是大写字母,且前一个字符不是下划线,并且不是第一个字符 + // 如果是大写字母,则在前面添加下划线 if (Character.isUpperCase(currentChar)) { - // 检查前一个字符是否为大写,如果是连续大写,可能是缩写(如HTTP) - // 这种情况只在遇到小写字母前才添加下划线 + // 在特定条件下添加下划线: + // 1. 前一个字符是小写 + // 2. 前一个字符是数字 + // 3. 当前大写字母不是最后一个字符,且下一个字符是小写(处理连续大写字母如"XMLParser" -> "xml_parser") char previousChar = camelCase.charAt(i - 1); - if (Character.isLowerCase(previousChar) || (i < camelCase.length() - 1 && Character.isLowerCase(camelCase.charAt(i + 1)))) { + if (Character.isLowerCase(previousChar) + || Character.isDigit(previousChar) + || (i < camelCase.length() - 1 && Character.isLowerCase(camelCase.charAt(i + 1)))) { result.append('_'); } result.append(Character.toLowerCase(currentChar)); diff --git a/src/test/java/com/lanyuanxiaoyao/service/template/HelperTest.java b/src/test/java/com/lanyuanxiaoyao/service/template/HelperTest.java new file mode 100644 index 0000000..304bd24 --- /dev/null +++ b/src/test/java/com/lanyuanxiaoyao/service/template/HelperTest.java @@ -0,0 +1,90 @@ +package com.lanyuanxiaoyao.service.template; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.Assert; + +/** + * Helper测试类 + * 用于测试驼峰命名法转下划线命名法的功能 + * + * @author lanyuanxiaoyao + */ +@Slf4j +public class HelperTest { + + public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + // 通过反射调用Helper类中的private静态方法camelConvert + var camelConvert = Helper.class.getDeclaredMethod("camelConvert", String.class); + camelConvert.setAccessible(true); + + // 测试用例集合 + Map testCases = new HashMap<>(); + + // 基本转换测试 + testCases.put("helloWorld", "hello_world"); + testCases.put("firstName", "first_name"); + testCases.put("lastName", "last_name"); + testCases.put("URL", "url"); + testCases.put("HTTPResponse", "http_response"); + testCases.put("XMLParser", "xml_parser"); + + // 边界情况测试 + testCases.put(null, null); // null输入 + testCases.put("", ""); // 空字符串 + testCases.put("a", "a"); // 单个小写字母 + testCases.put("A", "a"); // 单个大写字母 + testCases.put("aB", "a_b"); // 两个字符 + testCases.put("Ab", "ab"); // 首字母大写 + + // 数字相关测试 + testCases.put("field1Name", "field1_name"); + testCases.put("field12Name", "field12_name"); + testCases.put("2FARequired", "2_fa_required"); + testCases.put("ID", "id"); + testCases.put("userID", "user_id"); + testCases.put("HTML5Parser", "html5_parser"); + + // 连续大写字母测试 + testCases.put("HTTPSConnection", "https_connection"); + testCases.put("XMLHttpRequest", "xml_http_request"); + testCases.put("URLPath", "url_path"); + testCases.put("APIKey", "api_key"); + testCases.put("JWTToken", "jwt_token"); + + // 特殊场景测试 + testCases.put("iPhone", "i_phone"); // 以小写字母开头,后面有大写 + testCases.put("iOSVersion", "i_os_version"); // 连续小写字母后跟大写 + testCases.put("CAPTCHA", "captcha"); // 全大写字母缩写 + + log.info("开始执行驼峰命名转下划线命名测试..."); + + int passedTests = 0; + int totalTests = testCases.size(); + + for (Map.Entry testCase : testCases.entrySet()) { + String input = testCase.getKey(); + String expected = testCase.getValue(); + String actual = (String) camelConvert.invoke(null, input); + + try { + Assert.isTrue(Objects.equals(expected, actual), "测试失败: 输入='%s', 期望='%s', 实际='%s'".formatted(input, expected, actual)); + passedTests++; + log.info("✓ 测试通过: '{}' -> '{}'", input, actual); + } catch (Exception e) { + log.error("✗ {}", e.getMessage()); + } + } + + log.info("测试结果: {}/{} 通过", passedTests, totalTests); + if (passedTests == totalTests) { + log.info("所有测试通过!✓"); + } else { + log.error("有测试失败!✗"); + System.exit(1); + } + } +}