diff --git a/Directory.Packages.props b/Directory.Packages.props
index 80b727627..c1ee99a57 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -31,6 +31,7 @@
+
diff --git a/Source/Testably.Abstractions.AccessControl/Testably.Abstractions.AccessControl.csproj b/Source/Testably.Abstractions.AccessControl/Testably.Abstractions.AccessControl.csproj
index 72082860d..1db38b623 100644
--- a/Source/Testably.Abstractions.AccessControl/Testably.Abstractions.AccessControl.csproj
+++ b/Source/Testably.Abstractions.AccessControl/Testably.Abstractions.AccessControl.csproj
@@ -25,6 +25,9 @@
<_Parameter1>true
<_Parameter1_TypeName>System.Boolean
+
+ <_Parameter1>Testably.Abstractions.AccessControl.Tests
+
diff --git a/Source/Testably.Abstractions.Compression/Internal/ZipUtilities.cs b/Source/Testably.Abstractions.Compression/Internal/ZipUtilities.cs
index 0516470ca..ea3701804 100644
--- a/Source/Testably.Abstractions.Compression/Internal/ZipUtilities.cs
+++ b/Source/Testably.Abstractions.Compression/Internal/ZipUtilities.cs
@@ -7,6 +7,8 @@ namespace Testably.Abstractions.Internal;
internal static class ZipUtilities
{
+ private const string SearchPattern = "*";
+
internal static IZipArchiveEntry CreateEntryFromFile(
IZipArchive destination,
string sourceFileName,
@@ -28,7 +30,7 @@ internal static IZipArchiveEntry CreateEntryFromFile(
DateTime lastWrite =
destination.FileSystem.File.GetLastWriteTime(sourceFileName);
- if (lastWrite.Year < 1980 || lastWrite.Year > 2107)
+ if (lastWrite.Year is < 1980 or > 2107)
{
lastWrite = new DateTime(1980, 1, 1, 0, 0, 0);
}
@@ -79,7 +81,7 @@ internal static void CreateFromDirectory(IFileSystem fileSystem,
}
foreach (IFileSystemInfo file in di
- .EnumerateFileSystemInfos("*", SearchOption.AllDirectories))
+ .EnumerateFileSystemInfos(SearchPattern, SearchOption.AllDirectories))
{
directoryIsEmpty = false;
diff --git a/Source/Testably.Abstractions.Compression/Testably.Abstractions.Compression.csproj b/Source/Testably.Abstractions.Compression/Testably.Abstractions.Compression.csproj
index 6c3a31a50..b49aa471b 100644
--- a/Source/Testably.Abstractions.Compression/Testably.Abstractions.Compression.csproj
+++ b/Source/Testably.Abstractions.Compression/Testably.Abstractions.Compression.csproj
@@ -20,4 +20,10 @@
+
+
+ <_Parameter1>Testably.Abstractions.Compression.Tests
+
+
+
diff --git a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs
index e331d5e42..1ec1e0ca4 100644
--- a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs
+++ b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs
@@ -512,6 +512,15 @@ internal IReadOnlyList GetContainers()
.Select(x => x.Value)
.ToList();
+ ///
+ /// Removes the drive with the given .
+ ///
+ internal IStorageDrive? RemoveDrive(string driveName)
+ {
+ _drives.TryRemove(driveName, out IStorageDrive? drive);
+ return drive;
+ }
+
private void CheckAndAdjustParentDirectoryTimes(IStorageLocation location)
{
IStorageContainer? parentContainer = GetContainer(location.GetParent());
diff --git a/Source/Testably.Abstractions.Testing/Storage/LocationExtensions.cs b/Source/Testably.Abstractions.Testing/Storage/LocationExtensions.cs
index d9350087a..dcb7fb617 100644
--- a/Source/Testably.Abstractions.Testing/Storage/LocationExtensions.cs
+++ b/Source/Testably.Abstractions.Testing/Storage/LocationExtensions.cs
@@ -8,7 +8,8 @@ internal static class LocationExtensions
{
[return: NotNullIfNotNull("location")]
public static IStorageLocation? ThrowIfNotFound(
- this IStorageLocation? location, MockFileSystem fileSystem,
+ this IStorageLocation? location,
+ MockFileSystem fileSystem,
Action fileNotFoundException,
Action? directoryNotFoundException = null)
{
@@ -38,7 +39,8 @@ internal static class LocationExtensions
}
public static IStorageLocation ThrowExceptionIfNotFound(
- this IStorageLocation location, MockFileSystem fileSystem,
+ this IStorageLocation location,
+ MockFileSystem fileSystem,
bool allowMissingFile = false,
Func? onDirectoryNotFound = null,
Func? onFileNotFound = null)
diff --git a/Tests/Testably.Abstractions.AccessControl.Tests/AccessControlHelperTests.cs b/Tests/Testably.Abstractions.AccessControl.Tests/AccessControlHelperTests.cs
new file mode 100644
index 000000000..6d1e368ee
--- /dev/null
+++ b/Tests/Testably.Abstractions.AccessControl.Tests/AccessControlHelperTests.cs
@@ -0,0 +1,48 @@
+using System.IO;
+
+namespace Testably.Abstractions.AccessControl.Tests;
+
+// ReSharper disable once PartialTypeWithSinglePart
+public abstract partial class AccessControlHelperTests
+ : FileSystemTestBase
+ where TFileSystem : IFileSystem
+{
+ [Fact]
+ public void GetExtensibilityOrThrow_DirectoryInfo_ShouldNotThrow()
+ {
+ IDirectoryInfo sut = FileSystem.DirectoryInfo.New("foo");
+
+ Exception? exception = Record.Exception(() =>
+ {
+ sut.GetExtensibilityOrThrow();
+ });
+
+ exception.Should().BeNull();
+ }
+
+ [Fact]
+ public void GetExtensibilityOrThrow_FileSystemStream_ShouldNotThrow()
+ {
+ FileSystemStream sut = FileSystem.FileStream.New("foo", FileMode.Create);
+
+ Exception? exception = Record.Exception(() =>
+ {
+ sut.GetExtensibilityOrThrow();
+ });
+
+ exception.Should().BeNull();
+ }
+
+ [Fact]
+ public void GetExtensibilityOrThrow_FileInfo_ShouldNotThrow()
+ {
+ IFileInfo sut = FileSystem.FileInfo.New("foo");
+
+ Exception? exception = Record.Exception(() =>
+ {
+ sut.GetExtensibilityOrThrow();
+ });
+
+ exception.Should().BeNull();
+ }
+}
diff --git a/Tests/Testably.Abstractions.AccessControl.Tests/Internal/AccessControlHelperTests.cs b/Tests/Testably.Abstractions.AccessControl.Tests/Internal/AccessControlHelperTests.cs
new file mode 100644
index 000000000..83168ce0e
--- /dev/null
+++ b/Tests/Testably.Abstractions.AccessControl.Tests/Internal/AccessControlHelperTests.cs
@@ -0,0 +1,126 @@
+using NSubstitute;
+using System.IO;
+using Testably.Abstractions.Helpers;
+
+namespace Testably.Abstractions.AccessControl.Tests.Internal;
+
+public sealed class AccessControlHelperTests
+{
+ [Fact]
+ public void ThrowIfMissing_MissingDirectoryInfo_ShouldThrowDirectoryNotFoundException()
+ {
+ MockFileSystem fileSystem = new();
+ IDirectoryInfo sut = fileSystem.DirectoryInfo.New("foo");
+
+ Exception? exception = Record.Exception(() =>
+ {
+ sut.ThrowIfMissing();
+ });
+
+ exception.Should().BeOfType()
+ .Which.HResult.Should().Be(-2147024893);
+ exception!.Message.Should().Contain($"'{sut.FullName}'");
+ }
+
+ [Fact]
+ public void ThrowIfMissing_ExistingDirectoryInfo_ShouldNotThrow()
+ {
+ MockFileSystem fileSystem = new();
+ IDirectoryInfo sut = fileSystem.DirectoryInfo.New("foo");
+ fileSystem.Directory.CreateDirectory("foo");
+
+ Exception? exception = Record.Exception(() =>
+ {
+ sut.ThrowIfMissing();
+ });
+
+ exception.Should().BeNull();
+ }
+
+ [Fact]
+ public void ThrowIfMissing_MissingFileInfo_ShouldThrowFileNotFoundException()
+ {
+ MockFileSystem fileSystem = new();
+ IFileInfo sut = fileSystem.FileInfo.New("foo");
+
+ Exception? exception = Record.Exception(() =>
+ {
+ sut.ThrowIfMissing();
+ });
+
+ exception.Should().BeOfType()
+ .Which.HResult.Should().Be(-2147024894);
+ exception!.Message.Should().Contain($"'{sut.FullName}'");
+ }
+
+ [Fact]
+ public void ThrowIfMissing_ExistingFileInfo_ShouldNotThrow()
+ {
+ MockFileSystem fileSystem = new();
+ IFileInfo sut = fileSystem.FileInfo.New("foo");
+ fileSystem.File.WriteAllText("foo", "some content");
+
+ Exception? exception = Record.Exception(() =>
+ {
+ sut.ThrowIfMissing();
+ });
+
+ exception.Should().BeNull();
+ }
+
+ [Fact]
+ public void GetExtensibilityOrThrow_CustomDirectoryInfo_ShouldThrowNotSupportedException()
+ {
+ IDirectoryInfo? sut = Substitute.For();
+
+ Exception? exception = Record.Exception(() =>
+ {
+ sut.GetExtensibilityOrThrow();
+ });
+
+ exception.Should().BeOfType()
+ .Which.Message.Should()
+ .Contain(nameof(IFileSystemExtensibility)).And
+ .Contain(sut.GetType().Name);
+ }
+
+ [Fact]
+ public void GetExtensibilityOrThrow_CustomFileSystemStream_ShouldThrowNotSupportedException()
+ {
+ FileSystemStream sut = new CustomFileSystemStream();
+
+ Exception? exception = Record.Exception(() =>
+ {
+ sut.GetExtensibilityOrThrow();
+ });
+
+ exception.Should().BeOfType()
+ .Which.Message.Should()
+ .Contain(nameof(IFileSystemExtensibility)).And
+ .Contain(sut.GetType().Name);
+ }
+
+ [Fact]
+ public void GetExtensibilityOrThrow_CustomFileInfo_ShouldThrowNotSupportedException()
+ {
+ IFileInfo? sut = Substitute.For();
+
+ Exception? exception = Record.Exception(() =>
+ {
+ sut.GetExtensibilityOrThrow();
+ });
+
+ exception.Should().BeOfType()
+ .Which.Message.Should()
+ .Contain(nameof(IFileSystemExtensibility)).And
+ .Contain(sut.GetType().Name);
+ }
+
+ private class CustomFileSystemStream : FileSystemStream
+ {
+ ///
+ public CustomFileSystemStream() : base(Null, ".", false)
+ {
+ }
+ }
+}
diff --git a/Tests/Testably.Abstractions.AccessControl.Tests/Testably.Abstractions.AccessControl.Tests.csproj b/Tests/Testably.Abstractions.AccessControl.Tests/Testably.Abstractions.AccessControl.Tests.csproj
index de9aba0c6..2b163db76 100644
--- a/Tests/Testably.Abstractions.AccessControl.Tests/Testably.Abstractions.AccessControl.Tests.csproj
+++ b/Tests/Testably.Abstractions.AccessControl.Tests/Testably.Abstractions.AccessControl.Tests.csproj
@@ -12,9 +12,8 @@
-
+
+
diff --git a/Tests/Testably.Abstractions.Compression.Tests/Internal/ExecuteTests.cs b/Tests/Testably.Abstractions.Compression.Tests/Internal/ExecuteTests.cs
new file mode 100644
index 000000000..99af40b2b
--- /dev/null
+++ b/Tests/Testably.Abstractions.Compression.Tests/Internal/ExecuteTests.cs
@@ -0,0 +1,34 @@
+using Testably.Abstractions.Internal;
+
+namespace Testably.Abstractions.Compression.Tests.Internal;
+
+public sealed class ExecuteTests
+{
+ [Fact]
+ public void WhenRealFileSystem_MockFileSystem_ShouldExecuteOnMockFileSystem()
+ {
+ bool onRealFileSystemExecuted = false;
+ bool onMockFileSystemExecuted = false;
+ MockFileSystem fileSystem = new();
+ Execute.WhenRealFileSystem(fileSystem,
+ () => onRealFileSystemExecuted = true,
+ () => onMockFileSystemExecuted = true);
+
+ onRealFileSystemExecuted.Should().BeFalse();
+ onMockFileSystemExecuted.Should().BeTrue();
+ }
+
+ [Fact]
+ public void WhenRealFileSystem_RealFileSystem_ShouldExecuteOnRealFileSystem()
+ {
+ bool onRealFileSystemExecuted = false;
+ bool onMockFileSystemExecuted = false;
+ RealFileSystem fileSystem = new();
+ Execute.WhenRealFileSystem(fileSystem,
+ () => onRealFileSystemExecuted = true,
+ () => onMockFileSystemExecuted = true);
+
+ onRealFileSystemExecuted.Should().BeTrue();
+ onMockFileSystemExecuted.Should().BeFalse();
+ }
+}
diff --git a/Tests/Testably.Abstractions.Compression.Tests/ZipArchiveEntry/ExtensionTests.cs b/Tests/Testably.Abstractions.Compression.Tests/ZipArchiveEntry/ExtensionTests.cs
index 2fdc5e131..a22f7691b 100644
--- a/Tests/Testably.Abstractions.Compression.Tests/ZipArchiveEntry/ExtensionTests.cs
+++ b/Tests/Testably.Abstractions.Compression.Tests/ZipArchiveEntry/ExtensionTests.cs
@@ -105,6 +105,37 @@ public void ExtractToFile_WithOverwrite_ShouldOverwriteExistingFile()
.Should().Be("FooFooFoo");
}
+
+ [SkippableTheory]
+ [InlineData("2000-01-01T12:14:15")]
+ [InlineData("1980-01-01T00:00:00")]
+ [InlineData("2107-12-31T23:59:59")]
+ public void ExtractToFile_LastWriteTime_ShouldBeCopiedFromFile(string lastWriteTimeString)
+ {
+ DateTime lastWriteTime = DateTime.Parse(lastWriteTimeString);
+ FileSystem.Initialize()
+ .WithSubdirectory("foo")
+ .WithSubdirectory("bar").Initialized(s => s
+ .WithFile("bar.txt"));
+ FileSystem.File.WriteAllText("bar/foo.txt", "FooFooFoo");
+ FileSystem.File.SetLastWriteTime("bar/foo.txt", lastWriteTime);
+ FileSystem.ZipFile()
+ .CreateFromDirectory("foo", "destination.zip", CompressionLevel.NoCompression,
+ false);
+ using FileSystemStream stream = FileSystem.File.Open("destination.zip",
+ FileMode.Open, FileAccess.ReadWrite);
+ IZipArchive archive = FileSystem.ZipArchive().New(stream, ZipArchiveMode.Update);
+ archive.CreateEntryFromFile("bar/foo.txt", "foo/bar.txt",
+ CompressionLevel.NoCompression);
+ IZipArchiveEntry entry = archive.Entries.Single();
+
+ entry.ExtractToFile("bar/bar.txt", true);
+
+ FileSystem.File.ReadAllText("bar/bar.txt")
+ .Should().Be("FooFooFoo");
+ FileSystem.FileInfo.New("bar/bar.txt").LastWriteTime.Should().Be(lastWriteTime);
+ }
+
[SkippableFact]
public void ExtractToFile_IncorrectEntryType_ShouldThrowIOException()
{
diff --git a/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializerOptionsTests.cs b/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializerOptionsTests.cs
new file mode 100644
index 000000000..4274b71f6
--- /dev/null
+++ b/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializerOptionsTests.cs
@@ -0,0 +1,15 @@
+#if NET6_0_OR_GREATER
+#endif
+
+namespace Testably.Abstractions.Testing.Tests;
+
+public sealed class FileSystemInitializerOptionsTests
+{
+ [Fact]
+ public void InitializeTempDirectory_ShouldBeInitializedToTrue()
+ {
+ FileSystemInitializerOptions sut = new();
+
+ sut.InitializeTempDirectory.Should().BeTrue();
+ }
+}
diff --git a/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemExtensionsTests.cs b/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemExtensionsTests.cs
new file mode 100644
index 000000000..fcfb71226
--- /dev/null
+++ b/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemExtensionsTests.cs
@@ -0,0 +1,21 @@
+using Testably.Abstractions.Testing.Helpers;
+using Testably.Abstractions.Testing.Storage;
+
+namespace Testably.Abstractions.Testing.Tests;
+
+public class MockFileSystemExtensionsTests
+{
+ [Fact]
+ public void GetDefaultDrive_WithoutDrives_ShouldThrowInvalidOperationException()
+ {
+ MockFileSystem fileSystem = new();
+ (fileSystem.Storage as InMemoryStorage)?.RemoveDrive(string.Empty.PrefixRoot());
+
+ Exception? exception = Record.Exception(() =>
+ {
+ fileSystem.GetDefaultDrive();
+ });
+
+ exception.Should().BeOfType();
+ }
+}
diff --git a/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs b/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs
index 0c18004d9..cea274681 100644
--- a/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs
+++ b/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs
@@ -106,6 +106,17 @@ public void FileSystemMock_ShouldInitializeDriveFromCurrentDirectory()
drives.Should().Contain(d => d.Name == driveName);
}
+ [SkippableFact]
+ public void ToString_ShouldContainStorageInformation()
+ {
+ MockFileSystem sut = new();
+ sut.File.WriteAllText("foo", "bar");
+
+ string result = sut.ToString();
+
+ result.Should().Contain("directories: 0, files: 1");
+ }
+
[SkippableTheory]
[AutoData]
public void WithAccessControl_Denied_CreateDirectoryShouldThrowIOException(
diff --git a/Tests/Testably.Abstractions.Testing.Tests/MockRandomSystemTests.cs b/Tests/Testably.Abstractions.Testing.Tests/MockRandomSystemTests.cs
new file mode 100644
index 000000000..f075c7b49
--- /dev/null
+++ b/Tests/Testably.Abstractions.Testing.Tests/MockRandomSystemTests.cs
@@ -0,0 +1,14 @@
+namespace Testably.Abstractions.Testing.Tests;
+
+public class MockRandomSystemTests
+{
+ [Fact]
+ public void ToString_ShouldContainMockRandomSystem()
+ {
+ MockRandomSystem randomSystem = new();
+
+ string result = randomSystem.ToString();
+
+ result.Should().Contain(nameof(MockRandomSystem));
+ }
+}
diff --git a/Tests/Testably.Abstractions.Testing.Tests/MockTimeSystemTests.cs b/Tests/Testably.Abstractions.Testing.Tests/MockTimeSystemTests.cs
index 36ff5f92d..6599b30b2 100644
--- a/Tests/Testably.Abstractions.Testing.Tests/MockTimeSystemTests.cs
+++ b/Tests/Testably.Abstractions.Testing.Tests/MockTimeSystemTests.cs
@@ -1,5 +1,6 @@
using System.Threading;
using System.Threading.Tasks;
+using Testably.Abstractions.Testing.Tests.TestHelpers;
namespace Testably.Abstractions.Testing.Tests;
@@ -89,4 +90,38 @@ public void Sleep_LessThanInfiniteTimeSpan_ShouldThrowArgumentOutOfRangeExceptio
exception.Should().BeOfType();
}
+
+ [Fact]
+ public void ToString_WithFixedContainer_ShouldContainTimeProvider()
+ {
+ DateTime now = TimeTestHelper.GetRandomTime();
+ MockTimeSystem timeSystem = new(TimeProvider.Use(now));
+
+ string result = timeSystem.ToString();
+
+ result.Should().Contain("Fixed");
+ result.Should().Contain($"{now.ToUniversalTime()}Z");
+ }
+
+ [Fact]
+ public void ToString_WithNowContainer_ShouldContainTimeProvider()
+ {
+ MockTimeSystem timeSystem = new(TimeProvider.Now());
+
+ string result = timeSystem.ToString();
+
+ result.Should().Contain("Now");
+ result.Should().Contain($"{timeSystem.DateTime.UtcNow}Z");
+ }
+
+ [Fact]
+ public void ToString_WithRandomContainer_ShouldContainTimeProvider()
+ {
+ MockTimeSystem timeSystem = new(TimeProvider.Random());
+
+ string result = timeSystem.ToString();
+
+ result.Should().Contain("Random");
+ result.Should().Contain($"{timeSystem.DateTime.UtcNow}Z");
+ }
}
diff --git a/Tests/Testably.Abstractions.Testing.Tests/Storage/InMemoryContainerTests.cs b/Tests/Testably.Abstractions.Testing.Tests/Storage/InMemoryContainerTests.cs
index 92fb2c8f7..4968d41c2 100644
--- a/Tests/Testably.Abstractions.Testing.Tests/Storage/InMemoryContainerTests.cs
+++ b/Tests/Testably.Abstractions.Testing.Tests/Storage/InMemoryContainerTests.cs
@@ -1,4 +1,5 @@
using System.IO;
+using System.Linq;
using Testably.Abstractions.Testing.FileSystem;
using Testably.Abstractions.Testing.Storage;
using Testably.Abstractions.Testing.Tests.TestHelpers;
@@ -100,6 +101,18 @@ public void AdjustAttributes_ShouldHaveReparsePointAttributeWhenLinkTargetIsNotN
}
#endif
+ [Theory]
+ [AutoData]
+ public void Container_ShouldProvideCorrectTimeAndFileSystem(string path)
+ {
+ MockFileSystem fileSystem = new();
+ IStorageLocation location = InMemoryLocation.New(null, path);
+ IStorageContainer sut = InMemoryContainer.NewFile(location, fileSystem);
+
+ sut.FileSystem.Should().BeSameAs(fileSystem);
+ sut.TimeSystem.Should().BeSameAs(fileSystem.TimeSystem);
+ }
+
[Theory]
[AutoData]
public void Decrypt_Encrypted_ShouldDecryptBytes(
@@ -177,6 +190,41 @@ public void Encrypt_ShouldEncryptBytes(
fileContainer.GetBytes().Should().NotBeEquivalentTo(bytes);
}
+ [Theory]
+ [AutoData]
+ public void RequestAccess_ToString_DeleteAccess_ShouldContainAccessAndShare(string path,
+ FileAccess access, FileShare share)
+ {
+ MockFileSystem fileSystem = new();
+ fileSystem.Initialize()
+ .WithFile(path);
+ IStorageLocation location = fileSystem.Storage.GetLocation(path);
+ IStorageContainer sut = InMemoryContainer.NewFile(location, fileSystem);
+
+ IStorageAccessHandle result = sut.RequestAccess(access, share, true);
+
+ result.ToString().Should().NotContain(access.ToString());
+ result.ToString().Should().Contain("Delete");
+ result.ToString().Should().Contain(share.ToString());
+ }
+
+ [Theory]
+ [AutoData]
+ public void RequestAccess_ToString_ShouldContainAccessAndShare(string path, FileAccess access,
+ FileShare share)
+ {
+ MockFileSystem fileSystem = new();
+ fileSystem.Initialize()
+ .WithFile(path);
+ IStorageLocation location = fileSystem.Storage.GetLocation(path);
+ IStorageContainer sut = InMemoryContainer.NewFile(location, fileSystem);
+
+ IStorageAccessHandle result = sut.RequestAccess(access, share);
+
+ result.ToString().Should().Contain(access.ToString());
+ result.ToString().Should().Contain(share.ToString());
+ }
+
[Theory]
[AutoData]
public void RequestAccess_WithoutDrive_ShouldThrowDirectoryNotFoundException(
@@ -215,48 +263,60 @@ public void TimeContainer_Time_Set_WithUnspecifiedKind_ShouldSetToProvidedKind(
[Theory]
[AutoData]
- public void Container_ShouldProvideCorrectTimeAndFileSystem(string path)
+ public void TimeContainer_ToString_ShouldReturnUtcTime(
+ string path, DateTime time)
{
+ time = DateTime.SpecifyKind(time, DateTimeKind.Local);
+ string expectedString = time.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ssZ");
MockFileSystem fileSystem = new();
IStorageLocation location = InMemoryLocation.New(null, path);
- IStorageContainer sut = InMemoryContainer.NewFile(location, fileSystem);
+ IStorageContainer fileContainer = InMemoryContainer.NewFile(location, fileSystem);
- sut.FileSystem.Should().BeSameAs(fileSystem);
- sut.TimeSystem.Should().BeSameAs(fileSystem.TimeSystem);
+ fileContainer.CreationTime.Set(time, DateTimeKind.Unspecified);
+
+ string? result = fileContainer.CreationTime.ToString();
+
+ result.Should().Be(expectedString);
}
- [Theory]
- [AutoData]
- public void RequestAccess_ToString_ShouldContainAccessAndShare(string path, FileAccess access,
- FileShare share)
+ [Fact]
+ public void ToString_Directory_ShouldIncludePath()
{
MockFileSystem fileSystem = new();
- fileSystem.Initialize()
- .WithFile(path);
- IStorageLocation location = fileSystem.Storage.GetLocation(path);
- IStorageContainer sut = InMemoryContainer.NewFile(location, fileSystem);
+ string expectedPath = fileSystem.Path.GetFullPath("foo");
+ fileSystem.Directory.CreateDirectory(expectedPath);
+ IStorageContainer sut = fileSystem.StorageContainers.Last();
- IStorageAccessHandle result = sut.RequestAccess(access, share);
+ string? result = sut.ToString();
- result.ToString().Should().Contain(access.ToString());
- result.ToString().Should().Contain(share.ToString());
+ result.Should().Be($"{expectedPath}: Directory");
}
[Theory]
[AutoData]
- public void RequestAccess_ToString_DeleteAccess_ShouldContainAccessAndShare(string path,
- FileAccess access, FileShare share)
+ public void ToString_File_ShouldIncludePathAndFileSize(byte[] bytes)
{
MockFileSystem fileSystem = new();
- fileSystem.Initialize()
- .WithFile(path);
- IStorageLocation location = fileSystem.Storage.GetLocation(path);
- IStorageContainer sut = InMemoryContainer.NewFile(location, fileSystem);
+ string expectedPath = fileSystem.Path.GetFullPath("foo.txt");
+ fileSystem.File.WriteAllBytes(expectedPath, bytes);
+ IStorageContainer sut = fileSystem.StorageContainers.Single();
- IStorageAccessHandle result = sut.RequestAccess(access, share, true);
+ string? result = sut.ToString();
- result.ToString().Should().NotContain(access.ToString());
- result.ToString().Should().Contain("Delete");
- result.ToString().Should().Contain(share.ToString());
+ result.Should().Be($"{expectedPath}: File ({bytes.Length} bytes)");
+ }
+
+ [Fact]
+ public void ToString_UnknownContainer_ShouldIncludePath()
+ {
+ MockFileSystem fileSystem = new();
+ string expectedPath = fileSystem.Path.GetFullPath("foo");
+ IStorageLocation location = InMemoryLocation.New(null, expectedPath);
+ IStorageContainer sut = new InMemoryContainer(FileSystemTypes.DirectoryOrFile, location,
+ fileSystem);
+
+ string? result = sut.ToString();
+
+ result.Should().Be($"{expectedPath}: Unknown Container");
}
}
diff --git a/Tests/Testably.Abstractions.Testing.Tests/Storage/LocationExtensionsTests.cs b/Tests/Testably.Abstractions.Testing.Tests/Storage/LocationExtensionsTests.cs
new file mode 100644
index 000000000..f396bff81
--- /dev/null
+++ b/Tests/Testably.Abstractions.Testing.Tests/Storage/LocationExtensionsTests.cs
@@ -0,0 +1,118 @@
+using System.IO;
+using Testably.Abstractions.Testing.Storage;
+
+namespace Testably.Abstractions.Testing.Tests.Storage;
+
+public sealed class LocationExtensionsTests
+{
+ [SkippableFact]
+ public void ThrowExceptionIfNotFound_MissingDirectory_ShouldThrowDirectoryNotFoundException()
+ {
+ MockFileSystem fileSystem = new();
+ IStorageLocation location = fileSystem.Storage.GetLocation("foo/bar.txt");
+
+ Exception? exception = Record.Exception(() =>
+ {
+ location.ThrowExceptionIfNotFound(fileSystem);
+ });
+
+ exception.Should().BeOfType();
+ }
+
+ [SkippableTheory]
+ [AutoData]
+ public void
+ ThrowExceptionIfNotFound_MissingDirectory_WithCustomCallback_ShouldThrowExceptionFromCallback(
+ Exception expectedException)
+ {
+ MockFileSystem fileSystem = new();
+ IStorageLocation location = fileSystem.Storage.GetLocation("foo/bar.txt");
+
+ Exception? exception = Record.Exception(() =>
+ {
+ location.ThrowExceptionIfNotFound(fileSystem,
+ onDirectoryNotFound: _ => expectedException);
+ });
+
+ exception.Should().BeSameAs(expectedException);
+ }
+
+ [SkippableFact]
+ public void ThrowExceptionIfNotFound_MissingFile_ShouldThrowFileNotFoundException()
+ {
+ MockFileSystem fileSystem = new();
+ IStorageLocation location = fileSystem.Storage.GetLocation("foo.txt");
+
+ Exception? exception = Record.Exception(() =>
+ {
+ location.ThrowExceptionIfNotFound(fileSystem);
+ });
+
+ exception.Should().BeOfType();
+ }
+
+ [SkippableTheory]
+ [AutoData]
+ public void
+ ThrowExceptionIfNotFound_MissingFile_WithCustomCallback_ShouldThrowExceptionFromCallback(
+ Exception expectedException)
+ {
+ MockFileSystem fileSystem = new();
+ IStorageLocation location = fileSystem.Storage.GetLocation("foo");
+
+ Exception? exception = Record.Exception(() =>
+ {
+ location.ThrowExceptionIfNotFound(fileSystem, onFileNotFound: _ => expectedException);
+ });
+
+ exception.Should().BeSameAs(expectedException);
+ }
+
+ [SkippableTheory]
+ [AutoData]
+ public void ThrowIfNotFound_MissingDirectory_ShouldExecuteFileNotFoundAction(
+ Exception expectedException)
+ {
+ MockFileSystem fileSystem = new();
+ IStorageLocation location = fileSystem.Storage.GetLocation("foo/bar.txt");
+
+ Exception? exception = Record.Exception(() =>
+ {
+ location.ThrowIfNotFound(fileSystem, () => { },
+ directoryNotFoundException: () => throw expectedException);
+ });
+
+ exception.Should().BeSameAs(expectedException);
+ }
+
+ [SkippableTheory]
+ [AutoData]
+ public void ThrowIfNotFound_MissingFile_ShouldExecuteFileNotFoundAction(
+ Exception expectedException)
+ {
+ MockFileSystem fileSystem = new();
+ IStorageLocation location = fileSystem.Storage.GetLocation("foo");
+
+ Exception? exception = Record.Exception(() =>
+ {
+ location.ThrowIfNotFound(fileSystem, () => throw expectedException);
+ });
+
+ exception.Should().BeSameAs(expectedException);
+ }
+
+ [SkippableTheory]
+ [AutoData]
+ public void ThrowIfNotFound_Null_ShouldExecuteFileNotFoundAction(Exception expectedException)
+ {
+ MockFileSystem fileSystem = new();
+ IStorageLocation? location = null;
+
+ Exception? exception = Record.Exception(() =>
+ {
+ location.ThrowIfNotFound(fileSystem, () => throw expectedException);
+ });
+
+ exception.Should().BeSameAs(expectedException);
+ }
+}
diff --git a/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/TimerMockTests.cs b/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/TimerMockTests.cs
index c01444846..9deba7b05 100644
--- a/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/TimerMockTests.cs
+++ b/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/TimerMockTests.cs
@@ -109,7 +109,8 @@ public void Dispose_WithUnknownWaitHandle_ShouldThrowNotSupportedException()
timer.Dispose(waitHandle);
});
- exception.Should().BeOfType();
+ exception.Should().BeOfType()
+ .Which.Message.Should().Contain(typeof(DummyWaitHandle).ToString());
}
[Fact]
@@ -217,6 +218,7 @@ public void Wait_InvalidExecutionCount_ShouldThrowArgumentOutOfRangeException()
exception.Should().BeOfType()
.Which.ParamName.Should().Be("executionCount");
+ exception!.Message.Should().Contain("Execution count must be greater than zero.");
}
[SkippableFact]
diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/Directory/CreateDirectoryTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/Directory/CreateDirectoryTests.cs
index f7f07919f..6b16919bc 100644
--- a/Tests/Testably.Abstractions.Tests/FileSystem/Directory/CreateDirectoryTests.cs
+++ b/Tests/Testably.Abstractions.Tests/FileSystem/Directory/CreateDirectoryTests.cs
@@ -24,7 +24,7 @@ public void CreateDirectory_AlreadyExisting_ShouldDoNothing(string path)
[SkippableTheory]
[AutoData]
- public void CreateDirectory_ReadOnlyParent_ShouldStillCreateDirectory(string parent,
+ public void CreateDirectory_ReadOnlyParent_ShouldStillCreateDirectoryUnderWindows(string parent,
string subdirectory)
{
string subdirectoryPath = FileSystem.Path.Combine(parent, subdirectory);