/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/Core/CodeAnalysisTest/FileSystem/PathUtilitiesTests.cs
491 строка
22 KB
Copilot
Add compilation caching mode to VBCSCompiler server (#82881)
04 апр 2026, 01:17
Не верифицирован
04 апр 2026, 01:17
ae96a65
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System; using System.IO; using Roslyn.Test.Utilities; using Roslyn.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.UnitTests.FileSystem { public class PathUtilitiesTests { private void TestGetDirectoryNameAndCompareToDotnet(string expectedDirectoryName, string fullPath) { var roslynName = PathUtilities.TestAccessor.GetDirectoryName(fullPath, isUnixLike: false); Assert.Equal(expectedDirectoryName, roslynName); var dotnetName = Path.GetDirectoryName(fullPath); Assert.Equal(dotnetName, roslynName); } [ConditionalFact(typeof(WindowsOnly))] public void TestGetDirectoryName_WindowsPaths_Absolute() { TestGetDirectoryNameAndCompareToDotnet(@"C:\temp", @"C:\temp\goo.txt"); TestGetDirectoryNameAndCompareToDotnet(@"C:\temp", @"C:\temp\goo"); TestGetDirectoryNameAndCompareToDotnet(@"C:\temp", @"C:\temp\"); TestGetDirectoryNameAndCompareToDotnet(@"C:\", @"C:\temp"); TestGetDirectoryNameAndCompareToDotnet(null, @"C:\"); TestGetDirectoryNameAndCompareToDotnet(null, @"C:"); // dotnet throws on empty argument. But not on null... go figure. Assert.Null(PathUtilities.TestAccessor.GetDirectoryName(@"", isUnixLike: false)); TestGetDirectoryNameAndCompareToDotnet(null, null); } [ConditionalFact(typeof(WindowsOnly))] public void TestGetDirectoryName_WindowsPaths_Relative() { TestGetDirectoryNameAndCompareToDotnet(@"goo\temp", @"goo\temp\goo.txt"); TestGetDirectoryNameAndCompareToDotnet(@"goo\temp", @"goo\temp\goo"); TestGetDirectoryNameAndCompareToDotnet(@"goo\temp", @"goo\temp\"); TestGetDirectoryNameAndCompareToDotnet(@"goo", @"goo\temp"); TestGetDirectoryNameAndCompareToDotnet(@"goo", @"goo\"); TestGetDirectoryNameAndCompareToDotnet("", @"goo"); } [Fact] public void TestGetDirectoryName_UnixPaths_Absolute() { Assert.Equal( @"/temp", PathUtilities.TestAccessor.GetDirectoryName(@"/temp/goo.txt", isUnixLike: true)); Assert.Equal( @"/temp", PathUtilities.TestAccessor.GetDirectoryName(@"/temp/goo", isUnixLike: true)); Assert.Equal( @"/temp", PathUtilities.TestAccessor.GetDirectoryName(@"/temp/", isUnixLike: true)); Assert.Equal( @"/", PathUtilities.TestAccessor.GetDirectoryName(@"/temp", isUnixLike: true)); Assert.Null( PathUtilities.TestAccessor.GetDirectoryName(@"/", isUnixLike: true)); Assert.Null( PathUtilities.TestAccessor.GetDirectoryName(@"", isUnixLike: true)); Assert.Null( PathUtilities.TestAccessor.GetDirectoryName(null, isUnixLike: true)); } [Fact] public void TestGetDirectoryName_UnixPaths_Relative() { Assert.Equal( @"goo/temp", PathUtilities.TestAccessor.GetDirectoryName(@"goo/temp/goo.txt", isUnixLike: true)); Assert.Equal( @"goo/temp", PathUtilities.TestAccessor.GetDirectoryName(@"goo/temp/goo", isUnixLike: true)); Assert.Equal( @"goo/temp", PathUtilities.TestAccessor.GetDirectoryName(@"goo/temp/", isUnixLike: true)); Assert.Equal( @"goo", PathUtilities.TestAccessor.GetDirectoryName(@"goo/temp", isUnixLike: true)); Assert.Equal( @"goo", PathUtilities.TestAccessor.GetDirectoryName(@"goo/", isUnixLike: true)); Assert.Equal( "", PathUtilities.TestAccessor.GetDirectoryName(@"goo", isUnixLike: true)); Assert.Null( PathUtilities.TestAccessor.GetDirectoryName(@"", isUnixLike: true)); Assert.Null( PathUtilities.TestAccessor.GetDirectoryName(null, isUnixLike: true)); } [Fact] public void GetTempCachePath_UsesLocalApplicationData() { var directoryName = "roslyn-cache-" + Guid.NewGuid().ToString("N"); var expectedParentPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); var expectedPath = string.IsNullOrEmpty(expectedParentPath) ? null : Path.Combine(expectedParentPath, directoryName); try { var path = PathUtilities.GetTempCachePath(directoryName); Assert.Equal(expectedPath, path); if (path is not null) { Assert.True(Directory.Exists(path)); } } finally { if (expectedPath is not null && Directory.Exists(expectedPath)) { Directory.Delete(expectedPath, recursive: true); } } } [ConditionalFact(typeof(WindowsOnly))] public void TestGetDirectoryName_WindowsSharePaths() { TestGetDirectoryNameAndCompareToDotnet(@"\\server\temp", @"\\server\temp\goo.txt"); TestGetDirectoryNameAndCompareToDotnet(@"\\server\temp", @"\\server\temp\goo"); TestGetDirectoryNameAndCompareToDotnet(@"\\server\temp", @"\\server\temp\"); TestGetDirectoryNameAndCompareToDotnet(null, @"\\server\temp"); TestGetDirectoryNameAndCompareToDotnet(null, @"\\server\"); TestGetDirectoryNameAndCompareToDotnet(null, @"\\server"); TestGetDirectoryNameAndCompareToDotnet(null, @"\\"); TestGetDirectoryNameAndCompareToDotnet(null, @"\"); } [ConditionalFact(typeof(WindowsOnly))] public void TestGetDirectoryName_EsotericCases() { TestGetDirectoryNameAndCompareToDotnet(@"C:\temp", @"C:\temp\\goo.txt"); TestGetDirectoryNameAndCompareToDotnet(@"C:\temp", @"C:\temp\\\goo.txt"); // Dotnet does normalization of dots, so we can't compare against it here. Assert.Equal( @"C:\temp\..", PathUtilities.TestAccessor.GetDirectoryName(@"C:\temp\..\goo.txt", isUnixLike: false)); Assert.Equal( @"C:\temp", PathUtilities.TestAccessor.GetDirectoryName(@"C:\temp\..", isUnixLike: false)); Assert.Equal( @"C:\temp\.", PathUtilities.TestAccessor.GetDirectoryName(@"C:\temp\.\goo.txt", isUnixLike: false)); Assert.Equal( @"C:\temp", PathUtilities.TestAccessor.GetDirectoryName(@"C:\temp\.", isUnixLike: false)); TestGetDirectoryNameAndCompareToDotnet(@"C:temp", @"C:temp\\goo.txt"); TestGetDirectoryNameAndCompareToDotnet(@"C:temp", @"C:temp\\\goo.txt"); Assert.Equal( @"C:temp\..", PathUtilities.TestAccessor.GetDirectoryName(@"C:temp\..\goo.txt", isUnixLike: false)); Assert.Equal( @"C:temp", PathUtilities.TestAccessor.GetDirectoryName(@"C:temp\..", isUnixLike: false)); Assert.Equal( @"C:temp\.", PathUtilities.TestAccessor.GetDirectoryName(@"C:temp\.\goo.txt", isUnixLike: false)); Assert.Equal( @"C:temp", PathUtilities.TestAccessor.GetDirectoryName(@"C:temp\.", isUnixLike: false)); TestGetDirectoryNameAndCompareToDotnet(@"C:temp", @"C:temp\"); TestGetDirectoryNameAndCompareToDotnet(@"C:", @"C:temp"); TestGetDirectoryNameAndCompareToDotnet(null, @"C:"); } [ConditionalFact(typeof(WindowsOnly))] public void TestContainsPathComponent() { Assert.True( PathUtilities.ContainsPathComponent(@"c:\packages\temp", "packages", ignoreCase: true)); Assert.True( PathUtilities.ContainsPathComponent(@"\\server\packages\temp", "packages", ignoreCase: true)); Assert.False( PathUtilities.ContainsPathComponent(@"\\packages\temp", "packages", ignoreCase: true)); Assert.True( PathUtilities.ContainsPathComponent(@"c:\packages", "packages", ignoreCase: true)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\packages1\temp", "packages", ignoreCase: true)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\package\temp", "packages", ignoreCase: true)); Assert.True( PathUtilities.ContainsPathComponent(@"c:\packages\temp", "packages", ignoreCase: false)); Assert.True( PathUtilities.ContainsPathComponent(@"\\server\packages\temp", "packages", ignoreCase: false)); Assert.False( PathUtilities.ContainsPathComponent(@"\\packages\temp", "packages", ignoreCase: false)); Assert.True( PathUtilities.ContainsPathComponent(@"c:\packages", "packages", ignoreCase: false)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\packages1\temp", "packages", ignoreCase: false)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\package\temp", "packages", ignoreCase: false)); Assert.True( PathUtilities.ContainsPathComponent(@"c:\packages\temp", "Packages", ignoreCase: true)); Assert.True( PathUtilities.ContainsPathComponent(@"\\server\packages\temp", "Packages", ignoreCase: true)); Assert.False( PathUtilities.ContainsPathComponent(@"\\packages\temp", "Packages", ignoreCase: true)); Assert.True( PathUtilities.ContainsPathComponent(@"c:\packages", "Packages", ignoreCase: true)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\packages1\temp", "Packages", ignoreCase: true)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\package\temp", "Packages", ignoreCase: true)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\packages\temp", "Packages", ignoreCase: false)); Assert.False( PathUtilities.ContainsPathComponent(@"\\server\packages\temp", "Packages", ignoreCase: false)); Assert.False( PathUtilities.ContainsPathComponent(@"\\packages\temp", "Packages", ignoreCase: false)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\packages", "Packages", ignoreCase: false)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\packages1\temp", "Packages", ignoreCase: false)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\package\temp", "Packages", ignoreCase: false)); Assert.True( PathUtilities.ContainsPathComponent(@"c:\Packages\temp", "packages", ignoreCase: true)); Assert.True( PathUtilities.ContainsPathComponent(@"\\server\Packages\temp", "packages", ignoreCase: true)); Assert.False( PathUtilities.ContainsPathComponent(@"\\Packages\temp", "packages", ignoreCase: true)); Assert.True( PathUtilities.ContainsPathComponent(@"c:\Packages", "packages", ignoreCase: true)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\Packages1\temp", "packages", ignoreCase: true)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\Package\temp", "packages", ignoreCase: true)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\Packages\temp", "packages", ignoreCase: false)); Assert.False( PathUtilities.ContainsPathComponent(@"\\server\Packages\temp", "packages", ignoreCase: false)); Assert.False( PathUtilities.ContainsPathComponent(@"\\Packages\temp", "packages", ignoreCase: false)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\Packages", "packages", ignoreCase: false)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\Packages1\temp", "packages", ignoreCase: false)); Assert.False( PathUtilities.ContainsPathComponent(@"c:\Package\temp", "packages", ignoreCase: false)); } [ConditionalFact(typeof(WindowsOnly))] public void IsSameDirectoryOrChildOfHandlesDifferentSlashes() { Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\", @"C:")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\", @"C:\")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:", @"C:")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:", @"C:\")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABCD\EFGH", @"C:")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABCD\EFGH", @"C:\")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABCD\EFGH\", @"C:")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABCD\EFGH\", @"C:\")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABCD\EFGH", @"C:\ABCD")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABCD\EFGH", @"C:\ABCD\")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABCD\EFGH\", @"C:\ABCD")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABCD\EFGH\", @"C:\ABCD\")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABCD\EFGH", @"C:\ABCD\EFGH")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABCD\EFGH", @"C:\ABCD\EFGH\")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABCD\EFGH\", @"C:\ABCD\EFGH")); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABCD\EFGH\", @"C:\ABCD\EFGH\")); } [Fact] public void IsSameDirectoryOrChildOfNegativeTests() { Assert.False(PathUtilities.IsSameDirectoryOrChildOf(@"C:\", @"C:\ABCD")); Assert.False(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABC", @"C:\ABCD")); Assert.False(PathUtilities.IsSameDirectoryOrChildOf(@"C:\ABCDE", @"C:\ABCD")); Assert.False(PathUtilities.IsSameDirectoryOrChildOf(@"C:\A\B\C", @"C:\A\B\C\D")); } [ConditionalFact(typeof(WindowsOnly))] public void IsSameDirectoryOrChildOfSpecifyingCaseSensitivity_Windows() { Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\a\B\C", @"C:\A\B", StringComparison.OrdinalIgnoreCase)); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"C:\A\b\C", @"C:\A\B", StringComparison.OrdinalIgnoreCase)); Assert.False(PathUtilities.IsSameDirectoryOrChildOf(@"C:\a\B\C", @"C:\A\B", StringComparison.Ordinal)); Assert.False(PathUtilities.IsSameDirectoryOrChildOf(@"C:\A\b\C", @"C:\A\B", StringComparison.Ordinal)); } [ConditionalFact(typeof(UnixLikeOnly))] public void IsSameDirectoryOrChildOfSpecifyingCaseSensitivity_Unix() { Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"/a/B/C", @"/A/B", StringComparison.OrdinalIgnoreCase)); Assert.True(PathUtilities.IsSameDirectoryOrChildOf(@"/A/b/C", @"/A/B", StringComparison.OrdinalIgnoreCase)); Assert.False(PathUtilities.IsSameDirectoryOrChildOf(@"/a/B/C", @"/A/B", StringComparison.Ordinal)); Assert.False(PathUtilities.IsSameDirectoryOrChildOf(@"/A/b/C", @"/A/B", StringComparison.Ordinal)); } [Fact] public void IsValidFilePath() { var cases = new[] { ("test/data1.txt", true), ("test\\data1.txt", true), ("data1.txt", true), ("data1", true), ("data1\\", PathUtilities.IsUnixLikePlatform), ("data1//", false), (null, false), ("", false), (" ", ExecutionConditionUtil.IsCoreClrUnix), ("path/?.txt", !ExecutionConditionUtil.IsWindowsDesktop), ("path/*.txt", !ExecutionConditionUtil.IsWindowsDesktop), ("path/:.txt", !ExecutionConditionUtil.IsWindowsDesktop), ("path/\".txt", !ExecutionConditionUtil.IsWindowsDesktop), ("IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" + "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" + "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" + "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" + "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII.txt", !ExecutionConditionUtil.IsWindowsDesktop) }; foreach (var (path, isValid) in cases) { Assert.True(isValid == PathUtilities.IsValidFilePath(path), $"Expected {isValid} for \"{path}\""); } } [ConditionalTheory(typeof(WindowsOnly))] [InlineData(@"C:\", "B")] [InlineData(@"C:\A", "B")] [InlineData(@"C:\A\", "B")] [InlineData(@"C:A\", "B")] [InlineData(@"\A", "B")] [InlineData(@"\\A\B\C", "B")] [InlineData(@"C", @"B:\")] [InlineData(@"C:", @"B:\")] [InlineData(@"C:\", @"B:\")] [InlineData(@"C:\A", @"B:\")] [InlineData(@"C:\A\", @"B:\")] [InlineData(@"C:A\", @"B:\")] [InlineData(@"\A", @"B:\")] [InlineData(@"\\A\B\C", @"B:\")] [InlineData("", @"B:\")] [InlineData(" ", @"B:\")] public void CombinePaths_SameAsPathCombine_Windows(string path1, string path2) { Assert.Equal(Path.Combine(path1, path2), PathUtilities.CombinePaths(path1, path2)); } [ConditionalTheory(typeof(UnixLikeOnly))] [InlineData("C", "B")] [InlineData("C/", "\t")] [InlineData("C/", "B")] [InlineData("/C", "B")] [InlineData("/C/", "B")] [InlineData("C", "/B")] [InlineData("C/", "/B")] [InlineData("/C", "/B")] [InlineData("/C/", "/B")] [InlineData("", "/B/")] [InlineData(" ", "/B/")] public void CombinePaths_SameAsPathCombine_Linux(string path1, string path2) { Assert.Equal(Path.Combine(path1, path2), PathUtilities.CombinePaths(path1, path2)); } [Theory] [InlineData("C", " ")] [InlineData("C", "B")] [InlineData("", "")] [InlineData(" ", " ")] [InlineData("", "B")] [InlineData(" ", "B")] public void CombinePaths_SameAsPathCombine_Common(string path1, string path2) { Assert.Equal(Path.Combine(path1, path2), PathUtilities.CombinePaths(path1, path2)); } [ConditionalTheory(typeof(WindowsOnly))] [InlineData(@"C:\|\<>", @"C:\|", "<>")] [InlineData("C:\\\t", @"C:\", "\t")] [InlineData("C", "C", null)] [InlineData("C:B", "C:", "B")] [InlineData(null, null, null)] [InlineData("B", null, "B")] public void CombinePaths_DifferentFromPathCombine(string expected, string path1, string path2) { Assert.Equal(expected, PathUtilities.CombinePaths(path1, path2)); } [ConditionalFact(typeof(WindowsOnly)), WorkItem(51602, @"https://github.com/dotnet/roslyn/issues/51602")] public void GetRelativePath_EnsureNo_IndexOutOfRangeException_Windows() { var expected = ""; var result = PathUtilities.GetRelativePath(@"C:\A\B\", @"C:\A\B"); Assert.Equal(expected, result); } [ConditionalFact(typeof(UnixLikeOnly)), WorkItem(51602, @"https://github.com/dotnet/roslyn/issues/51602")] public void GetRelativePath_EnsureNo_IndexOutOfRangeException_Unix() { var expected = ""; var result = PathUtilities.GetRelativePath(@"/A/B/", @"/A/B"); Assert.Equal(expected, result); } [Theory] [InlineData(@"//a/b/c", @"//a/b/c")] [InlineData(@"/a\b/c/", @"/a/b/c/")] [InlineData(@"\a\b/c/", @"/a/b/c/")] [InlineData(@"C:\\a", @"C:/a")] [InlineData(@"C:\a\b\c\", @"C:/a/b/c/")] [InlineData(@"/\a", @"//a")] [InlineData(@"a\\\b", @"a/b")] [InlineData(@"\\\a\b\c", @"///a/b/c")] [InlineData(@"\\\\a\b\c", @"///a/b/c")] public void CollapseWithForwardSlash(string input, string output) { AssertEx.Equal(output, PathUtilities.CollapseWithForwardSlash(input.AsSpan())); } [ConditionalTheory(typeof(WindowsOnly))] [InlineData(@"//a/b/c", @"//a/b/c")] [InlineData(@"/a\b/c/", @"/a\b/c/")] [InlineData(@"C:B", @"C:B")] [InlineData(@"c:b", @"c:b")] [InlineData(@"c:\b", @"C:\b")] [InlineData(@"c:/b", @"C:/b")] public void NormalizeDriveLetter_Windows(string input, string output) { AssertEx.Equal(output, PathUtilities.NormalizeDriveLetter(input)); } [ConditionalTheory(typeof(UnixLikeOnly))] [InlineData(@"//a/b/c")] [InlineData(@"/a\b/c/")] [InlineData(@"C:B")] [InlineData(@"c:b")] [InlineData(@"c:\b")] [InlineData(@"c:/b")] public void NormalizeDriveLetter_UnixLike(string input) { AssertEx.Equal(input, PathUtilities.NormalizeDriveLetter(input)); } } }