/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/Core/CodeAnalysisTest/FileUtilitiesTests.cs
326 строк
18 KB
Joey Robichaud
Return the absolute glob paths in ProjectFileInfo
29 янв 2025, 21:07
29 янв 2025, 21:07
d616079
Код
Авторство
О чём код?
// 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.Collections.Generic; using System.IO; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Roslyn.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.UnitTests { public class FileUtilitiesTests { [ConditionalFact(typeof(WindowsOnly))] public void IsAbsolute() { Assert.False(PathUtilities.IsAbsolute(null)); Assert.False(PathUtilities.IsAbsolute("")); Assert.False(PathUtilities.IsAbsolute("C")); Assert.False(PathUtilities.IsAbsolute("C:")); Assert.True(PathUtilities.IsAbsolute(@"C:\")); Assert.True(PathUtilities.IsAbsolute(@"C:/")); Assert.True(PathUtilities.IsAbsolute(@"C:\\")); Assert.False(PathUtilities.IsAbsolute(@"C\")); Assert.True(PathUtilities.IsAbsolute(@"\\")); // incomplete UNC Assert.True(PathUtilities.IsAbsolute(@"\\S")); // incomplete UNC Assert.True(PathUtilities.IsAbsolute(@"\/C")); // incomplete UNC Assert.True(PathUtilities.IsAbsolute(@"\/C\")); // incomplete UNC Assert.True(PathUtilities.IsAbsolute(@"\\server")); // incomplete UNC Assert.True(PathUtilities.IsAbsolute(@"\\server\share")); // UNC Assert.True(PathUtilities.IsAbsolute(@"\\?\C:\share")); // long UNC Assert.False(PathUtilities.IsAbsolute(@"\C")); Assert.False(PathUtilities.IsAbsolute(@"/C")); } [ConditionalFact(typeof(WindowsOnly))] public void GetPathRoot() { Assert.Null(PathUtilities.GetPathRoot(null)); Assert.Equal("", PathUtilities.GetPathRoot("")); Assert.Equal("", PathUtilities.GetPathRoot("C")); Assert.Equal("", PathUtilities.GetPathRoot("abc.txt")); Assert.Equal("C:", PathUtilities.GetPathRoot("C:")); Assert.Equal(@"C:\", PathUtilities.GetPathRoot(@"C:\")); Assert.Equal(@"C:/", PathUtilities.GetPathRoot(@"C:/")); Assert.Equal(@"C:\", PathUtilities.GetPathRoot(@"C:\\")); Assert.Equal(@"C:/", PathUtilities.GetPathRoot(@"C:/\")); Assert.Equal(@"*:/", PathUtilities.GetPathRoot(@"*:/")); Assert.Equal(@"0:/", PathUtilities.GetPathRoot(@"0:/")); Assert.Equal(@"::/", PathUtilities.GetPathRoot(@"::/")); // '/' is an absolute path on unix-like systems switch (Environment.OSVersion.Platform) { case PlatformID.MacOSX: case PlatformID.Unix: Assert.Equal("/", PathUtilities.GetPathRoot(@"/")); Assert.Equal(@"/", PathUtilities.GetPathRoot(@"/x")); // Be permissive of either directory separator, just // like we are in other cases Assert.Equal(@"\", PathUtilities.GetPathRoot(@"\")); Assert.Equal(@"\", PathUtilities.GetPathRoot(@"\x")); break; default: Assert.Equal(@"\", PathUtilities.GetPathRoot(@"\")); Assert.Equal(@"\", PathUtilities.GetPathRoot(@"\x")); break; } Assert.Equal(@"\\", PathUtilities.GetPathRoot(@"\\")); Assert.Equal(@"\\x", PathUtilities.GetPathRoot(@"\\x")); Assert.Equal(@"\\x\", PathUtilities.GetPathRoot(@"\\x\")); Assert.Equal(@"\\x\y", PathUtilities.GetPathRoot(@"\\x\y")); Assert.Equal(@"\\\x\y", PathUtilities.GetPathRoot(@"\\\x\y")); Assert.Equal(@"\\\\x\y", PathUtilities.GetPathRoot(@"\\\\x\y")); Assert.Equal(@"\\x\\y", PathUtilities.GetPathRoot(@"\\x\\y")); Assert.Equal(@"\\/x\\/y", PathUtilities.GetPathRoot(@"\\/x\\/y")); Assert.Equal(@"\\/x\\/y", PathUtilities.GetPathRoot(@"\\/x\\/y/")); Assert.Equal(@"\\/x\\/y", PathUtilities.GetPathRoot(@"\\/x\\/y\/")); Assert.Equal(@"\\/x\\/y", PathUtilities.GetPathRoot(@"\\/x\\/y\/zzz")); Assert.Equal(@"\\x\y", PathUtilities.GetPathRoot(@"\\x\y")); Assert.Equal(@"\\x\y", PathUtilities.GetPathRoot(@"\\x\y\\")); Assert.Equal(@"\\abc\xyz", PathUtilities.GetPathRoot(@"\\abc\xyz")); Assert.Equal(@"\\server\$c", PathUtilities.GetPathRoot(@"\\server\$c\Public")); // TODO (tomat): long UNC paths // Assert.Equal(@"\\?\C:\", PathUtilities.GetPathRoot(@"\\?\C:\abc\def")); } [ConditionalFact(typeof(WindowsOnly))] public void CombinePaths() { Assert.Equal(@"C:\x/y", PathUtilities.CombineAbsoluteAndRelativePaths(@"C:\x/y", @"")); Assert.Equal(@"C:\x/y", PathUtilities.CombineAbsoluteAndRelativePaths(@"C:\x/y", null)); Assert.Equal(@"C:\x/y", PathUtilities.CombineAbsoluteAndRelativePaths(@"C:\x/y", null)); Assert.Null(PathUtilities.CombineAbsoluteAndRelativePaths(@"C:\", @"C:\goo")); Assert.Null(PathUtilities.CombineAbsoluteAndRelativePaths(@"C:\", @"C:goo")); Assert.Null(PathUtilities.CombineAbsoluteAndRelativePaths(@"C:\", @"\goo")); Assert.Equal(@"C:\x\y\goo", PathUtilities.CombineAbsoluteAndRelativePaths(@"C:\x\y", @"goo")); Assert.Equal(@"C:\x/y\goo", PathUtilities.CombineAbsoluteAndRelativePaths(@"C:\x/y", @"goo")); Assert.Equal(@"C:\x/y\.\goo", PathUtilities.CombineAbsoluteAndRelativePaths(@"C:\x/y", @".\goo")); Assert.Equal(@"C:\x/y\./goo", PathUtilities.CombineAbsoluteAndRelativePaths(@"C:\x/y", @"./goo")); Assert.Equal(@"C:\x/y\..\goo", PathUtilities.CombineAbsoluteAndRelativePaths(@"C:\x/y", @"..\goo")); Assert.Equal(@"C:\x/y\../goo", PathUtilities.CombineAbsoluteAndRelativePaths(@"C:\x/y", @"../goo")); } [ConditionalFact(typeof(WindowsOnly))] public void ResolveRelativePath() { string baseDir = @"X:\rootdir\dir"; string[] noSearchPaths = new string[0]; // absolute path: TestPath(@"C:\abc\def.dll", @"Q:\baz\x.csx", baseDir, noSearchPaths, @"C:\abc\def.dll"); TestPath(@"C:\abc\\\\\def.dll", @"Q:\baz\x.csx", baseDir, noSearchPaths, @"C:\abc\\\\\def.dll"); // root-relative path: TestPath(@"\abc\def.dll", @"Q:\baz\x.csx", baseDir, noSearchPaths, @"Q:\abc\def.dll"); TestPath(@"\abc\def.dll", null, baseDir, noSearchPaths, @"X:\abc\def.dll"); TestPath(@"\abc\def.dll", "goo.csx", null, noSearchPaths, null); // TestPath(@"\abc\def.dll", @"C:goo.csx", null, noSearchPaths, null); // TestPath(@"/abc\def.dll", @"\goo.csx", null, noSearchPaths, null); TestPath(@"/abc\def.dll", null, @"\\x\y\z", noSearchPaths, @"\\x\y\abc\def.dll"); TestPath(@"/abc\def.dll", null, null, noSearchPaths, null); TestPath(@"/**/", null, baseDir, noSearchPaths, @"X:\**/"); TestPath(@"/a/z.txt", null, @"?:\*\<>", noSearchPaths, @"?:\a/z.txt"); // UNC path: TestPath(@"\abc\def.dll", @"\\mymachine\root\x.csx", baseDir, noSearchPaths, @"\\mymachine\root\abc\def.dll"); TestPath(@"\abc\def.dll", null, @"\\mymachine\root\x.csx", noSearchPaths, @"\\mymachine\root\abc\def.dll"); TestPath(@"\\abc\def\baz.dll", null, @"\\mymachine\root\x.csx", noSearchPaths, @"\\abc\def\baz.dll"); // incomplete UNC paths (considered absolute and returned as they are): TestPath(@"\\", null, @"\\mymachine\root\x.csx", noSearchPaths, @"\\"); TestPath(@"\\goo", null, @"\\mymachine\root\x.csx", noSearchPaths, @"\\goo"); // long UNC path: // TODO (tomat): // Doesn't work since "?" in paths is not handled by BCL // TestPath(resolver, @"\abc\def.dll", @"\\?\C:\zzz\x.csx", @"\\?\C:\abc\def.dll"); TestPath(@"./def.dll", @"Q:\abc\x.csx", baseDir, noSearchPaths, @"Q:\abc\./def.dll"); TestPath(@"./def.dll", @"Q:\abc\x.csx", baseDir, noSearchPaths, @"Q:\abc\./def.dll"); TestPath(@".", @"Q:\goo\x.csx", baseDir, noSearchPaths, @"Q:\goo"); TestPath(@"..", @"Q:\goo\x.csx", baseDir, noSearchPaths, @"Q:\goo\.."); // doesn't normalize TestPath(@".\", @"Q:\goo\x.csx", baseDir, noSearchPaths, @"Q:\goo\.\"); TestPath(@"..\", @"Q:\goo\x.csx", baseDir, noSearchPaths, @"Q:\goo\..\"); // doesn't normalize // relative base paths: TestPath(@".\y.dll", @"x.csx", baseDir, noSearchPaths, @"X:\rootdir\dir\.\y.dll"); TestPath(@".\y.dll", @"goo\x.csx", baseDir, noSearchPaths, @"X:\rootdir\dir\goo\.\y.dll"); TestPath(@".\y.dll", @".\goo\x.csx", baseDir, noSearchPaths, @"X:\rootdir\dir\.\goo\.\y.dll"); TestPath(@".\y.dll", @"..\x.csx", baseDir, noSearchPaths, @"X:\rootdir\dir\..\.\y.dll"); // doesn't normalize TestPath(@".\\y.dll", @"..\x.csx", baseDir, noSearchPaths, @"X:\rootdir\dir\..\.\\y.dll"); // doesn't normalize TestPath(@".\/y.dll", @"..\x.csx", baseDir, noSearchPaths, @"X:\rootdir\dir\..\.\/y.dll"); // doesn't normalize TestPath(@"..\y.dll", @"..\x.csx", baseDir, noSearchPaths, @"X:\rootdir\dir\..\..\y.dll"); // doesn't normalize // unqualified relative path, look in base directory: TestPath(@"y.dll", @"x.csx", baseDir, noSearchPaths, @"X:\rootdir\dir\y.dll"); TestPath(@"y.dll", @"x.csx", baseDir, new[] { @"Z:\" }, @"X:\rootdir\dir\y.dll"); // drive-relative path (not supported -> null) TestPath(@"C:y.dll", @"x.csx", baseDir, noSearchPaths, null); TestPath("C:\tools\\", null, @"d:\z", noSearchPaths, null); // invalid paths Assert.Equal(PathKind.RelativeToCurrentRoot, PathUtilities.GetPathKind(@"/c:x.dll")); TestPath(@"/c:x.dll", null, @"d:\", noSearchPaths, @"d:\c:x.dll"); Assert.Equal(PathKind.RelativeToCurrentRoot, PathUtilities.GetPathKind(@"/:x.dll")); TestPath(@"/:x.dll", null, @"d:\", noSearchPaths, @"d:\:x.dll"); Assert.Equal(PathKind.Absolute, PathUtilities.GetPathKind(@"//:x.dll")); TestPath(@"//:x.dll", null, @"d:\", noSearchPaths, @"//:x.dll"); Assert.Equal(PathKind.RelativeToDriveDirectory, PathUtilities.GetPathKind(@"c::x.dll")); TestPath(@"c::x.dll", null, @"d:\", noSearchPaths, null); Assert.Equal(PathKind.RelativeToCurrentDirectory, PathUtilities.GetPathKind(@".\:x.dll")); TestPath(@".\:x.dll", null, @"d:\z", noSearchPaths, @"d:\z\.\:x.dll"); Assert.Equal(PathKind.RelativeToCurrentParent, PathUtilities.GetPathKind(@"..\:x.dll")); TestPath(@"..\:x.dll", null, @"d:\z", noSearchPaths, @"d:\z\..\:x.dll"); // empty paths Assert.Equal(PathKind.Empty, PathUtilities.GetPathKind(@"")); TestPath(@"", @"c:\temp", @"d:\z", noSearchPaths, null); Assert.Equal(PathKind.Empty, PathUtilities.GetPathKind(" \t\r\n ")); TestPath(" \t\r\n ", @"c:\temp", @"d:\z", noSearchPaths, null); } private void TestPath(string path, string basePath, string baseDirectory, IEnumerable<String> searchPaths, string expected) { string actual = FileUtilities.ResolveRelativePath(path, basePath, baseDirectory, searchPaths, p => true); Assert.Equal(expected, actual, StringComparer.OrdinalIgnoreCase); } private void TestGetExtension(string path, string expected) { Assert.Equal(expected, PathUtilities.GetExtension(path)); Assert.Equal(expected, Path.GetExtension(path)); } private void TestRemoveExtension(string path, string expected) { Assert.Equal(expected, PathUtilities.RemoveExtension(path)); Assert.Equal(expected, Path.GetFileNameWithoutExtension(path)); } private void TestChangeExtension(string path, string extension, string expected) { Assert.Equal(expected, PathUtilities.ChangeExtension(path, extension)); Assert.Equal(expected, Path.ChangeExtension(path, extension)); } [ConditionalFact(typeof(WindowsOnly))] public void Extension() { TestGetExtension(path: "a.dll", expected: ".dll"); TestGetExtension(path: "a.exe.config", expected: ".config"); TestGetExtension(path: ".goo", expected: ".goo"); TestGetExtension(path: ".goo.dll", expected: ".dll"); TestGetExtension(path: "goo", expected: ""); TestGetExtension(path: "goo.", expected: ""); TestGetExtension(path: "goo..", expected: ""); TestGetExtension(path: "goo...", expected: ""); Assert.Equal(".dll", PathUtilities.GetExtension("*.dll")); TestRemoveExtension(path: "a.dll", expected: "a"); TestRemoveExtension(path: "a.exe.config", expected: "a.exe"); TestRemoveExtension(path: ".goo", expected: ""); TestRemoveExtension(path: ".goo.dll", expected: ".goo"); TestRemoveExtension(path: "goo", expected: "goo"); TestRemoveExtension(path: "goo.", expected: "goo"); TestRemoveExtension(path: "goo..", expected: "goo."); TestRemoveExtension(path: "goo...", expected: "goo.."); Assert.Equal("*", PathUtilities.RemoveExtension("*.dll")); TestChangeExtension(path: "a.dll", extension: ".exe", expected: "a.exe"); TestChangeExtension(path: "a.dll", extension: "exe", expected: "a.exe"); TestChangeExtension(path: "a.dll", extension: "", expected: "a."); TestChangeExtension(path: "a.dll", extension: ".", expected: "a."); TestChangeExtension(path: "a.dll", extension: "..", expected: "a.."); TestChangeExtension(path: "a.dll", extension: "...", expected: "a..."); TestChangeExtension(path: "a.dll", extension: " ", expected: "a. "); TestChangeExtension(path: "a", extension: ".exe", expected: "a.exe"); TestChangeExtension(path: "a.", extension: "exe", expected: "a.exe"); TestChangeExtension(path: "a..", extension: "exe", expected: "a..exe"); TestChangeExtension(path: "a.", extension: "e.x.e", expected: "a.e.x.e"); TestChangeExtension(path: ".", extension: "", expected: "."); TestChangeExtension(path: "..", extension: ".", expected: ".."); TestChangeExtension(path: "..", extension: "..", expected: "..."); TestChangeExtension(path: "", extension: "", expected: ""); TestChangeExtension(path: null, extension: "", expected: null); TestChangeExtension(path: null, extension: null, expected: null); Assert.Equal("*", PathUtilities.RemoveExtension("*.dll")); } [ConditionalTheory(typeof(WindowsOnly))] [InlineData(@"x:\a\b\file.cs", "x:/a/b/file.cs")] [InlineData(@"x:/a/b/file.cs", "x:/a/b/file.cs")] [InlineData(@"x:\a\b\", "x:/a/b/")] [InlineData(@"x:\a\b", "x:/a/b")] [InlineData(@"x:\a\..\b\file.cs", "x:/b/file.cs")] [InlineData(@"x:/a/../b/file.cs", "x:/b/file.cs")] [InlineData(@"x:\a\b\..\c\", "x:/a/c/")] [InlineData(@"x:\a\.\.\b\..\c\", "x:/a/c/")] [InlineData(@"x:\..\..\a\.\.\b\..\c\", "x:/a/c/")] [InlineData(@"\\server\a\b\", @"\\server\a\b\")] [InlineData(@"\\server\..\a\.\.\b\..\c\", @"\\server\..\a\.\.\b\..\c\")] [InlineData(@"x:a.cs", "x:a.cs")] [InlineData(@"x:a//b//..//a.cs", "x:a//b//..//a.cs")] [InlineData(@"ab:\c\d\", @"ab:\c\d\")] [InlineData(@"ab:/c/d", @"ab:/c/d")] [InlineData(@"ab:\c\..\d\", @"ab:\c\..\d\")] [InlineData(@"\\.\C:\a\b.cs", @"\\.\C:\a\b.cs")] [InlineData(@"\\.\C:\a\..\b.cs", @"\\.\C:\a\..\b.cs")] [InlineData(@"\\?\C:\a\b.cs", @"\\?\C:\a\b.cs")] [InlineData(@"\\.\Volume{00000000-0000-0000-0000-000000000000}\a\b.cs", @"\\.\Volume{00000000-0000-0000-0000-000000000000}\a\b.cs")] [InlineData(@"\", @"\")] [InlineData(@"\\", @"\\")] [InlineData(@"\\server", @"\\server")] [InlineData(@"x:", "x:")] [InlineData(@"x:\", @"x:/")] public void TestExpandAbsolutePathWithRelativeParts_Windows(string input, string expected) => TestExpandAbsolutePathWithRelativeParts(input, expected); [Theory] [InlineData("/", "/")] [InlineData("/a/b/c", "/a/b/c")] [InlineData("/a/b/c/file.cs", "/a/b/c/file.cs")] [InlineData("/a/b/../c/file.cs", "/a/c/file.cs")] [InlineData("/a/../b/../c/file.cs", "/c/file.cs")] [InlineData("/../../c/file.cs", "/c/file.cs")] [InlineData("/a/../b/./././../c/file.cs", "/c/file.cs")] [InlineData("/tmp/../.config/../.roslyn/**/*.cs", "/.roslyn/**/*.cs")] // not absolute paths [InlineData("a/b/c", "a/b/c")] [InlineData("./a/b/c", "./a/b/c")] [InlineData("./a/../b/c", "./a/../b/c")] [InlineData("../a/../b/c", "../a/../b/c")] [InlineData("foo", "foo")] [InlineData("", "")] [InlineData(".", ".")] [InlineData("..", "..")] [InlineData("../", "../")] [InlineData("./", "./")] public void TestExpandAbsolutePathWithRelativeParts(string input, string expected) { var result = PathUtilities.ExpandAbsolutePathWithRelativeParts(input); Assert.Equal(expected, result); } } }