diff --git a/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFile.Async.cs b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFile.Async.cs index d7fe76f6e..fd4a764f9 100644 --- a/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFile.Async.cs +++ b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFile.Async.cs @@ -1,6 +1,7 @@ #if FEATURE_ASYNC_FILE using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -23,7 +24,7 @@ partial class MockFile /// public override Task AppendAllTextAsync(string path, string contents, CancellationToken cancellationToken = default(CancellationToken)) => - AppendAllTextAsync(path, contents, MockFileData.DefaultEncoding, cancellationToken); + AppendAllTextAsync(path, contents, MockFileData.DefaultEncoding, cancellationToken); /// @@ -43,7 +44,7 @@ partial class MockFile /// public override Task ReadAllLinesAsync(string path, CancellationToken cancellationToken = default(CancellationToken)) => - ReadAllLinesAsync(path, MockFileData.DefaultEncoding, cancellationToken); + ReadAllLinesAsync(path, MockFileData.DefaultEncoding, cancellationToken); /// @@ -55,7 +56,7 @@ partial class MockFile /// public override Task ReadAllTextAsync(string path, CancellationToken cancellationToken) => - ReadAllTextAsync(path, MockFileData.DefaultEncoding, cancellationToken); + ReadAllTextAsync(path, MockFileData.DefaultEncoding, cancellationToken); /// @@ -67,17 +68,16 @@ public override Task ReadAllTextAsync(string path, Encoding encoding, Ca #if FEATURE_READ_LINES_ASYNC /// - public override IAsyncEnumerable ReadLinesAsync(string path, - CancellationToken cancellationToken = default) - { - throw CommonExceptions.NotImplemented(); - } + public override IAsyncEnumerable ReadLinesAsync(string path, CancellationToken cancellationToken = default) => + ReadLinesAsync(path, MockFileData.DefaultEncoding, cancellationToken); /// - public override IAsyncEnumerable ReadLinesAsync(string path, Encoding encoding, - CancellationToken cancellationToken = default) + public override async IAsyncEnumerable ReadLinesAsync(string path, Encoding encoding, + [EnumeratorCancellation] CancellationToken cancellationToken = default) { - throw CommonExceptions.NotImplemented(); + var lines = await ReadAllLinesAsync(path, encoding, cancellationToken); + foreach (var line in lines) + yield return line; } #endif @@ -103,7 +103,7 @@ public override Task WriteAllLinesAsync(string path, IEnumerable content /// public override Task WriteAllTextAsync(string path, string contents, CancellationToken cancellationToken) => -WriteAllTextAsync(path, contents, MockFileData.DefaultEncoding, cancellationToken); + WriteAllTextAsync(path, contents, MockFileData.DefaultEncoding, cancellationToken); /// public override Task WriteAllTextAsync(string path, string contents, Encoding encoding, CancellationToken cancellationToken) @@ -115,4 +115,4 @@ public override Task WriteAllTextAsync(string path, string contents, Encoding en } } -#endif \ No newline at end of file +#endif diff --git a/tests/TestableIO.System.IO.Abstractions.TestingHelpers.Tests/MockFileReadAllLinesTests.cs b/tests/TestableIO.System.IO.Abstractions.TestingHelpers.Tests/MockFileReadAllLinesTests.cs index a92eceda3..e80aea213 100644 --- a/tests/TestableIO.System.IO.Abstractions.TestingHelpers.Tests/MockFileReadAllLinesTests.cs +++ b/tests/TestableIO.System.IO.Abstractions.TestingHelpers.Tests/MockFileReadAllLinesTests.cs @@ -1,6 +1,9 @@ namespace System.IO.Abstractions.TestingHelpers.Tests { using Collections.Generic; + using Collections.Specialized; + using Threading; + using Threading.Tasks; using NUnit.Framework; @@ -8,9 +11,6 @@ namespace System.IO.Abstractions.TestingHelpers.Tests using XFS = MockUnixSupport; - using System.Threading.Tasks; - using System.Threading; - public class MockFileReadAllLinesTests { [Test] @@ -63,7 +63,7 @@ public void MockFile_ReadAllLines_NotExistingFile_ThrowsCorrectFileNotFoundExcep var mockFileSystem = new MockFileSystem(); var act = new TestDelegate(() => - mockFileSystem.File.ReadAllText(absentFileNameFullPath) + mockFileSystem.File.ReadAllLines(absentFileNameFullPath) ); var exception = Assert.Catch(act); @@ -149,13 +149,95 @@ public void MockFile_ReadAllLinesAsync_NotExistingFile_ThrowsCorrectFileNotFound var mockFileSystem = new MockFileSystem(); var act = new AsyncTestDelegate(async () => - await mockFileSystem.File.ReadAllTextAsync(absentFileNameFullPath) + await mockFileSystem.File.ReadAllLinesAsync(absentFileNameFullPath) ); var exception = Assert.CatchAsync(act); Assert.That(exception.FileName, Is.EqualTo(absentFileNameFullPath)); Assert.That(exception.Message, Is.EqualTo("Could not find file '" + absentFileNameFullPath + "'.")); } + +#if FEATURE_READ_LINES_ASYNC + [Test] + public async Task MockFile_ReadLinesAsync_ShouldReturnOriginalTextData() + { + // Arrange + var fileSystem = new MockFileSystem(new Dictionary + { + { XFS.Path(@"c:\something\demo.txt"), new MockFileData("Demo\r\ntext\ncontent\rvalue") }, + { XFS.Path(@"c:\something\other.gif"), new MockFileData(new byte[] { 0x21, 0x58, 0x3f, 0xa9 }) } + }); + + var file = new MockFile(fileSystem); + + // Act + var enumerable = file.ReadLinesAsync(XFS.Path(@"c:\something\demo.txt")); + StringCollection result = new(); + await foreach (var line in enumerable) + result.Add(line); + + // Assert + CollectionAssert.AreEqual( + new[] { "Demo", "text", "content", "value" }, + result); + } + + [Test] + public async Task MockFile_ReadLinesAsync_ShouldReturnOriginalDataWithCustomEncoding() + { + // Arrange + string text = "Hello\r\nthere\rBob\nBob!"; + var encodedText = Encoding.BigEndianUnicode.GetBytes(text); + var fileSystem = new MockFileSystem(new Dictionary + { + { XFS.Path(@"c:\something\demo.txt"), new MockFileData(encodedText) } + }); + + var file = new MockFile(fileSystem); + + // Act + var enumerable = file.ReadLinesAsync(XFS.Path(@"c:\something\demo.txt"), Encoding.BigEndianUnicode); + StringCollection result = new(); + await foreach (var line in enumerable) + result.Add(line); + + // Assert + CollectionAssert.AreEqual( + new[] { "Hello", "there", "Bob", "Bob!" }, + result); + } + + [Test] + public void MockFile_ReadLinesAsync_ShouldThrowOperationCanceledExceptionIfCanceled() + { + var fileSystem = new MockFileSystem(); + + AsyncTestDelegate action = async () => + { + var enumerable = fileSystem.File.ReadLinesAsync(@"C:\a.txt", new CancellationToken(canceled: true)); + await foreach (var line in enumerable); + }; + + Assert.ThrowsAsync(action); + } + + [Test] + public void MockFile_ReadLinesAsync_NotExistingFile_ThrowsCorrectFileNotFoundException() + { + var absentFileNameFullPath = XFS.Path(@"c:\you surely don't have such file.hope-so"); + var mockFileSystem = new MockFileSystem(); + + AsyncTestDelegate action = async () => + { + var enumerable = mockFileSystem.File.ReadLinesAsync(absentFileNameFullPath); + await foreach (var line in enumerable) ; + }; + + var exception = Assert.CatchAsync(action); + Assert.That(exception.FileName, Is.EqualTo(absentFileNameFullPath)); + Assert.That(exception.Message, Is.EqualTo("Could not find file '" + absentFileNameFullPath + "'.")); + } +#endif #endif } -} \ No newline at end of file +}