Skip to content

Commit

Permalink
refactor: add missing tests from simulation mode implementation (#585)
Browse files Browse the repository at this point in the history
* Add tests for Execute and ExecuteExtensions

* Add test for uncovered code in ExceptionFactory

* Improve implementation and test coverage of SimulatedPaths and NativePath

* Run ReSharper cleanup

* Add dispose test for Notification

* Use feature flag `CAN_SIMULATE_OTHER_OS` instead of `!NETFRAMEWORK`
  • Loading branch information
vbreuss committed Apr 29, 2024
1 parent 615a74e commit bf27a22
Show file tree
Hide file tree
Showing 30 changed files with 342 additions and 186 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public Guid Parse(string input)
#endif

#if FEATURE_GUID_PARSE
#pragma warning disable MA0011
#pragma warning disable MA0011
/// <inheritdoc cref="IGuid.Parse(ReadOnlySpan{char})" />
public Guid Parse(ReadOnlySpan<char> input)
=> Guid.Parse(input);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@ private void TriggerRenameNotification(ChangeDescription item)
.GetField("_oldFullPath", BindingFlags.Instance | BindingFlags.NonPublic)?
.SetValue(eventArgs, oldFullPath);
}

return _fileSystem.Execute.Path.GetDirectoryName(changeDescription.Path)?
.Equals(_fileSystem.Execute.Path.GetDirectoryName(changeDescription.OldPath),
_fileSystem.Execute.StringComparisonMode) ?? true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,15 @@ public string GetFullPath(string path)
string? pathRoot = System.IO.Path.GetPathRoot(path);
string? directoryRoot =
System.IO.Path.GetPathRoot(fileSystem.Storage.CurrentDirectory);
if (!string.IsNullOrEmpty(pathRoot) && !string.IsNullOrEmpty(directoryRoot))
if (pathRoot?.Length < directoryRoot?.Length)
{
if (char.ToUpperInvariant(pathRoot[0]) != char.ToUpperInvariant(directoryRoot[0]))
if (pathRoot.Length > 0 &&
char.ToUpperInvariant(pathRoot[0]) != char.ToUpperInvariant(directoryRoot[0]))
{
return System.IO.Path.GetFullPath(path);
}

if (pathRoot.Length < directoryRoot.Length)
{
path = path.Substring(pathRoot.Length);
}
path = path.Substring(pathRoot.Length);
}

return System.IO.Path.GetFullPath(System.IO.Path.Combine(
Expand Down Expand Up @@ -183,7 +181,6 @@ public string GetRandomFileName()
public string GetRelativePath(string relativeTo, string path)
{
relativeTo.EnsureValidArgument(fileSystem, nameof(relativeTo));
path.EnsureValidArgument(fileSystem, nameof(path));

relativeTo = fileSystem.Execute.Path.GetFullPath(relativeTo);
path = fileSystem.Execute.Path.GetFullPath(path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,17 +290,10 @@ public string GetRandomFileName()
public string GetRelativePath(string relativeTo, string path)
{
relativeTo.EnsureValidArgument(fileSystem, nameof(relativeTo));
path.EnsureValidArgument(fileSystem, nameof(path));

relativeTo = fileSystem.Execute.Path.GetFullPath(relativeTo);
path = fileSystem.Execute.Path.GetFullPath(path);

// Need to check if the roots are different- if they are we need to return the "to" path.
if (!AreRootsEqual(relativeTo, path, fileSystem.Execute.StringComparisonMode))
{
return path;
}

Func<char, char, bool> charComparer = (c1, c2) => c1 == c2;
if (fileSystem.Execute.StringComparisonMode == StringComparison.OrdinalIgnoreCase)
{
Expand Down Expand Up @@ -505,35 +498,10 @@ public string TrimEndingDirectorySeparator(string path)

#endregion

/// <summary>
/// Returns true if the two paths have the same root
/// </summary>
private bool AreRootsEqual(string first, string second, StringComparison comparisonType)
{
int firstRootLength = GetRootLength(first);
int secondRootLength = GetRootLength(second);

return firstRootLength == secondRootLength
&& string.Compare(
strA: first,
indexA: 0,
strB: second,
indexB: 0,
length: firstRootLength,
comparisonType: comparisonType) == 0;
}

private string CombineInternal(string[] paths)
{
string NormalizePath(string path, bool ignoreStartingSeparator)
string NormalizePath(string path)
{
if (!ignoreStartingSeparator && (
path[0] == DirectorySeparatorChar ||
path[0] == AltDirectorySeparatorChar))
{
path = path.Substring(1);
}

if (path[path.Length - 1] == DirectorySeparatorChar ||
path[path.Length - 1] == AltDirectorySeparatorChar)
{
Expand All @@ -550,7 +518,6 @@ string NormalizePath(string path, bool ignoreStartingSeparator)

StringBuilder sb = new();

bool isFirst = true;
bool endsWithDirectorySeparator = false;
foreach (string path in paths)
{
Expand All @@ -567,10 +534,9 @@ string NormalizePath(string path, bool ignoreStartingSeparator)
if (IsPathRooted(path))
{
sb.Clear();
isFirst = true;
}

sb.Append(NormalizePath(path, isFirst));
sb.Append(NormalizePath(path));
sb.Append(DirectorySeparatorChar);
endsWithDirectorySeparator = path.EndsWith(DirectorySeparatorChar) ||
path.EndsWith(AltDirectorySeparatorChar);
Expand Down Expand Up @@ -650,7 +616,7 @@ string NormalizePath(string path, bool ignoreStartingSeparator)
int commonChars = 0;
for (; commonChars < first.Length; commonChars++)
{
if (second.Length < commonChars)
if (second.Length <= commonChars)
{
break;
}
Expand All @@ -668,13 +634,13 @@ string NormalizePath(string path, bool ignoreStartingSeparator)
}

// Or we're a full string and equal length or match to a separator
if (commonChars == first.Length
&& (commonChars == second.Length || IsDirectorySeparator(second[commonChars])))
if (commonChars == first.Length && commonChars == second.Length)
{
return commonChars;
}

if (commonChars == second.Length && IsDirectorySeparator(first[commonChars]))
if ((second.Length > commonChars && IsDirectorySeparator(second[commonChars])) ||
IsDirectorySeparator(first[commonChars - 1]))
{
return commonChars;
}
Expand Down
7 changes: 4 additions & 3 deletions Source/Testably.Abstractions.Testing/Helpers/Execute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,13 @@ internal partial class Execute
#if !CAN_SIMULATE_OTHER_OS
[Obsolete("Simulating other operating systems is not supported on .NET Framework")]
#endif
internal Execute(MockFileSystem fileSystem, SimulationMode simulationMode)
internal Execute(MockFileSystem fileSystem, SimulationMode simulationMode,
bool isNetFramework = false)
{
IsLinux = simulationMode == SimulationMode.Linux;
IsMac = simulationMode == SimulationMode.MacOS;
IsWindows = simulationMode == SimulationMode.Windows;
IsNetFramework = false;
IsNetFramework = IsWindows && isNetFramework;
StringComparisonMode = IsLinux
? StringComparison.Ordinal
: StringComparison.OrdinalIgnoreCase;
Expand All @@ -67,7 +68,7 @@ internal Execute(MockFileSystem fileSystem, SimulationMode simulationMode)
else
{
throw new NotSupportedException(
"The operating system must be one of Linux, OSX or Windows");
"The operating system must be one of Linux, MacOS or Windows");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ internal static Execute ExecuteOrDefault(this IFileSystem fileSystem)
{
fullFilePath = fullFilePath.Substring(currentDirectory.Length);
}
else if (fullFilePath.StartsWith(currentDirectory + fileSystem.Execute.Path.DirectorySeparatorChar,
else if (fullFilePath.StartsWith(
currentDirectory + fileSystem.Execute.Path.DirectorySeparatorChar,
fileSystem.Execute.StringComparisonMode))
{
fullFilePath = fullFilePath.Substring(currentDirectory.Length + 1);
Expand All @@ -75,11 +76,13 @@ internal static Execute ExecuteOrDefault(this IFileSystem fileSystem)
{
string? parentName = currentDirectory;
while (parentName != null &&
!fullFilePath.StartsWith(parentName + fileSystem.Execute.Path.DirectorySeparatorChar,
!fullFilePath.StartsWith(
parentName + fileSystem.Execute.Path.DirectorySeparatorChar,
fileSystem.Execute.StringComparisonMode))
{
parentName = fileSystem.Execute.Path.GetDirectoryName(parentName);
int lastIndex = givenPath.LastIndexOf(fileSystem.Execute.Path.DirectorySeparatorChar);
int lastIndex =
givenPath.LastIndexOf(fileSystem.Execute.Path.DirectorySeparatorChar);
if (lastIndex >= 0)
{
givenPath = givenPath.Substring(0, lastIndex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public CallStatistics(IStatisticsGate statisticsGate, string name)
_name = name;
}

#region IStatistics Members
#region IStatistics<TType> Members

/// <inheritdoc cref="IStatistics.Methods" />
public MethodStatistic[] Methods => _methods.ToArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

namespace Testably.Abstractions.Testing.Statistics;

internal class PathStatistics<TFactory, TType> : CallStatistics<TFactory>, IPathStatistics<TFactory, TType>
internal class PathStatistics<TFactory, TType> : CallStatistics<TFactory>,
IPathStatistics<TFactory, TType>
{
private readonly MockFileSystem _fileSystem;

Expand All @@ -26,7 +27,7 @@ internal class PathStatistics<TFactory, TType> : CallStatistics<TFactory>, IPath
_fileSystem = fileSystem;
}

#region IPathStatistics Members
#region IPathStatistics<TFactory,TType> Members

/// <inheritdoc cref="IPathStatistics{TFactory,TType}.this[string]" />
public IStatistics<TType> this[string path]
Expand Down
12 changes: 10 additions & 2 deletions Source/Testably.Abstractions.Testing/Storage/InMemoryContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,11 @@ internal FileAttributes AdjustAttributes(FileAttributes attributes)
return attributes;
}

private bool CanGetAccess(FileAccess access, FileShare share, bool deleteAccess, bool ignoreFileShare)
private bool CanGetAccess(
FileAccess access,
FileShare share,
bool deleteAccess,
bool ignoreFileShare)
{
foreach (KeyValuePair<Guid, FileHandle> fileHandle in _fileHandles)
{
Expand Down Expand Up @@ -386,7 +390,11 @@ public void Dispose()

#endregion

public bool GrantAccess(FileAccess access, FileShare share, bool deleteAccess, bool ignoreFileShare)
public bool GrantAccess(
FileAccess access,
FileShare share,
bool deleteAccess,
bool ignoreFileShare)
{
FileShare usedShare = share;
FileShare currentShare = Share;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ internal static class StorageExtensions
StringBuilder givenPathPrefix = new();

while (searchPattern.StartsWith(
".." + fileSystem.Execute.Path.DirectorySeparatorChar, StringComparison.Ordinal) ||
".." + fileSystem.Execute.Path.DirectorySeparatorChar,
StringComparison.Ordinal) ||
searchPattern.StartsWith(
".." + fileSystem.Execute.Path.AltDirectorySeparatorChar, StringComparison.Ordinal))
".." + fileSystem.Execute.Path.AltDirectorySeparatorChar,
StringComparison.Ordinal))
{
fileSystem.Execute.OnNetFramework(
() => throw ExceptionFactory.SearchPatternCannotContainTwoDots());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ public sealed class LinuxFileSystemTests : {@class.Name}<MockFileSystem>, IDispo
private readonly IDirectoryCleaner _directoryCleaner;
public LinuxFileSystemTests() : this(new MockFileSystem(i =>
i.SimulatingOperatingSystem(SimulationMode.Linux)))
public LinuxFileSystemTests() : this(new MockFileSystem(o =>
o.SimulatingOperatingSystem(SimulationMode.Linux)))
{{
}}
Expand Down Expand Up @@ -187,8 +187,8 @@ public sealed class MacFileSystemTests : {@class.Name}<MockFileSystem>, IDisposa
private readonly IDirectoryCleaner _directoryCleaner;
public MacFileSystemTests() : this(new MockFileSystem(i =>
i.SimulatingOperatingSystem(SimulationMode.MacOS)))
public MacFileSystemTests() : this(new MockFileSystem(o =>
o.SimulatingOperatingSystem(SimulationMode.MacOS)))
{{
}}
private MacFileSystemTests(MockFileSystem mockFileSystem) : base(
Expand Down Expand Up @@ -226,8 +226,8 @@ public sealed class WindowsFileSystemTests : {@class.Name}<MockFileSystem>, IDis
private readonly IDirectoryCleaner _directoryCleaner;
public WindowsFileSystemTests() : this(new MockFileSystem(i =>
i.SimulatingOperatingSystem(SimulationMode.Windows)))
public WindowsFileSystemTests() : this(new MockFileSystem(o =>
o.SimulatingOperatingSystem(SimulationMode.Windows)))
{{
}}
private WindowsFileSystemTests(MockFileSystem mockFileSystem) : base(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,17 @@ private sealed class DummyZipArchiveEntry(
Stream? stream = null)
: IZipArchiveEntry
{
/// <inheritdoc cref="IZipArchiveEntry.Comment" />
public string Comment { get; set; } = comment;

/// <inheritdoc cref="IZipArchiveEntry.IsEncrypted" />
public bool IsEncrypted { get; } = isEncrypted;

#region IZipArchiveEntry Members

/// <inheritdoc cref="IZipArchiveEntry.Archive" />
public IZipArchive Archive => archive ?? throw new NotSupportedException();

/// <inheritdoc cref="IZipArchiveEntry.Comment" />
public string Comment { get; set; } = comment;

/// <inheritdoc cref="IZipArchiveEntry.CompressedLength" />
public long CompressedLength => stream?.Length ?? 0L;

Expand All @@ -69,9 +72,6 @@ private sealed class DummyZipArchiveEntry(
/// <inheritdoc cref="IZipArchiveEntry.FullName" />
public string FullName { get; } = fullName ?? "";

/// <inheritdoc cref="IZipArchiveEntry.IsEncrypted" />
public bool IsEncrypted { get; } = isEncrypted;

/// <inheritdoc cref="IZipArchiveEntry.LastWriteTime" />
public DateTimeOffset LastWriteTime { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ public void InternalBufferSize_ShouldResetQueue(string path1, string path2)
result.Should().BeNull();
}

#if !NETFRAMEWORK
#if CAN_SIMULATE_OTHER_OS
public sealed class EventArgsTests
{
[SkippableTheory]
Expand All @@ -244,8 +244,7 @@ public sealed class EventArgsTests
public void FileSystemEventArgs_ShouldUseDirectorySeparatorFromSimulatedFileSystem(
SimulationMode simulationMode, string parentDirectory, string directoryName)
{
MockFileSystem fileSystem =
new MockFileSystem(s => s.SimulatingOperatingSystem(simulationMode));
MockFileSystem fileSystem = new(o => o.SimulatingOperatingSystem(simulationMode));
fileSystem.Directory.CreateDirectory(parentDirectory);
FileSystemEventArgs? result = null;
string expectedFullPath = fileSystem.Path.GetFullPath(
Expand Down Expand Up @@ -278,7 +277,9 @@ public sealed class EventArgsTests
result.Name.Should().Be(expectedName);
result.ChangeType.Should().Be(WatcherChangeTypes.Created);
}
#endif

#if CAN_SIMULATE_OTHER_OS
[SkippableTheory]
[InlineAutoData(SimulationMode.Linux)]
[InlineAutoData(SimulationMode.MacOS)]
Expand All @@ -287,8 +288,7 @@ public sealed class EventArgsTests
SimulationMode simulationMode, string parentDirectory,
string sourceName, string destinationName)
{
MockFileSystem fileSystem =
new MockFileSystem(s => s.SimulatingOperatingSystem(simulationMode));
MockFileSystem fileSystem = new(o => o.SimulatingOperatingSystem(simulationMode));
fileSystem.Directory.CreateDirectory(parentDirectory);
RenamedEventArgs? result = null;
string expectedOldFullPath = fileSystem.Path.GetFullPath(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public sealed class PathMockTests
{
[Theory]
[InlineAutoData(SimulationMode.Native)]
#if !NETFRAMEWORK
#if CAN_SIMULATE_OTHER_OS
[InlineAutoData(SimulationMode.Linux)]
[InlineAutoData(SimulationMode.MacOS)]
[InlineAutoData(SimulationMode.Windows)]
Expand All @@ -15,7 +15,7 @@ public sealed class PathMockTests
SimulationMode simulationMode, int fixedRandomValue)
{
#pragma warning disable CS0618
MockFileSystem fileSystem = new(i => i
MockFileSystem fileSystem = new(o => o
.SimulatingOperatingSystem(simulationMode)
.UseRandomProvider(RandomProvider.Generate(
intGenerator: new RandomProvider.Generator<int>(() => fixedRandomValue))));
Expand Down

0 comments on commit bf27a22

Please sign in to comment.