diff --git a/source/StoneAge.Data.FileSystem.Tests/FileSystemTests.cs b/source/StoneAge.Data.FileSystem.Tests/FileSystemTests.cs index 77d96a4..9dddd38 100644 --- a/source/StoneAge.Data.FileSystem.Tests/FileSystemTests.cs +++ b/source/StoneAge.Data.FileSystem.Tests/FileSystemTests.cs @@ -1,694 +1,1180 @@ -using System; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using FluentAssertions; -using NUnit.Framework; -using StoneAge.FileStore.Domain; - -namespace StoneAge.FileStore.Tests -{ - [TestFixture] - public class FileSystemTests - { - [TestFixture] - class Write - { - [Test] - public async Task WhenFileAndPathValid_ExpectFileWritten() - { - //---------------Arrange------------------- - var path = Path.GetTempPath(); - var fileName = Guid.NewGuid()+".csv"; - var document = Create_CsvFile(fileName); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = await sut.Write(path, document); - //---------------Assert----------------------- - var fileWritten = File.Exists(result.FullFilePath); - result.HadError.Should().BeFalse(); - fileWritten.Should().BeTrue(); - } - - [Test] - public async Task WhenFileAndPathContainNewSubDirectories_ExpectFileWritten() - { - //---------------Arrange------------------- - var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); - var fileName = Guid.NewGuid() + ".csv"; - var document = Create_CsvFile(fileName); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = await sut.Write(path, document); - //---------------Assert----------------------- - var fileWritten = File.Exists(Path.Combine(path, fileName)); - result.HadError.Should().BeFalse(); - fileWritten.Should().BeTrue(); - } - - [TestCase(" ")] - [TestCase("")] - [TestCase(null)] - public async Task WhenPathContainsNullOrWhiteSpace_ExpectErrorMessage(string path) - { - //---------------Arrange------------------- - var document = Create_CsvFile("test.csv"); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = await sut.Write(path, document); - //---------------Assert----------------------- - result.HadError.Should().BeTrue(); - } - - [TestCase("abc")] - [TestCase("~f0")] - public async Task WhenRelativePath_ExpectFileWritten(string path) - { - //---------------Arrange------------------- - var document = Create_CsvFile("test.csv"); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = await sut.Write(path, document); - //---------------Assert----------------------- - var fileWritten = File.Exists(Path.Combine(path, "test.csv")); - result.HadError.Should().BeFalse(); - fileWritten.Should().BeTrue(); - } - - [Test] - public async Task WhenFileAndPathValid_ExpectFullFilePathReturned() - { - //---------------Arrange------------------- - var path = Path.GetTempPath(); - var fileName = Guid.NewGuid() + ".csv"; - var document = Create_CsvFile(fileName); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = await sut.Write(path, document); - //---------------Assert----------------------- - var expected = Path.Combine(path, fileName); - result.FullFilePath.Should().Be(expected); - } - - [Test] - public async Task WhenFileExist_ExpectItOverWritten() - { - //---------------Arrange------------------- - var path = Path.GetTempPath(); - var fileName = Guid.NewGuid() + ".csv"; - Write_File_Contents_For_Testing(path, fileName); - var document = Create_CsvFile(fileName); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = await sut.Write(path, document); - //---------------Assert----------------------- - var contents = File.ReadAllBytes(result.FullFilePath); - contents.Should().BeEquivalentTo(new byte[5]); - } - - [Test] - public async Task WhenFileDataIsNull_ExpectErrorMessage() - { - //---------------Arrange------------------- - var path = Path.GetTempPath(); - var fileName = Guid.NewGuid() + ".txt"; - var document = new DocumentBuilder() - .With_Name(fileName) - .With_Bytes(null) // explicitly set null data - .Create_Document(); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = await sut.Write(path, document); - //---------------Assert----------------------- - result.HadError.Should().BeTrue(); - result.ErrorMessages.Should().Contain("No file data provided; cannot write file."); - } - - private static void Write_File_Contents_For_Testing(string path, string fileName) - { - File.WriteAllText(Path.Combine(path, fileName), "test line"); - } - } - - [TestFixture] - class Append - { - [Test] - public async Task WhenFileAndPathValid_ExpectFileWritten() - { - //---------------Arrange------------------- - var path = Path.GetTempPath(); - var fileName = Guid.NewGuid() + ".csv"; - var document = Create_CsvFile(fileName); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = await sut.Append(path, document); - //---------------Assert----------------------- - var fileWritten = File.Exists(result.FullFilePath); - result.HadError.Should().BeFalse(); - fileWritten.Should().BeTrue(); - } - - [Test] - public async Task WhenFileAndPathContainNewSubDirectories_ExpectFileWritten() - { - //---------------Arrange------------------- - var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); - var fileName = Guid.NewGuid() + ".csv"; - var document = Create_CsvFile(fileName); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = await sut.Write(path, document); - //---------------Assert----------------------- - var fileWritten = File.Exists(Path.Combine(path, fileName)); - result.HadError.Should().BeFalse(); - fileWritten.Should().BeTrue(); - } - - [TestCase(" ")] - [TestCase("")] - [TestCase(null)] - public async Task WhenPathContainsNullOrWhiteSpace_ExpectErrorMessage(string path) - { - //---------------Arrange------------------- - var document = Create_CsvFile("test.csv"); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = await sut.Write(path, document); - //---------------Assert----------------------- - result.HadError.Should().BeTrue(); - } - - [TestCase("abc")] - [TestCase("~f0")] - public async Task WhenRelativePath_ExpectFileWritten(string path) - { - //---------------Arrange------------------- - var document = Create_CsvFile("test.csv"); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = await sut.Write(path, document); - //---------------Assert----------------------- - var fileWritten = File.Exists(Path.Combine(path, "test.csv")); - result.HadError.Should().BeFalse(); - fileWritten.Should().BeTrue(); - } - - [Test] - public async Task WhenFileAndPathValid_ExpectFullFilePathReturned() - { - //---------------Arrange------------------- - var path = Path.GetTempPath(); - var fileName = Guid.NewGuid() + ".csv"; - var document = Create_CsvFile(fileName); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = await sut.Write(path, document); - //---------------Assert----------------------- - var expected = Path.Combine(path, fileName); - result.FullFilePath.Should().Be(expected); - } - } - - [TestFixture] - class List - { - [Test] - public void WhenDirectoryExist_ExpectContents() - { - //---------------Arrange------------------- - var path = Path.GetTempPath(); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = sut.List(path); - //---------------Assert----------------------- - result.Count().Should().BeGreaterThanOrEqualTo(1); - } - - [Test] - public void WhenFilePassedIn_ExpectEmptyList() - { - //---------------Arrange------------------- - var path = Path.GetTempFileName(); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = sut.List(path); - //---------------Assert----------------------- - result.Should().BeEmpty(); - } - - [TestCase(" ")] - [TestCase("")] - [TestCase(null)] - public void WhenNullOrWhiteSpaceDirectory_ExpectEmptyList(string path) - { - //---------------Arrange------------------- - var sut = new FileSystem(); - //---------------Act---------------------- - var result = sut.List(path); - //---------------Assert----------------------- - result.Should().BeEmpty(); - } - } - - [TestFixture] - class Exists - { - [Test] - public void WhenFileDoesNotExist_ExpectFalse() - { - //---------------Arrange------------------- - var path = Create_Missing_File(); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = sut.Exists(path); - //---------------Assert----------------------- - result.Should().BeFalse(); - } - - [Test] - public void WhenFileExist_ExpectTrue() - { - //---------------Arrange------------------- - var path = Create_File(); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = sut.Exists(path); - //---------------Assert----------------------- - result.Should().BeTrue(); - } - - [TestCase(" ")] - [TestCase("")] - [TestCase(null)] - public void WhenFileNullOrWhiteSpace_ExpectTrue(string path) - { - //---------------Arrange------------------- - var sut = new FileSystem(); - //---------------Act---------------------- - var result = sut.Exists(path); - //---------------Assert----------------------- - result.Should().BeFalse(); - } - - [Test] - public void WhenDirectoryExist_ExpectTrue() - { - //---------------Arrange------------------- - var path = Path.GetTempPath(); - - var sut = new FileSystem(); - //---------------Act---------------------- - var result = sut.Exists(path); - //---------------Assert----------------------- - result.Should().BeTrue(); - } - } - - [TestFixture] - class Delete - { - [Test] - public void WhenFileExist_ExpectItIsRemoved() - { - //---------------Arrange------------------- - var path = Create_File(); - - var sut = new FileSystem(); - //---------------Act---------------------- - sut.Delete(path); - //---------------Assert----------------------- - var fileExists = File.Exists(path); - fileExists.Should().BeFalse(); - } - - [Test] - public void WhenFileDoesNotExist_ExpectNothingToHappen() - { - //---------------Arrange------------------- - var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); - - var sut = new FileSystem(); - //---------------Act---------------------- - sut.Delete(path); - //---------------Assert----------------------- - var fileExists = File.Exists(path); - fileExists.Should().BeFalse(); - } - - [TestCase(" ")] - [TestCase("")] - [TestCase(null)] - public void WhenFileNullOrWhitespace_ExpectNoExceptionsThrown(string path) - { - //---------------Arrange------------------- - var sut = new FileSystem(); - //---------------Act---------------------- - Assert.DoesNotThrow(()=>sut.Delete(path)); - //---------------Assert----------------------- - var fileExists = File.Exists(path); - fileExists.Should().BeFalse(); - } - - [Test] - public void WhenDirectoryExist_ExpectItIsRemoved() - { - //---------------Arrange------------------- - var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); - Directory.CreateDirectory(path); - - var sut = new FileSystem(); - //---------------Act---------------------- - sut.Delete(path); - //---------------Assert----------------------- - var fileExists = File.Exists(path); - fileExists.Should().BeFalse(); - } - } - - [TestFixture] - class ReadDocument - { - [Test] - public void GivenFileExist_ExpectDocumentWithBytesReturned() - { - //---------------Arrange------------------- - var contents = "hi, this is some text for a file"; - - var path = Create_File(contents); - - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = sut.GetDocument(path); - //---------------Assert----------------------- - var expected = "hi, this is some text for a file"; - actual.ToString().Should().Be(expected); - } - - [Test] - public void GivenFileDoesExist_ExpectNullDocument() - { - //---------------Arrange------------------- - var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); - - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = sut.GetDocument(path); - //---------------Assert----------------------- - actual.Should().Be(FileSystem.NullDocument); - } - - [Test] - public void GivenNullPath_ExpectNullDocument() - { - //---------------Arrange------------------- - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = sut.GetDocument(null); - //---------------Assert----------------------- - actual.Should().Be(FileSystem.NullDocument); - } - } - - [TestFixture] - class Read - { - [Test] - public void GivenFileExist_ExpectDocumentWithBytesReturned() - { - //---------------Arrange------------------- - var contents = "hi, this is some text for a file"; - - var path = Create_File(contents); - - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = sut.Read(path); - //---------------Assert----------------------- - var expected = "hi, this is some text for a file"; - actual.ToString().Should().Be(expected); - } - - [Test] - public void GivenFileDoesExist_ExpectNullDocument() - { - //---------------Arrange------------------- - var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); - - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = sut.Read(path); - //---------------Assert----------------------- - actual.Should().Be(FileSystem.NullDocument); - } - - [Test] - public void GivenNullPath_ExpectNullDocument() - { - //---------------Arrange------------------- - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = sut.Read(null); - //---------------Assert----------------------- - actual.Should().Be(FileSystem.NullDocument); - } - } - - [TestFixture] - class ReadAllLines - { - [Test] - public async Task GivenFileExist_ExpectDocumentWithBytesReturned() - { - //---------------Arrange------------------- - var path = Create_File_With_Million_Lines(); - - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = await sut.ReadAllLines(path); - //---------------Assert----------------------- - var expectedFirst = "GlobalRank,TldRank,Domain,TLD,RefSubNets,RefIPs,IDN_Domain,IDN_TLD,PrevGlobalRank,PrevTldRank,PrevRefSubNets,PrevRefIPs"; - var expectedLast = "1000000,499336,alexandrevicenzi.com,com,341,364,alexandrevicenzi.com,com,982364,490355,345,368"; - var enumerable = actual as string[] ?? actual.ToArray(); - enumerable.Count().Should().Be(1000001); - enumerable.FirstOrDefault().Should().BeEquivalentTo(expectedFirst); - enumerable.LastOrDefault().Should().BeEquivalentTo(expectedLast); - } - - [Test] - public void GivenFileDoesExist_ExpectException() - { - //---------------Arrange------------------- - var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); - - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = Assert.ThrowsAsync(async ()=>await sut.ReadAllLines(path)); - //---------------Assert----------------------- - actual?.Message.Should().NotBeEmpty(); - } - - [Test] - public void GivenNullPath_ExpectException() - { - //---------------Arrange------------------- - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = Assert.ThrowsAsync(async () => await sut.ReadAllLines(null)); - //---------------Assert----------------------- - actual?.Message.Should().NotBeEmpty(); - } - } - - [TestFixture] - class Move - { - [Test] - public void GivenFileExist_ExpectItIsMoved() - { - //---------------Arrange------------------- - var file = Create_File(); - var newFileName = Create_File(); - File.Delete(newFileName); - - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = sut.Move(file, newFileName); - //---------------Assert----------------------- - var oldFileExist = File.Exists(file); - var newFileExist = File.Exists(newFileName); - - actual.Should().BeTrue(); - oldFileExist.Should().BeFalse(); - newFileExist.Should().BeTrue(); - } - - [Test] - public void GivenFileDoesNotExist_ExpectFalse() - { - //---------------Arrange------------------- - var file = Create_File(); - var newFileName = Create_File(); - File.Delete(newFileName); - File.Delete(file); - - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = sut.Move(file, newFileName); - //---------------Assert----------------------- - var oldFileExist = File.Exists(file); - var newFileExist = File.Exists(newFileName); - - actual.Should().BeFalse(); - oldFileExist.Should().BeFalse(); - newFileExist.Should().BeFalse(); - } - - [Test] - public void GivenDestinationFileExist_ExpectItIsNotMoved() - { - //---------------Arrange------------------- - var file = Create_File(); - var newFileName = Create_File(); - - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = sut.Move(file, newFileName); - //---------------Assert----------------------- - var oldFileExist = File.Exists(file); - var newFileExist = File.Exists(newFileName); - - actual.Should().BeFalse(); - oldFileExist.Should().BeTrue(); - newFileExist.Should().BeTrue(); - } - } - - [TestFixture] - class MoveWithOverwrite - { - [Test] - public void GivenDestinationFileExist_ExpectItIsMoved() - { - //---------------Arrange------------------- - var file = Create_File(); - var newFileName = Create_File(); - - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = sut.MoveWithOverwrite(file, newFileName); - //---------------Assert----------------------- - var oldFileExist = File.Exists(file); - var newFileExist = File.Exists(newFileName); - - actual.Should().BeTrue(); - oldFileExist.Should().BeFalse(); - newFileExist.Should().BeTrue(); - } - } - - [TestFixture] - class Rename - { - [Test] - public void GivenFileExist_ExpectItIsRenamed() - { - //---------------Arrange------------------- - var file = Create_File(); - var newFileName = $"{Guid.NewGuid()}-moved.txt"; - - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = sut.Rename(file, newFileName); - //---------------Assert----------------------- - var oldFileExist = File.Exists(file); - var newFileExist = File.Exists(Path.Combine(Path.GetTempPath(), newFileName)); - - actual.Should().BeTrue(); - oldFileExist.Should().BeFalse(); - newFileExist.Should().BeTrue(); - } - - [Test] - public void GivenFileDoesNotExist_ExpectFalse() - { - //---------------Arrange------------------- - var file = Create_File(); - var newFileName = $"{Guid.NewGuid()}-moved.txt"; - File.Delete(file); - - var sut = new FileSystem(); - //---------------Act---------------------- - var actual = sut.Rename(file, newFileName); - //---------------Assert----------------------- - var oldFileExist = File.Exists(file); - var newFileExist = File.Exists(Path.Combine(Path.GetTempPath(), newFileName)); - - actual.Should().BeFalse(); - oldFileExist.Should().BeFalse(); - newFileExist.Should().BeFalse(); - } - } - - private static string Create_File_With_Million_Lines() - { - var tmp = Path.GetTempPath(); - var path = Path.Combine(tmp, Guid.NewGuid().ToString()); - - var location = TestContext.CurrentContext.WorkDirectory; - var moveFilePath = Path.Combine(location, "majestic_million.csv"); - File.Move(moveFilePath, path); - - return path; - } - - private static string Create_File(string content) - { - var tmp = Path.GetTempPath(); - var path = Path.Combine(tmp, Guid.NewGuid().ToString()); - - File.WriteAllText(path, content); - - return path; - } - - private static string Create_File() - { - return Create_File(string.Empty); - } - - private static string Create_Missing_File() - { - var tmp = Path.GetTempPath(); - var path = Path.Combine(tmp, Guid.NewGuid().ToString()); - - return path; - } - - private static IDocument Create_CsvFile(string fileName) - { - var csvFile = new DocumentBuilder() - .With_Name(fileName) - .With_Bytes(new byte[5]) - .Create_Document(); - return csvFile; - } - - } -} +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using FluentAssertions; +using NUnit.Framework; +using StoneAge.FileStore.Domain; + +namespace StoneAge.FileStore.Tests +{ + [TestFixture] + public class FileSystemTests + { + [TestFixture] + class Write + { + [Test] + public async Task WhenFileAndPathValid_ExpectFileWritten() + { + //---------------Arrange------------------- + var path = Path.GetTempPath(); + var fileName = Guid.NewGuid()+".csv"; + var document = Create_CsvFile(fileName); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.Write(path, document); + //---------------Assert----------------------- + var fileWritten = File.Exists(result.FullFilePath); + result.HadError.Should().BeFalse(); + fileWritten.Should().BeTrue(); + } + + [Test] + public async Task WhenFileAndPathContainNewSubDirectories_ExpectFileWritten() + { + //---------------Arrange------------------- + var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); + var fileName = Guid.NewGuid() + ".csv"; + var document = Create_CsvFile(fileName); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.Write(path, document); + //---------------Assert----------------------- + var fileWritten = File.Exists(Path.Combine(path, fileName)); + result.HadError.Should().BeFalse(); + fileWritten.Should().BeTrue(); + } + + [TestCase(" ")] + [TestCase("")] + [TestCase(null)] + public async Task WhenPathContainsNullOrWhiteSpace_ExpectErrorMessage(string path) + { + //---------------Arrange------------------- + var document = Create_CsvFile("test.csv"); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.Write(path, document); + //---------------Assert----------------------- + result.HadError.Should().BeTrue(); + } + + [TestCase("abc")] + [TestCase("~f0")] + public async Task WhenRelativePath_ExpectFileWritten(string path) + { + //---------------Arrange------------------- + var document = Create_CsvFile("test.csv"); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.Write(path, document); + //---------------Assert----------------------- + var fileWritten = File.Exists(Path.Combine(path, "test.csv")); + result.HadError.Should().BeFalse(); + fileWritten.Should().BeTrue(); + } + + [Test] + public async Task WhenFileAndPathValid_ExpectFullFilePathReturned() + { + //---------------Arrange------------------- + var path = Path.GetTempPath(); + var fileName = Guid.NewGuid() + ".csv"; + var document = Create_CsvFile(fileName); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.Write(path, document); + //---------------Assert----------------------- + var expected = Path.Combine(path, fileName); + result.FullFilePath.Should().Be(expected); + } + + [Test] + public async Task WhenFileExist_ExpectItOverWritten() + { + //---------------Arrange------------------- + var path = Path.GetTempPath(); + var fileName = Guid.NewGuid() + ".csv"; + Write_File_Contents_For_Testing(path, fileName); + var document = Create_CsvFile(fileName); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.Write(path, document); + //---------------Assert----------------------- + var contents = File.ReadAllBytes(result.FullFilePath); + contents.Should().BeEquivalentTo(new byte[5]); + } + + [Test] + public async Task WhenFileDataIsNull_ExpectErrorMessage() + { + //---------------Arrange------------------- + var path = Path.GetTempPath(); + var fileName = Guid.NewGuid() + ".txt"; + var document = new DocumentBuilder() + .With_Name(fileName) + .With_Bytes(null) // explicitly set null data + .Create_Document(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.Write(path, document); + //---------------Assert----------------------- + result.HadError.Should().BeTrue(); + result.ErrorMessages.Should().Contain("No file data provided; cannot write file."); + } + + private static void Write_File_Contents_For_Testing(string path, string fileName) + { + File.WriteAllText(Path.Combine(path, fileName), "test line"); + } + } + + [TestFixture] + class Append + { + [Test] + public async Task WhenFileAndPathValid_ExpectFileWritten() + { + //---------------Arrange------------------- + var path = Path.GetTempPath(); + var fileName = Guid.NewGuid() + ".csv"; + var document = Create_CsvFile(fileName); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.Append(path, document); + //---------------Assert----------------------- + var fileWritten = File.Exists(result.FullFilePath); + result.HadError.Should().BeFalse(); + fileWritten.Should().BeTrue(); + } + + [Test] + public async Task WhenFileAndPathContainNewSubDirectories_ExpectFileWritten() + { + //---------------Arrange------------------- + var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); + var fileName = Guid.NewGuid() + ".csv"; + var document = Create_CsvFile(fileName); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.Append(path, document); + //---------------Assert----------------------- + var fileWritten = File.Exists(Path.Combine(path, fileName)); + result.HadError.Should().BeFalse(); + fileWritten.Should().BeTrue(); + } + + [TestCase(" ")] + [TestCase("")] + [TestCase(null)] + public async Task WhenPathContainsNullOrWhiteSpace_ExpectErrorMessage(string path) + { + //---------------Arrange------------------- + var document = Create_CsvFile("test.csv"); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.Append(path, document); + //---------------Assert----------------------- + result.HadError.Should().BeTrue(); + } + + [TestCase("abc")] + [TestCase("~f0")] + public async Task WhenRelativePath_ExpectFileWritten(string path) + { + //---------------Arrange------------------- + var document = Create_CsvFile("test.csv"); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.Append(path, document); + //---------------Assert----------------------- + var fileWritten = File.Exists(Path.Combine(path, "test.csv")); + result.HadError.Should().BeFalse(); + fileWritten.Should().BeTrue(); + } + + [Test] + public async Task WhenFileAndPathValid_ExpectFullFilePathReturned() + { + //---------------Arrange------------------- + var path = Path.GetTempPath(); + var fileName = Guid.NewGuid() + ".csv"; + var document = Create_CsvFile(fileName); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.Append(path, document); + //---------------Assert----------------------- + var expected = Path.Combine(path, fileName); + result.FullFilePath.Should().Be(expected); + } + } + + [TestFixture] + class List + { + [Test] + public void WhenDirectoryExist_ExpectContents() + { + //---------------Arrange------------------- + var path = Path.GetTempPath(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = sut.List(path); + //---------------Assert----------------------- + result.Count().Should().BeGreaterThanOrEqualTo(1); + } + + [Test] + public void WhenFilePassedIn_ExpectEmptyList() + { + //---------------Arrange------------------- + var path = Path.GetTempFileName(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = sut.List(path); + //---------------Assert----------------------- + result.Should().BeEmpty(); + } + + [TestCase(" ")] + [TestCase("")] + [TestCase(null)] + public void WhenNullOrWhiteSpaceDirectory_ExpectEmptyList(string path) + { + //---------------Arrange------------------- + var sut = new FileSystem(); + //---------------Act---------------------- + var result = sut.List(path); + //---------------Assert----------------------- + result.Should().BeEmpty(); + } + } + + [TestFixture] + class ListAsync + { + [Test] + public async Task WhenDirectoryExist_ExpectContents() + { + //---------------Arrange------------------- + var path = Path.GetTempPath(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.ListAsync(path); + //---------------Assert----------------------- + result.Count().Should().BeGreaterThanOrEqualTo(1); + } + + [Test] + public async Task WhenFilePassedIn_ExpectEmptyList() + { + //---------------Arrange------------------- + var path = Path.GetTempFileName(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.ListAsync(path); + //---------------Assert----------------------- + result.Should().BeEmpty(); + } + + [TestCase(" ")] + [TestCase("")] + [TestCase(null)] + public async Task WhenNullOrWhiteSpaceDirectory_ExpectEmptyList(string path) + { + //---------------Arrange------------------- + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.ListAsync(path); + //---------------Assert----------------------- + result.Should().BeEmpty(); + } + + [Test] + public async Task ShouldBehaveSameAsSyncVersion() + { + //---------------Arrange------------------- + var path = Path.GetTempPath(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var syncResult = sut.List(path); + var asyncResult = await sut.ListAsync(path); + //---------------Assert----------------------- + asyncResult.Should().BeEquivalentTo(syncResult); + } + } + + [TestFixture] + class Exists + { + [Test] + public void WhenFileDoesNotExist_ExpectFalse() + { + //---------------Arrange------------------- + var path = Create_Missing_File(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = sut.Exists(path); + //---------------Assert----------------------- + result.Should().BeFalse(); + } + + [Test] + public void WhenFileExist_ExpectTrue() + { + //---------------Arrange------------------- + var path = Create_File(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = sut.Exists(path); + //---------------Assert----------------------- + result.Should().BeTrue(); + } + + [TestCase(" ")] + [TestCase("")] + [TestCase(null)] + public void WhenFileNullOrWhiteSpace_ExpectTrue(string path) + { + //---------------Arrange------------------- + var sut = new FileSystem(); + //---------------Act---------------------- + var result = sut.Exists(path); + //---------------Assert----------------------- + result.Should().BeFalse(); + } + + [Test] + public void WhenDirectoryExist_ExpectTrue() + { + //---------------Arrange------------------- + var path = Path.GetTempPath(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = sut.Exists(path); + //---------------Assert----------------------- + result.Should().BeTrue(); + } + } + + [TestFixture] + class ExistsAsync + { + [Test] + public async Task WhenFileDoesNotExist_ExpectFalse() + { + //---------------Arrange------------------- + var path = Create_Missing_File(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.ExistsAsync(path); + //---------------Assert----------------------- + result.Should().BeFalse(); + } + + [Test] + public async Task WhenFileExist_ExpectTrue() + { + //---------------Arrange------------------- + var path = Create_File(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.ExistsAsync(path); + //---------------Assert----------------------- + result.Should().BeTrue(); + } + + [TestCase(" ")] + [TestCase("")] + [TestCase(null)] + public async Task WhenFileNullOrWhiteSpace_ExpectFalse(string path) + { + //---------------Arrange------------------- + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.ExistsAsync(path); + //---------------Assert----------------------- + result.Should().BeFalse(); + } + + [Test] + public async Task WhenDirectoryExist_ExpectTrue() + { + //---------------Arrange------------------- + var path = Path.GetTempPath(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var result = await sut.ExistsAsync(path); + //---------------Assert----------------------- + result.Should().BeTrue(); + } + + [Test] + public async Task ShouldBehaveSameAsSyncVersion() + { + //---------------Arrange------------------- + var path = Create_File(); + var nonExistingPath = Create_Missing_File(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var syncExistResult = sut.Exists(path); + var asyncExistResult = await sut.ExistsAsync(path); + var syncNonExistResult = sut.Exists(nonExistingPath); + var asyncNonExistResult = await sut.ExistsAsync(nonExistingPath); + //---------------Assert----------------------- + asyncExistResult.Should().Be(syncExistResult); + asyncNonExistResult.Should().Be(syncNonExistResult); + } + } + + [TestFixture] + class Delete + { + [Test] + public void WhenFileExist_ExpectItIsRemoved() + { + //---------------Arrange------------------- + var path = Create_File(); + + var sut = new FileSystem(); + //---------------Act---------------------- + sut.Delete(path); + //---------------Assert----------------------- + var fileExists = File.Exists(path); + fileExists.Should().BeFalse(); + } + + [Test] + public void WhenFileDoesNotExist_ExpectNothingToHappen() + { + //---------------Arrange------------------- + var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + + var sut = new FileSystem(); + //---------------Act---------------------- + sut.Delete(path); + //---------------Assert----------------------- + var fileExists = File.Exists(path); + fileExists.Should().BeFalse(); + } + + [TestCase(" ")] + [TestCase("")] + [TestCase(null)] + public void WhenFileNullOrWhitespace_ExpectNoExceptionsThrown(string path) + { + //---------------Arrange------------------- + var sut = new FileSystem(); + //---------------Act---------------------- + Assert.DoesNotThrow(()=>sut.Delete(path)); + //---------------Assert----------------------- + var fileExists = File.Exists(path); + fileExists.Should().BeFalse(); + } + + [Test] + public void WhenDirectoryExist_ExpectItIsRemoved() + { + //---------------Arrange------------------- + var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + Directory.CreateDirectory(path); + + var sut = new FileSystem(); + //---------------Act---------------------- + sut.Delete(path); + //---------------Assert----------------------- + var fileExists = File.Exists(path); + fileExists.Should().BeFalse(); + } + } + + [TestFixture] + class DeleteAsync + { + [Test] + public async Task WhenFileExist_ExpectItIsRemoved() + { + //---------------Arrange------------------- + var path = Create_File(); + + var sut = new FileSystem(); + //---------------Act---------------------- + await sut.DeleteAsync(path); + //---------------Assert----------------------- + var fileExists = File.Exists(path); + fileExists.Should().BeFalse(); + } + + [Test] + public async Task WhenFileDoesNotExist_ExpectNothingToHappen() + { + //---------------Arrange------------------- + var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + + var sut = new FileSystem(); + //---------------Act---------------------- + await sut.DeleteAsync(path); + //---------------Assert----------------------- + var fileExists = File.Exists(path); + fileExists.Should().BeFalse(); + } + + [TestCase(" ")] + [TestCase("")] + [TestCase(null)] + public async Task WhenFileNullOrWhitespace_ExpectNoExceptionsThrown(string path) + { + //---------------Arrange------------------- + var sut = new FileSystem(); + //---------------Act---------------------- + await sut.DeleteAsync(path); + //---------------Assert----------------------- + var fileExists = File.Exists(path); + fileExists.Should().BeFalse(); + } + + [Test] + public async Task WhenDirectoryExist_ExpectItIsRemoved() + { + //---------------Arrange------------------- + var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + Directory.CreateDirectory(path); + + var sut = new FileSystem(); + //---------------Act---------------------- + await sut.DeleteAsync(path); + //---------------Assert----------------------- + var fileExists = File.Exists(path); + fileExists.Should().BeFalse(); + } + + [Test] + public async Task ShouldBehaveSameAsSyncVersion() + { + //---------------Arrange------------------- + var path1 = Create_File(); + var path2 = Create_File(); + + var sut = new FileSystem(); + //---------------Act---------------------- + sut.Delete(path1); + await sut.DeleteAsync(path2); + //---------------Assert----------------------- + var syncFileExists = File.Exists(path1); + var asyncFileExists = File.Exists(path2); + syncFileExists.Should().BeFalse(); + asyncFileExists.Should().BeFalse(); + } + } + + [TestFixture] + class ReadDocument + { + [Test] + public void GivenFileExist_ExpectDocumentWithBytesReturned() + { + //---------------Arrange------------------- + var contents = "hi, this is some text for a file"; + + var path = Create_File(contents); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = sut.GetDocument(path); + //---------------Assert----------------------- + var expected = "hi, this is some text for a file"; + actual.ToString().Should().Be(expected); + } + + [Test] + public void GivenFileDoesExist_ExpectNullDocument() + { + //---------------Arrange------------------- + var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = sut.GetDocument(path); + //---------------Assert----------------------- + actual.Should().Be(FileSystem.NullDocument); + } + + [Test] + public void GivenNullPath_ExpectNullDocument() + { + //---------------Arrange------------------- + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = sut.GetDocument(null); + //---------------Assert----------------------- + actual.Should().Be(FileSystem.NullDocument); + } + } + + [TestFixture] + class GetDocumentAsync + { + [Test] + public async Task GivenFileExist_ExpectDocumentWithBytesReturned() + { + //---------------Arrange------------------- + var contents = "hi, this is some text for a file"; + + var path = Create_File(contents); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = await sut.GetDocumentAsync(path); + //---------------Assert----------------------- + var expected = "hi, this is some text for a file"; + actual.ToString().Should().Be(expected); + } + + [Test] + public async Task GivenFileDoesExist_ExpectNullDocument() + { + //---------------Arrange------------------- + var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = await sut.GetDocumentAsync(path); + //---------------Assert----------------------- + actual.Should().Be(FileSystem.NullDocument); + } + + [Test] + public async Task GivenNullPath_ExpectNullDocument() + { + //---------------Arrange------------------- + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = await sut.GetDocumentAsync(null); + //---------------Assert----------------------- + actual.Should().Be(FileSystem.NullDocument); + } + + [Test] + public async Task ShouldBehaveSameAsSyncVersion() + { + //---------------Arrange------------------- + var contents = "hi, this is some text for a file"; + var path = Create_File(contents); + + var sut = new FileSystem(); + //---------------Act---------------------- + var syncResult = sut.GetDocument(path); + var asyncResult = await sut.GetDocumentAsync(path); + //---------------Assert----------------------- + asyncResult.Name.Should().Be(syncResult.Name); + asyncResult.Data.Should().BeEquivalentTo(syncResult.Data); + } + } + + [TestFixture] + class Read + { + [Test] + public void GivenFileExist_ExpectDocumentWithBytesReturned() + { + //---------------Arrange------------------- + var contents = "hi, this is some text for a file"; + + var path = Create_File(contents); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = sut.Read(path); + //---------------Assert----------------------- + var expected = "hi, this is some text for a file"; + actual.ToString().Should().Be(expected); + } + + [Test] + public void GivenFileDoesExist_ExpectNullDocument() + { + //---------------Arrange------------------- + var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = sut.Read(path); + //---------------Assert----------------------- + actual.Should().Be(FileSystem.NullDocument); + } + + [Test] + public void GivenNullPath_ExpectNullDocument() + { + //---------------Arrange------------------- + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = sut.Read(null); + //---------------Assert----------------------- + actual.Should().Be(FileSystem.NullDocument); + } + } + + [TestFixture] + class ReadAllLines + { + [Test] + public async Task GivenFileExist_ExpectDocumentWithBytesReturned() + { + //---------------Arrange------------------- + var path = Create_File_With_Million_Lines(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = await sut.ReadAllLines(path); + //---------------Assert----------------------- + var expectedFirst = "GlobalRank,TldRank,Domain,TLD,RefSubNets,RefIPs,IDN_Domain,IDN_TLD,PrevGlobalRank,PrevTldRank,PrevRefSubNets,PrevRefIPs"; + var expectedLast = "1000000,499336,alexandrevicenzi.com,com,341,364,alexandrevicenzi.com,com,982364,490355,345,368"; + var enumerable = actual as string[] ?? actual.ToArray(); + enumerable.Count().Should().Be(1000001); + enumerable.FirstOrDefault().Should().BeEquivalentTo(expectedFirst); + enumerable.LastOrDefault().Should().BeEquivalentTo(expectedLast); + } + + [Test] + public void GivenFileDoesExist_ExpectException() + { + //---------------Arrange------------------- + var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = Assert.ThrowsAsync(async ()=>await sut.ReadAllLines(path)); + //---------------Assert----------------------- + actual?.Message.Should().NotBeEmpty(); + } + + [Test] + public void GivenNullPath_ExpectException() + { + //---------------Arrange------------------- + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = Assert.ThrowsAsync(async () => await sut.ReadAllLines(null)); + //---------------Assert----------------------- + actual?.Message.Should().NotBeEmpty(); + } + } + + [TestFixture] + class Move + { + [Test] + public void GivenFileExist_ExpectItIsMoved() + { + //---------------Arrange------------------- + var file = Create_File(); + var newFileName = Create_File(); + File.Delete(newFileName); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = sut.Move(file, newFileName); + //---------------Assert----------------------- + var oldFileExist = File.Exists(file); + var newFileExist = File.Exists(newFileName); + + actual.Should().BeTrue(); + oldFileExist.Should().BeFalse(); + newFileExist.Should().BeTrue(); + } + + [Test] + public void GivenFileDoesNotExist_ExpectFalse() + { + //---------------Arrange------------------- + var file = Create_File(); + var newFileName = Create_File(); + File.Delete(newFileName); + File.Delete(file); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = sut.Move(file, newFileName); + //---------------Assert----------------------- + var oldFileExist = File.Exists(file); + var newFileExist = File.Exists(newFileName); + + actual.Should().BeFalse(); + oldFileExist.Should().BeFalse(); + newFileExist.Should().BeFalse(); + } + + [Test] + public void GivenDestinationFileExist_ExpectItIsNotMoved() + { + //---------------Arrange------------------- + var file = Create_File(); + var newFileName = Create_File(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = sut.Move(file, newFileName); + //---------------Assert----------------------- + var oldFileExist = File.Exists(file); + var newFileExist = File.Exists(newFileName); + + actual.Should().BeFalse(); + oldFileExist.Should().BeTrue(); + newFileExist.Should().BeTrue(); + } + } + + [TestFixture] + class MoveAsync + { + [Test] + public async Task GivenFileExist_ExpectItIsMoved() + { + //---------------Arrange------------------- + var file = Create_File(); + var newFileName = Create_File(); + File.Delete(newFileName); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = await sut.MoveAsync(file, newFileName); + //---------------Assert----------------------- + var oldFileExist = File.Exists(file); + var newFileExist = File.Exists(newFileName); + + actual.Should().BeTrue(); + oldFileExist.Should().BeFalse(); + newFileExist.Should().BeTrue(); + } + + [Test] + public async Task GivenFileDoesNotExist_ExpectFalse() + { + //---------------Arrange------------------- + var file = Create_File(); + var newFileName = Create_File(); + File.Delete(newFileName); + File.Delete(file); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = await sut.MoveAsync(file, newFileName); + //---------------Assert----------------------- + var oldFileExist = File.Exists(file); + var newFileExist = File.Exists(newFileName); + + actual.Should().BeFalse(); + oldFileExist.Should().BeFalse(); + newFileExist.Should().BeFalse(); + } + + [Test] + public async Task GivenDestinationFileExist_ExpectItIsNotMoved() + { + //---------------Arrange------------------- + var file = Create_File(); + var newFileName = Create_File(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = await sut.MoveAsync(file, newFileName); + //---------------Assert----------------------- + var oldFileExist = File.Exists(file); + var newFileExist = File.Exists(newFileName); + + actual.Should().BeFalse(); + oldFileExist.Should().BeTrue(); + newFileExist.Should().BeTrue(); + } + + [Test] + public async Task ShouldBehaveSameAsSyncVersion() + { + //---------------Arrange------------------- + var file1 = Create_File(); + var file2 = Create_File(); + var newFileName1 = Create_File(); + var newFileName2 = Create_File(); + File.Delete(newFileName1); + File.Delete(newFileName2); + + var sut = new FileSystem(); + //---------------Act---------------------- + var syncResult = sut.Move(file1, newFileName1); + var asyncResult = await sut.MoveAsync(file2, newFileName2); + //---------------Assert----------------------- + syncResult.Should().BeTrue(); + asyncResult.Should().BeTrue(); + + File.Exists(file1).Should().BeFalse(); + File.Exists(file2).Should().BeFalse(); + File.Exists(newFileName1).Should().BeTrue(); + File.Exists(newFileName2).Should().BeTrue(); + } + } + + [TestFixture] + class MoveWithOverwrite + { + [Test] + public void GivenDestinationFileExist_ExpectItIsMoved() + { + //---------------Arrange------------------- + var file = Create_File(); + var newFileName = Create_File(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = sut.MoveWithOverwrite(file, newFileName); + //---------------Assert----------------------- + var oldFileExist = File.Exists(file); + var newFileExist = File.Exists(newFileName); + + actual.Should().BeTrue(); + oldFileExist.Should().BeFalse(); + newFileExist.Should().BeTrue(); + } + } + + [TestFixture] + class MoveWithOverwriteAsync + { + [Test] + public async Task GivenDestinationFileExist_ExpectItIsMoved() + { + //---------------Arrange------------------- + var file = Create_File(); + var newFileName = Create_File(); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = await sut.MoveWithOverwriteAsync(file, newFileName); + //---------------Assert----------------------- + var oldFileExist = File.Exists(file); + var newFileExist = File.Exists(newFileName); + + actual.Should().BeTrue(); + oldFileExist.Should().BeFalse(); + newFileExist.Should().BeTrue(); + } + + [Test] + public async Task GivenFileDoesNotExist_ExpectFalse() + { + //---------------Arrange------------------- + var file = Create_File(); + var newFileName = Create_File(); + File.Delete(file); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = await sut.MoveWithOverwriteAsync(file, newFileName); + //---------------Assert----------------------- + actual.Should().BeFalse(); + } + + [Test] + public async Task ShouldBehaveSameAsSyncVersion() + { + //---------------Arrange------------------- + var file1 = Create_File("test content 1"); + var file2 = Create_File("test content 2"); + var dest1 = Create_File("original content 1"); + var dest2 = Create_File("original content 2"); + + var sut = new FileSystem(); + //---------------Act---------------------- + var syncResult = sut.MoveWithOverwrite(file1, dest1); + var asyncResult = await sut.MoveWithOverwriteAsync(file2, dest2); + //---------------Assert----------------------- + syncResult.Should().BeTrue(); + asyncResult.Should().BeTrue(); + + File.Exists(file1).Should().BeFalse(); + File.Exists(file2).Should().BeFalse(); + File.Exists(dest1).Should().BeTrue(); + File.Exists(dest2).Should().BeTrue(); + } + } + + [TestFixture] + class Rename + { + [Test] + public void GivenFileExist_ExpectItIsRenamed() + { + //---------------Arrange------------------- + var file = Create_File(); + var newFileName = $"{Guid.NewGuid()}-moved.txt"; + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = sut.Rename(file, newFileName); + //---------------Assert----------------------- + var oldFileExist = File.Exists(file); + var newFileExist = File.Exists(Path.Combine(Path.GetTempPath(), newFileName)); + + actual.Should().BeTrue(); + oldFileExist.Should().BeFalse(); + newFileExist.Should().BeTrue(); + } + + [Test] + public void GivenFileDoesNotExist_ExpectFalse() + { + //---------------Arrange------------------- + var file = Create_File(); + var newFileName = $"{Guid.NewGuid()}-moved.txt"; + File.Delete(file); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = sut.Rename(file, newFileName); + //---------------Assert----------------------- + var oldFileExist = File.Exists(file); + var newFileExist = File.Exists(Path.Combine(Path.GetTempPath(), newFileName)); + + actual.Should().BeFalse(); + oldFileExist.Should().BeFalse(); + newFileExist.Should().BeFalse(); + } + } + + [TestFixture] + class RenameAsync + { + [Test] + public async Task GivenFileExist_ExpectItIsRenamed() + { + //---------------Arrange------------------- + var file = Create_File(); + var newFileName = $"{Guid.NewGuid()}-moved.txt"; + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = await sut.RenameAsync(file, newFileName); + //---------------Assert----------------------- + var oldFileExist = File.Exists(file); + var newFileExist = File.Exists(Path.Combine(Path.GetTempPath(), newFileName)); + + actual.Should().BeTrue(); + oldFileExist.Should().BeFalse(); + newFileExist.Should().BeTrue(); + } + + [Test] + public async Task GivenFileDoesNotExist_ExpectFalse() + { + //---------------Arrange------------------- + var file = Create_File(); + var newFileName = $"{Guid.NewGuid()}-moved.txt"; + File.Delete(file); + + var sut = new FileSystem(); + //---------------Act---------------------- + var actual = await sut.RenameAsync(file, newFileName); + //---------------Assert----------------------- + var oldFileExist = File.Exists(file); + var newFileExist = File.Exists(Path.Combine(Path.GetTempPath(), newFileName)); + + actual.Should().BeFalse(); + oldFileExist.Should().BeFalse(); + newFileExist.Should().BeFalse(); + } + + [Test] + public async Task ShouldBehaveSameAsSyncVersion() + { + //---------------Arrange------------------- + var file1 = Create_File(); + var file2 = Create_File(); + var newFileName1 = $"{Guid.NewGuid()}-moved.txt"; + var newFileName2 = $"{Guid.NewGuid()}-moved.txt"; + + var sut = new FileSystem(); + //---------------Act---------------------- + var syncResult = sut.Rename(file1, newFileName1); + var asyncResult = await sut.RenameAsync(file2, newFileName2); + //---------------Assert----------------------- + syncResult.Should().BeTrue(); + asyncResult.Should().BeTrue(); + + File.Exists(file1).Should().BeFalse(); + File.Exists(file2).Should().BeFalse(); + File.Exists(Path.Combine(Path.GetTempPath(), newFileName1)).Should().BeTrue(); + File.Exists(Path.Combine(Path.GetTempPath(), newFileName2)).Should().BeTrue(); + } + } + + private static string Create_File_With_Million_Lines() + { + var tmp = Path.GetTempPath(); + var path = Path.Combine(tmp, Guid.NewGuid().ToString()); + + var location = TestContext.CurrentContext.WorkDirectory; + var moveFilePath = Path.Combine(location, "majestic_million.csv"); + File.Move(moveFilePath, path); + + return path; + } + + private static string Create_File(string content) + { + var tmp = Path.GetTempPath(); + var path = Path.Combine(tmp, Guid.NewGuid().ToString()); + + File.WriteAllText(path, content); + + return path; + } + + private static string Create_File() + { + return Create_File(string.Empty); + } + + private static string Create_Missing_File() + { + var tmp = Path.GetTempPath(); + var path = Path.Combine(tmp, Guid.NewGuid().ToString()); + + return path; + } + + private static IDocument Create_CsvFile(string fileName) + { + var csvFile = new DocumentBuilder() + .With_Name(fileName) + .With_Bytes(new byte[5]) + .Create_Document(); + return csvFile; + } + + } +} diff --git a/source/StoneAge.Data.FileSystem/Document.cs b/source/StoneAge.Data.FileSystem/Document.cs index b76b39d..2fc8f5d 100644 --- a/source/StoneAge.Data.FileSystem/Document.cs +++ b/source/StoneAge.Data.FileSystem/Document.cs @@ -1,16 +1,38 @@ -using System.Text; -using StoneAge.FileStore.Domain; - -namespace StoneAge.FileStore -{ - public class Document : IDocument - { - public string Name { get; internal set; } - public byte[] Data { get; internal set; } - - public override string ToString() - { - return Data == null ? string.Empty : Encoding.UTF8.GetString(Data); - } - } -} +using System.Text; +using StoneAge.FileStore.Domain; + +namespace StoneAge.FileStore +{ + /// + /// Represents a file document with name and binary data. + /// Implements the interface. + /// + public class Document : IDocument + { + /// + /// Gets or sets the name of the document. + /// + public string Name { get; internal set; } + + /// + /// Gets or sets the binary data of the document. + /// + public byte[] Data { get; internal set; } + + /// + /// Converts the document's binary data to a string using UTF-8 encoding. + /// + /// + /// A UTF-8 encoded string representation of the document's data, + /// or an empty string if the data is null. + /// + /// + /// This method assumes that the document's data is encoded in UTF-8. + /// If the data uses a different encoding, this method may not return the expected result. + /// + public override string ToString() + { + return Data == null ? string.Empty : Encoding.UTF8.GetString(Data); + } + } +} diff --git a/source/StoneAge.Data.FileSystem/Domain/IDocument.cs b/source/StoneAge.Data.FileSystem/Domain/IDocument.cs index 737e99e..94bf100 100644 --- a/source/StoneAge.Data.FileSystem/Domain/IDocument.cs +++ b/source/StoneAge.Data.FileSystem/Domain/IDocument.cs @@ -1,8 +1,20 @@ -namespace StoneAge.FileStore.Domain -{ - public interface IDocument - { - string Name { get; } - byte[] Data { get; } - } -} +using System.Text; + +namespace StoneAge.FileStore.Domain +{ + /// + /// Defines the interface for a file document, containing the name and binary data. + /// + public interface IDocument + { + /// + /// Gets the name of the document, typically representing the file name. + /// + string Name { get; } + + /// + /// Gets the binary data of the document as a byte array. + /// + byte[] Data { get; } + } +} diff --git a/source/StoneAge.Data.FileSystem/Domain/IFileSystem.cs b/source/StoneAge.Data.FileSystem/Domain/IFileSystem.cs index b9fb8ee..eceb21b 100644 --- a/source/StoneAge.Data.FileSystem/Domain/IFileSystem.cs +++ b/source/StoneAge.Data.FileSystem/Domain/IFileSystem.cs @@ -1,20 +1,144 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace StoneAge.FileStore.Domain -{ - public interface IFileSystem - { - Task Write(string directory, IDocument file); - Task Append(string directory, IDocument file); - IEnumerable List(string directory); - bool Exists(string path); - void Delete(string path); - IDocument Read(string path); - IDocument GetDocument(string path); - Task> ReadAllLines(string path); - bool Move(string currentPath, string newPath); - bool MoveWithOverwrite(string file, string newLocation); - bool Rename(string filePath, string newName); - } -} +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace StoneAge.FileStore.Domain +{ + /// + /// Defines an interface for file system operations. + /// + public interface IFileSystem + { + /// + /// Writes a document to the specified directory. + /// + /// The directory path where the file should be written. + /// The document to write. + /// A WriteFileResult containing information about the operation. + Task Write(string directory, IDocument file); + + /// + /// Appends data to a file in the specified directory. + /// + /// The directory path where the file should be appended. + /// The document containing data to append. + /// A WriteFileResult containing information about the operation. + Task Append(string directory, IDocument file); + + /// + /// Lists all files in the specified directory. + /// + /// The directory path to list files from. + /// A collection of FileInformation objects representing the files. + IEnumerable List(string directory); + + /// + /// Asynchronously lists all files in the specified directory. + /// + /// The directory path to list files from. + /// A task that represents the asynchronous operation. The task result contains a collection of FileInformation objects representing the files. + Task> ListAsync(string directory); + + /// + /// Checks if a file or directory exists at the specified path. + /// + /// The path to check. + /// True if the file or directory exists, false otherwise. + bool Exists(string path); + + /// + /// Asynchronously checks if a file or directory exists at the specified path. + /// + /// The path to check. + /// A task that represents the asynchronous operation. The task result contains a boolean indicating whether the file or directory exists. + Task ExistsAsync(string path); + + /// + /// Deletes a file or directory at the specified path. + /// + /// The path to delete. + void Delete(string path); + + /// + /// Asynchronously deletes a file or directory at the specified path. + /// + /// The path to delete. + /// A task that represents the asynchronous operation. + Task DeleteAsync(string path); + + /// + /// Reads a document from the specified path. + /// + /// The path to read from. + /// The document read from the path, or NullDocument if the file doesn't exist. + IDocument Read(string path); + + /// + /// Gets a document from the specified path. + /// + /// The path to get the document from. + /// The document from the path, or NullDocument if the file doesn't exist. + IDocument GetDocument(string path); + + /// + /// Asynchronously gets a document from the specified path. + /// + /// The path to get the document from. + /// A task that represents the asynchronous operation. The task result contains the document from the path, or NullDocument if the file doesn't exist. + Task GetDocumentAsync(string path); + + /// + /// Reads all lines from a file at the specified path. + /// + /// The path of the file to read. + /// An enumerable collection of strings representing the lines in the file. + Task> ReadAllLines(string path); + + /// + /// Moves a file from one location to another. + /// + /// The source file path. + /// The destination file path. + /// True if the move was successful, false otherwise. + bool Move(string currentPath, string newPath); + + /// + /// Asynchronously moves a file from one location to another. + /// + /// The source file path. + /// The destination file path. + /// A task that represents the asynchronous operation. The task result contains a boolean indicating whether the move was successful. + Task MoveAsync(string currentPath, string newPath); + + /// + /// Moves a file from one location to another, overwriting the destination if it exists. + /// + /// The source file path. + /// The destination file path. + /// True if the move was successful, false otherwise. + bool MoveWithOverwrite(string file, string newLocation); + + /// + /// Asynchronously moves a file from one location to another, overwriting the destination if it exists. + /// + /// The source file path. + /// The destination file path. + /// A task that represents the asynchronous operation. The task result contains a boolean indicating whether the move was successful. + Task MoveWithOverwriteAsync(string file, string newLocation); + + /// + /// Renames a file. + /// + /// The path of the file to rename. + /// The new name for the file. + /// True if the rename was successful, false otherwise. + bool Rename(string filePath, string newName); + + /// + /// Asynchronously renames a file. + /// + /// The path of the file to rename. + /// The new name for the file. + /// A task that represents the asynchronous operation. The task result contains a boolean indicating whether the rename was successful. + Task RenameAsync(string filePath, string newName); + } +} diff --git a/source/StoneAge.Data.FileSystem/FileSystem.cs b/source/StoneAge.Data.FileSystem/FileSystem.cs index ae57b95..7f9ddcd 100644 --- a/source/StoneAge.Data.FileSystem/FileSystem.cs +++ b/source/StoneAge.Data.FileSystem/FileSystem.cs @@ -1,243 +1,445 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using StoneAge.FileStore.Domain; - -namespace StoneAge.FileStore -{ - public class FileSystem : IFileSystem - { - public static readonly IDocument NullDocument = new Document{Name = "NullDocument"}; - - public async Task Write(string directory, IDocument file) - { - return await Task.Run(() => - { - var result = new WriteFileResult(); - if (string.IsNullOrWhiteSpace(file.Name)) - { - result.ErrorMessages.Add("No file name provided"); - return result; - } - - if (string.IsNullOrWhiteSpace(directory)) - { - result.ErrorMessages.Add("No directory provided"); - return result; - } - - result = Ensure_Directory_Is_Created(directory); - - if (result.HadError) - { - return result; - } - - var filePath = Path.Combine(directory, file.Name); - result = Write_File_To_Path(file, filePath, FileMode.Create); - - return result; - }); - } - - public IEnumerable List(string directory) - { - if (!Directory.Exists(directory)) return new List(); - - var directoryInfo = new DirectoryInfo(directory); - var fileInformations = directoryInfo.GetFiles().Select(info => new FileInformation - { - Name = info.Name, - Size = Convert_Bytes_To_Megabytes(info.Length).ToString() - }); - - double Convert_Bytes_To_Megabytes(long bytes) - { - var fileSizeInKB = bytes / 1024; - var fileSizeInMB = fileSizeInKB / 1024; - return fileSizeInMB; - } - - return fileInformations; - } - - public bool Exists(string path) - { - if (string.IsNullOrEmpty(path)) - { - return false; - } - - return Directory.Exists(path) || File.Exists(path); - } - - public void Delete(string path) - { - if (Directory.Exists(path)) - { - Directory.Delete(path, true); - return; - } - - if (File.Exists(path)) - { - File.Delete(path); - } - } - - public IDocument Read(string path) - { - return GetDocument(path); - } - - public IDocument GetDocument(string path) - { - if (!File.Exists(path)) - { - return NullDocument; - } - - var name = Path.GetFileName(path); - return new DocumentBuilder() - .With_Name(name) - .With_File(path) - .Create_Document(); - } - - public bool Move(string file, string newLocation) - { - if (!File.Exists(file)) - { - return false; - } - - try - { - File.Move(file, newLocation); - return true; - } - catch (Exception) - { - return false; - } - - } - - public bool MoveWithOverwrite(string file, string newLocation) - { - if (!File.Exists(file)) - { - return false; - } - - if (File.Exists(newLocation)) - { - File.Delete(newLocation); - } - - File.Move(file, newLocation); - return true; - - } - - public bool Rename(string file, string newFileName) - { - if (!File.Exists(file)) - { - return false; - } - - var directoryPath = Path.GetDirectoryName(file); - var newFilePath = Path.Combine(directoryPath, newFileName); - - File.Move(file, newFilePath); - - return true; - } - - public async Task Append(string directory, IDocument file) - { - return await Task.Run(() => - { - var result = new WriteFileResult(); - if (string.IsNullOrWhiteSpace(file.Name)) - { - result.ErrorMessages.Add("No file name provided"); - return result; - } - - if (string.IsNullOrWhiteSpace(directory)) - { - result.ErrorMessages.Add("No directory provided"); - return result; - } - - result = Ensure_Directory_Is_Created(directory); - - if (result.HadError) - { - return result; - } - - var filePath = Path.Combine(directory, file.Name); - result = Write_File_To_Path(file, filePath, FileMode.Append); - - return result; - }); - } - - public async Task> ReadAllLines(string path) - { - return await File.ReadAllLinesAsync(path); - } - - private WriteFileResult Write_File_To_Path(IDocument file, string filePath, FileMode fileMode) - { - var result = new WriteFileResult(); - - if (file.Data == null) - { - result.ErrorMessages.Add("No file data provided; cannot write file."); - return result; - } - - try - { - using (var stream = new FileStream(filePath, fileMode)) - { - stream.Write(file.Data); - } - - result.FullFilePath = filePath; - } - catch (Exception e) - { - result.ErrorMessages.Add($"An error occured writing the file [{e.Message}]"); - } - - return result; - } - - private WriteFileResult Ensure_Directory_Is_Created(string currentDirectory) - { - var result= new WriteFileResult(); - if (!Directory.Exists(currentDirectory)) - { - try - { - Directory.CreateDirectory(currentDirectory); - } - catch (Exception e) - { - result.ErrorMessages.Add($"An error occured creating directory structure [{e.Message}]"); - return result; - } - } - - return result; - } - - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using StoneAge.FileStore.Domain; + +namespace StoneAge.FileStore +{ + /// + /// A concrete implementation of the IFileSystem interface that interacts with the actual file system. + /// + public class FileSystem : IFileSystem + { + /// + /// A null document instance to be returned when a document cannot be found. + /// + public static readonly IDocument NullDocument = new Document{Name = "NullDocument"}; + + /// + /// Writes a document to the specified directory. + /// + /// The directory path where the file should be written. + /// The document to write. + /// A WriteFileResult containing information about the operation. + public async Task Write(string directory, IDocument file) + { + return await Task.Run(() => + { + var result = new WriteFileResult(); + if (string.IsNullOrWhiteSpace(file.Name)) + { + result.ErrorMessages.Add("No file name provided"); + return result; + } + + if (string.IsNullOrWhiteSpace(directory)) + { + result.ErrorMessages.Add("No directory provided"); + return result; + } + + // Validate that the file name doesn't contain path separators + if (file.Name.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) + { + result.ErrorMessages.Add("File name contains invalid characters"); + return result; + } + + result = Ensure_Directory_Is_Created(directory); + + if (result.HadError) + { + return result; + } + + var filePath = Path.Combine(directory, file.Name); + result = Write_File_To_Path(file, filePath, FileMode.Create); + + return result; + }); + } + + /// + /// Lists all files in the specified directory. + /// + /// The directory path to list files from. + /// A collection of FileInformation objects representing the files. + public IEnumerable List(string directory) + { + if (string.IsNullOrWhiteSpace(directory) || !Directory.Exists(directory)) + return new List(); + + var directoryInfo = new DirectoryInfo(directory); + var fileInformations = directoryInfo.GetFiles().Select(info => new FileInformation + { + Name = info.Name, + Size = Convert_Bytes_To_Megabytes(info.Length).ToString() + }); + + double Convert_Bytes_To_Megabytes(long bytes) + { + var fileSizeInKB = bytes / 1024; + var fileSizeInMB = fileSizeInKB / 1024; + return fileSizeInMB; + } + + return fileInformations; + } + + /// + /// Asynchronously lists all files in the specified directory. + /// + /// The directory path to list files from. + /// A task that represents the asynchronous operation. The task result contains a collection of FileInformation objects representing the files. + public async Task> ListAsync(string directory) + { + return await Task.Run(() => List(directory)); + } + + /// + /// Checks if a file or directory exists at the specified path. + /// + /// The path to check. + /// True if the file or directory exists, false otherwise. + public bool Exists(string path) + { + if (string.IsNullOrWhiteSpace(path)) + { + return false; + } + + return Directory.Exists(path) || File.Exists(path); + } + + /// + /// Asynchronously checks if a file or directory exists at the specified path. + /// + /// The path to check. + /// A task that represents the asynchronous operation. The task result contains a boolean indicating whether the file or directory exists. + public async Task ExistsAsync(string path) + { + return await Task.Run(() => Exists(path)); + } + + /// + /// Deletes a file or directory at the specified path. + /// + /// The path to delete. + public void Delete(string path) + { + if (string.IsNullOrWhiteSpace(path)) + { + return; + } + + if (Directory.Exists(path)) + { + Directory.Delete(path, true); + return; + } + + if (File.Exists(path)) + { + File.Delete(path); + } + } + + /// + /// Asynchronously deletes a file or directory at the specified path. + /// + /// The path to delete. + /// A task that represents the asynchronous operation. + public async Task DeleteAsync(string path) + { + await Task.Run(() => Delete(path)); + } + + /// + /// Reads a document from the specified path. + /// + /// The path to read from. + /// The document read from the path, or NullDocument if the file doesn't exist. + public IDocument Read(string path) + { + return GetDocument(path); + } + + /// + /// Gets a document from the specified path. + /// + /// The path to get the document from. + /// The document from the path, or NullDocument if the file doesn't exist. + /// + /// The document's content is assumed to be in UTF-8 encoding when converted to string. + /// + public IDocument GetDocument(string path) + { + if (string.IsNullOrWhiteSpace(path) || !File.Exists(path)) + { + return NullDocument; + } + + var name = Path.GetFileName(path); + return new DocumentBuilder() + .With_Name(name) + .With_File(path) + .Create_Document(); + } + + /// + /// Asynchronously gets a document from the specified path. + /// + /// The path to get the document from. + /// A task that represents the asynchronous operation. The task result contains the document from the path, or NullDocument if the file doesn't exist. + public async Task GetDocumentAsync(string path) + { + return await Task.Run(() => GetDocument(path)); + } + + /// + /// Moves a file from one location to another. + /// + /// The source file path. + /// The destination file path. + /// True if the move was successful, false otherwise. + public bool Move(string file, string newLocation) + { + if (string.IsNullOrWhiteSpace(file) || string.IsNullOrWhiteSpace(newLocation) || !File.Exists(file)) + { + return false; + } + + try + { + File.Move(file, newLocation); + return true; + } + catch (Exception) + { + return false; + } + } + + /// + /// Asynchronously moves a file from one location to another. + /// + /// The source file path. + /// The destination file path. + /// A task that represents the asynchronous operation. The task result contains a boolean indicating whether the move was successful. + public async Task MoveAsync(string file, string newLocation) + { + return await Task.Run(() => Move(file, newLocation)); + } + + /// + /// Moves a file from one location to another, overwriting the destination if it exists. + /// + /// The source file path. + /// The destination file path. + /// True if the move was successful, false otherwise. + public bool MoveWithOverwrite(string file, string newLocation) + { + if (string.IsNullOrWhiteSpace(file) || string.IsNullOrWhiteSpace(newLocation) || !File.Exists(file)) + { + return false; + } + + try + { + if (File.Exists(newLocation)) + { + File.Delete(newLocation); + } + + File.Move(file, newLocation); + return true; + } + catch (Exception) + { + return false; + } + } + + /// + /// Asynchronously moves a file from one location to another, overwriting the destination if it exists. + /// + /// The source file path. + /// The destination file path. + /// A task that represents the asynchronous operation. The task result contains a boolean indicating whether the move was successful. + public async Task MoveWithOverwriteAsync(string file, string newLocation) + { + return await Task.Run(() => MoveWithOverwrite(file, newLocation)); + } + + /// + /// Renames a file. + /// + /// The path of the file to rename. + /// The new name for the file. + /// True if the rename was successful, false otherwise. + public bool Rename(string filePath, string newName) + { + if (string.IsNullOrWhiteSpace(filePath) || string.IsNullOrWhiteSpace(newName) || !File.Exists(filePath)) + { + return false; + } + + try + { + // Validate that the new name doesn't contain path separators + if (newName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) + { + return false; + } + + var directoryPath = Path.GetDirectoryName(filePath); + var newFilePath = Path.Combine(directoryPath, newName); + + File.Move(filePath, newFilePath); + return true; + } + catch (Exception) + { + return false; + } + } + + /// + /// Asynchronously renames a file. + /// + /// The path of the file to rename. + /// The new name for the file. + /// A task that represents the asynchronous operation. The task result contains a boolean indicating whether the rename was successful. + public async Task RenameAsync(string filePath, string newName) + { + return await Task.Run(() => Rename(filePath, newName)); + } + + /// + /// Appends data to a file in the specified directory. + /// + /// The directory path where the file should be appended. + /// The document containing data to append. + /// A WriteFileResult containing information about the operation. + public async Task Append(string directory, IDocument file) + { + return await Task.Run(() => + { + var result = new WriteFileResult(); + if (string.IsNullOrWhiteSpace(file.Name)) + { + result.ErrorMessages.Add("No file name provided"); + return result; + } + + if (string.IsNullOrWhiteSpace(directory)) + { + result.ErrorMessages.Add("No directory provided"); + return result; + } + + // Validate that the file name doesn't contain path separators + if (file.Name.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) + { + result.ErrorMessages.Add("File name contains invalid characters"); + return result; + } + + result = Ensure_Directory_Is_Created(directory); + + if (result.HadError) + { + return result; + } + + var filePath = Path.Combine(directory, file.Name); + result = Write_File_To_Path(file, filePath, FileMode.Append); + + return result; + }); + } + + /// + /// Reads all lines from a file at the specified path. + /// + /// The path of the file to read. + /// An enumerable collection of strings representing the lines in the file. + /// + /// This method assumes the file is encoded in the default encoding for the system. + /// + public async Task> ReadAllLines(string path) + { + if (string.IsNullOrWhiteSpace(path)) + { + throw new ArgumentNullException(nameof(path), "Path cannot be null or empty"); + } + + if (!File.Exists(path)) + { + throw new FileNotFoundException($"File not found: {path}", path); + } + + return await File.ReadAllLinesAsync(path); + } + + /// + /// Writes file data to the specified path with the given file mode. + /// + /// The document to write. + /// The path to write to. + /// The file mode to use (Create or Append). + /// A WriteFileResult containing information about the operation. + private WriteFileResult Write_File_To_Path(IDocument file, string filePath, FileMode fileMode) + { + var result = new WriteFileResult(); + + if (file.Data == null) + { + result.ErrorMessages.Add("No file data provided; cannot write file."); + return result; + } + + try + { + // Modern using declaration (C# 8.0+) + using var stream = new FileStream(filePath, fileMode); + stream.Write(file.Data); + + result.FullFilePath = filePath; + } + catch (Exception e) + { + result.ErrorMessages.Add($"An error occured writing the file [{e.Message}]"); + } + + return result; + } + + /// + /// Ensures that the specified directory exists, creating it if necessary. + /// + /// The directory path to check or create. + /// A WriteFileResult containing information about the operation. + private WriteFileResult Ensure_Directory_Is_Created(string currentDirectory) + { + var result= new WriteFileResult(); + if (!Directory.Exists(currentDirectory)) + { + try + { + Directory.CreateDirectory(currentDirectory); + } + catch (Exception e) + { + result.ErrorMessages.Add($"An error occured creating directory structure [{e.Message}]"); + return result; + } + } + + return result; + } + + } +}