diff --git a/Directory.Build.props b/Directory.Build.props index 0f3335b8f..ed4f6a281 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,6 +5,8 @@ Tatham Oddie & friends True $(MSBuildThisFileDirectory)StrongName.snk + $(DefineConstants);FEATURE_ASYNC_FILE;FEATURE_ENUMERATION_OPTIONS;FEATURE_ADVANCED_PATH_OPERATIONS + diff --git a/System.IO.Abstractions.TestingHelpers.Tests/MockPathTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/MockPathTests.cs index 3c59d6646..d66fb281b 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/MockPathTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/MockPathTests.cs @@ -143,13 +143,13 @@ public static IEnumerable GetFullPath_RelativePaths_Cases { get { - yield return new [] { XFS.Path(@"c:\a"), "b", XFS.Path(@"c:\a\b") }; - yield return new [] { XFS.Path(@"c:\a\b"), "c", XFS.Path(@"c:\a\b\c") }; - yield return new [] { XFS.Path(@"c:\a\b"), XFS.Path(@"c\"), XFS.Path(@"c:\a\b\c\") }; - yield return new [] { XFS.Path(@"c:\a\b"), XFS.Path(@"..\c"), XFS.Path(@"c:\a\c") }; - yield return new [] { XFS.Path(@"c:\a\b\c"), XFS.Path(@"..\c\..\"), XFS.Path(@"c:\a\b\") }; - yield return new [] { XFS.Path(@"c:\a\b\c"), XFS.Path(@"..\..\..\..\..\d"), XFS.Path(@"c:\d") }; - yield return new [] { XFS.Path(@"c:\a\b\c"), XFS.Path(@"..\..\..\..\..\d\"), XFS.Path(@"c:\d\") }; + yield return new[] { XFS.Path(@"c:\a"), "b", XFS.Path(@"c:\a\b") }; + yield return new[] { XFS.Path(@"c:\a\b"), "c", XFS.Path(@"c:\a\b\c") }; + yield return new[] { XFS.Path(@"c:\a\b"), XFS.Path(@"c\"), XFS.Path(@"c:\a\b\c\") }; + yield return new[] { XFS.Path(@"c:\a\b"), XFS.Path(@"..\c"), XFS.Path(@"c:\a\c") }; + yield return new[] { XFS.Path(@"c:\a\b\c"), XFS.Path(@"..\c\..\"), XFS.Path(@"c:\a\b\") }; + yield return new[] { XFS.Path(@"c:\a\b\c"), XFS.Path(@"..\..\..\..\..\d"), XFS.Path(@"c:\d") }; + yield return new[] { XFS.Path(@"c:\a\b\c"), XFS.Path(@"..\..\..\..\..\d\"), XFS.Path(@"c:\d\") }; } } @@ -172,11 +172,11 @@ public static IEnumerable GetFullPath_RootedPathWithRelativeSegments_C { get { - yield return new [] { XFS.Path(@"c:\a\b\..\c"), XFS.Path(@"c:\a\c") }; - yield return new [] { XFS.Path(@"c:\a\b\.\.\..\.\c"), XFS.Path(@"c:\a\c") }; - yield return new [] { XFS.Path(@"c:\a\b\.\c"), XFS.Path(@"c:\a\b\c") }; - yield return new [] { XFS.Path(@"c:\a\b\.\.\.\.\c"), XFS.Path(@"c:\a\b\c") }; - yield return new [] { XFS.Path(@"c:\a\..\..\c"), XFS.Path(@"c:\c") }; + yield return new[] { XFS.Path(@"c:\a\b\..\c"), XFS.Path(@"c:\a\c") }; + yield return new[] { XFS.Path(@"c:\a\b\.\.\..\.\c"), XFS.Path(@"c:\a\c") }; + yield return new[] { XFS.Path(@"c:\a\b\.\c"), XFS.Path(@"c:\a\b\c") }; + yield return new[] { XFS.Path(@"c:\a\b\.\.\.\.\c"), XFS.Path(@"c:\a\b\c") }; + yield return new[] { XFS.Path(@"c:\a\..\..\c"), XFS.Path(@"c:\c") }; } } @@ -198,14 +198,14 @@ public static IEnumerable GetFullPath_AbsolutePaths_Cases { get { - yield return new [] { XFS.Path(@"c:\a"), XFS.Path(@"/b"), XFS.Path(@"c:\b") }; - yield return new [] { XFS.Path(@"c:\a"), XFS.Path(@"/b\"), XFS.Path(@"c:\b\") }; - yield return new [] { XFS.Path(@"c:\a"), XFS.Path(@"\b"), XFS.Path(@"c:\b") }; - yield return new [] { XFS.Path(@"c:\a"), XFS.Path(@"\b\..\c"), XFS.Path(@"c:\c") }; - yield return new [] { XFS.Path(@"z:\a"), XFS.Path(@"\b\..\c"), XFS.Path(@"z:\c") }; - yield return new [] { XFS.Path(@"z:\a"), XFS.Path(@"\\computer\share\c"), XFS.Path(@"\\computer\share\c") }; - yield return new [] { XFS.Path(@"z:\a"), XFS.Path(@"\\computer\share\c\..\d"), XFS.Path(@"\\computer\share\d") }; - yield return new [] { XFS.Path(@"z:\a"), XFS.Path(@"\\computer\share\c\..\..\d"), XFS.Path(@"\\computer\share\d") }; + yield return new[] { XFS.Path(@"c:\a"), XFS.Path(@"/b"), XFS.Path(@"c:\b") }; + yield return new[] { XFS.Path(@"c:\a"), XFS.Path(@"/b\"), XFS.Path(@"c:\b\") }; + yield return new[] { XFS.Path(@"c:\a"), XFS.Path(@"\b"), XFS.Path(@"c:\b") }; + yield return new[] { XFS.Path(@"c:\a"), XFS.Path(@"\b\..\c"), XFS.Path(@"c:\c") }; + yield return new[] { XFS.Path(@"z:\a"), XFS.Path(@"\b\..\c"), XFS.Path(@"z:\c") }; + yield return new[] { XFS.Path(@"z:\a"), XFS.Path(@"\\computer\share\c"), XFS.Path(@"\\computer\share\c") }; + yield return new[] { XFS.Path(@"z:\a"), XFS.Path(@"\\computer\share\c\..\d"), XFS.Path(@"\\computer\share\d") }; + yield return new[] { XFS.Path(@"z:\a"), XFS.Path(@"\\computer\share\c\..\..\d"), XFS.Path(@"\\computer\share\d") }; } } @@ -274,7 +274,7 @@ public void GetFullPath_WithMultipleDirectorySeparators_ShouldReturnTheNormalize var mockPath = new MockPath(mockFileSystem); //Act - var actualFullPath = mockPath.GetFullPath(XFS.Path(@"c:\foo\\//bar\file.dat")); + var actualFullPath = mockPath.GetFullPath(XFS.Path(@"c:\foo\\//bar\file.dat")); //Assert Assert.AreEqual(XFS.Path(@"c:\foo\bar\file.dat"), actualFullPath); @@ -397,5 +397,61 @@ public void IsPathRooted_PathSentIn_DeterminesPathExists() //Assert Assert.AreEqual(true, result); } + +#if FEATURE_ADVANCED_PATH_OPERATIONS + [Test] + public void IsPathFullyQualified_WithAbsolutePath_ReturnsTrue() + { + //Arrange + var mockPath = new MockPath(new MockFileSystem()); + + //Act + var result = mockPath.IsPathFullyQualified(XFS.Path("C:\\directory\\file.txt")); + + //Assert + Assert.IsTrue(result); + } + + [Test] + public void IsPathFullyQualified_WithRelativePath_ReturnsFalse() + { + //Arrange + var mockPath = new MockPath(new MockFileSystem()); + + //Act + var result = mockPath.IsPathRooted(XFS.Path("directory\\file.txt")); + + //Assert + Assert.IsFalse(result); + } + + [Test] + public void IsPathFullyQualified_WithRelativePathParts_ReturnsFalse() + { + //Arrange + var mockPath = new MockPath(new MockFileSystem()); + + //Act + var result = mockPath.IsPathRooted(XFS.Path("directory\\..\\file.txt")); + + //Assert + Assert.IsFalse(result); + } + + + + [Test] + public void GetRelativePath_Works() + { + //Arrange + var mockPath = new MockPath(new MockFileSystem()); + + //Act + var result = mockPath.GetRelativePath(XFS.Path("c:\\d"), XFS.Path("c:\\d\\e\\f.txt")); + + //Assert + Assert.AreEqual(XFS.Path("e\\f.txt"), result); + } +#endif } } diff --git a/System.IO.Abstractions.TestingHelpers.Tests/System.IO.Abstractions.TestingHelpers.Tests.csproj b/System.IO.Abstractions.TestingHelpers.Tests/System.IO.Abstractions.TestingHelpers.Tests.csproj index cdda5b513..aab6cfb50 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/System.IO.Abstractions.TestingHelpers.Tests.csproj +++ b/System.IO.Abstractions.TestingHelpers.Tests/System.IO.Abstractions.TestingHelpers.Tests.csproj @@ -7,7 +7,6 @@ System.IO.Abstractions.TestingHelpers.Tests false true - $(DefineConstants);FEATURE_ASYNC_FILE;FEATURE_ENUMERATION_OPTIONS diff --git a/System.IO.Abstractions.TestingHelpers/System.IO.Abstractions.TestingHelpers.csproj b/System.IO.Abstractions.TestingHelpers/System.IO.Abstractions.TestingHelpers.csproj index 6d3c39440..772bb052a 100644 --- a/System.IO.Abstractions.TestingHelpers/System.IO.Abstractions.TestingHelpers.csproj +++ b/System.IO.Abstractions.TestingHelpers/System.IO.Abstractions.TestingHelpers.csproj @@ -7,7 +7,6 @@ https://github.com/System-IO-Abstractions/System.IO.Abstractions MIT testing - $(DefineConstants);FEATURE_ASYNC_FILE;FEATURE_ENUMERATION_OPTIONS diff --git a/System.IO.Abstractions/IPath.cs b/System.IO.Abstractions/IPath.cs index 2d6651d81..43270776c 100644 --- a/System.IO.Abstractions/IPath.cs +++ b/System.IO.Abstractions/IPath.cs @@ -51,5 +51,13 @@ public interface IPath bool HasExtension(string path); /// bool IsPathRooted(string path); + +#if FEATURE_ADVANCED_PATH_OPERATIONS + /// + bool IsPathFullyQualified(string path); + + /// + string GetRelativePath(string relativeTo, string path); +#endif } } \ No newline at end of file diff --git a/System.IO.Abstractions/PathBase.cs b/System.IO.Abstractions/PathBase.cs index d87853bfc..142bce6ad 100644 --- a/System.IO.Abstractions/PathBase.cs +++ b/System.IO.Abstractions/PathBase.cs @@ -86,5 +86,13 @@ internal PathBase() { } /// public abstract bool IsPathRooted(string path); + +#if FEATURE_ADVANCED_PATH_OPERATIONS + /// + public abstract bool IsPathFullyQualified(string path); + + /// + public abstract string GetRelativePath(string relativeTo, string path); +#endif } } diff --git a/System.IO.Abstractions/PathWrapper.cs b/System.IO.Abstractions/PathWrapper.cs index c4bac2fb1..aafca0b2c 100644 --- a/System.IO.Abstractions/PathWrapper.cs +++ b/System.IO.Abstractions/PathWrapper.cs @@ -118,6 +118,18 @@ public override bool HasExtension(string path) return Path.HasExtension(path); } +#if FEATURE_ADVANCED_PATH_OPERATIONS + public override bool IsPathFullyQualified(string path) + { + return Path.IsPathFullyQualified(path); + } + + public override string GetRelativePath(string relativeTo, string path) + { + return Path.GetRelativePath(relativeTo, path); + } +#endif + public override bool IsPathRooted(string path) { return Path.IsPathRooted(path); diff --git a/System.IO.Abstractions/System.IO.Abstractions.csproj b/System.IO.Abstractions/System.IO.Abstractions.csproj index 3faff2155..3ed380e75 100644 --- a/System.IO.Abstractions/System.IO.Abstractions.csproj +++ b/System.IO.Abstractions/System.IO.Abstractions.csproj @@ -7,7 +7,7 @@ https://github.com/System-IO-Abstractions/System.IO.Abstractions MIT testing - $(DefineConstants);FEATURE_ASYNC_FILE;FEATURE_ENUMERATION_OPTIONS + $(DefineConstants);FEATURE_ASYNC_FILE;FEATURE_ENUMERATION_OPTIONS;FEATURE_ADVANCED_PATH_OPERATIONS diff --git a/version.json b/version.json index 70240ba98..7dd9adefb 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "8.1", + "version": "9.0", "assemblyVersion": { "precision": "major" },