diff --git a/Source/Testably.Abstractions.Testing/FileSystemInitializerExtensions.cs b/Source/Testably.Abstractions.Testing/FileSystemInitializerExtensions.cs index edefa8047..322b54633 100644 --- a/Source/Testably.Abstractions.Testing/FileSystemInitializerExtensions.cs +++ b/Source/Testably.Abstractions.Testing/FileSystemInitializerExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Reflection; using Testably.Abstractions.Testing.Helpers; @@ -189,7 +189,27 @@ public static IDirectoryCleaner SetCurrentDirectoryToEmptyTemporaryDirectory( this IFileSystem fileSystem, string? prefix = null, Action? logger = null) { using IDisposable release = fileSystem.IgnoreStatistics(); - return new DirectoryCleaner(fileSystem, prefix, logger); + return new DirectoryCleaner(fileSystem, prefix, logger, true); + } + + /// + /// Creates a new empty temporary directory without changing the current directory. + /// + /// The file system. + /// + /// A prefix to use for the temporary directory.
+ /// This simplifies matching directories to tests. + /// + /// (optional) A callback to log the cleanup process. + /// + /// A that will + /// force delete all content in the temporary directory on dispose. + /// + public static IDirectoryCleaner CreateEmptyTemporaryDirectory( + this IFileSystem fileSystem, string? prefix = null, Action? logger = null) + { + using IDisposable release = fileSystem.IgnoreStatistics(); + return new DirectoryCleaner(fileSystem, prefix, logger, false); } private static void CopyDirectory( diff --git a/Source/Testably.Abstractions.Testing/Initializer/DirectoryCleaner.cs b/Source/Testably.Abstractions.Testing/Initializer/DirectoryCleaner.cs index cd546abbe..d3f7cb54a 100644 --- a/Source/Testably.Abstractions.Testing/Initializer/DirectoryCleaner.cs +++ b/Source/Testably.Abstractions.Testing/Initializer/DirectoryCleaner.cs @@ -18,7 +18,7 @@ internal sealed class DirectoryCleaner : IDirectoryCleaner private readonly Action? _logger; private readonly string _pathToDelete; - public DirectoryCleaner(IFileSystem fileSystem, string? prefix, Action? logger) + public DirectoryCleaner(IFileSystem fileSystem, string? prefix, Action? logger, bool setCurrentDirectory) { _fileSystem = fileSystem; _logger = logger; @@ -26,6 +26,10 @@ public DirectoryCleaner(IFileSystem fileSystem, string? prefix, Action? fileSystem.ExecuteOrDefault(), prefix ?? ""); BasePath = _fileSystem.Path.Combine(_pathToDelete, EmptyDirectoryName); + if (setCurrentDirectory) + { + SetCurrentDirectoryToTestDirectory(BasePath); + } } #region IDirectoryCleaner Members @@ -189,13 +193,18 @@ private string InitializeTestDirectory(Execute execute, string prefix) $"Could not create current directory '{basePath}' for tests"); } - _logger?.Invoke($"Use '{basePath}' as current directory."); - _fileSystem.Directory.SetCurrentDirectory(basePath); + return pathToDelete; + } + + private void SetCurrentDirectoryToTestDirectory(string testDirectoryPath) + { + _logger?.Invoke($"Use '{testDirectoryPath}' as current directory."); + _fileSystem.Directory.SetCurrentDirectory(testDirectoryPath); for (int i = 0; i <= 10 && !string.Equals( _fileSystem.Directory.GetCurrentDirectory(), - basePath, + testDirectoryPath, _fileSystem.ExecuteOrDefault().StringComparisonMode); i++) { @@ -204,13 +213,11 @@ private string InitializeTestDirectory(Execute execute, string prefix) if (!string.Equals( _fileSystem.Directory.GetCurrentDirectory(), - basePath, + testDirectoryPath, _fileSystem.ExecuteOrDefault().StringComparisonMode)) { throw new TestingException( - $"Could not set current directory to '{basePath}' for tests"); + $"Could not set current directory to '{testDirectoryPath}' for tests"); } - - return pathToDelete; } } diff --git a/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializer/DirectoryCleanerTests.cs b/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializer/DirectoryCleanerTests.cs index aa1eaa4dc..bcfc047ca 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializer/DirectoryCleanerTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializer/DirectoryCleanerTests.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using Testably.Abstractions.Testing.Initializer; @@ -117,4 +117,59 @@ public async Task InitializeBasePath_ShouldCreateDirectoryAndLogBasePath() await That(sut.Directory.Exists(currentDirectory)).IsTrue(); await That(receivedLogs).Contains(m => m.Contains($"'{currentDirectory}'", StringComparison.Ordinal)); } + + [Test] + public async Task CreateEmptyTemporaryDirectory_Dispose_ShouldForceDeleteDirectory() + { + MockFileSystem sut = new(); + List receivedLogs = []; + IDirectoryCleaner directoryCleaner = + sut.CreateEmptyTemporaryDirectory(logger: m => receivedLogs.Add(m)); + string basePath = directoryCleaner.BasePath; + + directoryCleaner.Dispose(); + + await That(sut.Directory.Exists(basePath)).IsFalse(); + await That(receivedLogs).Contains("Cleanup was successful :-)"); + } + + [Test] + public async Task CreateEmptyTemporaryDirectory_Dispose_ShouldNotChangeCurrentDirectory() + { + MockFileSystem sut = new(); + string currentDirectory = sut.Directory.GetCurrentDirectory(); + IDirectoryCleaner directoryCleaner = + sut.CreateEmptyTemporaryDirectory(); + + directoryCleaner.Dispose(); + + await That(sut.Directory.GetCurrentDirectory()).IsEqualTo(currentDirectory); + } + + [Test] + public async Task CreateEmptyTemporaryDirectory_ShouldCreateDirectory() + { + MockFileSystem sut = new(); + List receivedLogs = []; + + using IDirectoryCleaner directoryCleaner = + sut.CreateEmptyTemporaryDirectory(logger: m => receivedLogs.Add(m)); + + await That(sut.Statistics.TotalCount).IsEqualTo(0); + await That(sut.Directory.Exists(directoryCleaner.BasePath)).IsTrue(); + await That(receivedLogs).DoesNotContain(m => + m.Contains("as current directory", StringComparison.Ordinal)); + } + + [Test] + public async Task CreateEmptyTemporaryDirectory_ShouldNotChangeCurrentDirectory() + { + MockFileSystem sut = new(); + string currentDirectory = sut.Directory.GetCurrentDirectory(); + + using IDirectoryCleaner directoryCleaner = + sut.CreateEmptyTemporaryDirectory(); + + await That(sut.Directory.GetCurrentDirectory()).IsEqualTo(currentDirectory); + } }