From 0a092a2ef5d192eba762ddff205dfa13861c37eb Mon Sep 17 00:00:00 2001 From: Jeremy Kuhne Date: Wed, 28 Feb 2018 13:02:34 -0800 Subject: [PATCH] Expose Path.Join and tests (#27522) * Expose Path.Join and test. Depends on https://github.com/dotnet/coreclr/pull/16561 * Update for final API review changes * Address feedback * Address more feedback. --- .../ref/System.Runtime.Extensions.cs | 4 + .../System.Runtime.Extensions.Tests.csproj | 1 + .../tests/System/IO/PathTestsBase.cs | 3 + .../System/IO/PathTests_Join.netcoreapp.cs | 111 ++++++++++++++++++ 4 files changed, 119 insertions(+) create mode 100644 src/System.Runtime.Extensions/tests/System/IO/PathTests_Join.netcoreapp.cs diff --git a/src/System.Runtime.Extensions/ref/System.Runtime.Extensions.cs b/src/System.Runtime.Extensions/ref/System.Runtime.Extensions.cs index f1fff4f12ddc..a9a829da969a 100644 --- a/src/System.Runtime.Extensions/ref/System.Runtime.Extensions.cs +++ b/src/System.Runtime.Extensions/ref/System.Runtime.Extensions.cs @@ -1224,6 +1224,10 @@ public static partial class Path public static bool IsPathFullyQualified(string path) { throw null; } public static bool IsPathFullyQualified(ReadOnlySpan path) { throw null; } public static string GetRelativePath(string relativeTo, string path) { throw null; } + public static string Join(ReadOnlySpan path1, ReadOnlySpan path2) { throw null; } + public static string Join(ReadOnlySpan path1, ReadOnlySpan path2, ReadOnlySpan path3) { throw null; } + public static bool TryJoin(ReadOnlySpan path1, ReadOnlySpan path2, Span destination, out int charsWritten) { throw null; } + public static bool TryJoin(ReadOnlySpan path1, ReadOnlySpan path2, ReadOnlySpan path3, Span destination, out int charsWritten) { throw null; } } public partial class BinaryReader : System.IDisposable diff --git a/src/System.Runtime.Extensions/tests/System.Runtime.Extensions.Tests.csproj b/src/System.Runtime.Extensions/tests/System.Runtime.Extensions.Tests.csproj index 59eaf96f2212..ca766d374463 100644 --- a/src/System.Runtime.Extensions/tests/System.Runtime.Extensions.Tests.csproj +++ b/src/System.Runtime.Extensions/tests/System.Runtime.Extensions.Tests.csproj @@ -42,6 +42,7 @@ + diff --git a/src/System.Runtime.Extensions/tests/System/IO/PathTestsBase.cs b/src/System.Runtime.Extensions/tests/System/IO/PathTestsBase.cs index 5331d20f0e46..edb6e4163244 100644 --- a/src/System.Runtime.Extensions/tests/System/IO/PathTestsBase.cs +++ b/src/System.Runtime.Extensions/tests/System/IO/PathTestsBase.cs @@ -8,6 +8,9 @@ namespace System.IO.Tests { public partial class PathTestsBase { + protected static string Sep = Path.DirectorySeparatorChar.ToString(); + protected static string AltSep = Path.AltDirectorySeparatorChar.ToString(); + public static TheoryData TestData_EmbeddedNull => new TheoryData { "a\0b" diff --git a/src/System.Runtime.Extensions/tests/System/IO/PathTests_Join.netcoreapp.cs b/src/System.Runtime.Extensions/tests/System/IO/PathTests_Join.netcoreapp.cs new file mode 100644 index 000000000000..4c8a9b9bdb03 --- /dev/null +++ b/src/System.Runtime.Extensions/tests/System/IO/PathTests_Join.netcoreapp.cs @@ -0,0 +1,111 @@ +// 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. + +using Xunit; + +namespace System.IO.Tests +{ + public class PathTests_Join : PathTestsBase + { + public static TheoryData TestData_JoinTwoPaths = new TheoryData + { + { "", "", "" }, + { Sep, "", Sep }, + { AltSep, "", AltSep }, + { "", Sep, Sep }, + { "", AltSep, AltSep }, + { Sep, Sep, $"{Sep}{Sep}" }, + { AltSep, AltSep, $"{AltSep}{AltSep}" }, + { "a", "", "a" }, + { "", "a", "a" }, + { "a", "a", $"a{Sep}a" }, + { $"a{Sep}", "a", $"a{Sep}a" }, + { "a", $"{Sep}a", $"a{Sep}a" }, + { $"a{Sep}", $"{Sep}a", $"a{Sep}{Sep}a" }, + { "a", $"a{Sep}", $"a{Sep}a{Sep}" }, + { $"a{AltSep}", "a", $"a{AltSep}a" }, + { "a", $"{AltSep}a", $"a{AltSep}a" }, + { $"a{Sep}", $"{AltSep}a", $"a{Sep}{AltSep}a" }, + { $"a{AltSep}", $"{AltSep}a", $"a{AltSep}{AltSep}a" }, + { "a", $"a{AltSep}", $"a{Sep}a{AltSep}" }, + }; + + [Theory, MemberData(nameof(TestData_JoinTwoPaths))] + public void JoinTwoPaths(string path1, string path2, string expected) + { + Assert.Equal(expected, Path.Join(path1, path2)); + } + + [Theory, MemberData(nameof(TestData_JoinTwoPaths))] + public void TryJoinTwoPaths(string path1, string path2, string expected) + { + char[] output = new char[expected.Length]; + + Assert.True(Path.TryJoin(path1, path2, output, out int written)); + Assert.Equal(expected.Length, written); + Assert.Equal(expected, new string(output)); + + if (expected.Length > 0) + { + Assert.False(Path.TryJoin(path1, path2, Span.Empty, out written)); + Assert.Equal(0, written); + + output = new char[expected.Length - 1]; + Assert.False(Path.TryJoin(path1, path2, output, out written)); + Assert.Equal(0, written); + Assert.Equal(output, new char[output.Length]); + } + } + + public static TheoryData TestData_JoinThreePaths = new TheoryData + { + { "", "", "", "" }, + { Sep, Sep, Sep, $"{Sep}{Sep}{Sep}" }, + { AltSep, AltSep, AltSep, $"{AltSep}{AltSep}{AltSep}" }, + { "a", "", "", "a" }, + { "", "a", "", "a" }, + { "", "", "a", "a" }, + { "a", "", "a", $"a{Sep}a" }, + { "a", "a", "", $"a{Sep}a" }, + { "", "a", "a", $"a{Sep}a" }, + { "a", "a", "a", $"a{Sep}a{Sep}a" }, + { "a", Sep, "a", $"a{Sep}a" }, + { $"a{Sep}", "", "a", $"a{Sep}a" }, + { $"a{Sep}", "a", "", $"a{Sep}a" }, + { "", $"a{Sep}", "a", $"a{Sep}a" }, + { "a", "", $"{Sep}a", $"a{Sep}a" }, + { $"a{AltSep}", "", "a", $"a{AltSep}a" }, + { $"a{AltSep}", "a", "", $"a{AltSep}a" }, + { "", $"a{AltSep}", "a", $"a{AltSep}a" }, + { "a", "", $"{AltSep}a", $"a{AltSep}a" }, + }; + + [Theory, MemberData(nameof(TestData_JoinThreePaths))] + public void JoinThreePaths(string path1, string path2, string path3, string expected) + { + Assert.Equal(expected, Path.Join(path1, path2, path3)); + } + + [Theory, MemberData(nameof(TestData_JoinThreePaths))] + public void TryJoinThreePaths(string path1, string path2, string path3, string expected) + { + char[] output = new char[expected.Length]; + + Assert.True(Path.TryJoin(path1, path2, path3, output, out int written)); + Assert.Equal(expected.Length, written); + Assert.Equal(expected, new string(output)); + + if (expected.Length > 0) + { + Assert.False(Path.TryJoin(path1, path2, path3, Span.Empty, out written)); + Assert.Equal(0, written); + + output = new char[expected.Length - 1]; + Assert.False(Path.TryJoin(path1, path2, path3, output, out written)); + Assert.Equal(0, written); + Assert.Equal(output, new char[output.Length]); + } + } + } +}