Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement Join for simulated Path #567

Merged
merged 2 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 45 additions & 59 deletions Source/Testably.Abstractions.Testing/Helpers/Execute.SimulatedPath.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Text;

#if FEATURE_FILESYSTEM_NET7
using Testably.Abstractions.Testing.Storage;
#endif
Expand Down Expand Up @@ -342,15 +344,15 @@ public bool IsPathRooted(ReadOnlySpan<char> path)
#if FEATURE_PATH_JOIN
/// <inheritdoc cref="IPath.Join(ReadOnlySpan{char}, ReadOnlySpan{char})" />
public string Join(ReadOnlySpan<char> path1, ReadOnlySpan<char> path2)
=> System.IO.Path.Join(path1, path2);
=> JoinInternal([path1.ToString(), path2.ToString()]);
#endif

#if FEATURE_PATH_JOIN
/// <inheritdoc cref="IPath.Join(ReadOnlySpan{char}, ReadOnlySpan{char}, ReadOnlySpan{char})" />
public string Join(ReadOnlySpan<char> path1,
ReadOnlySpan<char> path2,
ReadOnlySpan<char> path3)
=> System.IO.Path.Join(path1, path2, path3);
=> JoinInternal([path1.ToString(), path2.ToString(), path3.ToString()]);
#endif

#if FEATURE_PATH_ADVANCED
Expand All @@ -366,70 +368,19 @@ public string Join(ReadOnlySpan<char> path1,
#if FEATURE_PATH_ADVANCED
/// <inheritdoc cref="IPath.Join(string, string)" />
public string Join(string? path1, string? path2)
{
if (string.IsNullOrEmpty(path1))
{
return path2 ?? string.Empty;
}

if (string.IsNullOrEmpty(path2))
{
return path1;
}

return JoinInternal([path1, path2]);
}
=> JoinInternal([path1, path2]);
#endif

#if FEATURE_PATH_ADVANCED
/// <inheritdoc cref="IPath.Join(string, string, string)" />
public string Join(string? path1, string? path2, string? path3)
{
if (string.IsNullOrEmpty(path1))
{
return Join(path2, path3);
}

if (string.IsNullOrEmpty(path2))
{
return Join(path1, path3);
}

if (string.IsNullOrEmpty(path3))
{
return Join(path1, path2);
}

return JoinInternal([path1, path2, path3]);
}
=> JoinInternal([path1, path2, path3]);
#endif

#if FEATURE_PATH_ADVANCED
/// <inheritdoc cref="IPath.Join(string, string, string, string)" />
public string Join(string? path1, string? path2, string? path3, string? path4)
{
if (string.IsNullOrEmpty(path1))
{
return Join(path2, path3, path4);
}

if (string.IsNullOrEmpty(path2))
{
return Join(path1, path3, path4);
}

if (string.IsNullOrEmpty(path3))
{
return Join(path1, path2, path4);
}

if (string.IsNullOrEmpty(path4))
{
return Join(path1, path2, path3);
}

return JoinInternal([path1, path2, path3, path4]);
}
=> JoinInternal([path1, path2, path3, path4]);
#endif

#if FEATURE_PATH_ADVANCED
Expand Down Expand Up @@ -476,9 +427,44 @@ private static string CombineInternal(string[] paths)

protected abstract bool IsDirectorySeparator(char c);

#if FEATURE_PATH_ADVANCED
private static string JoinInternal(string?[] paths)
=> System.IO.Path.Join(paths);
#if FEATURE_PATH_JOIN || FEATURE_PATH_ADVANCED
private string JoinInternal(string?[] paths)
{
if (paths == null)
{
throw new ArgumentNullException(nameof(paths));
}

if (paths.Length == 0)
{
return string.Empty;
}

StringBuilder sb = new StringBuilder();
foreach (string? path in paths)
{
if (string.IsNullOrEmpty(path))
{
continue;
}

if (sb.Length == 0)
{
sb.Append(path);
}
else
{
if (!IsDirectorySeparator(sb[sb.Length - 1]) && !IsDirectorySeparator(path[0]))
{
sb.Append(DirectorySeparatorChar);
}

sb.Append(path);
}
}

return sb.ToString();
}
#endif

private bool TryGetExtensionIndex(string path, [NotNullWhen(true)] out int? dotIndex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ private bool IncludeSimulatedTests(ClassModel @class)
"GetRandomFileNameTests",
"GetTempPathTests",
"IsPathRootedTests",
"JoinTests",
"Tests"
];
return @class.Namespace
Expand Down
106 changes: 106 additions & 0 deletions Tests/Testably.Abstractions.Tests/FileSystem/Path/JoinTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,25 @@ public void Join_2Paths_OneNullOrEmpty_ShouldReturnCombinationOfOtherParts(
result2.Should().Be(path);
}

[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 Join_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);

string result = FileSystem.Path.Join(path1, path2);

result.Should().Be(expectedResult);
}

[SkippableTheory]
[AutoData]
public void Join_2Paths_ShouldReturnPathsCombinedByDirectorySeparatorChar(
Expand Down Expand Up @@ -64,6 +83,27 @@ public void Join_3Paths_OneNullOrEmpty_ShouldReturnCombinationOfOtherParts(
result3.Should().Be(expectedPath);
}

[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 Join_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);

string result = FileSystem.Path.Join(path1, path2, path3);

result.Should().Be(expectedResult);
}

[SkippableTheory]
[AutoData]
public void Join_3Paths_ShouldReturnPathsCombinedByDirectorySeparatorChar(
Expand Down Expand Up @@ -115,6 +155,28 @@ public void Join_4Paths_OneNullOrEmpty_ShouldReturnCombinationOfOtherParts(
result4.Should().Be(expectedPath);
}

[SkippableTheory]
[InlineAutoData("/foo/", "/bar/", "/baz/", "/muh/", "/foo//bar//baz//muh/")]
[InlineAutoData("foo/", "/bar/", "/baz/", "/muh", "foo//bar//baz//muh")]
[InlineAutoData("foo/", "bar", "/baz", "/muh", "foo/bar/baz/muh")]
[InlineAutoData("foo", "/bar", "/baz", "/muh", "foo/bar/baz/muh")]
[InlineAutoData("foo", "/bar/", "baz/", "muh", "foo/bar/baz/muh")]
[InlineAutoData("foo", "bar", "baz", "muh", "foo/bar/baz/muh")]
[InlineAutoData("/foo", "bar", "baz", "muh/", "/foo/bar/baz/muh/")]
public void Join_4Paths_ShouldReturnExpectedResult(
string path1, string path2, string path3, string path4, string expectedResult)
{
path1 = path1.Replace('/', FileSystem.Path.DirectorySeparatorChar);
path2 = path2.Replace('/', FileSystem.Path.DirectorySeparatorChar);
path3 = path3.Replace('/', FileSystem.Path.DirectorySeparatorChar);
path4 = path4.Replace('/', FileSystem.Path.DirectorySeparatorChar);
expectedResult = expectedResult.Replace('/', FileSystem.Path.DirectorySeparatorChar);

string result = FileSystem.Path.Join(path1, path2, path3, path4);

result.Should().Be(expectedResult);
}

[SkippableTheory]
[AutoData]
public void Join_4Paths_ShouldReturnPathsCombinedByDirectorySeparatorChar(
Expand Down Expand Up @@ -149,6 +211,27 @@ public void Join_4Paths_Span_ShouldReturnPathsCombinedByDirectorySeparatorChar(
result.Should().Be(expectedResult);
}

[SkippableFact]
public void Join_ParamPaths_Empty_ShouldReturnEmptyString()
{
string?[] paths = Array.Empty<string?>();

string result = FileSystem.Path.Join(paths);

result.Should().Be(string.Empty);
}

[SkippableFact]
public void Join_ParamPaths_Null_ShouldThrow()
{
Exception? exception = Record.Exception(() =>
{
_ = FileSystem.Path.Join(null!);
});

exception.Should().BeException<ArgumentNullException>(paramName: "paths");
}

[SkippableTheory]
[InlineAutoData((string?)null)]
[InlineAutoData("")]
Expand Down Expand Up @@ -176,6 +259,29 @@ public void Join_ParamPaths_OneNullOrEmpty_ShouldReturnCombinationOfOtherParts(
result5.Should().Be(expectedPath);
}

[SkippableTheory]
[InlineAutoData("/foo/", "/bar/", "/baz/", "/muh/", "/maeh/", "/foo//bar//baz//muh//maeh/")]
[InlineAutoData("foo/", "/bar/", "/baz/", "/muh", "/maeh", "foo//bar//baz//muh/maeh")]
[InlineAutoData("foo/", "bar", "/baz", "/muh", "/maeh", "foo/bar/baz/muh/maeh")]
[InlineAutoData("foo", "/bar", "/baz", "/muh", "/maeh", "foo/bar/baz/muh/maeh")]
[InlineAutoData("foo", "/bar/", "baz/", "muh/", "maeh", "foo/bar/baz/muh/maeh")]
[InlineAutoData("foo", "bar", "baz", "muh", "maeh", "foo/bar/baz/muh/maeh")]
[InlineAutoData("/foo", "bar", "baz", "muh", "maeh/", "/foo/bar/baz/muh/maeh/")]
public void Join_ParamPaths_ShouldReturnExpectedResult(
string path1, string path2, string path3, string path4, string path5, string expectedResult)
{
path1 = path1.Replace('/', FileSystem.Path.DirectorySeparatorChar);
path2 = path2.Replace('/', FileSystem.Path.DirectorySeparatorChar);
path3 = path3.Replace('/', FileSystem.Path.DirectorySeparatorChar);
path4 = path4.Replace('/', FileSystem.Path.DirectorySeparatorChar);
path5 = path5.Replace('/', FileSystem.Path.DirectorySeparatorChar);
expectedResult = expectedResult.Replace('/', FileSystem.Path.DirectorySeparatorChar);

string result = FileSystem.Path.Join(path1, path2, path3, path4, path5);

result.Should().Be(expectedResult);
}

[SkippableTheory]
[AutoData]
public void Join_ParamPaths_ShouldReturnPathsCombinedByDirectorySeparatorChar(
Expand Down
Loading