Skip to content

Commit 473e320

Browse files
feat: implement MockFile.ReadLinesAsync (#935)
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. 😀
1 parent c099e04 commit 473e320

File tree

2 files changed

+101
-19
lines changed

2 files changed

+101
-19
lines changed

src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFile.Async.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#if FEATURE_ASYNC_FILE
22

33
using System.Collections.Generic;
4+
using System.Runtime.CompilerServices;
45
using System.Text;
56
using System.Threading;
67
using System.Threading.Tasks;
@@ -23,7 +24,7 @@ partial class MockFile
2324

2425
/// <inheritdoc />
2526
public override Task AppendAllTextAsync(string path, string contents, CancellationToken cancellationToken = default(CancellationToken)) =>
26-
AppendAllTextAsync(path, contents, MockFileData.DefaultEncoding, cancellationToken);
27+
AppendAllTextAsync(path, contents, MockFileData.DefaultEncoding, cancellationToken);
2728

2829

2930
/// <inheritdoc />
@@ -43,7 +44,7 @@ partial class MockFile
4344

4445
/// <inheritdoc />
4546
public override Task<string[]> ReadAllLinesAsync(string path, CancellationToken cancellationToken = default(CancellationToken)) =>
46-
ReadAllLinesAsync(path, MockFileData.DefaultEncoding, cancellationToken);
47+
ReadAllLinesAsync(path, MockFileData.DefaultEncoding, cancellationToken);
4748

4849
/// <inheritdoc />
4950

@@ -55,7 +56,7 @@ partial class MockFile
5556

5657
/// <inheritdoc />
5758
public override Task<string> ReadAllTextAsync(string path, CancellationToken cancellationToken) =>
58-
ReadAllTextAsync(path, MockFileData.DefaultEncoding, cancellationToken);
59+
ReadAllTextAsync(path, MockFileData.DefaultEncoding, cancellationToken);
5960

6061

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

6869
#if FEATURE_READ_LINES_ASYNC
6970
/// <inheritdoc />
70-
public override IAsyncEnumerable<string> ReadLinesAsync(string path,
71-
CancellationToken cancellationToken = default)
72-
{
73-
throw CommonExceptions.NotImplemented();
74-
}
71+
public override IAsyncEnumerable<string> ReadLinesAsync(string path, CancellationToken cancellationToken = default) =>
72+
ReadLinesAsync(path, MockFileData.DefaultEncoding, cancellationToken);
7573

7674
/// <inheritdoc />
77-
public override IAsyncEnumerable<string> ReadLinesAsync(string path, Encoding encoding,
78-
CancellationToken cancellationToken = default)
75+
public override async IAsyncEnumerable<string> ReadLinesAsync(string path, Encoding encoding,
76+
[EnumeratorCancellation] CancellationToken cancellationToken = default)
7977
{
80-
throw CommonExceptions.NotImplemented();
78+
var lines = await ReadAllLinesAsync(path, encoding, cancellationToken);
79+
foreach (var line in lines)
80+
yield return line;
8181
}
8282
#endif
8383

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

104104
/// <inheritdoc />
105105
public override Task WriteAllTextAsync(string path, string contents, CancellationToken cancellationToken) =>
106-
WriteAllTextAsync(path, contents, MockFileData.DefaultEncoding, cancellationToken);
106+
WriteAllTextAsync(path, contents, MockFileData.DefaultEncoding, cancellationToken);
107107

108108
/// <inheritdoc />
109109
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
115115
}
116116
}
117117

118-
#endif
118+
#endif

tests/TestableIO.System.IO.Abstractions.TestingHelpers.Tests/MockFileReadAllLinesTests.cs

Lines changed: 88 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
namespace System.IO.Abstractions.TestingHelpers.Tests
22
{
33
using Collections.Generic;
4+
using Collections.Specialized;
5+
using Threading;
6+
using Threading.Tasks;
47

58
using NUnit.Framework;
69

710
using Text;
811

912
using XFS = MockUnixSupport;
1013

11-
using System.Threading.Tasks;
12-
using System.Threading;
13-
1414
public class MockFileReadAllLinesTests
1515
{
1616
[Test]
@@ -63,7 +63,7 @@ public void MockFile_ReadAllLines_NotExistingFile_ThrowsCorrectFileNotFoundExcep
6363
var mockFileSystem = new MockFileSystem();
6464

6565
var act = new TestDelegate(() =>
66-
mockFileSystem.File.ReadAllText(absentFileNameFullPath)
66+
mockFileSystem.File.ReadAllLines(absentFileNameFullPath)
6767
);
6868

6969
var exception = Assert.Catch<FileNotFoundException>(act);
@@ -149,13 +149,95 @@ public void MockFile_ReadAllLinesAsync_NotExistingFile_ThrowsCorrectFileNotFound
149149
var mockFileSystem = new MockFileSystem();
150150

151151
var act = new AsyncTestDelegate(async () =>
152-
await mockFileSystem.File.ReadAllTextAsync(absentFileNameFullPath)
152+
await mockFileSystem.File.ReadAllLinesAsync(absentFileNameFullPath)
153153
);
154154

155155
var exception = Assert.CatchAsync<FileNotFoundException>(act);
156156
Assert.That(exception.FileName, Is.EqualTo(absentFileNameFullPath));
157157
Assert.That(exception.Message, Is.EqualTo("Could not find file '" + absentFileNameFullPath + "'."));
158158
}
159+
160+
#if FEATURE_READ_LINES_ASYNC
161+
[Test]
162+
public async Task MockFile_ReadLinesAsync_ShouldReturnOriginalTextData()
163+
{
164+
// Arrange
165+
var fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
166+
{
167+
{ XFS.Path(@"c:\something\demo.txt"), new MockFileData("Demo\r\ntext\ncontent\rvalue") },
168+
{ XFS.Path(@"c:\something\other.gif"), new MockFileData(new byte[] { 0x21, 0x58, 0x3f, 0xa9 }) }
169+
});
170+
171+
var file = new MockFile(fileSystem);
172+
173+
// Act
174+
var enumerable = file.ReadLinesAsync(XFS.Path(@"c:\something\demo.txt"));
175+
StringCollection result = new();
176+
await foreach (var line in enumerable)
177+
result.Add(line);
178+
179+
// Assert
180+
CollectionAssert.AreEqual(
181+
new[] { "Demo", "text", "content", "value" },
182+
result);
183+
}
184+
185+
[Test]
186+
public async Task MockFile_ReadLinesAsync_ShouldReturnOriginalDataWithCustomEncoding()
187+
{
188+
// Arrange
189+
string text = "Hello\r\nthere\rBob\nBob!";
190+
var encodedText = Encoding.BigEndianUnicode.GetBytes(text);
191+
var fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
192+
{
193+
{ XFS.Path(@"c:\something\demo.txt"), new MockFileData(encodedText) }
194+
});
195+
196+
var file = new MockFile(fileSystem);
197+
198+
// Act
199+
var enumerable = file.ReadLinesAsync(XFS.Path(@"c:\something\demo.txt"), Encoding.BigEndianUnicode);
200+
StringCollection result = new();
201+
await foreach (var line in enumerable)
202+
result.Add(line);
203+
204+
// Assert
205+
CollectionAssert.AreEqual(
206+
new[] { "Hello", "there", "Bob", "Bob!" },
207+
result);
208+
}
209+
210+
[Test]
211+
public void MockFile_ReadLinesAsync_ShouldThrowOperationCanceledExceptionIfCanceled()
212+
{
213+
var fileSystem = new MockFileSystem();
214+
215+
AsyncTestDelegate action = async () =>
216+
{
217+
var enumerable = fileSystem.File.ReadLinesAsync(@"C:\a.txt", new CancellationToken(canceled: true));
218+
await foreach (var line in enumerable);
219+
};
220+
221+
Assert.ThrowsAsync<OperationCanceledException>(action);
222+
}
223+
224+
[Test]
225+
public void MockFile_ReadLinesAsync_NotExistingFile_ThrowsCorrectFileNotFoundException()
226+
{
227+
var absentFileNameFullPath = XFS.Path(@"c:\you surely don't have such file.hope-so");
228+
var mockFileSystem = new MockFileSystem();
229+
230+
AsyncTestDelegate action = async () =>
231+
{
232+
var enumerable = mockFileSystem.File.ReadLinesAsync(absentFileNameFullPath);
233+
await foreach (var line in enumerable) ;
234+
};
235+
236+
var exception = Assert.CatchAsync<FileNotFoundException>(action);
237+
Assert.That(exception.FileName, Is.EqualTo(absentFileNameFullPath));
238+
Assert.That(exception.Message, Is.EqualTo("Could not find file '" + absentFileNameFullPath + "'."));
239+
}
240+
#endif
159241
#endif
160242
}
161-
}
243+
}

0 commit comments

Comments
 (0)