Skip to content

Commit c408bc5

Browse files
authored
Merge branch 'main' into topic/initialize-drives-with-root-directory
2 parents 8c56d85 + c6a2782 commit c408bc5

File tree

11 files changed

+447
-148
lines changed

11 files changed

+447
-148
lines changed

Source/Testably.Abstractions.Testing/FileSystem/FileMock.cs

Lines changed: 147 additions & 91 deletions
Large diffs are not rendered by default.

Source/Testably.Abstractions.Testing/Storage/InMemoryLocation.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,12 @@ public override int GetHashCode()
9090
/// <inheritdoc cref="IStorageLocation.GetParent()" />
9191
public IStorageLocation? GetParent()
9292
{
93-
string? parentPath = _fileSystem.Execute.Path.GetDirectoryName(FullPath);
93+
string fullPathWithoutTrailingSeparator = FullPath
94+
.TrimEnd(_fileSystem.Path.DirectorySeparatorChar);
95+
string? parentPath =
96+
_fileSystem.Execute.Path.GetDirectoryName(fullPathWithoutTrailingSeparator);
9497
if (string.Equals(
95-
_fileSystem.Execute.Path.GetPathRoot(FullPath),
98+
_fileSystem.Execute.Path.GetPathRoot(fullPathWithoutTrailingSeparator),
9699
FullPath,
97100
_fileSystem.Execute.StringComparisonMode)
98101
|| parentPath == null)

Tests/Testably.Abstractions.Tests/FileSystem/DirectoryInfo/Tests.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,8 @@ public async Task Parent_ArbitraryPaths_ShouldNotBeNull(string path1,
279279
IDirectoryInfo sut = FileSystem.DirectoryInfo.New(path);
280280

281281
await That(sut.Parent).IsNotNull();
282-
await That(sut?.Exists).IsFalse();
283-
await That(sut?.Parent).IsNotNull();
284-
await That(sut?.Parent?.Exists).IsFalse();
282+
await That(sut.Exists).IsFalse();
283+
await That(sut.Parent!.Exists).IsFalse();
285284
}
286285

287286
[Fact]
@@ -343,6 +342,21 @@ public async Task Parent_ToString_ShouldBeDirectoryNameOnNetFramework(
343342
}
344343
}
345344

345+
[Theory]
346+
[AutoData]
347+
public async Task Parent_WithTrailingDirectorySeparator_ShouldReturnCorrectParent(string path1,
348+
string path2)
349+
{
350+
string path = FileSystem.Path.Combine(path1, path2);
351+
string expectedParent = FileSystem.Path.GetFullPath(path1);
352+
353+
IDirectoryInfo sut =
354+
FileSystem.DirectoryInfo.New(path + FileSystem.Path.DirectorySeparatorChar);
355+
356+
await That(sut.Parent).IsNotNull();
357+
await That(sut.Parent!.FullName).IsEqualTo(expectedParent);
358+
}
359+
346360
[Fact]
347361
public async Task Root_Name_ShouldBeCorrect()
348362
{

Tests/Testably.Abstractions.Tests/FileSystem/File/AppendAllLinesAsyncTests.cs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Linq;
66
using System.Text;
77
using System.Threading;
8-
using System.Threading.Tasks;
98

109
namespace Testably.Abstractions.Tests.FileSystem.File;
1110

@@ -43,16 +42,32 @@ await FileSystem.File.AppendAllLinesAsync(path, contents, Encoding.UTF8,
4342
await That(Act).Throws<TaskCanceledException>().WithHResult(-2146233029);
4443
}
4544

45+
[Theory]
46+
[AutoData]
47+
public async Task AppendAllLinesAsync_Enumerable_WithoutEncoding_ShouldUseUtf8(
48+
string path)
49+
{
50+
string[] contents = ["breuß"];
51+
52+
await FileSystem.File.AppendAllLinesAsync(path, contents.AsEnumerable(),
53+
CancellationToken.None);
54+
55+
byte[] bytes = FileSystem.File.ReadAllBytes(path);
56+
await That(bytes.Length).IsEqualTo(6 + Environment.NewLine.Length);
57+
}
58+
4659
[Theory]
4760
[AutoData]
4861
public async Task AppendAllLinesAsync_ExistingFile_ShouldAppendLinesToFile(
4962
string path, List<string> previousContents, List<string> contents)
5063
{
5164
string expectedContent = string.Join(Environment.NewLine, previousContents.Concat(contents))
5265
+ Environment.NewLine;
53-
await FileSystem.File.AppendAllLinesAsync(path, previousContents, TestContext.Current.CancellationToken);
66+
await FileSystem.File.AppendAllLinesAsync(path, previousContents,
67+
TestContext.Current.CancellationToken);
5468

55-
await FileSystem.File.AppendAllLinesAsync(path, contents, TestContext.Current.CancellationToken);
69+
await FileSystem.File.AppendAllLinesAsync(path, contents,
70+
TestContext.Current.CancellationToken);
5671

5772
await That(FileSystem.File.Exists(path)).IsTrue();
5873
await That(FileSystem.File.ReadAllText(path)).IsEqualTo(expectedContent);
@@ -67,7 +82,8 @@ public async Task AppendAllLinesAsync_MissingDirectory_ShouldThrowDirectoryNotFo
6782

6883
async Task Act()
6984
{
70-
await FileSystem.File.AppendAllLinesAsync(filePath, contents, TestContext.Current.CancellationToken);
85+
await FileSystem.File.AppendAllLinesAsync(filePath, contents,
86+
TestContext.Current.CancellationToken);
7187
}
7288

7389
await That(Act).Throws<DirectoryNotFoundException>().WithHResult(-2147024893);
@@ -81,7 +97,8 @@ public async Task AppendAllLinesAsync_MissingFile_ShouldCreateFile(
8197
string expectedContent = string.Join(Environment.NewLine, contents)
8298
+ Environment.NewLine;
8399

84-
await FileSystem.File.AppendAllLinesAsync(path, contents, TestContext.Current.CancellationToken);
100+
await FileSystem.File.AppendAllLinesAsync(path, contents,
101+
TestContext.Current.CancellationToken);
85102

86103
await That(FileSystem.File.Exists(path)).IsTrue();
87104
await That(FileSystem.File.ReadAllText(path)).IsEqualTo(expectedContent);
@@ -94,7 +111,8 @@ public async Task AppendAllLinesAsync_NullContent_ShouldThrowArgumentNullExcepti
94111
{
95112
async Task Act()
96113
{
97-
await FileSystem.File.AppendAllLinesAsync(path, null!, TestContext.Current.CancellationToken);
114+
await FileSystem.File.AppendAllLinesAsync(path, null!,
115+
TestContext.Current.CancellationToken);
98116
}
99117

100118
await That(Act).Throws<ArgumentNullException>()
@@ -109,7 +127,8 @@ public async Task AppendAllLinesAsync_NullEncoding_ShouldThrowArgumentNullExcept
109127
{
110128
async Task Act()
111129
{
112-
await FileSystem.File.AppendAllLinesAsync(path, [], null!, TestContext.Current.CancellationToken);
130+
await FileSystem.File.AppendAllLinesAsync(path, [], null!,
131+
TestContext.Current.CancellationToken);
113132
}
114133

115134
await That(Act).Throws<ArgumentNullException>()
@@ -124,7 +143,8 @@ public async Task AppendAllLinesAsync_ShouldEndWithNewline(string path)
124143
string[] contents = ["foo", "bar"];
125144
string expectedResult = "foo" + Environment.NewLine + "bar" + Environment.NewLine;
126145

127-
await FileSystem.File.AppendAllLinesAsync(path, contents, TestContext.Current.CancellationToken);
146+
await FileSystem.File.AppendAllLinesAsync(path, contents,
147+
TestContext.Current.CancellationToken);
128148

129149
await That(FileSystem.File.Exists(path)).IsTrue();
130150
await That(FileSystem.File.ReadAllText(path)).IsEqualTo(expectedResult);
@@ -140,7 +160,8 @@ public async Task
140160

141161
async Task Act()
142162
{
143-
await FileSystem.File.AppendAllLinesAsync(path, contents, TestContext.Current.CancellationToken);
163+
await FileSystem.File.AppendAllLinesAsync(path, contents,
164+
TestContext.Current.CancellationToken);
144165
}
145166

146167
await That(Act).Throws<UnauthorizedAccessException>().WithHResult(-2147024891);
@@ -157,7 +178,8 @@ public async Task
157178
string path = new Fixture().Create<string>();
158179
string[] lines = new Fixture().Create<string[]>();
159180
lines[1] = specialLine;
160-
await FileSystem.File.AppendAllLinesAsync(path, lines, writeEncoding, TestContext.Current.CancellationToken);
181+
await FileSystem.File.AppendAllLinesAsync(path, lines, writeEncoding,
182+
TestContext.Current.CancellationToken);
161183

162184
string[] result = FileSystem.File.ReadAllLines(path, readEncoding);
163185

Tests/Testably.Abstractions.Tests/FileSystem/File/AppendAllLinesTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@ namespace Testably.Abstractions.Tests.FileSystem.File;
88
[FileSystemTests]
99
public partial class AppendAllLinesTests
1010
{
11+
[Theory]
12+
[AutoData]
13+
public async Task AppendAllLines_Enumerable_WithoutEncoding_ShouldUseUtf8(
14+
string path)
15+
{
16+
string[] contents = ["breuß"];
17+
18+
FileSystem.File.AppendAllLines(path, contents.AsEnumerable());
19+
20+
byte[] bytes = FileSystem.File.ReadAllBytes(path);
21+
await That(bytes.Length).IsEqualTo(6 + Environment.NewLine.Length);
22+
}
23+
1124
[Theory]
1225
[AutoData]
1326
public async Task AppendAllLines_ExistingFile_ShouldAppendLinesToFile(
@@ -112,4 +125,17 @@ public async Task AppendAllLines_WithDifferentEncoding_ShouldNotReturnWrittenTex
112125
await That(result).IsNotEqualTo(lines).InAnyOrder();
113126
await That(result[0]).IsEqualTo(lines[0]);
114127
}
128+
129+
[Theory]
130+
[AutoData]
131+
public async Task AppendAllLines_WithoutEncoding_ShouldUseUtf8(
132+
string path)
133+
{
134+
string[] contents = ["breuß"];
135+
136+
FileSystem.File.AppendAllLines(path, contents);
137+
138+
byte[] bytes = FileSystem.File.ReadAllBytes(path);
139+
await That(bytes.Length).IsEqualTo(6 + Environment.NewLine.Length);
140+
}
115141
}

Tests/Testably.Abstractions.Tests/FileSystem/File/AppendAllTextAsyncTests.cs

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@ async Task Act() =>
4444
public async Task AppendAllTextAsync_ExistingFile_ShouldAppendLinesToFile(
4545
string path, string previousContents, string contents)
4646
{
47-
await FileSystem.File.AppendAllTextAsync(path, previousContents, TestContext.Current.CancellationToken);
47+
await FileSystem.File.AppendAllTextAsync(path, previousContents,
48+
TestContext.Current.CancellationToken);
4849

49-
await FileSystem.File.AppendAllTextAsync(path, contents, TestContext.Current.CancellationToken);
50+
await FileSystem.File.AppendAllTextAsync(path, contents,
51+
TestContext.Current.CancellationToken);
5052

5153
await That(FileSystem.File.Exists(path)).IsTrue();
5254
await That(FileSystem.File.ReadAllText(path)).IsEqualTo(previousContents + contents);
@@ -61,7 +63,8 @@ public async Task AppendAllTextAsync_MissingDirectory_ShouldThrowDirectoryNotFou
6163

6264
async Task Act()
6365
{
64-
await FileSystem.File.AppendAllTextAsync(filePath, contents, TestContext.Current.CancellationToken);
66+
await FileSystem.File.AppendAllTextAsync(filePath, contents,
67+
TestContext.Current.CancellationToken);
6568
}
6669

6770
await That(Act).Throws<DirectoryNotFoundException>().WithHResult(-2147024893);
@@ -72,7 +75,8 @@ async Task Act()
7275
public async Task AppendAllTextAsync_MissingFile_ShouldCreateFile(
7376
string path, string contents)
7477
{
75-
await FileSystem.File.AppendAllTextAsync(path, contents, TestContext.Current.CancellationToken);
78+
await FileSystem.File.AppendAllTextAsync(path, contents,
79+
TestContext.Current.CancellationToken);
7680

7781
await That(FileSystem.File.Exists(path)).IsTrue();
7882
await That(FileSystem.File.ReadAllText(path)).IsEqualTo(contents);
@@ -84,7 +88,8 @@ public async Task AppendAllTextAsync_ShouldNotEndWithNewline(string path)
8488
{
8589
string contents = "foo";
8690

87-
await FileSystem.File.AppendAllTextAsync(path, contents, TestContext.Current.CancellationToken);
91+
await FileSystem.File.AppendAllTextAsync(path, contents,
92+
TestContext.Current.CancellationToken);
8893

8994
await That(FileSystem.File.Exists(path)).IsTrue();
9095
await That(FileSystem.File.ReadAllText(path)).IsEqualTo(contents);
@@ -100,7 +105,8 @@ public async Task
100105

101106
async Task Act()
102107
{
103-
await FileSystem.File.AppendAllTextAsync(path, contents, TestContext.Current.CancellationToken);
108+
await FileSystem.File.AppendAllTextAsync(path, contents,
109+
TestContext.Current.CancellationToken);
104110
}
105111

106112
await That(Act).Throws<UnauthorizedAccessException>().WithHResult(-2147024891);
@@ -114,13 +120,27 @@ public async Task AppendAllTextAsync_WithDifferentEncoding_ShouldNotReturnWritte
114120
string contents, Encoding writeEncoding, Encoding readEncoding)
115121
{
116122
string path = new Fixture().Create<string>();
117-
await FileSystem.File.AppendAllTextAsync(path, contents, writeEncoding, TestContext.Current.CancellationToken);
123+
await FileSystem.File.AppendAllTextAsync(path, contents, writeEncoding,
124+
TestContext.Current.CancellationToken);
118125

119126
string[] result = FileSystem.File.ReadAllLines(path, readEncoding);
120127

121128
await That(result).IsNotEqualTo([contents]);
122129
}
123130

131+
[Theory]
132+
[AutoData]
133+
public async Task AppendAllTextAsync_WithoutEncoding_ShouldUseUtf8(
134+
string path)
135+
{
136+
string contents = "breuß";
137+
138+
await FileSystem.File.AppendAllTextAsync(path, contents, CancellationToken.None);
139+
140+
byte[] bytes = FileSystem.File.ReadAllBytes(path);
141+
await That(bytes.Length).IsEqualTo(6);
142+
}
143+
124144
#if FEATURE_FILE_SPAN
125145
[Theory]
126146
[AutoData]
@@ -146,7 +166,8 @@ public async Task
146166
cts.Cancel();
147167

148168
async Task Act() =>
149-
await FileSystem.File.AppendAllTextAsync(path, contents.AsMemory(), Encoding.UTF8, cts.Token);
169+
await FileSystem.File.AppendAllTextAsync(path, contents.AsMemory(), Encoding.UTF8,
170+
cts.Token);
150171

151172
await That(Act).Throws<TaskCanceledException>().WithHResult(-2146233029);
152173
}
@@ -156,24 +177,28 @@ async Task Act() =>
156177
public async Task AppendAllTextAsync_ReadOnlyMemory_ExistingFile_ShouldAppendLinesToFile(
157178
string path, string previousContents, string contents)
158179
{
159-
await FileSystem.File.AppendAllTextAsync(path, previousContents, TestContext.Current.CancellationToken);
180+
await FileSystem.File.AppendAllTextAsync(path, previousContents,
181+
TestContext.Current.CancellationToken);
160182

161-
await FileSystem.File.AppendAllTextAsync(path, contents.AsMemory(), TestContext.Current.CancellationToken);
183+
await FileSystem.File.AppendAllTextAsync(path, contents.AsMemory(),
184+
TestContext.Current.CancellationToken);
162185

163186
await That(FileSystem.File.Exists(path)).IsTrue();
164187
await That(FileSystem.File.ReadAllText(path)).IsEqualTo(previousContents + contents);
165188
}
166189

167190
[Theory]
168191
[AutoData]
169-
public async Task AppendAllTextAsync_ReadOnlyMemory_MissingDirectory_ShouldThrowDirectoryNotFoundException(
170-
string missingPath, string fileName, string contents)
192+
public async Task
193+
AppendAllTextAsync_ReadOnlyMemory_MissingDirectory_ShouldThrowDirectoryNotFoundException(
194+
string missingPath, string fileName, string contents)
171195
{
172196
string filePath = FileSystem.Path.Combine(missingPath, fileName);
173197

174198
async Task Act()
175199
{
176-
await FileSystem.File.AppendAllTextAsync(filePath, contents.AsMemory(), TestContext.Current.CancellationToken);
200+
await FileSystem.File.AppendAllTextAsync(filePath, contents.AsMemory(),
201+
TestContext.Current.CancellationToken);
177202
}
178203

179204
await That(Act).Throws<DirectoryNotFoundException>().WithHResult(-2147024893);
@@ -184,7 +209,8 @@ async Task Act()
184209
public async Task AppendAllTextAsync_ReadOnlyMemory_MissingFile_ShouldCreateFile(
185210
string path, string contents)
186211
{
187-
await FileSystem.File.AppendAllTextAsync(path, contents.AsMemory(), TestContext.Current.CancellationToken);
212+
await FileSystem.File.AppendAllTextAsync(path, contents.AsMemory(),
213+
TestContext.Current.CancellationToken);
188214

189215
await That(FileSystem.File.Exists(path)).IsTrue();
190216
await That(FileSystem.File.ReadAllText(path)).IsEqualTo(contents);
@@ -196,7 +222,8 @@ public async Task AppendAllTextAsync_ReadOnlyMemory_ShouldNotEndWithNewline(stri
196222
{
197223
string contents = "foo";
198224

199-
await FileSystem.File.AppendAllTextAsync(path, contents.AsMemory(), TestContext.Current.CancellationToken);
225+
await FileSystem.File.AppendAllTextAsync(path, contents.AsMemory(),
226+
TestContext.Current.CancellationToken);
200227

201228
await That(FileSystem.File.Exists(path)).IsTrue();
202229
await That(FileSystem.File.ReadAllText(path)).IsEqualTo(contents);
@@ -212,7 +239,8 @@ public async Task
212239

213240
async Task Act()
214241
{
215-
await FileSystem.File.AppendAllTextAsync(path, contents.AsMemory(), TestContext.Current.CancellationToken);
242+
await FileSystem.File.AppendAllTextAsync(path, contents.AsMemory(),
243+
TestContext.Current.CancellationToken);
216244
}
217245

218246
await That(Act).Throws<UnauthorizedAccessException>().WithHResult(-2147024891);
@@ -222,16 +250,31 @@ async Task Act()
222250

223251
[Theory]
224252
[ClassData(typeof(TestDataGetEncodingDifference))]
225-
public async Task AppendAllTextAsync_ReadOnlyMemory_WithDifferentEncoding_ShouldNotReturnWrittenText(
226-
string contents, Encoding writeEncoding, Encoding readEncoding)
253+
public async Task
254+
AppendAllTextAsync_ReadOnlyMemory_WithDifferentEncoding_ShouldNotReturnWrittenText(
255+
string contents, Encoding writeEncoding, Encoding readEncoding)
227256
{
228257
string path = new Fixture().Create<string>();
229-
await FileSystem.File.AppendAllTextAsync(path, contents.AsMemory(), writeEncoding, TestContext.Current.CancellationToken);
258+
await FileSystem.File.AppendAllTextAsync(path, contents.AsMemory(), writeEncoding,
259+
TestContext.Current.CancellationToken);
230260

231261
string[] result = FileSystem.File.ReadAllLines(path, readEncoding);
232262

233263
await That(result).IsNotEqualTo([contents]);
234264
}
265+
266+
[Theory]
267+
[AutoData]
268+
public async Task AppendAllTextAsync_ReadOnlyMemory_WithoutEncoding_ShouldUseUtf8(
269+
string path)
270+
{
271+
string contents = "breuß";
272+
273+
await FileSystem.File.AppendAllTextAsync(path, contents.AsMemory(), CancellationToken.None);
274+
275+
byte[] bytes = FileSystem.File.ReadAllBytes(path);
276+
await That(bytes.Length).IsEqualTo(6);
277+
}
235278
#endif
236279
}
237280
#endif

0 commit comments

Comments
 (0)