diff --git a/Source/Testably.Abstractions.Testing/MockFileSystem.cs b/Source/Testably.Abstractions.Testing/MockFileSystem.cs
index 94992e864..d07cb196d 100644
--- a/Source/Testably.Abstractions.Testing/MockFileSystem.cs
+++ b/Source/Testably.Abstractions.Testing/MockFileSystem.cs
@@ -1,7 +1,6 @@
using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
-using System.Linq;
using Testably.Abstractions.Testing.FileSystem;
using Testably.Abstractions.Testing.Storage;
@@ -45,11 +44,8 @@ public sealed class MockFileSystem : IFileSystem
///
/// The registered containers in the in-Memory .
///
- internal IReadOnlyList Containers
- => _storage.Containers
- .OrderBy(x => x.Key.FullPath)
- .Select(x => x.Value)
- .ToList();
+ internal IReadOnlyList StorageContainers
+ => _storage.GetContainers();
private readonly DirectoryMock _directoryMock;
private readonly FileMock _fileMock;
@@ -123,7 +119,7 @@ public IPath Path
///
public override string ToString()
- => $"MockFileSystem (directories: {_storage.Containers.Count(x => x.Value.Type == FileSystemTypes.Directory)}, files: {_storage.Containers.Count(x => x.Value.Type == FileSystemTypes.File)})";
+ => $"MockFileSystem ({_storage})";
///
/// Implements a custom access control (ACL) mechanism.
diff --git a/Source/Testably.Abstractions.Testing/MockTimeSystem.cs b/Source/Testably.Abstractions.Testing/MockTimeSystem.cs
index 146a52f73..5eee0bc3d 100644
--- a/Source/Testably.Abstractions.Testing/MockTimeSystem.cs
+++ b/Source/Testably.Abstractions.Testing/MockTimeSystem.cs
@@ -82,7 +82,7 @@ public ITimerFactory Timer
///
public override string ToString()
- => $"MockTimeSystem (now: {DateTime.UtcNow}Z)";
+ => $"MockTimeSystem (provider: {TimeProvider}, now: {DateTime.UtcNow}Z)";
///
/// Specifies the to use when dealing with timers.
diff --git a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs
index 4ed2a7119..e331d5e42 100644
--- a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs
+++ b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs
@@ -15,8 +15,8 @@ namespace Testably.Abstractions.Testing.Storage;
///
internal sealed class InMemoryStorage : IStorage
{
- internal readonly ConcurrentDictionary
- Containers = new();
+ private readonly ConcurrentDictionary
+ _containers = new();
private readonly ConcurrentDictionary _drives =
new(StringComparer.OrdinalIgnoreCase);
@@ -45,7 +45,7 @@ public InMemoryStorage(MockFileSystem fileSystem)
{
ThrowIfParentDoesNotExist(destination, _ => ExceptionFactory.DirectoryNotFound());
- if (!Containers.TryGetValue(source,
+ if (!_containers.TryGetValue(source,
out IStorageContainer? sourceContainer))
{
return null;
@@ -59,7 +59,7 @@ public InMemoryStorage(MockFileSystem fileSystem)
using (_ = sourceContainer.RequestAccess(FileAccess.ReadWrite, FileShare.None))
{
if (overwrite &&
- Containers.TryRemove(destination,
+ _containers.TryRemove(destination,
out IStorageContainer? existingContainer))
{
existingContainer.ClearBytes();
@@ -67,7 +67,7 @@ public InMemoryStorage(MockFileSystem fileSystem)
IStorageContainer copiedContainer =
InMemoryContainer.NewFile(destination, _fileSystem);
- if (Containers.TryAdd(destination, copiedContainer))
+ if (_containers.TryAdd(destination, copiedContainer))
{
copiedContainer.WriteBytes(sourceContainer.GetBytes().ToArray());
Execute.OnMac(
@@ -99,11 +99,11 @@ public InMemoryStorage(MockFileSystem fileSystem)
///
public bool DeleteContainer(IStorageLocation location, bool recursive = false)
{
- if (!Containers.TryGetValue(location, out IStorageContainer? container))
+ if (!_containers.TryGetValue(location, out IStorageContainer? container))
{
IStorageLocation? parentLocation = location.GetParent();
if (parentLocation != null &&
- !Containers.TryGetValue(parentLocation, out _))
+ !_containers.TryGetValue(parentLocation, out _))
{
throw ExceptionFactory.DirectoryNotFound(parentLocation.FullPath);
}
@@ -140,7 +140,7 @@ public bool DeleteContainer(IStorageLocation location, bool recursive = false)
using (container.RequestAccess(FileAccess.Write, FileShare.ReadWrite,
deleteAccess: true))
{
- if (Containers.TryRemove(location, out IStorageContainer? removed))
+ if (_containers.TryRemove(location, out IStorageContainer? removed))
{
removed.ClearBytes();
_fileSystem.ChangeHandler.NotifyCompletedChange(fileSystemChange);
@@ -160,7 +160,7 @@ public IEnumerable EnumerateLocations(
EnumerationOptions? enumerationOptions = null)
{
ValidateExpression(searchPattern);
- if (!Containers.ContainsKey(location))
+ if (!_containers.ContainsKey(location))
{
throw ExceptionFactory.DirectoryNotFound(location.FullPath);
}
@@ -177,7 +177,7 @@ public IEnumerable EnumerateLocations(
fullPath += _fileSystem.Path.DirectorySeparatorChar;
}
- foreach (KeyValuePair item in Containers
+ foreach (KeyValuePair item in _containers
.Where(x => x.Key.FullPath.StartsWith(fullPath,
InMemoryLocation.StringComparisonMode) &&
!x.Key.Equals(location)))
@@ -215,7 +215,7 @@ public IEnumerable EnumerateLocations(
return null;
}
- if (Containers.TryGetValue(location, out IStorageContainer? container))
+ if (_containers.TryGetValue(location, out IStorageContainer? container))
{
return container;
}
@@ -287,7 +287,7 @@ public IStorageContainer GetOrCreateContainer(
IFileSystemExtensibility? fileSystemExtensibility = null)
{
ChangeDescription? fileSystemChange = null;
- IStorageContainer container = Containers.GetOrAdd(location,
+ IStorageContainer container = _containers.GetOrAdd(location,
loc =>
{
IStorageContainer container =
@@ -302,7 +302,7 @@ public IStorageContainer GetOrCreateContainer(
{
IStorageLocation? parentLocation = loc.GetParent();
if (parentLocation is { IsRooted: false } &&
- !Containers.ContainsKey(parentLocation))
+ !_containers.ContainsKey(parentLocation))
{
throw ExceptionFactory.DirectoryNotFound(loc.FullPath);
}
@@ -359,13 +359,13 @@ public IStorageContainer GetOrCreateContainer(
() => ExceptionFactory.DirectoryNotFound(location.FullPath),
() => ExceptionFactory.FileNotFound(location.FullPath)));
- if (!Containers.TryGetValue(source,
+ if (!_containers.TryGetValue(source,
out IStorageContainer? sourceContainer))
{
return null;
}
- if (!Containers.TryGetValue(destination,
+ if (!_containers.TryGetValue(destination,
out IStorageContainer? destinationContainer))
{
return null;
@@ -383,14 +383,14 @@ public IStorageContainer GetOrCreateContainer(
using (_ = destinationContainer.RequestAccess(FileAccess.ReadWrite,
FileShare.None, ignoreMetadataErrors: ignoreMetadataErrors))
{
- if (Containers.TryRemove(destination,
+ if (_containers.TryRemove(destination,
out IStorageContainer? existingDestinationContainer))
{
int destinationBytesLength =
existingDestinationContainer.GetBytes().Length;
destination.Drive?.ChangeUsedBytes(-1 * destinationBytesLength);
if (backup != null &&
- Containers.TryAdd(backup, existingDestinationContainer))
+ _containers.TryAdd(backup, existingDestinationContainer))
{
Execute.OnWindowsIf(sourceContainer.Type == FileSystemTypes.File,
() => existingDestinationContainer.Attributes |=
@@ -398,7 +398,7 @@ public IStorageContainer GetOrCreateContainer(
backup.Drive?.ChangeUsedBytes(destinationBytesLength);
}
- if (Containers.TryRemove(source,
+ if (_containers.TryRemove(source,
out IStorageContainer? existingSourceContainer))
{
int sourceBytesLength = existingSourceContainer.GetBytes().Length;
@@ -414,7 +414,7 @@ public IStorageContainer GetOrCreateContainer(
DateTimeKind.Utc),
DateTimeKind.Utc);
});
- Containers.TryAdd(destination, existingSourceContainer);
+ _containers.TryAdd(destination, existingSourceContainer);
return destination;
}
}
@@ -429,13 +429,13 @@ public IStorageContainer GetOrCreateContainer(
public IStorageLocation? ResolveLinkTarget(IStorageLocation location,
bool returnFinalTarget = false)
{
- if (Containers.TryGetValue(location,
+ if (_containers.TryGetValue(location,
out IStorageContainer? initialContainer) &&
initialContainer.LinkTarget != null)
{
IStorageLocation? nextLocation =
_fileSystem.Storage.GetLocation(initialContainer.LinkTarget);
- if (Containers.TryGetValue(nextLocation,
+ if (_containers.TryGetValue(nextLocation,
out IStorageContainer? container))
{
if (returnFinalTarget)
@@ -462,14 +462,14 @@ public bool TryAddContainer(
{
IStorageLocation? parentLocation = location.GetParent();
if (parentLocation is { IsRooted: false } &&
- !Containers.ContainsKey(parentLocation))
+ !_containers.ContainsKey(parentLocation))
{
throw ExceptionFactory.DirectoryNotFound(location.FullPath);
}
ChangeDescription? fileSystemChange = null;
- container = Containers.GetOrAdd(
+ container = _containers.GetOrAdd(
location,
_ =>
{
@@ -499,6 +499,19 @@ public bool TryAddContainer(
#endregion
+ ///
+ public override string ToString()
+ => $"directories: {_containers.Count(x => x.Value.Type == FileSystemTypes.Directory)}, files: {_containers.Count(x => x.Value.Type == FileSystemTypes.File)}";
+
+ ///
+ /// Returns an ordered list of all stored containers.
+ ///
+ internal IReadOnlyList GetContainers()
+ => _containers
+ .OrderBy(x => x.Key.FullPath)
+ .Select(x => x.Value)
+ .ToList();
+
private void CheckAndAdjustParentDirectoryTimes(IStorageLocation location)
{
IStorageContainer? parentContainer = GetContainer(location.GetParent());
@@ -535,7 +548,7 @@ private void CreateParents(MockFileSystem fileSystem, IStorageLocation location)
ChangeDescription? fileSystemChange = null;
IStorageLocation parentLocation =
_fileSystem.Storage.GetLocation(parentPath);
- _ = Containers.AddOrUpdate(
+ _ = _containers.AddOrUpdate(
parentLocation,
loc =>
{
@@ -571,7 +584,7 @@ private void CreateParents(MockFileSystem fileSystem, IStorageLocation location)
FileSystemTypes? sourceType,
List? rollbacks = null)
{
- if (!Containers.TryGetValue(source,
+ if (!_containers.TryGetValue(source,
out IStorageContainer? container))
{
return null;
@@ -615,16 +628,16 @@ private void CreateParents(MockFileSystem fileSystem, IStorageLocation location)
NotifyFilters.FileName,
destination,
source);
- if (Containers.TryRemove(source, out IStorageContainer? sourceContainer))
+ if (_containers.TryRemove(source, out IStorageContainer? sourceContainer))
{
if (overwrite &&
- Containers.TryRemove(destination,
+ _containers.TryRemove(destination,
out IStorageContainer? existingContainer))
{
existingContainer.ClearBytes();
}
- if (Containers.TryAdd(destination, sourceContainer))
+ if (_containers.TryAdd(destination, sourceContainer))
{
int bytesLength = sourceContainer.GetBytes().Length;
source.Drive?.ChangeUsedBytes(-1 * bytesLength);
@@ -638,7 +651,7 @@ private void CreateParents(MockFileSystem fileSystem, IStorageLocation location)
return destination;
}
- Containers.TryAdd(source, sourceContainer);
+ _containers.TryAdd(source, sourceContainer);
throw ExceptionFactory.CannotCreateFileWhenAlreadyExists(
sourceType == FileSystemTypes.Directory
? -2147024891
@@ -665,7 +678,7 @@ private void CreateParents(MockFileSystem fileSystem, IStorageLocation location)
}
nextLocation = _fileSystem.Storage.GetLocation(container.LinkTarget);
- if (!Containers.TryGetValue(nextLocation,
+ if (!_containers.TryGetValue(nextLocation,
out IStorageContainer? nextContainer))
{
return nextLocation;
@@ -692,7 +705,7 @@ private void ThrowIfParentDoesNotExist(IStorageLocation location,
if (parentLocation != null &&
_fileSystem.Path.GetPathRoot(parentLocation.FullPath) !=
parentLocation.FullPath &&
- !Containers.TryGetValue(parentLocation, out _))
+ !_containers.TryGetValue(parentLocation, out _))
{
throw exceptionCallback(parentLocation);
}
diff --git a/Source/Testably.Abstractions.Testing/TimeProvider.cs b/Source/Testably.Abstractions.Testing/TimeProvider.cs
index f24a0e922..6c94e4084 100644
--- a/Source/Testably.Abstractions.Testing/TimeProvider.cs
+++ b/Source/Testably.Abstractions.Testing/TimeProvider.cs
@@ -14,7 +14,7 @@ public static class TimeProvider
///
public static ITimeProvider Now()
{
- return new TimeProviderMock(DateTime.UtcNow);
+ return new TimeProviderMock(DateTime.UtcNow, "Now");
}
///
@@ -26,7 +26,7 @@ public static ITimeProvider Random()
{
DateTime randomTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
.AddSeconds(RandomFactory.Shared.Next());
- return new TimeProviderMock(randomTime);
+ return new TimeProviderMock(randomTime, "Random");
}
///
@@ -34,6 +34,6 @@ public static ITimeProvider Random()
///
public static ITimeProvider Use(DateTime time)
{
- return new TimeProviderMock(time);
+ return new TimeProviderMock(time, "Fixed");
}
}
diff --git a/Source/Testably.Abstractions.Testing/TimeSystem/TimeProviderMock.cs b/Source/Testably.Abstractions.Testing/TimeSystem/TimeProviderMock.cs
index 55438f0c9..c33347633 100644
--- a/Source/Testably.Abstractions.Testing/TimeSystem/TimeProviderMock.cs
+++ b/Source/Testably.Abstractions.Testing/TimeSystem/TimeProviderMock.cs
@@ -8,11 +8,13 @@ namespace Testably.Abstractions.Testing.TimeSystem;
internal sealed class TimeProviderMock : ITimeProvider
{
private DateTime _now;
+ private readonly string _description;
private readonly object _lock = new();
- public TimeProviderMock(DateTime now)
+ public TimeProviderMock(DateTime now, string description)
{
_now = now;
+ _description = description;
}
#region ITimeProvider Members
@@ -57,4 +59,8 @@ public void SetTo(DateTime value)
}
#endregion
+
+ ///
+ public override string ToString()
+ => _description;
}