Browse Source

fix: 让路径比较不受当前语言设置影响

Meloong Bot 1 week ago
parent
commit
201948eac8

+ 3 - 3
Shared/Utils/PathUtils.cs

@@ -232,7 +232,7 @@ public static class PathUtils {
         return PathUtils.Compare(path1, path2) == 0;
     }
     /// <summary>
-    /// 比较两个路径,忽略大小写。
+    /// 比较两个路径,忽略大小写,且不受当前语言设置影响。
     /// <para/><c>null</c> 与空字符串视为相同的空路径,空路径排在非空路径之前。
     /// </summary>
     /// <returns>
@@ -243,7 +243,7 @@ public static class PathUtils {
     public static int Compare(string? path1, string? path2) {
         if (string.IsNullOrEmpty(path1)) return string.IsNullOrEmpty(path2) ? 0 : -1;
         if (string.IsNullOrEmpty(path2)) return 1;
-        return string.Compare(PathUtils.ForCompare(path1!), PathUtils.ForCompare(path2!), true);
+        return string.Compare(PathUtils.ForCompare(path1!), PathUtils.ForCompare(path2!), StringComparison.OrdinalIgnoreCase);
     }
 
     /// <summary>
@@ -265,7 +265,7 @@ public static class PathUtils {
     public static bool IsParentOf(string parentPath, string childPath) {
         parentPath = PathUtils.ForCompare(parentPath);
         childPath = PathUtils.ForCompare(childPath);
-        return childPath.StartsWithF(parentPath + @"\", true) || PathUtils.IsSame(childPath, parentPath);
+        return childPath.StartsWith(parentPath + @"\", StringComparison.OrdinalIgnoreCase) || PathUtils.IsSame(childPath, parentPath);
     }
 
 }

+ 28 - 0
Tests/Utils/DirectoryUtilsTest.cs

@@ -1,6 +1,34 @@
 namespace MeloongCore.Tests;
 public class DirectoryUtilsTest : TestWithFolder {
 
+    [Test]
+    [Arguments(false)]
+    [Arguments(true)]
+    public async Task 土耳其语_目录同源及仅改大小写保留内容(bool copy) {
+        var originalCulture = System.Globalization.CultureInfo.CurrentCulture;
+        string root = tempFolder;
+        string source = Path.Combine(root, "FILES");
+        string destination = Path.Combine(root, "files");
+        try {
+            System.Globalization.CultureInfo.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("tr-TR");
+            DirectoryUtils.Create(source);
+            FileUtils.Write(Path.Combine(source, "keep.txt"), "目录内容");
+            if (copy) {
+                DirectoryUtils.Copy(source, source);
+                DirectoryUtils.Copy(source, destination);
+            } else {
+                DirectoryUtils.Move(source, source);
+                DirectoryUtils.Move(source, destination);
+            }
+            await Assert.That(FileUtils.ReadAsString(Path.Combine(destination, "keep.txt"))).IsEqualTo("目录内容");
+            await Assert.That(Directory.GetDirectories(PathUtils.ForApi(root)).Select(Path.GetFileName).Single()).IsEqualTo("files");
+        } finally {
+            System.Globalization.CultureInfo.CurrentCulture = originalCulture;
+            DirectoryUtils.Delete(root);
+        }
+    }
+
+
     #region 剪切、复制
 
     [Test]

+ 27 - 0
Tests/Utils/FileUtilsTest.cs

@@ -1,6 +1,33 @@
 namespace MeloongCore.Tests;
 public class FileUtilsTest : TestWithFolder {
 
+    [Test]
+    [Arguments(false)]
+    [Arguments(true)]
+    public async Task 土耳其语_文件同源及仅改大小写保留内容(bool copy) {
+        var originalCulture = System.Globalization.CultureInfo.CurrentCulture;
+        string root = tempFolder;
+        string source = Path.Combine(root, "FILE.txt");
+        string destination = Path.Combine(root, "file.txt");
+        try {
+            System.Globalization.CultureInfo.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("tr-TR");
+            DirectoryUtils.Create(root);
+            FileUtils.Write(source, "文件内容");
+            if (copy) {
+                FileUtils.Copy(source, source);
+                FileUtils.Copy(source, destination);
+            } else {
+                FileUtils.Move(source, source);
+                FileUtils.Move(source, destination);
+            }
+            await Assert.That(FileUtils.ReadAsString(destination)).IsEqualTo("文件内容");
+            await Assert.That(Directory.GetFiles(PathUtils.ForApi(root)).Select(Path.GetFileName).Single()).IsEqualTo("file.txt");
+        } finally {
+            System.Globalization.CultureInfo.CurrentCulture = originalCulture;
+            DirectoryUtils.Delete(root);
+        }
+    }
+
     [Test]
     public async Task 文件可用性_只读与占用() {
         string path = Path.Combine(tempFolder, "available.txt");

+ 25 - 0
Tests/Utils/PathUtilsTest.cs

@@ -37,6 +37,31 @@ public class PathUtilsTests : TestBase {
 
     #region 路径处理
 
+    [Test]
+    [Arguments("en-US")]
+    [Arguments("zh-CN")]
+    [Arguments("tr-TR")]
+    public async Task 路径比较_不受当前语言影响(string cultureName) {
+        var originalCulture = System.Globalization.CultureInfo.CurrentCulture;
+        try {
+            System.Globalization.CultureInfo.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo(cultureName);
+            await Assert.That(PathUtils.Compare(@"C:\FILES\FILE.jar", @"C:\files\file.jar")).IsEqualTo(0);
+            await Assert.That(PathUtils.IsSame(@"C:\FILES\FILE.jar", @"C:\files\file.jar")).IsTrue();
+            await Assert.That(PathUtils.IsSame(@"C:\files\I.jar", @"C:\files\ı.jar")).IsFalse();
+            await Assert.That(PathUtils.IsSame(@"C:\files\ab.jar", "C:\\files\\a\u00adb.jar")).IsFalse();
+            await Assert.That(PathUtils.Compare(@"C:\files\I.jar", @"C:\files\J.jar") < 0).IsTrue();
+            await Assert.That(PathUtils.IsParentOf(@"C:\FILES", @"C:\files\child")).IsTrue();
+            await Assert.That(PathUtils.IsParentOf(@"C:\FILES", @"C:\files")).IsTrue();
+            await Assert.That(PathUtils.IsParentOf(@"C:\FILES", @"C:\files-other\child")).IsFalse();
+            await Assert.That(PathUtils.IsParentOf(@"C:\I", @"C:\ı\child")).IsFalse();
+            await Assert.That(PathUtils.IsSame(null, "")).IsTrue();
+            await Assert.That(PathUtils.Compare("", @"C:\files") < 0).IsTrue();
+            await Assert.That(PathUtils.Compare(@"C:\files", null) > 0).IsTrue();
+        } finally {
+            System.Globalization.CultureInfo.CurrentCulture = originalCulture;
+        }
+    }
+
     [Test]
     [Arguments(@"\\?\C:\foo\bar.txt", @"\\?\C:\foo")]
     [Arguments(@"C:\foo\extra/bar.txt", @"C:\foo\extra")]