From 5128fdc88ef151399cc9a8e146063107c3ad4263 Mon Sep 17 00:00:00 2001 From: Florian Greinacher Date: Tue, 11 Feb 2020 21:34:05 +0100 Subject: [PATCH 1/4] Add IPath.IsPathFullyQualified Resolves #548 --- Directory.Build.props | 2 + .../MockPathTests.cs | 83 ++++++++++++++----- ...O.Abstractions.TestingHelpers.Tests.csproj | 1 - ...stem.IO.Abstractions.TestingHelpers.csproj | 1 - System.IO.Abstractions/IPath.cs | 4 + System.IO.Abstractions/PathBase.cs | 5 ++ System.IO.Abstractions/PathWrapper.cs | 7 ++ .../System.IO.Abstractions.csproj | 2 +- 8 files changed, 81 insertions(+), 24 deletions(-) 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..17c22af95 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,46 @@ 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); + } +#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 228f2120d..03a8e652e 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 3f4c12ae9..0276ef766 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..169798b8c 100644 --- a/System.IO.Abstractions/IPath.cs +++ b/System.IO.Abstractions/IPath.cs @@ -51,5 +51,9 @@ public interface IPath bool HasExtension(string path); /// bool IsPathRooted(string path); +#if FEATURE_ADVANCED_PATH_OPERATIONS + /// + bool IsPathFullyQualified(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..50bcbe75c 100644 --- a/System.IO.Abstractions/PathBase.cs +++ b/System.IO.Abstractions/PathBase.cs @@ -86,5 +86,10 @@ internal PathBase() { } /// public abstract bool IsPathRooted(string path); + +#if FEATURE_ADVANCED_PATH_OPERATIONS + /// + public abstract bool IsPathFullyQualified(string path); +#endif } } diff --git a/System.IO.Abstractions/PathWrapper.cs b/System.IO.Abstractions/PathWrapper.cs index c4bac2fb1..32cd3958e 100644 --- a/System.IO.Abstractions/PathWrapper.cs +++ b/System.IO.Abstractions/PathWrapper.cs @@ -118,6 +118,13 @@ 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); + } +#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 2f418f5e5..21d6863eb 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 From 1dc0bc2e743f3c7fcdd34a980c8ac6f6d6043f63 Mon Sep 17 00:00:00 2001 From: Florian Greinacher Date: Tue, 11 Feb 2020 21:39:13 +0100 Subject: [PATCH 2/4] Add IPath.GetRelativePath Resolves #399 --- .../MockPathTests.cs | 15 +++++++++++++++ System.IO.Abstractions/IPath.cs | 4 ++++ System.IO.Abstractions/PathBase.cs | 5 ++++- System.IO.Abstractions/PathWrapper.cs | 5 +++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/System.IO.Abstractions.TestingHelpers.Tests/MockPathTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/MockPathTests.cs index 17c22af95..d66fb281b 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/MockPathTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/MockPathTests.cs @@ -437,6 +437,21 @@ public void IsPathFullyQualified_WithRelativePathParts_ReturnsFalse() //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/IPath.cs b/System.IO.Abstractions/IPath.cs index 169798b8c..43270776c 100644 --- a/System.IO.Abstractions/IPath.cs +++ b/System.IO.Abstractions/IPath.cs @@ -51,9 +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 50bcbe75c..142bce6ad 100644 --- a/System.IO.Abstractions/PathBase.cs +++ b/System.IO.Abstractions/PathBase.cs @@ -88,8 +88,11 @@ 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 32cd3958e..aafca0b2c 100644 --- a/System.IO.Abstractions/PathWrapper.cs +++ b/System.IO.Abstractions/PathWrapper.cs @@ -123,6 +123,11 @@ 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) From b87c5d09d83c6902efdafc6607cd08e505333627 Mon Sep 17 00:00:00 2001 From: Florian Greinacher Date: Tue, 11 Feb 2020 20:53:32 +0100 Subject: [PATCH 3/4] Add back a .NET Framework target This changes adds a target for .NET Framework 4.6.1 so that we can get rid of the System.IO.FileSystem.AccessControl reference which causes problems for certain .NET Framework consumption patterns Fixes #547 --- .../System.IO.Abstractions.TestingHelpers.Tests.csproj | 2 +- .../System.IO.Abstractions.TestingHelpers.csproj | 8 +++++++- System.IO.Abstractions/System.IO.Abstractions.csproj | 10 ++++++++-- version.json | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) 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 03a8e652e..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 @@ -1,7 +1,7 @@  netcoreapp2.1;netcoreapp3.0 - $(TargetFrameworks);net472 + $(TargetFrameworks);net461 The unit tests for our pre-built mocks System.IO.Abstractions.TestingHelpers.Tests System.IO.Abstractions.TestingHelpers.Tests diff --git a/System.IO.Abstractions.TestingHelpers/System.IO.Abstractions.TestingHelpers.csproj b/System.IO.Abstractions.TestingHelpers/System.IO.Abstractions.TestingHelpers.csproj index 0276ef766..772bb052a 100644 --- a/System.IO.Abstractions.TestingHelpers/System.IO.Abstractions.TestingHelpers.csproj +++ b/System.IO.Abstractions.TestingHelpers/System.IO.Abstractions.TestingHelpers.csproj @@ -3,7 +3,7 @@ System.IO.Abstractions.TestingHelpers System.IO.Abstractions.TestingHelpers A set of pre-built mocks to help when testing file system interactions. - netstandard2.0;netstandard2.1 + netstandard2.0;netstandard2.1;net461 https://github.com/System-IO-Abstractions/System.IO.Abstractions MIT testing @@ -11,4 +11,10 @@ + + + all + runtime; build; native; contentfiles; analyzers + + diff --git a/System.IO.Abstractions/System.IO.Abstractions.csproj b/System.IO.Abstractions/System.IO.Abstractions.csproj index 21d6863eb..3ed380e75 100644 --- a/System.IO.Abstractions/System.IO.Abstractions.csproj +++ b/System.IO.Abstractions/System.IO.Abstractions.csproj @@ -3,13 +3,19 @@ System.IO.Abstractions System.IO.Abstractions A set of abstractions to help make file system interactions testable. - netstandard2.0;netstandard2.1 + netstandard2.0;netstandard2.1;net461 https://github.com/System-IO-Abstractions/System.IO.Abstractions MIT testing $(DefineConstants);FEATURE_ASYNC_FILE;FEATURE_ENUMERATION_OPTIONS;FEATURE_ADVANCED_PATH_OPERATIONS - + + + + all + runtime; build; native; contentfiles; analyzers + + diff --git a/version.json b/version.json index b5a9115db..70240ba98 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.0", + "version": "8.1", "assemblyVersion": { "precision": "major" }, From aefba7c0bc05bde742d013728f6d2c10e9927c7b Mon Sep 17 00:00:00 2001 From: Florian Greinacher Date: Tue, 11 Feb 2020 21:43:20 +0100 Subject: [PATCH 4/4] Bump major to indicate API change --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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" },