Skip to content

Commit

Permalink
feat: implement TryJoin for simulated Path (#568)
Browse files Browse the repository at this point in the history
Implement the `TryJoin` methods for `Path`.
  • Loading branch information
vbreuss authored Apr 19, 2024
1 parent e1c23f8 commit bfaa9f3
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Text;

#if FEATURE_FILESYSTEM_NET7
using Testably.Abstractions.Testing.Storage;
#endif
Expand Down Expand Up @@ -407,7 +407,18 @@ public bool TryJoin(ReadOnlySpan<char> path1,
ReadOnlySpan<char> path2,
Span<char> destination,
out int charsWritten)
=> System.IO.Path.TryJoin(path1, path2, destination, out charsWritten);
{
string result = Join(path1, path2);
if (destination.Length < result.Length)
{
charsWritten = 0;
return false;
}

result.AsSpan().CopyTo(destination);
charsWritten = result.Length;
return true;
}
#endif

#if FEATURE_PATH_JOIN
Expand All @@ -417,7 +428,18 @@ public bool TryJoin(ReadOnlySpan<char> path1,
ReadOnlySpan<char> path3,
Span<char> destination,
out int charsWritten)
=> System.IO.Path.TryJoin(path1, path2, path3, destination, out charsWritten);
{
string result = Join(path1, path2, path3);
if (destination.Length < result.Length)
{
charsWritten = 0;
return false;
}

result.AsSpan().CopyTo(destination);
charsWritten = result.Length;
return true;
}
#endif

#endregion
Expand All @@ -440,7 +462,7 @@ private string JoinInternal(string?[] paths)
return string.Empty;
}

StringBuilder sb = new StringBuilder();
StringBuilder sb = new();
foreach (string? path in paths)
{
if (string.IsNullOrEmpty(path))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ private bool IncludeSimulatedTests(ClassModel @class)
"GetTempPathTests",
"IsPathRootedTests",
"JoinTests",
"Tests"
"Tests",
"TryJoinTests"
];
return @class.Namespace
.StartsWith("Testably.Abstractions.Tests.FileSystem.Path", StringComparison.Ordinal)
Expand Down
57 changes: 57 additions & 0 deletions Tests/Testably.Abstractions.Tests/FileSystem/Path/TryJoinTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,33 @@ public void TryJoin_2Paths_BufferTooLittle_ShouldReturnFalse(
charsWritten.Should().Be(0);
}

[SkippableTheory]
[InlineAutoData("/foo/", "/bar/", "/foo//bar/")]
[InlineAutoData("foo/", "/bar", "foo//bar")]
[InlineAutoData("foo/", "bar", "foo/bar")]
[InlineAutoData("foo", "/bar", "foo/bar")]
[InlineAutoData("foo", "bar", "foo/bar")]
[InlineAutoData("/foo", "bar/", "/foo/bar/")]
public void TryJoin_2Paths_ShouldReturnExpectedResult(
string path1, string path2, string expectedResult)
{
path1 = path1.Replace('/', FileSystem.Path.DirectorySeparatorChar);
path2 = path2.Replace('/', FileSystem.Path.DirectorySeparatorChar);
expectedResult = expectedResult.Replace('/', FileSystem.Path.DirectorySeparatorChar);
char[] buffer = new char[expectedResult.Length];
Span<char> destination = new(buffer);

bool result = FileSystem.Path.TryJoin(
path1.AsSpan(),
path2.AsSpan(),
destination,
out int charsWritten);

result.Should().BeTrue();
charsWritten.Should().Be(expectedResult.Length);
destination.Slice(0, charsWritten).ToString().Should().Be(expectedResult);
}

[SkippableTheory]
[AutoData]
public void TryJoin_2Paths_ShouldReturnPathsCombinedByDirectorySeparatorChar(
Expand Down Expand Up @@ -72,6 +99,36 @@ public void TryJoin_3Paths_BufferTooLittle_ShouldReturnFalse(
charsWritten.Should().Be(0);
}

[SkippableTheory]
[InlineAutoData("/foo/", "/bar/", "/baz/", "/foo//bar//baz/")]
[InlineAutoData("foo/", "/bar/", "/baz", "foo//bar//baz")]
[InlineAutoData("foo/", "bar", "/baz", "foo/bar/baz")]
[InlineAutoData("foo", "/bar", "/baz", "foo/bar/baz")]
[InlineAutoData("foo", "/bar/", "baz", "foo/bar/baz")]
[InlineAutoData("foo", "bar", "baz", "foo/bar/baz")]
[InlineAutoData("/foo", "bar", "baz/", "/foo/bar/baz/")]
public void TryJoin_3Paths_ShouldReturnExpectedResult(
string path1, string path2, string path3, string expectedResult)
{
path1 = path1.Replace('/', FileSystem.Path.DirectorySeparatorChar);
path2 = path2.Replace('/', FileSystem.Path.DirectorySeparatorChar);
path3 = path3.Replace('/', FileSystem.Path.DirectorySeparatorChar);
expectedResult = expectedResult.Replace('/', FileSystem.Path.DirectorySeparatorChar);
char[] buffer = new char[expectedResult.Length];
Span<char> destination = new(buffer);

bool result = FileSystem.Path.TryJoin(
path1.AsSpan(),
path2.AsSpan(),
path3.AsSpan(),
destination,
out int charsWritten);

result.Should().BeTrue();
charsWritten.Should().Be(expectedResult.Length);
destination.Slice(0, charsWritten).ToString().Should().Be(expectedResult);
}

[SkippableTheory]
[AutoData]
public void TryJoin_3Paths_ShouldReturnPathsCombinedByDirectorySeparatorChar(
Expand Down

0 comments on commit bfaa9f3

Please sign in to comment.