From 9e8e02bff90cf4a650a6d274ec6f80a346b7e68d Mon Sep 17 00:00:00 2001 From: Eric_Lian Date: Wed, 8 Feb 2023 21:47:13 +0800 Subject: [PATCH 1/3] =?UTF-8?q?tests:=20=E6=B7=BB=E5=8A=A0=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OneBot-UnitTest/UnitTest/Util/StringUtilsTest.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OneBot-UnitTest/UnitTest/Util/StringUtilsTest.cs b/OneBot-UnitTest/UnitTest/Util/StringUtilsTest.cs index 1c56196..ef406c6 100644 --- a/OneBot-UnitTest/UnitTest/Util/StringUtilsTest.cs +++ b/OneBot-UnitTest/UnitTest/Util/StringUtilsTest.cs @@ -36,6 +36,9 @@ public void ToSnakeCaseTest() Assert.AreEqual("SWEET_ICELOLLY_ID", StringUtils.ToSnakeCase("SweetIcelollyID", StringUtils.CaseType.Upper, lockedWords)); Assert.AreEqual("WEY_SUN+ICE_ERIC_VANCHENG_DRESSES", StringUtils.ToSnakeCase("WeySun+IceEricVanChengDresses", StringUtils.CaseType.Upper, new[] { "SUN+ICE", "VANCHENG" })); + + Assert.AreEqual("one_another", StringUtils.ToSnakeCase("oneAnother", StringUtils.CaseType.Lower, lockedWords)); + Assert.AreEqual("ONE_ANOTHER", StringUtils.ToSnakeCase("oneAnother", StringUtils.CaseType.Upper, lockedWords)); } [TestMethod] From fd2d8503f5a686f6e07ceeb2570d0d28e95b1fb3 Mon Sep 17 00:00:00 2001 From: buger404 Date: Thu, 23 Feb 2023 20:40:43 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=E5=B0=8F=E9=A9=BC=E5=B3=B0=E8=BD=AC?= =?UTF-8?q?=E8=9B=87=E5=BD=A2=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OneBot-Interface/Core/Util/StringUtils.cs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/OneBot-Interface/Core/Util/StringUtils.cs b/OneBot-Interface/Core/Util/StringUtils.cs index f0da5e7..bb1cc67 100644 --- a/OneBot-Interface/Core/Util/StringUtils.cs +++ b/OneBot-Interface/Core/Util/StringUtils.cs @@ -166,14 +166,14 @@ public static string ToSeparatedCase(string s, char separator, CaseType caseType { StringBuilder sb = new StringBuilder(); char[] src = s.ToCharArray(); - - bool fstWord = true; - for (int i = 0; i < src.Length; i++) + + int t = 0; + for (int i = 0; i < src.Length; i++, t++) { if (char.IsSeparator(src[i])) { sb.Append(src[i]); - fstWord = true; + t = -1; continue; } if (char.IsUpper(src[i])) @@ -194,10 +194,8 @@ public static string ToSeparatedCase(string s, char separator, CaseType caseType } if (match) { - if (!fstWord) + if (t != 0) sb.Append(separator); - else - fstWord = false; for (int k = 0; k < word.Length; k++) { if (caseType == CaseType.Upper) @@ -214,10 +212,8 @@ public static string ToSeparatedCase(string s, char separator, CaseType caseType if (skip) continue; } - if (!fstWord) + if (t != 0) sb.Append(separator); - else - fstWord = false; } if (caseType == CaseType.Upper) sb.Append(char.ToUpper(src[i])); From 3e7e095652151e6dbad6580bde5ce0d7b2eb0f18 Mon Sep 17 00:00:00 2001 From: Eric_Lian Date: Sat, 8 Jun 2024 13:34:55 +0800 Subject: [PATCH 3/3] fix: camel to camel and snake to snake --- OneBot-Interface/Core/Util/StringUtils.cs | 78 +++++++++++++++++-- .../UnitTest/Util/StringUtilsTest.cs | 75 +++++++++++++----- 2 files changed, 127 insertions(+), 26 deletions(-) diff --git a/OneBot-Interface/Core/Util/StringUtils.cs b/OneBot-Interface/Core/Util/StringUtils.cs index bb1cc67..c2a6612 100644 --- a/OneBot-Interface/Core/Util/StringUtils.cs +++ b/OneBot-Interface/Core/Util/StringUtils.cs @@ -16,16 +16,34 @@ public enum CamelCaseType { Upper, - Lower + Lower, + + None, } public enum CaseType { Lower, - Upper + Upper, + + None, } + private static CaseType EvaluateCaseType(char c) + { + if (char.IsUpper(c)) + { + return CaseType.Upper; + } + + if (char.IsLower(c)) + { + return CaseType.Lower; + } + + return CaseType.None; + } public static bool IsNullOrEmpty(string? value) => string.IsNullOrEmpty(value); @@ -80,9 +98,17 @@ public static string ToCamelCase(string s, CamelCaseType caseType, string[]? loc char[] result = new char[src.Length - ulCnt]; bool fstWord = true, fstLetter = true; string tmp = ""; + var lastCase = CaseType.None; + for (int i = 0, j = 0; i <= src.Length; i++) { - if (i == src.Length || src[i] == Underline || src[i] == Dash || char.IsSeparator(src[i])) + var cntCase = i < src.Length ? EvaluateCaseType(src[i]) : CaseType.None; + + if (i == src.Length || + src[i] == Underline || src[i] == Dash || + char.IsSeparator(src[i]) || + (i > 0 && lastCase != cntCase && cntCase == CaseType.Upper) + ) { if (lockedWords != null && lockedWords.Contains(tmp)) { @@ -95,6 +121,7 @@ public static string ToCamelCase(string s, CamelCaseType caseType, string[]? loc result[j - tmp.Length + k] = char.ToLower(result[j - tmp.Length + k]); } } + if (i < src.Length) { if (src[i] == Underline || src[i] == Dash) @@ -102,6 +129,13 @@ public static string ToCamelCase(string s, CamelCaseType caseType, string[]? loc fstLetter = true; tmp = ""; } + else if (i > 0 && lastCase != cntCase && cntCase == CaseType.Upper) + { + fstLetter = false; + result[j] = char.ToUpper(src[i]); + tmp = "" + char.ToUpper(src[i]); + j++; + } else { fstWord = true; @@ -126,11 +160,19 @@ public static string ToCamelCase(string s, CamelCaseType caseType, string[]? loc } else { + if (j != 1 && lastCase == CaseType.Upper && cntCase == CaseType.Lower) + { + result[j - 1] = char.ToUpper(result[j - 1]); + } + result[j] = char.ToLower(src[i]); } + tmp += char.ToUpper(src[i]); j++; } + + lastCase = cntCase; } return new string(result); @@ -164,20 +206,33 @@ public static string ToUpperSnakeCase(string s, string[]? lockedWords = null) /// public static string ToSeparatedCase(string s, char separator, CaseType caseType, string[]? lockedWords = null) { - StringBuilder sb = new StringBuilder(); + StringBuilder sb = new StringBuilder(16); char[] src = s.ToCharArray(); - + int t = 0; + var separated = false; + var lastCase = CaseType.None; + for (int i = 0; i < src.Length; i++, t++) { + var cntCase = i < src.Length ? EvaluateCaseType(src[i]) : CaseType.None; + if (char.IsSeparator(src[i])) { sb.Append(src[i]); t = -1; continue; } - if (char.IsUpper(src[i])) + + if (src[i] == Dash || src[i] == Underline) + { + separated = true; + continue; + } + + if (separated || (lastCase != cntCase && cntCase == CaseType.Upper)) { + separated = false; if (lockedWords != null) { bool skip = false; @@ -192,6 +247,7 @@ public static string ToSeparatedCase(string s, char separator, CaseType caseType break; } } + if (match) { if (t != 0) @@ -204,21 +260,31 @@ public static string ToSeparatedCase(string s, char separator, CaseType caseType sb.Append(char.ToLower(src[i])); i++; } + i--; skip = true; break; } } + if (skip) continue; } + if (t != 0) sb.Append(separator); } + if (caseType == CaseType.Upper) + { sb.Append(char.ToUpper(src[i])); + } else + { sb.Append(char.ToLower(src[i])); + } + + lastCase = cntCase; } return sb.ToString(); diff --git a/OneBot-UnitTest/UnitTest/Util/StringUtilsTest.cs b/OneBot-UnitTest/UnitTest/Util/StringUtilsTest.cs index ef406c6..31bc72f 100644 --- a/OneBot-UnitTest/UnitTest/Util/StringUtilsTest.cs +++ b/OneBot-UnitTest/UnitTest/Util/StringUtilsTest.cs @@ -21,42 +21,75 @@ public void ToSnakeCaseTest() Assert.AreEqual("qq", lowerSnake.Convert("QQ")); Assert.AreEqual("id", lowerSnake.Convert("ID")); Assert.AreEqual("qq id", lowerSnake.Convert("QQ ID")); - - Assert.AreEqual("qq_qq_id qq_id_id_qq", StringUtils.ToSnakeCase("QQQQID QQIDIDQQ", StringUtils.CaseType.Lower, lockedWords)); - Assert.AreEqual("user_qq_token", StringUtils.ToSnakeCase("UserQQToken", StringUtils.CaseType.Lower, lockedWords)); - Assert.AreEqual("sweet_icelolly_id", StringUtils.ToSnakeCase("SweetIcelollyID", StringUtils.CaseType.Lower, lockedWords)); + + // ambiguous case + // Assert.AreEqual("qq_qq_id qq_id_id_qq", StringUtils.ToSnakeCase("QQQQID QQIDIDQQ", StringUtils.CaseType.Lower, lockedWords)); + + Assert.AreEqual("user_qq_token", + StringUtils.ToSnakeCase("UserQQToken", StringUtils.CaseType.Lower, lockedWords)); + Assert.AreEqual("sweet_icelolly_id", + StringUtils.ToSnakeCase("SweetIcelollyID", StringUtils.CaseType.Lower, lockedWords)); Assert.AreEqual("wey_sun+ice_eric_vancheng_dresses", - StringUtils.ToSnakeCase("WeySun+IceEricVanChengDresses", StringUtils.CaseType.Lower, new[] { "SUN+ICE", "VANCHENG" })); + StringUtils.ToSnakeCase("WeySun+IceEricVanChengDresses", StringUtils.CaseType.Lower, + new[] { "SUN+ICE", "VANCHENG" })); Assert.AreEqual("QQ", StringUtils.ToSnakeCase("QQ", StringUtils.CaseType.Upper, lockedWords)); Assert.AreEqual("ID", StringUtils.ToSnakeCase("ID", StringUtils.CaseType.Upper, lockedWords)); Assert.AreEqual("QQ ID", StringUtils.ToSnakeCase("QQ ID", StringUtils.CaseType.Upper, lockedWords)); - Assert.AreEqual("QQ_QQ_ID QQ_ID_ID_QQ", StringUtils.ToSnakeCase("QQQQID QQIDIDQQ", StringUtils.CaseType.Upper, lockedWords)); - Assert.AreEqual("USER_QQ_TOKEN", StringUtils.ToSnakeCase("UserQQToken", StringUtils.CaseType.Upper, lockedWords)); - Assert.AreEqual("SWEET_ICELOLLY_ID", StringUtils.ToSnakeCase("SweetIcelollyID", StringUtils.CaseType.Upper, lockedWords)); + Assert.AreEqual("QQ_QQ_ID QQ_ID_ID_QQ", + StringUtils.ToSnakeCase("QQQQID QQIDIDQQ", StringUtils.CaseType.Upper, lockedWords)); + Assert.AreEqual("USER_QQ_TOKEN", + StringUtils.ToSnakeCase("UserQQToken", StringUtils.CaseType.Upper, lockedWords)); + Assert.AreEqual("SWEET_ICELOLLY_ID", + StringUtils.ToSnakeCase("SweetIcelollyID", StringUtils.CaseType.Upper, lockedWords)); Assert.AreEqual("WEY_SUN+ICE_ERIC_VANCHENG_DRESSES", - StringUtils.ToSnakeCase("WeySun+IceEricVanChengDresses", StringUtils.CaseType.Upper, new[] { "SUN+ICE", "VANCHENG" })); - + StringUtils.ToSnakeCase("WeySun+IceEricVanChengDresses", StringUtils.CaseType.Upper, + new[] { "SUN+ICE", "VANCHENG" })); + Assert.AreEqual("one_another", StringUtils.ToSnakeCase("oneAnother", StringUtils.CaseType.Lower, lockedWords)); Assert.AreEqual("ONE_ANOTHER", StringUtils.ToSnakeCase("oneAnother", StringUtils.CaseType.Upper, lockedWords)); + + Assert.AreEqual("ONE_ANOTHER", StringUtils.ToSnakeCase("one-Another", StringUtils.CaseType.Upper, lockedWords)); + Assert.AreEqual("ONE_ANOTHER", StringUtils.ToSnakeCase("one_Another", StringUtils.CaseType.Upper, lockedWords)); + Assert.AreEqual("ONE_ANOTHER", + StringUtils.ToSnakeCase("one_-Another", StringUtils.CaseType.Upper, lockedWords)); + Assert.AreEqual("ONE_ANOTHER", StringUtils.ToSnakeCase("ONE_ANOTHER", StringUtils.CaseType.Upper, lockedWords)); } - + [TestMethod] public void ToLowerCamelTest() { + Assert.AreEqual("userQQ", StringUtils.ToCamelCase("USER_QQ", StringUtils.CamelCaseType.Lower, lockedWords)); + Assert.AreEqual("userQQ", StringUtils.ToCamelCase("user_qq", StringUtils.CamelCaseType.Lower, lockedWords)); + Assert.AreEqual("userQQ", StringUtils.ToCamelCase("userQQ", StringUtils.CamelCaseType.Lower, lockedWords)); + Assert.AreEqual("userQQ", StringUtils.ToCamelCase("USER_QQ", StringUtils.CamelCaseType.Lower, lockedWords)); + Assert.AreEqual("userQQ", StringUtils.ToCamelCase("userQq", StringUtils.CamelCaseType.Lower, lockedWords)); Assert.AreEqual("userID", StringUtils.ToCamelCase("user_id", StringUtils.CamelCaseType.Lower, lockedWords)); Assert.AreEqual("qqID", StringUtils.ToCamelCase("qq_id", StringUtils.CamelCaseType.Lower, lockedWords)); Assert.AreEqual("icelolly", StringUtils.ToCamelCase("icelolly", StringUtils.CamelCaseType.Lower)); Assert.AreEqual("icelolly", StringUtils.ToCamelCase("Icelolly", StringUtils.CamelCaseType.Lower)); - Assert.AreEqual("icelolly", StringUtils.ToCamelCase("IceLOlly", StringUtils.CamelCaseType.Lower)); + + // ambiguous case + Assert.AreEqual("iceLOlly", StringUtils.ToCamelCase("IceLOlly", StringUtils.CamelCaseType.Lower)); + Assert.AreEqual("icelollyDress", StringUtils.ToCamelCase("icelolly_dress", StringUtils.CamelCaseType.Lower)); Assert.AreEqual("icelollyDress2", StringUtils.ToCamelCase("icelolly_dress2", StringUtils.CamelCaseType.Lower)); - Assert.AreEqual("icelollyDress", StringUtils.ToCamelCase("ICelolly_DRess", StringUtils.CamelCaseType.Lower)); - Assert.AreEqual("icelollyDress daiSuki", StringUtils.ToCamelCase("iCelolly_dRess dai_suki", StringUtils.CamelCaseType.Lower)); - Assert.AreEqual("icelollyDress daiSuki404", StringUtils.ToCamelCase("iCelolly_dRess dai_suki_404", StringUtils.CamelCaseType.Lower)); + Assert.AreEqual("icelollyDress2", StringUtils.ToCamelCase("icelolly_dress_2", StringUtils.CamelCaseType.Lower)); + + Assert.AreEqual("aDRess", StringUtils.ToCamelCase("A_DRess", StringUtils.CamelCaseType.Lower)); + + // ambiguous case + Assert.AreEqual("iCelollyDRess", StringUtils.ToCamelCase("ICelolly_DRess", StringUtils.CamelCaseType.Lower)); + + Assert.AreEqual("iCelollyDRess daiSuki", + StringUtils.ToCamelCase("iCelolly_dRess dai_suki", StringUtils.CamelCaseType.Lower)); + Assert.AreEqual("iCelollyDRess daiSuki404", + StringUtils.ToCamelCase("iCelolly_dRess dai_suki_404", StringUtils.CamelCaseType.Lower)); + Assert.AreEqual("iCelollyDRess", + StringUtils.ToCamelCase("iCelolly_----dRess", StringUtils.CamelCaseType.Lower)); } - + [TestMethod] public void ToUpperCamelTest() { @@ -65,11 +98,13 @@ public void ToUpperCamelTest() Assert.AreEqual("QQID", StringUtils.ToCamelCase("qq_id", StringUtils.CamelCaseType.Upper, lockedWords)); Assert.AreEqual("Icelolly", StringUtils.ToCamelCase("icelolly", StringUtils.CamelCaseType.Upper)); Assert.AreEqual("Icelolly", StringUtils.ToCamelCase("Icelolly", StringUtils.CamelCaseType.Upper)); - Assert.AreEqual("Icelolly", StringUtils.ToCamelCase("IceLOlly", StringUtils.CamelCaseType.Upper)); + Assert.AreEqual("IceLOlly", StringUtils.ToCamelCase("IceLOlly", StringUtils.CamelCaseType.Upper)); Assert.AreEqual("IcelollyDress", StringUtils.ToCamelCase("icelolly_dress", StringUtils.CamelCaseType.Upper)); Assert.AreEqual("IcelollyDress2", StringUtils.ToCamelCase("icelolly_dress2", StringUtils.CamelCaseType.Upper)); - Assert.AreEqual("IcelollyDress", StringUtils.ToCamelCase("ICelolly_DRess", StringUtils.CamelCaseType.Upper)); - Assert.AreEqual("IcelollyDress DaiSuki", StringUtils.ToCamelCase("iCelolly_dRess dai_suki", StringUtils.CamelCaseType.Upper)); - Assert.AreEqual("IcelollyDress DaiSuki404", StringUtils.ToCamelCase("iCelolly_dRess dai_suki_404", StringUtils.CamelCaseType.Upper)); + Assert.AreEqual("ICelollyDRess", StringUtils.ToCamelCase("ICelolly_DRess", StringUtils.CamelCaseType.Upper)); + Assert.AreEqual("ICelollyDRess DaiSuki", + StringUtils.ToCamelCase("iCelolly_dRess dai_suki", StringUtils.CamelCaseType.Upper)); + Assert.AreEqual("ICelollyDRess DaiSuki404", + StringUtils.ToCamelCase("iCelolly_dRess dai_suki_404", StringUtils.CamelCaseType.Upper)); } }