|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.Build.Shared;
using Shouldly;
using Xunit;
using Xunit.NetCore.Extensions;
#nullable disable
namespace Microsoft.Build.UnitTests
{
public class FileUtilities_Tests
{
/// <summary>
/// Exercises FileUtilities.ItemSpecModifiers.GetItemSpecModifier
/// </summary>
[Fact]
[Trait("Category", "netcore-osx-failing")]
[Trait("Category", "netcore-linux-failing")]
public void GetItemSpecModifier()
{
TestGetItemSpecModifier(Directory.GetCurrentDirectory());
TestGetItemSpecModifier(null);
}
private static void TestGetItemSpecModifier(string currentDirectory)
{
string cache = null;
string modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, "foo", String.Empty, FileUtilities.ItemSpecModifiers.RecursiveDir, ref cache);
Assert.Equal(String.Empty, modifier);
cache = null;
modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, "foo", String.Empty, FileUtilities.ItemSpecModifiers.ModifiedTime, ref cache);
Assert.Equal(String.Empty, modifier);
cache = null;
modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, @"foo\goo", String.Empty, FileUtilities.ItemSpecModifiers.RelativeDir, ref cache);
Assert.Equal(@"foo" + Path.DirectorySeparatorChar, modifier);
// confirm we get the same thing back the second time
modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, @"foo\goo", String.Empty, FileUtilities.ItemSpecModifiers.RelativeDir, ref cache);
Assert.Equal(@"foo" + Path.DirectorySeparatorChar, modifier);
cache = null;
string itemSpec = NativeMethodsShared.IsWindows ? @"c:\foo.txt" : "/foo.txt";
string itemSpecDir = NativeMethodsShared.IsWindows ? @"c:\" : "/";
modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, itemSpec, String.Empty, FileUtilities.ItemSpecModifiers.FullPath, ref cache);
Assert.Equal(itemSpec, modifier);
Assert.Equal(itemSpec, cache);
modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, itemSpec, String.Empty, FileUtilities.ItemSpecModifiers.RootDir, ref cache);
Assert.Equal(itemSpecDir, modifier);
modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, itemSpec, String.Empty, FileUtilities.ItemSpecModifiers.Filename, ref cache);
Assert.Equal(@"foo", modifier);
modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, itemSpec, String.Empty, FileUtilities.ItemSpecModifiers.Extension, ref cache);
Assert.Equal(@".txt", modifier);
modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, itemSpec, String.Empty, FileUtilities.ItemSpecModifiers.Directory, ref cache);
Assert.Equal(String.Empty, modifier);
modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, itemSpec, String.Empty, FileUtilities.ItemSpecModifiers.Identity, ref cache);
Assert.Equal(itemSpec, modifier);
string projectPath = NativeMethodsShared.IsWindows ? @"c:\abc\goo.proj" : @"/abc/goo.proj";
string projectPathDir = NativeMethodsShared.IsWindows ? @"c:\abc\" : @"/abc/";
modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, itemSpec, projectPath, FileUtilities.ItemSpecModifiers.DefiningProjectDirectory, ref cache);
Assert.Equal(projectPathDir, modifier);
modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, itemSpec, projectPath, FileUtilities.ItemSpecModifiers.DefiningProjectExtension, ref cache);
Assert.Equal(@".proj", modifier);
modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, itemSpec, projectPath, FileUtilities.ItemSpecModifiers.DefiningProjectFullPath, ref cache);
Assert.Equal(projectPath, modifier);
modifier = FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, itemSpec, projectPath, FileUtilities.ItemSpecModifiers.DefiningProjectName, ref cache);
Assert.Equal(@"goo", modifier);
}
[Fact]
public void MakeRelativeTests()
{
if (NativeMethodsShared.IsWindows)
{
Assert.Equal(@"foo.cpp", FileUtilities.MakeRelative(@"c:\abc\def", @"c:\abc\def\foo.cpp"));
Assert.Equal(@"def\foo.cpp", FileUtilities.MakeRelative(@"c:\abc\", @"c:\abc\def\foo.cpp"));
Assert.Equal(@"..\foo.cpp", FileUtilities.MakeRelative(@"c:\abc\def\xyz", @"c:\abc\def\foo.cpp"));
Assert.Equal(@"..\ttt\foo.cpp", FileUtilities.MakeRelative(@"c:\abc\def\xyz\", @"c:\abc\def\ttt\foo.cpp"));
Assert.Equal(@"e:\abc\def\foo.cpp", FileUtilities.MakeRelative(@"c:\abc\def", @"e:\abc\def\foo.cpp"));
Assert.Equal(@"foo.cpp", FileUtilities.MakeRelative(@"\\aaa\abc\def", @"\\aaa\abc\def\foo.cpp"));
Assert.Equal(@"foo.cpp", FileUtilities.MakeRelative(@"c:\abc\def", @"foo.cpp"));
Assert.Equal(@"\\host\path\file", FileUtilities.MakeRelative(@"c:\abc\def", @"\\host\path\file"));
Assert.Equal(@"\\host\d$\file", FileUtilities.MakeRelative(@"c:\abc\def", @"\\host\d$\file"));
Assert.Equal(@"..\fff\ggg.hh", FileUtilities.MakeRelative(@"c:\foo\bar\..\abc\cde", @"c:\foo\bar\..\abc\fff\ggg.hh"));
/* Directories */
Assert.Equal(@"def\", FileUtilities.MakeRelative(@"c:\abc\", @"c:\abc\def\"));
Assert.Equal(@"..\", FileUtilities.MakeRelative(@"c:\abc\def\xyz\", @"c:\abc\def\"));
Assert.Equal(@"..\ttt\", FileUtilities.MakeRelative(@"c:\abc\def\xyz\", @"c:\abc\def\ttt\"));
Assert.Equal(@".", FileUtilities.MakeRelative(@"c:\abc\def\", @"c:\abc\def\"));
/* Directory + File */
Assert.Equal(@"def", FileUtilities.MakeRelative(@"c:\abc\", @"c:\abc\def"));
Assert.Equal(@"..\..\ghi", FileUtilities.MakeRelative(@"c:\abc\def\xyz\", @"c:\abc\ghi"));
Assert.Equal(@"..\ghi", FileUtilities.MakeRelative(@"c:\abc\def\xyz\", @"c:\abc\def\ghi"));
Assert.Equal(@"..\ghi", FileUtilities.MakeRelative(@"c:\abc\def\", @"c:\abc\ghi"));
/* File + Directory */
Assert.Equal(@"def\", FileUtilities.MakeRelative(@"c:\abc", @"c:\abc\def\"));
Assert.Equal(@"..\", FileUtilities.MakeRelative(@"c:\abc\def\xyz", @"c:\abc\def\"));
Assert.Equal(@"..\ghi\", FileUtilities.MakeRelative(@"c:\abc\def\xyz", @"c:\abc\def\ghi\"));
Assert.Equal(@".", FileUtilities.MakeRelative(@"c:\abc\def", @"c:\abc\def\"));
}
else
{
Assert.Equal(@"bar.cpp", FileUtilities.MakeRelative(@"/abc/def", @"/abc/def/bar.cpp"));
Assert.Equal(@"def/foo.cpp", FileUtilities.MakeRelative(@"/abc/", @"/abc/def/foo.cpp"));
Assert.Equal(@"../foo.cpp", FileUtilities.MakeRelative(@"/abc/def/xyz", @"/abc/def/foo.cpp"));
Assert.Equal(@"../ttt/foo.cpp", FileUtilities.MakeRelative(@"/abc/def/xyz/", @"/abc/def/ttt/foo.cpp"));
Assert.Equal(@"foo.cpp", FileUtilities.MakeRelative(@"/abc/def", @"foo.cpp"));
Assert.Equal(@"../fff/ggg.hh", FileUtilities.MakeRelative(@"/foo/bar/../abc/cde", @"/foo/bar/../abc/fff/ggg.hh"));
/* Directories */
Assert.Equal(@"def/", FileUtilities.MakeRelative(@"/abc/", @"/abc/def/"));
Assert.Equal(@"../", FileUtilities.MakeRelative(@"/abc/def/xyz/", @"/abc/def/"));
Assert.Equal(@"../ttt/", FileUtilities.MakeRelative(@"/abc/def/xyz/", @"/abc/def/ttt/"));
Assert.Equal(@".", FileUtilities.MakeRelative(@"/abc/def/", @"/abc/def/"));
/* Directory + File */
Assert.Equal(@"def", FileUtilities.MakeRelative(@"/abc/", @"/abc/def"));
Assert.Equal(@"../../ghi", FileUtilities.MakeRelative(@"/abc/def/xyz/", @"/abc/ghi"));
Assert.Equal(@"../ghi", FileUtilities.MakeRelative(@"/abc/def/xyz/", @"/abc/def/ghi"));
Assert.Equal(@"../ghi", FileUtilities.MakeRelative(@"/abc/def/", @"/abc/ghi"));
/* File + Directory */
Assert.Equal(@"def/", FileUtilities.MakeRelative(@"/abc", @"/abc/def/"));
Assert.Equal(@"../", FileUtilities.MakeRelative(@"/abc/def/xyz", @"/abc/def/"));
Assert.Equal(@"../ghi/", FileUtilities.MakeRelative(@"/abc/def/xyz", @"/abc/def/ghi/"));
Assert.Equal(@".", FileUtilities.MakeRelative(@"/abc/def", @"/abc/def/"));
}
}
/// <summary>
/// Exercises FileUtilities.ItemSpecModifiers.GetItemSpecModifier on a bad path.
/// </summary>
[WindowsFullFrameworkOnlyFact(additionalMessage: ".NET Core 2.1+ no longer validates paths: https://github.com/dotnet/corefx/issues/27779#issuecomment-371253486.")]
public void GetItemSpecModifierOnBadPath()
{
Assert.Throws<InvalidOperationException>(() =>
{
TestGetItemSpecModifierOnBadPath(Directory.GetCurrentDirectory());
});
}
/// <summary>
/// Exercises FileUtilities.ItemSpecModifiers.GetItemSpecModifier on a bad path.
/// </summary>
[WindowsFullFrameworkOnlyFact(additionalMessage: ".NET Core 2.1+ no longer validates paths: https://github.com/dotnet/corefx/issues/27779#issuecomment-371253486.")]
public void GetItemSpecModifierOnBadPath2()
{
Assert.Throws<InvalidOperationException>(() =>
{
TestGetItemSpecModifierOnBadPath(null);
});
}
private static void TestGetItemSpecModifierOnBadPath(string currentDirectory)
{
try
{
string cache = null;
FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, @"http://www.microsoft.com", String.Empty, FileUtilities.ItemSpecModifiers.RootDir, ref cache);
}
catch (Exception e)
{
// so I can see the exception message in NUnit's "Standard Out" window
Console.WriteLine(e.Message);
throw;
}
}
[Fact]
public void GetFileInfoNoThrowBasic()
{
string file = null;
try
{
file = FileUtilities.GetTemporaryFile();
FileInfo info = FileUtilities.GetFileInfoNoThrow(file);
Assert.Equal(info.LastWriteTime, new FileInfo(file).LastWriteTime);
}
finally
{
if (file != null)
{
File.Delete(file);
}
}
}
[Fact]
public void GetFileInfoNoThrowNonexistent()
{
FileInfo info = FileUtilities.GetFileInfoNoThrow("this_file_is_nonexistent");
Assert.Null(info);
}
/// <summary>
/// Exercises FileUtilities.EndsWithSlash
/// </summary>
[Fact]
[Trait("Category", "netcore-osx-failing")]
[Trait("Category", "netcore-linux-failing")]
public void EndsWithSlash()
{
Assert.True(FileUtilities.EndsWithSlash(@"C:\foo\"));
Assert.True(FileUtilities.EndsWithSlash(@"C:\"));
Assert.True(FileUtilities.EndsWithSlash(@"\"));
Assert.True(FileUtilities.EndsWithSlash(@"http://www.microsoft.com/"));
Assert.True(FileUtilities.EndsWithSlash(@"//server/share/"));
Assert.True(FileUtilities.EndsWithSlash(@"/"));
Assert.False(FileUtilities.EndsWithSlash(@"C:\foo"));
Assert.False(FileUtilities.EndsWithSlash(@"C:"));
Assert.False(FileUtilities.EndsWithSlash(@"foo"));
// confirm that empty string doesn't barf
Assert.False(FileUtilities.EndsWithSlash(String.Empty));
}
/// <summary>
/// Exercises FileUtilities.GetDirectory
/// </summary>
[Fact]
[Trait("Category", "netcore-osx-failing")]
[Trait("Category", "netcore-linux-failing")]
public void GetDirectoryWithTrailingSlash()
{
Assert.Equal(NativeMethodsShared.IsWindows ? @"c:\" : "/", FileUtilities.GetDirectory(NativeMethodsShared.IsWindows ? @"c:\" : "/"));
Assert.Equal(NativeMethodsShared.IsWindows ? @"c:\" : "/", FileUtilities.GetDirectory(NativeMethodsShared.IsWindows ? @"c:\foo" : "/foo"));
Assert.Equal(NativeMethodsShared.IsWindows ? @"c:" : "/", FileUtilities.GetDirectory(NativeMethodsShared.IsWindows ? @"c:" : "/"));
Assert.Equal(FileUtilities.FixFilePath(@"\"), FileUtilities.GetDirectory(@"\"));
Assert.Equal(FileUtilities.FixFilePath(@"\"), FileUtilities.GetDirectory(@"\foo"));
Assert.Equal(FileUtilities.FixFilePath(@"..\"), FileUtilities.GetDirectory(@"..\foo"));
Assert.Equal(FileUtilities.FixFilePath(@"\foo\"), FileUtilities.GetDirectory(@"\foo\"));
Assert.Equal(FileUtilities.FixFilePath(@"\\server\share"), FileUtilities.GetDirectory(@"\\server\share"));
Assert.Equal(FileUtilities.FixFilePath(@"\\server\share\"), FileUtilities.GetDirectory(@"\\server\share\"));
Assert.Equal(FileUtilities.FixFilePath(@"\\server\share\"), FileUtilities.GetDirectory(@"\\server\share\file"));
Assert.Equal(FileUtilities.FixFilePath(@"\\server\share\directory\"), FileUtilities.GetDirectory(@"\\server\share\directory\"));
Assert.Equal(FileUtilities.FixFilePath(@"foo\"), FileUtilities.GetDirectory(@"foo\bar"));
Assert.Equal(FileUtilities.FixFilePath(@"\foo\bar\"), FileUtilities.GetDirectory(@"\foo\bar\"));
Assert.Equal(String.Empty, FileUtilities.GetDirectory("foo"));
}
[Theory]
[InlineData("foo.txt", new[] { ".txt" })]
[InlineData("foo.txt", new[] { ".TXT" })]
[InlineData("foo.txt", new[] { ".EXE", ".TXT" })]
public void HasExtension_WhenFileNameHasExtension_ReturnsTrue(string fileName, string[] allowedExtensions)
{
var result = FileUtilities.HasExtension(fileName, allowedExtensions);
if (!FileUtilities.GetIsFileSystemCaseSensitive() || allowedExtensions.Any(extension => fileName.Contains(extension)))
{
result.ShouldBeTrue();
}
}
[Theory]
[InlineData("foo.txt", new[] { ".DLL" })]
[InlineData("foo.txt", new[] { ".EXE", ".DLL" })]
[InlineData("foo.exec", new[] { ".exe", })]
[InlineData("foo.exe", new[] { ".exec", })]
[InlineData("foo", new[] { ".exe", })]
[InlineData("", new[] { ".exe" })]
[InlineData(null, new[] { ".exe" })]
public void HasExtension_WhenFileNameDoesNotHaveExtension_ReturnsFalse(string fileName, string[] allowedExtensions)
{
var result = FileUtilities.HasExtension(fileName, allowedExtensions);
Assert.False(result);
}
[WindowsFullFrameworkOnlyFact]
public void HasExtension_WhenInvalidFileName_ThrowsArgumentException()
{
Assert.Throws<ArgumentException>(() =>
{
FileUtilities.HasExtension("|/", new[] { ".exe" });
});
}
[Fact]
public void HasExtension_UsesOrdinalIgnoreCase()
{
var currentCulture = Thread.CurrentThread.CurrentCulture;
try
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR"); // Turkish
var result = FileUtilities.HasExtension("foo.ini", new string[] { ".INI" });
result.ShouldBe(!FileUtilities.GetIsFileSystemCaseSensitive());
}
finally
{
Thread.CurrentThread.CurrentCulture = currentCulture;
}
}
/// <summary>
/// Exercises FileUtilities.EnsureTrailingSlash
/// </summary>
[Fact]
public void EnsureTrailingSlash()
{
// Doesn't have a trailing slash to start with.
Assert.Equal(FileUtilities.FixFilePath(@"foo\bar\"), FileUtilities.EnsureTrailingSlash(@"foo\bar")); // "test 1"
Assert.Equal(FileUtilities.FixFilePath(@"foo/bar\"), FileUtilities.EnsureTrailingSlash(@"foo/bar")); // "test 2"
// Already has a trailing slash to start with.
Assert.Equal(FileUtilities.FixFilePath(@"foo/bar/"), FileUtilities.EnsureTrailingSlash(@"foo/bar/")); // test 3"
Assert.Equal(FileUtilities.FixFilePath(@"foo\bar\"), FileUtilities.EnsureTrailingSlash(@"foo\bar\")); // test 4"
Assert.Equal(FileUtilities.FixFilePath(@"foo/bar\"), FileUtilities.EnsureTrailingSlash(@"foo/bar\")); // test 5"
Assert.Equal(FileUtilities.FixFilePath(@"foo\bar/"), FileUtilities.EnsureTrailingSlash(@"foo\bar/")); // "test 5"
}
/// <summary>
/// Exercises FileUtilities.ItemSpecModifiers.IsItemSpecModifier
/// </summary>
[Fact]
public void IsItemSpecModifier()
{
// Positive matches using exact case.
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("FullPath")); // "test 1"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("RootDir")); // "test 2"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Filename")); // "test 3"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Extension")); // "test 4"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("RelativeDir")); // "test 5"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Directory")); // "test 6"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("RecursiveDir")); // "test 7"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Identity")); // "test 8"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("ModifiedTime")); // "test 9"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("CreatedTime")); // "test 10"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("AccessedTime")); // "test 11"
// Positive matches using different case.
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("fullPath")); // "test 21"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("rootDir")); // "test 22"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("filename")); // "test 23"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("extension")); // "test 24"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("relativeDir")); // "test 25"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("directory")); // "test 26"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("recursiveDir")); // "test 27"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("identity")); // "test 28"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("modifiedTime")); // "test 29"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("createdTime")); // "test 30"
Assert.True(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("accessedTime")); // "test 31"
// Negative tests to get maximum code coverage inside the many different branches
// of FileUtilities.ItemSpecModifiers.IsItemSpecModifier.
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("rootxxx")); // "test 41"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Rootxxx")); // "test 42"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("xxxxxxx")); // "test 43"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("filexxxx")); // "test 44"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Filexxxx")); // "test 45"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("idenxxxx")); // "test 46"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Idenxxxx")); // "test 47"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("xxxxxxxx")); // "test 48"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("extenxxxx")); // "test 49"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Extenxxxx")); // "test 50"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("direcxxxx")); // "test 51"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Direcxxxx")); // "test 52"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("xxxxxxxxx")); // "test 53"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("xxxxxxxxxx")); // "test 54"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("relativexxx")); // "test 55"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Relativexxx")); // "test 56"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("createdxxxx")); // "test 57"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Createdxxxx")); // "test 58"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("xxxxxxxxxxx")); // "test 59"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("recursivexxx")); // "test 60"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Recursivexxx")); // "test 61"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("accessedxxxx")); // "test 62"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Accessedxxxx")); // "test 63"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("modifiedxxxx")); // "test 64"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("Modifiedxxxx")); // "test 65"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier("xxxxxxxxxxxx")); // "test 66"
Assert.False(FileUtilities.ItemSpecModifiers.IsItemSpecModifier(null)); // "test 67"
}
[Fact]
public void CheckDerivableItemSpecModifiers()
{
Assert.True(FileUtilities.ItemSpecModifiers.IsDerivableItemSpecModifier("Filename"));
Assert.False(FileUtilities.ItemSpecModifiers.IsDerivableItemSpecModifier("RecursiveDir"));
Assert.False(FileUtilities.ItemSpecModifiers.IsDerivableItemSpecModifier("recursivedir"));
}
[WindowsOnlyFact]
public void NormalizePathThatFitsIntoMaxPath()
{
string currentDirectory = @"c:\aardvark\aardvark\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890";
string filePath = @"..\..\..\..\..\..\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\a.cs";
string fullPath = @"c:\aardvark\aardvark\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\a.cs";
Assert.Equal(fullPath, FileUtilities.NormalizePath(Path.Combine(currentDirectory, filePath)));
}
[LongPathSupportDisabledFact(fullFrameworkOnly: true, additionalMessage: "https://github.com/dotnet/msbuild/issues/4363")]
public void NormalizePathThatDoesntFitIntoMaxPath()
{
Assert.Throws<PathTooLongException>(() =>
{
string currentDirectory = @"c:\aardvark\aardvark\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890";
string filePath = @"..\..\..\..\..\..\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\a.cs";
// This path ends up over 420 characters long
string fullPath = @"c:\aardvark\aardvark\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\a.cs";
Assert.Equal(fullPath, FileUtilities.NormalizePath(Path.Combine(currentDirectory, filePath)));
});
}
[WindowsOnlyFact]
public void GetItemSpecModifierRootDirThatFitsIntoMaxPath()
{
string currentDirectory = @"c:\aardvark\aardvark\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890";
string fullPath = @"c:\aardvark\aardvark\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\1234567890\a.cs";
string cache = fullPath;
Assert.Equal(@"c:\", FileUtilities.ItemSpecModifiers.GetItemSpecModifier(currentDirectory, fullPath, String.Empty, FileUtilities.ItemSpecModifiers.RootDir, ref cache));
}
[Fact]
public void NormalizePathNull()
{
Assert.Throws<ArgumentNullException>(() =>
{
Assert.Null(FileUtilities.NormalizePath(null, null));
});
}
[Fact]
public void NormalizePathEmpty()
{
Assert.Throws<ArgumentException>(() =>
{
Assert.Null(FileUtilities.NormalizePath(String.Empty));
});
}
[WindowsFullFrameworkOnlyFact(additionalMessage: ".NET Core 2.1+ no longer validates paths: https://github.com/dotnet/corefx/issues/27779#issuecomment-371253486.")]
public void NormalizePathBadUNC1()
{
Assert.Throws<ArgumentException>(() =>
{
Assert.Null(FileUtilities.NormalizePath(@"\\"));
});
}
[WindowsFullFrameworkOnlyFact(additionalMessage: ".NET Core 2.1+ no longer validates paths: https://github.com/dotnet/corefx/issues/27779#issuecomment-371253486.")]
public void NormalizePathBadUNC2()
{
Assert.Throws<ArgumentException>(() =>
{
Assert.Null(FileUtilities.NormalizePath(@"\\XXX\"));
});
}
[WindowsFullFrameworkOnlyFact(additionalMessage: ".NET Core 2.1+ no longer validates paths: https://github.com/dotnet/corefx/issues/27779#issuecomment-371253486.")]
public void NormalizePathBadUNC3()
{
Assert.Throws<ArgumentException>(() =>
{
Assert.Equal(@"\\localhost", FileUtilities.NormalizePath(@"\\localhost"));
});
}
[WindowsOnlyFact]
public void NormalizePathGoodUNC()
{
Assert.Equal(@"\\localhost\share", FileUtilities.NormalizePath(@"\\localhost\share"));
}
[WindowsOnlyFact]
public void NormalizePathTooLongWithDots()
{
string longPart = new string('x', 300);
Assert.Equal(@"c:\abc\def", FileUtilities.NormalizePath(@"c:\abc\" + longPart + @"\..\def"));
}
#if FEATURE_LEGACY_GETFULLPATH
[WindowsOnlyFact(Skip = "https://github.com/dotnet/msbuild/issues/4205")]
public void NormalizePathBadGlobalroot()
{
Assert.Throws<ArgumentException>(() =>
{
/*
From Path.cs
// Check for \\?\Globalroot, an internal mechanism to the kernel
// that provides aliases for drives and other undocumented stuff.
// The kernel team won't even describe the full set of what
// is available here - we don't want managed apps mucking
// with this for security reasons.
* */
Assert.Null(FileUtilities.NormalizePath(@"\\?\globalroot\XXX"));
});
}
#endif
[WindowsFullFrameworkOnlyFact(additionalMessage: ".NET Core 2.1+ no longer validates paths: https://github.com/dotnet/corefx/issues/27779#issuecomment-371253486.")]
public void NormalizePathInvalid()
{
string filePath = @"c:\aardvark\|||";
Assert.Throws<ArgumentException>(() =>
{
FileUtilities.NormalizePath(filePath);
});
}
[WindowsOnlyFact]
public void CannotNormalizePathWithNewLineAndSpace()
{
string filePath = "\r\n C:\\work\\sdk3\\artifacts\\tmp\\Debug\\SimpleNamesWi---6143883E\\NETFrameworkLibrary\\bin\\Debug\\net462\\NETFrameworkLibrary.dll\r\n ";
#if FEATURE_LEGACY_GETFULLPATH
Assert.Throws<ArgumentException>(() => FileUtilities.NormalizePath(filePath));
#else
Assert.NotEqual("C:\\work\\sdk3\\artifacts\\tmp\\Debug\\SimpleNamesWi---6143883E\\NETFrameworkLibrary\\bin\\Debug\\net462\\NETFrameworkLibrary.dll", FileUtilities.NormalizePath(filePath));
#endif
}
[Fact]
public void FileOrDirectoryExistsNoThrow()
{
var isWindows = NativeMethodsShared.IsWindows;
Assert.False(FileUtilities.FileOrDirectoryExistsNoThrow("||"));
Assert.False(FileUtilities.FileOrDirectoryExistsNoThrow(isWindows ? @"c:\doesnot_exist" : "/doesnot_exist"));
Assert.True(FileUtilities.FileOrDirectoryExistsNoThrow(isWindows ? @"c:\" : "/"));
Assert.True(FileUtilities.FileOrDirectoryExistsNoThrow(Path.GetTempPath()));
string path = null;
try
{
path = FileUtilities.GetTemporaryFile();
Assert.True(FileUtilities.FileOrDirectoryExistsNoThrow(path));
}
finally
{
File.Delete(path);
}
}
#if FEATURE_ENVIRONMENT_SYSTEMDIRECTORY
// These tests will need to be redesigned for Linux
[ConditionalFact(nameof(RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241))]
public void FileOrDirectoryExistsNoThrowTooLongWithDots()
{
int length = (Environment.SystemDirectory + @"\" + @"\..\..\..\" + Environment.SystemDirectory.Substring(3)).Length;
string longPart = new string('x', 260 - length); // We want the shortest that is > max path.
string inputPath = Environment.SystemDirectory + @"\" + longPart + @"\..\..\..\" + Environment.SystemDirectory.Substring(3);
Console.WriteLine(inputPath.Length);
// "c:\windows\system32\<verylong>\..\..\windows\system32" exists
Assert.True(FileUtilities.FileOrDirectoryExistsNoThrow(inputPath));
Assert.False(FileUtilities.FileOrDirectoryExistsNoThrow(inputPath.Replace('\\', 'X')));
}
[ConditionalFact(nameof(RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241))]
public void FileOrDirectoryExistsNoThrowTooLongWithDotsRelative()
{
int length = (Environment.SystemDirectory + @"\" + @"\..\..\..\" + Environment.SystemDirectory.Substring(3)).Length;
string longPart = new string('x', 260 - length); // We want the shortest that is > max path.
string inputPath = longPart + @"\..\..\..\" + Environment.SystemDirectory.Substring(3);
Console.WriteLine(inputPath.Length);
// "c:\windows\system32\<verylong>\..\..\windows\system32" exists
string currentDirectory = Directory.GetCurrentDirectory();
try
{
Directory.SetCurrentDirectory(Environment.SystemDirectory);
Assert.True(FileUtilities.FileOrDirectoryExistsNoThrow(inputPath));
Assert.False(FileUtilities.FileOrDirectoryExistsNoThrow(inputPath.Replace('\\', 'X')));
}
finally
{
Directory.SetCurrentDirectory(currentDirectory);
}
}
[Fact]
public void DirectoryExistsNoThrowTooLongWithDots()
{
string path = Path.Combine(Environment.SystemDirectory, "..", "..", "..") + Path.DirectorySeparatorChar;
if (NativeMethodsShared.IsWindows)
{
path += Environment.SystemDirectory.Substring(3);
}
int length = path.Length;
string longPart = new string('x', 260 - length); // We want the shortest that is > max path.
string inputPath = Path.Combine(new[] { Environment.SystemDirectory, longPart, "..", "..", ".." })
+ Path.DirectorySeparatorChar;
if (NativeMethodsShared.IsWindows)
{
path += Environment.SystemDirectory.Substring(3);
}
Console.WriteLine(inputPath.Length);
// "c:\windows\system32\<verylong>\..\..\windows\system32" exists
Assert.True(FileUtilities.DirectoryExistsNoThrow(inputPath));
}
[ConditionalFact(nameof(RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241))]
public void DirectoryExistsNoThrowTooLongWithDotsRelative()
{
int length = (Environment.SystemDirectory + @"\" + @"\..\..\..\" + Environment.SystemDirectory.Substring(3)).Length;
string longPart = new string('x', 260 - length); // We want the shortest that is > max path.
string inputPath = longPart + @"\..\..\..\" + Environment.SystemDirectory.Substring(3);
Console.WriteLine(inputPath.Length);
// "c:\windows\system32\<verylong>\..\..\..\windows\system32" exists
string currentDirectory = Directory.GetCurrentDirectory();
try
{
Directory.SetCurrentDirectory(Environment.SystemDirectory);
FileUtilities.DirectoryExistsNoThrow(inputPath).ShouldBeTrue();
FileUtilities.DirectoryExistsNoThrow(inputPath.Replace('\\', 'X')).ShouldBeFalse();
}
finally
{
Directory.SetCurrentDirectory(currentDirectory);
}
}
public static bool RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241()
{
// Run these tests only when we're not on Windows
return !NativeMethodsShared.IsWindows ||
// OR we're on Windows and long paths aren't enabled
// https://github.com/dotnet/msbuild/issues/4241
NativeMethodsShared.IsMaxPathLegacyWindows();
}
[ConditionalFact(nameof(RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241))]
public void FileExistsNoThrowTooLongWithDots()
{
int length = (Environment.SystemDirectory + @"\" + @"\..\..\..\" + Environment.SystemDirectory.Substring(3) + @"\..\explorer.exe").Length;
string longPart = new string('x', 260 - length); // We want the shortest that is > max path.
string inputPath = Environment.SystemDirectory + @"\" + longPart + @"\..\..\..\" + Environment.SystemDirectory.Substring(3) + @"\..\explorer.exe";
Console.WriteLine(inputPath.Length);
Console.WriteLine(inputPath);
// "c:\windows\system32\<verylong>\..\..\windows\system32" exists
Assert.True(FileUtilities.FileExistsNoThrow(inputPath));
}
[ConditionalFact(nameof(RunTestsThatDependOnWindowsShortPathBehavior_Workaround4241))]
public void FileExistsNoThrowTooLongWithDotsRelative()
{
int length = (Environment.SystemDirectory + @"\" + @"\..\..\..\" + Environment.SystemDirectory.Substring(3) + @"\..\explorer.exe").Length;
string longPart = new string('x', 260 - length); // We want the shortest that is > max path.
string inputPath = longPart + @"\..\..\..\" + Environment.SystemDirectory.Substring(3) + @"\..\explorer.exe";
Console.WriteLine(inputPath.Length);
// "c:\windows\system32\<verylong>\..\..\windows\system32" exists
string currentDirectory = Directory.GetCurrentDirectory();
try
{
Directory.SetCurrentDirectory(Environment.SystemDirectory);
Assert.True(FileUtilities.FileExistsNoThrow(inputPath));
Assert.False(FileUtilities.FileExistsNoThrow(inputPath.Replace('\\', 'X')));
}
finally
{
Directory.SetCurrentDirectory(currentDirectory);
}
}
[Fact]
public void GetFileInfoNoThrowTooLongWithDots()
{
int length = (Environment.SystemDirectory + @"\" + @"\..\..\..\" + Environment.SystemDirectory.Substring(3) + @"\..\explorer.exe").Length;
string longPart = new string('x', 260 - length); // We want the shortest that is > max path.
string inputPath = Environment.SystemDirectory + @"\" + longPart + @"\..\..\..\" + Environment.SystemDirectory.Substring(3) + @"\..\explorer.exe";
Console.WriteLine(inputPath.Length);
// "c:\windows\system32\<verylong>\..\..\windows\system32" exists
Assert.True(FileUtilities.GetFileInfoNoThrow(inputPath) != null);
Assert.False(FileUtilities.GetFileInfoNoThrow(inputPath.Replace('\\', 'X')) != null);
}
[Fact]
public void GetFileInfoNoThrowTooLongWithDotsRelative()
{
int length = (Environment.SystemDirectory + @"\" + @"\..\..\..\" + Environment.SystemDirectory.Substring(3) + @"\..\explorer.exe").Length;
string longPart = new string('x', 260 - length); // We want the shortest that is > max path.
string inputPath = longPart + @"\..\..\..\" + Environment.SystemDirectory.Substring(3) + @"\..\explorer.exe";
Console.WriteLine(inputPath.Length);
// "c:\windows\system32\<verylong>\..\..\windows\system32" exists
string currentDirectory = Directory.GetCurrentDirectory();
try
{
Directory.SetCurrentDirectory(Environment.SystemDirectory);
Assert.True(FileUtilities.GetFileInfoNoThrow(inputPath) != null);
Assert.False(FileUtilities.GetFileInfoNoThrow(inputPath.Replace('\\', 'X')) != null);
}
finally
{
Directory.SetCurrentDirectory(currentDirectory);
}
}
#endif
/// <summary>
/// Simple test, neither the base file nor retry files exist
/// </summary>
[Fact]
public void GenerateTempFileNameSimple()
{
string path = null;
try
{
path = FileUtilities.GetTemporaryFile();
Assert.EndsWith(".tmp", path);
Assert.True(File.Exists(path));
Assert.StartsWith(Path.GetTempPath(), path);
}
finally
{
File.Delete(path);
}
}
/// <summary>
/// Choose an extension
/// </summary>
[Fact]
public void GenerateTempFileNameWithExtension()
{
string path = null;
try
{
path = FileUtilities.GetTemporaryFile(".bat");
Assert.EndsWith(".bat", path);
Assert.True(File.Exists(path));
Assert.StartsWith(Path.GetTempPath(), path);
}
finally
{
File.Delete(path);
}
}
/// <summary>
/// Choose a (missing) directory and extension
/// </summary>
[Fact]
public void GenerateTempFileNameWithDirectoryAndExtension()
{
string path = null;
string directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "subfolder");
try
{
path = FileUtilities.GetTemporaryFile(directory, null, ".bat");
Assert.EndsWith(".bat", path);
Assert.True(File.Exists(path));
Assert.StartsWith(directory, path);
}
finally
{
File.Delete(path);
FileUtilities.DeleteWithoutTrailingBackslash(directory);
}
}
/// <summary>
/// Extension without a period
/// </summary>
[Fact]
public void GenerateTempFileNameWithExtensionNoPeriod()
{
string path = null;
try
{
path = FileUtilities.GetTemporaryFile("bat");
Assert.EndsWith(".bat", path);
Assert.True(File.Exists(path));
Assert.StartsWith(Path.GetTempPath(), path);
}
finally
{
File.Delete(path);
}
}
/// <summary>
/// Extension is invalid
/// </summary>
[Fact]
[Trait("Category", "netcore-osx-failing")]
[Trait("Category", "netcore-linux-failing")]
public void GenerateTempBatchFileWithBadExtension()
{
Assert.Throws<IOException>(() =>
{
FileUtilities.GetTemporaryFile("|");
});
}
/// <summary>
/// Directory is invalid
/// </summary>
[Fact]
[Trait("Category", "netcore-osx-failing")]
[Trait("Category", "netcore-linux-failing")]
public void GenerateTempBatchFileWithBadDirectory()
{
Assert.Throws<IOException>(() =>
{
FileUtilities.GetTemporaryFile("|", null, ".tmp");
});
}
[UnixOnlyFact]
public void AbsolutePathLooksLikeUnixPathOnUnix()
{
var secondSlash = SystemSpecificAbsolutePath.Substring(1).IndexOf(Path.DirectorySeparatorChar) + 1;
var rootLevelPath = SystemSpecificAbsolutePath.Substring(0, secondSlash);
Assert.True(FileUtilities.LooksLikeUnixFilePath(SystemSpecificAbsolutePath));
Assert.True(FileUtilities.LooksLikeUnixFilePath(rootLevelPath));
}
[WindowsOnlyFact]
public void PathDoesNotLookLikeUnixPathOnWindows()
{
Assert.False(FileUtilities.LooksLikeUnixFilePath(SystemSpecificAbsolutePath));
Assert.False(FileUtilities.LooksLikeUnixFilePath("/path/that/looks/unixy"));
Assert.False(FileUtilities.LooksLikeUnixFilePath("/root"));
}
[UnixOnlyFact]
public void RelativePathLooksLikeUnixPathOnUnixWithBaseDirectory()
{
string filePath = ObjectModelHelpers.CreateFileInTempProjectDirectory("first/second/file.txt", String.Empty);
string oldCWD = Directory.GetCurrentDirectory();
try
{
// <tmp_dir>/first
string firstDirectory = Path.GetDirectoryName(Path.GetDirectoryName(filePath));
string tmpDirectory = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(filePath)));
Directory.SetCurrentDirectory(tmpDirectory);
// We are in <tmp_dir> and second is not under that, so this will be false
Assert.False(FileUtilities.LooksLikeUnixFilePath("second/file.txt"));
// .. but if we have baseDirectory:firstDirectory, then it will be true
Assert.True(FileUtilities.LooksLikeUnixFilePath("second/file.txt", firstDirectory));
}
finally
{
if (filePath != null)
{
File.Delete(filePath);
}
Directory.SetCurrentDirectory(oldCWD);
}
}
[UnixOnlyFact]
public void RelativePathMaybeAdjustFilePathWithBaseDirectory()
{
// <tmp_dir>/first/second/file.txt
string filePath = ObjectModelHelpers.CreateFileInTempProjectDirectory("first/second/file.txt", String.Empty);
string oldCWD = Directory.GetCurrentDirectory();
try
{
// <tmp_dir>/first
string firstDirectory = Path.GetDirectoryName(Path.GetDirectoryName(filePath));
string tmpDirectory = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(filePath)));
Directory.SetCurrentDirectory(tmpDirectory);
// We are in <tmp_dir> and second is not under that, so this won't convert
Assert.Equal("second\\file.txt", FileUtilities.MaybeAdjustFilePath("second\\file.txt"));
// .. but if we have baseDirectory:firstDirectory, then it will
Assert.Equal("second/file.txt", FileUtilities.MaybeAdjustFilePath("second\\file.txt", firstDirectory));
}
finally
{
if (filePath != null)
{
File.Delete(filePath);
}
Directory.SetCurrentDirectory(oldCWD);
}
}
private static string SystemSpecificAbsolutePath => FileUtilities.ExecutingAssemblyPath;
[Fact]
public void GetFolderAboveTest()
{
string root = NativeMethodsShared.IsWindows ? @"c:\" : "/";
string path = Path.Combine(root, "1", "2", "3", "4", "5");
Assert.Equal(Path.Combine(root, "1", "2", "3", "4", "5"), FileUtilities.GetFolderAbove(path, 0));
Assert.Equal(Path.Combine(root, "1", "2", "3", "4"), FileUtilities.GetFolderAbove(path));
Assert.Equal(Path.Combine(root, "1", "2", "3"), FileUtilities.GetFolderAbove(path, 2));
Assert.Equal(Path.Combine(root, "1", "2"), FileUtilities.GetFolderAbove(path, 3));
Assert.Equal(Path.Combine(root, "1"), FileUtilities.GetFolderAbove(path, 4));
Assert.Equal(root, FileUtilities.GetFolderAbove(path, 5));
Assert.Equal(root, FileUtilities.GetFolderAbove(path, 99));
Assert.Equal(root, FileUtilities.GetFolderAbove(root, 99));
}
[Fact]
public void CombinePathsTest()
{
// These tests run in .NET 4+, so we can cheat
var root = @"c:\";
Assert.Equal(
Path.Combine(root, "path1"),
FileUtilities.CombinePaths(root, "path1"));
Assert.Equal(
Path.Combine(root, "path1", "path2", "file.txt"),
FileUtilities.CombinePaths(root, "path1", "path2", "file.txt"));
}
[Theory]
[InlineData(@"c:\a\.\b", true)]
[InlineData(@"c:\a\..\b", true)]
[InlineData(@"c:\a\..", true)]
[InlineData(@"c:\a\.", true)]
[InlineData(@".\a", true)]
[InlineData(@"..\b", true)]
[InlineData(@"..", true)]
[InlineData(@".", true)]
[InlineData(@"..\", true)]
[InlineData(@".\", true)]
[InlineData(@"\..", true)]
[InlineData(@"\.", true)]
[InlineData(@"..\..\a", true)]
[InlineData(@"..\..\..\a", true)]
[InlineData(@"b..\", false)]
[InlineData(@"b.\", false)]
[InlineData(@"\b..", false)]
[InlineData(@"\b.", false)]
[InlineData(@"\b..\", false)]
[InlineData(@"\b.\", false)]
[InlineData(@"...", false)]
[InlineData(@"....", false)]
public void ContainsRelativeSegmentsTest(string path, bool expectedResult)
{
FileUtilities.ContainsRelativePathSegments(path).ShouldBe(expectedResult);
}
[Theory]
[InlineData("a/b/c/d", 0, "")]
[InlineData("a/b/c/d", 1, "d")]
[InlineData("a/b/c/d", 2, "c/d")]
[InlineData("a/b/c/d", 3, "b/c/d")]
[InlineData("a/b/c/d", 4, "a/b/c/d")]
[InlineData("a/b/c/d", 5, "a/b/c/d")]
[InlineData(@"a\/\/\//b/\/\/\//c//\/\/\/d/\//\/\/", 2, "c/d")]
public static void TestTruncatePathToTrailingSegments(string path, int trailingSegments, string expectedTruncatedPath)
{
expectedTruncatedPath = expectedTruncatedPath.Replace('/', Path.DirectorySeparatorChar);
FileUtilities.TruncatePathToTrailingSegments(path, trailingSegments).ShouldBe(expectedTruncatedPath);
}
/// <summary>
/// Exercises FileUtilities.EnsureSingleQuotes
/// </summary>
[Theory]
[InlineData(null, null)] // Null test
[InlineData("", "")] // Empty string test
[InlineData(@" ", @"' '")] // One character which is a space
[InlineData(@"'", @"'''")] // One character which is a single quote
[InlineData(@"""", @"'""'")] // One character which is a double quote
[InlineData(@"example", @"'example'")] // Unquoted string
[InlineData(@"'example'", @"'example'")] // Single quoted string
[InlineData(@"""example""", @"'example'")] // Double quoted string
[InlineData(@"'example""", @"''example""'")] // Mixed Quotes - Leading Single
[InlineData(@"""example'", @"'""example''")] // Mixed Quotes - Leading Double
[InlineData(@"ex""am'ple", @"'ex""am'ple'")] // Interior Quotes
public void EnsureSingleQuotesTest(string path, string expectedResult)
{
FileUtilities.EnsureSingleQuotes(path).ShouldBe(expectedResult);
}
/// <summary>
/// Exercises FileUtilities.EnsureDoubleQuotes
/// </summary>
[Theory]
[InlineData(null, null)] // Null test
[InlineData("", "")] // Empty string test
[InlineData(@" ", @""" """)] // One character which is a space
[InlineData(@"'", @"""'""")] // One character which is a single quote
[InlineData(@"""", @"""""""")] // One character which is a double quote
[InlineData(@"example", @"""example""")] // Unquoted string
[InlineData(@"'example'", @"""example""")] // Single quoted string
[InlineData(@"""example""", @"""example""")] // Double quoted string
[InlineData(@"'example""", @"""'example""""")] // Mixed Quotes - Leading Single
[InlineData(@"""example'", @"""""example'""")] // Mixed Quotes - Leading Double
[InlineData(@"ex""am'ple", @"""ex""am'ple""")] // Interior Quotes
public void EnsureDoubleQuotesTest(string path, string expectedResult)
{
FileUtilities.EnsureDoubleQuotes(path).ShouldBe(expectedResult);
}
}
}
|