Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ jobs:

test-examples:
name: Test (Examples)
runs-on: ubuntu-latest
runs-on: windows-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ jobs:

test-examples:
name: Test (Examples)
runs-on: ubuntu-latest
runs-on: windows-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public void InitializeFileSystemInSpecifiedCurrentDirectory(string currentDirect
public void InitializeFileSystemInTheRootDirectory()
{
MockFileSystem fileSystem = new();
fileSystem.Initialize()
fileSystem.InitializeIn("base-directory")
.WithASubdirectory()
.WithSubdirectory("foo")
.Initialized(s => s
Expand All @@ -63,19 +63,17 @@ public void InitializeFileSystemInTheRootDirectory()
public void InitializeFileSystemWithUncDrive()
{
MockFileSystem fileSystem = new();
fileSystem.DriveInfo.GetDrives().Should().HaveCount(1);
var initialDriveCount = fileSystem.DriveInfo.GetDrives().Length;

fileSystem.WithUncDrive(@"//unc-server");

fileSystem.DriveInfo.GetDrives().Should().HaveCount(1);
fileSystem.DriveInfo.GetDrives().Should().HaveCount(initialDriveCount);
IDriveInfo drive = fileSystem.DriveInfo.New(@"//unc-server");
drive.IsReady.Should().BeTrue();

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
fileSystem.WithDrive(@"D:");

fileSystem.DriveInfo.GetDrives().Should().HaveCount(2);
fileSystem.DriveInfo.GetDrives().Should().HaveCount(initialDriveCount);
}
}

Expand All @@ -97,7 +95,7 @@ public void LimitAvailableSpaceOnDrives()

// Limit the main drive to 200 bytes
fileSystem.WithDrive(drive => drive.SetTotalSize(200));
IDriveInfo mainDrive = fileSystem.DriveInfo.GetDrives().Single();
IDriveInfo mainDrive = fileSystem.GetDefaultDrive();
mainDrive.AvailableFreeSpace.Should().Be(200);

fileSystem.File.WriteAllBytes("foo", firstFileContent);
Expand Down
2 changes: 1 addition & 1 deletion Examples/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<Reference Include="Testably.Abstractions.Testing">
<HintPath>..\..\..\Build\Binaries\net7.0\Testably.Abstractions.Testing.dll</HintPath>
</Reference>
<PackageReference Include="TestableIO.System.IO.Abstractions" Version="19.2.26" />
</ItemGroup>

<ItemGroup Condition="'$(UseFileReferenceToTestablyLibraries)' != 'True'">
Expand All @@ -36,7 +37,6 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="TestableIO.System.IO.Abstractions" Version="19.2.26" />
<PackageReference Include="AutoFixture.Xunit2" Version="4.18.0" />
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="Moq" Version="4.18.4" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<RootNamespace>Testably.Abstractions.Examples.DriveManagement.Tests</RootNamespace>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using FluentAssertions;
using System;
using System.IO;
using System.IO.Abstractions;
using Testably.Abstractions.Testing;
using Xunit;

namespace Testably.Abstractions.Examples.DriveManagement.Tests;

public class DriveManagementTests
{
[Fact]
public void DefineAdditionalDrive()
{
MockFileSystem fileSystem = new MockFileSystem()
.WithDrive("T:\\");

fileSystem.File.WriteAllText("T:\\foo.txt", "bar");

fileSystem.DriveInfo.GetDrives()
.Should().Contain(d => d.Name == "T:\\");
fileSystem.File.Exists("T:\\foo.txt").Should().BeTrue();
}

[Fact]
public void ChangeDefaultDrive()
{
MockFileSystem fileSystem = new MockFileSystem()
.InitializeIn("U:\\sub\\directory")
.FileSystem;

fileSystem.File.WriteAllText("foo.txt", "bar");

fileSystem.DriveInfo.GetDrives()
.Should().Contain(d => d.Name == "U:\\");
fileSystem.File.Exists("U:\\sub\\directory\\foo.txt")
.Should().BeTrue();
}

[Fact]
public void LimitAvailableDriveSize()
{
MockFileSystem fileSystem = new MockFileSystem()
.WithDrive("C:\\", d => d.SetTotalSize(100));
IDriveInfo drive = fileSystem.GetDefaultDrive();
byte[] largeFileContent = new byte[90];
Random.Shared.NextBytes(largeFileContent);

drive.AvailableFreeSpace.Should().Be(100);
fileSystem.File.WriteAllText("foo.txt", "This is a text with 29 bytes.");
drive.AvailableFreeSpace.Should().Be(71);
fileSystem.File.AppendAllText("foo.txt", "Another 17 bytes.");
drive.AvailableFreeSpace.Should().Be(54);

Exception? exception = Record.Exception(() =>
{
fileSystem.File.WriteAllBytes("bar.bin", largeFileContent);
});
exception.Should().BeOfType<IOException>();

drive.AvailableFreeSpace.Should().Be(54);
fileSystem.File.Delete("foo.txt");
drive.AvailableFreeSpace.Should().Be(100);
fileSystem.File.WriteAllBytes("bar.bin", largeFileContent);
drive.AvailableFreeSpace.Should().Be(10);
}
}
8 changes: 8 additions & 0 deletions Examples/DriveManagement/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Drive Management
This example illustrates how to define multiple drives and use space management on individual drives.

The test project shows some common use cases:
- Add and use an additional drive in the `MockFileSystem`
- Change the default drive (or directory) used for relative paths
- Define and limit the maximum total size of a drive.
When this limit is exhausted, an `IOException` is thrown for all file operations that write file content.
23 changes: 14 additions & 9 deletions Examples/Examples.sln
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SafeFileHandle", "SafeFileH
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SafeFileHandle.Tests", "SafeFileHandle\SafeFileHandle.Tests\SafeFileHandle.Tests.csproj", "{63F48EEB-F2A8-4A26-BEFF-A766EE2793DA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Timer", "Timer", "{B19433E1-9187-4A98-A2F9-4A84366CD2DC}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DriveManagement", "DriveManagement", "{B19433E1-9187-4A98-A2F9-4A84366CD2DC}"
ProjectSection(SolutionItems) = preProject
Timer\README.md = Timer\README.md
DriveManagement\README.md = DriveManagement\README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Timer", "Timer\Timer\Timer.csproj", "{1CD374DB-500B-4C49-93CC-2C3FB38475E7}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DriveManagement.Tests", "DriveManagement\DriveManagement.Tests\DriveManagement.Tests.csproj", "{C58E47F9-84D6-4D1C-8348-D72159597996}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Timer.Tests", "Timer\Timer.Tests\Timer.Tests.csproj", "{C58E47F9-84D6-4D1C-8348-D72159597996}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileSystemWatcher", "FileSystemWatcher", "{F05DF273-2CC0-4E23-81BF-AA48E8142144}"
ProjectSection(SolutionItems) = preProject
FileSystemWatcher\README.md = FileSystemWatcher\README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileSystemWatcher.Tests", "FileSystemWatcher\FileSystemWatcher.Tests\FileSystemWatcher.Tests.csproj", "{BD564722-10AE-481F-B13C-A1C319731E7D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -109,14 +114,14 @@ Global
{63F48EEB-F2A8-4A26-BEFF-A766EE2793DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{63F48EEB-F2A8-4A26-BEFF-A766EE2793DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{63F48EEB-F2A8-4A26-BEFF-A766EE2793DA}.Release|Any CPU.Build.0 = Release|Any CPU
{1CD374DB-500B-4C49-93CC-2C3FB38475E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1CD374DB-500B-4C49-93CC-2C3FB38475E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1CD374DB-500B-4C49-93CC-2C3FB38475E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1CD374DB-500B-4C49-93CC-2C3FB38475E7}.Release|Any CPU.Build.0 = Release|Any CPU
{C58E47F9-84D6-4D1C-8348-D72159597996}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C58E47F9-84D6-4D1C-8348-D72159597996}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C58E47F9-84D6-4D1C-8348-D72159597996}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C58E47F9-84D6-4D1C-8348-D72159597996}.Release|Any CPU.Build.0 = Release|Any CPU
{BD564722-10AE-481F-B13C-A1C319731E7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD564722-10AE-481F-B13C-A1C319731E7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD564722-10AE-481F-B13C-A1C319731E7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD564722-10AE-481F-B13C-A1C319731E7D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -132,8 +137,8 @@ Global
{916E6165-38B4-4B3D-A5A6-077113F98D34} = {AC5FCC95-CA9C-4A14-9330-945EF3A9BF9A}
{1D1F0C68-D9F9-4D34-BD8A-2E4EC41D9790} = {E116185F-52D4-48B4-BF55-D3BE0905805D}
{63F48EEB-F2A8-4A26-BEFF-A766EE2793DA} = {E116185F-52D4-48B4-BF55-D3BE0905805D}
{1CD374DB-500B-4C49-93CC-2C3FB38475E7} = {B19433E1-9187-4A98-A2F9-4A84366CD2DC}
{C58E47F9-84D6-4D1C-8348-D72159597996} = {B19433E1-9187-4A98-A2F9-4A84366CD2DC}
{BD564722-10AE-481F-B13C-A1C319731E7D} = {F05DF273-2CC0-4E23-81BF-AA48E8142144}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D439CFB9-E2DD-4DF9-AA90-F321B50EAD16}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<RootNamespace>Testably.Abstractions.Examples.FileSystemWatcher.Tests</RootNamespace>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using FluentAssertions;
using System.IO;
using System.IO.Abstractions;
using System.Threading;
using Testably.Abstractions.Testing;
using Xunit;

namespace Testably.Abstractions.Examples.FileSystemWatcher.Tests;

public class FileSystemWatcherTests
{
[Fact]
public void EnableRaisingEvents_ShouldTriggerWhenFileSystemChanges()
{
MockFileSystem fileSystem = new();
fileSystem.Initialize().WithSubdirectory("foo");
FileSystemEventArgs? result = null;
ManualResetEventSlim ms = new();
using IFileSystemWatcher fileSystemWatcher =
fileSystem.FileSystemWatcher.New(".");
fileSystemWatcher.Deleted += (_, eventArgs) =>
{
result = eventArgs;
ms.Set();
};
fileSystemWatcher.NotifyFilter = NotifyFilters.DirectoryName;
fileSystemWatcher.EnableRaisingEvents = true;

fileSystem.Directory.Delete("foo");

ms.Wait(1000).Should().BeTrue();

result.Should().NotBeNull();
}
}
5 changes: 5 additions & 0 deletions Examples/FileSystemWatcher/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Working with the `FileSystemWatcher`
This example illustrates how to use the mocked [`FileSystemWatcher`](https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher).

In the example we listen to a `Deleted` event and set a [`ManualResetEventSlim`](https://learn.microsoft.com/de-de/dotnet/api/system.threading.manualreseteventslim).
After deleting a directory this event is triggered within 1s.
10 changes: 6 additions & 4 deletions Examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ This is an overview of the provided examples for "Testably.Abstractions".
- **[Configuration](Configuration/README.md)**
This example illustrates how the testing libraries can be configured in unit tests.

- **[Drive Management](DriveManagement/README.md)**
This example illustrates how to define multiple drives and use space management on individual drives.

- **[File-System Watcher](FileSystemWatcher/README.md)**
This example illustrates how to use the mocked [`FileSystemWatcher`](https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher).

- **[SafeFileHandle](SafeFileHandle/README.md)**
This example illustrates how to work with `SafeFileHandle` in the `MockFileSystem`.

Expand All @@ -15,9 +21,5 @@ This is an overview of the provided examples for "Testably.Abstractions".
In a scenario with multiple threads running in parallel, these would each influence each other differently in the mocked instance than "in the real world".
This example illustrates how to implement a thread-aware time provider for such a scenario.

- **[Timer](Timer/README.md)**
Example implementation of a timer on top of `ITimeSystem`.
It uses the `ITask.Delay` methods, to implementing a customer timer class which can be unit tested.

- **[Zip-File](ZipFile/README.md)**
This example highlights how to use the `IFileSystem` to compress and uncompress directories using `System.IO.Compression`.
17 changes: 0 additions & 17 deletions Examples/Timer/README.md

This file was deleted.

50 changes: 0 additions & 50 deletions Examples/Timer/Timer.Tests/TimeSystemExtensionsTests.cs

This file was deleted.

11 changes: 0 additions & 11 deletions Examples/Timer/Timer.Tests/Timer.Tests.csproj

This file was deleted.

Loading