Skip to content

Commit

Permalink
feat: implement MockFile.ReadLinesAsync (#935)
Browse files Browse the repository at this point in the history
While executing a test a got a hint:

> System.NotImplementedException : This test helper hasn't been implemented yet. They are implemented on an as-needed basis. As it seems like you need it, now would be a great time to send us a pull request over at https://github.com/TestableIO/System.IO.Abstractions. You know, because it's open source and all.

So here is my pull request to add a not implemented feature. 😀
  • Loading branch information
patricksadowski committed Jan 24, 2023
1 parent c099e04 commit 473e320
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -23,7 +24,7 @@ public override Task AppendAllLinesAsync(string path, IEnumerable<string> conten

/// <inheritdoc />
public override Task AppendAllTextAsync(string path, string contents, CancellationToken cancellationToken = default(CancellationToken)) =>
AppendAllTextAsync(path, contents, MockFileData.DefaultEncoding, cancellationToken);
AppendAllTextAsync(path, contents, MockFileData.DefaultEncoding, cancellationToken);


/// <inheritdoc />
Expand All @@ -43,7 +44,7 @@ public override Task<byte[]> ReadAllBytesAsync(string path, CancellationToken ca

/// <inheritdoc />
public override Task<string[]> ReadAllLinesAsync(string path, CancellationToken cancellationToken = default(CancellationToken)) =>
ReadAllLinesAsync(path, MockFileData.DefaultEncoding, cancellationToken);
ReadAllLinesAsync(path, MockFileData.DefaultEncoding, cancellationToken);

/// <inheritdoc />

Expand All @@ -55,7 +56,7 @@ public override Task<string[]> ReadAllLinesAsync(string path, Encoding encoding,

/// <inheritdoc />
public override Task<string> ReadAllTextAsync(string path, CancellationToken cancellationToken) =>
ReadAllTextAsync(path, MockFileData.DefaultEncoding, cancellationToken);
ReadAllTextAsync(path, MockFileData.DefaultEncoding, cancellationToken);


/// <inheritdoc />
Expand All @@ -67,17 +68,16 @@ public override Task<string> ReadAllTextAsync(string path, Encoding encoding, Ca

#if FEATURE_READ_LINES_ASYNC
/// <inheritdoc />
public override IAsyncEnumerable<string> ReadLinesAsync(string path,
CancellationToken cancellationToken = default)
{
throw CommonExceptions.NotImplemented();
}
public override IAsyncEnumerable<string> ReadLinesAsync(string path, CancellationToken cancellationToken = default) =>
ReadLinesAsync(path, MockFileData.DefaultEncoding, cancellationToken);

/// <inheritdoc />
public override IAsyncEnumerable<string> ReadLinesAsync(string path, Encoding encoding,
CancellationToken cancellationToken = default)
public override async IAsyncEnumerable<string> 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

Expand All @@ -103,7 +103,7 @@ public override Task WriteAllLinesAsync(string path, IEnumerable<string> content

/// <inheritdoc />
public override Task WriteAllTextAsync(string path, string contents, CancellationToken cancellationToken) =>
WriteAllTextAsync(path, contents, MockFileData.DefaultEncoding, cancellationToken);
WriteAllTextAsync(path, contents, MockFileData.DefaultEncoding, cancellationToken);

/// <inheritdoc />
public override Task WriteAllTextAsync(string path, string contents, Encoding encoding, CancellationToken cancellationToken)
Expand All @@ -115,4 +115,4 @@ public override Task WriteAllTextAsync(string path, string contents, Encoding en
}
}

#endif
#endif
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
namespace System.IO.Abstractions.TestingHelpers.Tests
{
using Collections.Generic;
using Collections.Specialized;
using Threading;
using Threading.Tasks;

using NUnit.Framework;

using Text;

using XFS = MockUnixSupport;

using System.Threading.Tasks;
using System.Threading;

public class MockFileReadAllLinesTests
{
[Test]
Expand Down Expand Up @@ -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<FileNotFoundException>(act);
Expand Down Expand Up @@ -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<FileNotFoundException>(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<string, MockFileData>
{
{ 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<string, MockFileData>
{
{ 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<OperationCanceledException>(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<FileNotFoundException>(action);
Assert.That(exception.FileName, Is.EqualTo(absentFileNameFullPath));
Assert.That(exception.Message, Is.EqualTo("Could not find file '" + absentFileNameFullPath + "'."));
}
#endif
#endif
}
}
}

0 comments on commit 473e320

Please sign in to comment.