Skip to content

Commit 7a85165

Browse files
rkoeningerfgreinacher
authored andcommitted
Implemented MockFile.Create methods (#368)
Fixes #331 Fixes #332 Fixes #333 Implemented MockFile.Create methods as discussed in referenced issues. No unit test for the overload that just takes a buffer size as it's ignored. MockFileStream now receives a FileOptions which it checks on close to see if it should delete the file (FileOptions.DeleteOnClose) or encrypt it (FileOptions.Encrypted). The overload that takes FileSecurity doesn't do anything with the argument, just passes it on. No unit test for this overload.
1 parent 63b5d5c commit 7a85165

File tree

4 files changed

+139
-32
lines changed

4 files changed

+139
-32
lines changed

System.IO.Abstractions.TestingHelpers.Tests/MockFileCreateTests.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,5 +217,67 @@ public void MockFile_Create_TruncateShouldClearFileContentsOnOpen()
217217
// Assert
218218
Assert.That(fileSystem.File.ReadAllText(testFileName), Is.EqualTo(string.Empty));
219219
}
220+
221+
[Test]
222+
public void MockFile_Create_DeleteOnCloseOption_FileExistsWhileStreamIsOpen()
223+
{
224+
var root = XFS.Path(@"C:\");
225+
var filePath = XFS.Path(@"C:\test.txt");
226+
var fileSystem = new MockFileSystem();
227+
fileSystem.Directory.CreateDirectory(root);
228+
229+
using (fileSystem.File.Create(filePath, 4096, FileOptions.DeleteOnClose))
230+
{
231+
Assert.IsTrue(fileSystem.File.Exists(filePath));
232+
}
233+
}
234+
235+
[Test]
236+
public void MockFile_Create_DeleteOnCloseOption_FileDeletedWhenStreamIsClosed()
237+
{
238+
var root = XFS.Path(@"C:\");
239+
var filePath = XFS.Path(@"C:\test.txt");
240+
var fileSystem = new MockFileSystem();
241+
fileSystem.Directory.CreateDirectory(root);
242+
243+
using (fileSystem.File.Create(filePath, 4096, FileOptions.DeleteOnClose))
244+
{
245+
}
246+
247+
Assert.IsFalse(fileSystem.File.Exists(filePath));
248+
}
249+
250+
#if NET40
251+
[Test]
252+
public void MockFile_Create_EncryptedOption_FileNotYetEncryptedsWhenStreamIsOpen()
253+
{
254+
var root = XFS.Path(@"C:\");
255+
var filePath = XFS.Path(@"C:\test.txt");
256+
var fileSystem = new MockFileSystem();
257+
fileSystem.Directory.CreateDirectory(root);
258+
259+
using (var stream = fileSystem.File.Create(filePath, 4096, FileOptions.Encrypted))
260+
{
261+
var fileInfo = fileSystem.FileInfo.FromFileName(filePath);
262+
Assert.IsFalse(fileInfo.Attributes.HasFlag(FileAttributes.Encrypted));
263+
}
264+
}
265+
266+
[Test]
267+
public void MockFile_Create_EncryptedOption_EncryptsFileWhenStreamIsClose()
268+
{
269+
var root = XFS.Path(@"C:\");
270+
var filePath = XFS.Path(@"C:\test.txt");
271+
var fileSystem = new MockFileSystem();
272+
fileSystem.Directory.CreateDirectory(root);
273+
274+
using (var stream = fileSystem.File.Create(filePath, 4096, FileOptions.Encrypted))
275+
{
276+
}
277+
278+
var fileInfo = fileSystem.FileInfo.FromFileName(filePath);
279+
Assert.IsTrue(fileInfo.Attributes.HasFlag(FileAttributes.Encrypted));
280+
}
281+
#endif
220282
}
221283
}

System.IO.Abstractions.TestingHelpers/MockFile.cs

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -133,41 +133,46 @@ public override void Copy(string sourceFileName, string destFileName, bool overw
133133
mockFileDataAccessor.AddFile(destFileName, new MockFileData(sourceFileData));
134134
}
135135

136-
public override Stream Create(string path)
136+
public override Stream Create(string path) =>
137+
Create(path, 4096);
138+
139+
public override Stream Create(string path, int bufferSize) =>
140+
Create(path, bufferSize, FileOptions.None);
141+
142+
public override Stream Create(string path, int bufferSize, FileOptions options) =>
143+
CreateInternal(path, bufferSize, options, null);
144+
145+
#if NET40
146+
public override Stream Create(string path, int bufferSize, FileOptions options, FileSecurity fileSecurity) =>
147+
CreateInternal(path, bufferSize, options, fileSecurity);
148+
#endif
149+
150+
private Stream CreateInternal(string path, int bufferSize, FileOptions options, FileSecurity fileSecurity)
137151
{
138152
if (path == null)
139153
{
140154
throw new ArgumentNullException(nameof(path), "Path cannot be null.");
141155
}
142-
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
143156

157+
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, nameof(path));
144158
var directoryPath = mockPath.GetDirectoryName(path);
159+
145160
if (!mockFileDataAccessor.Directory.Exists(directoryPath))
146161
{
147-
throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("COULD_NOT_FIND_PART_OF_PATH_EXCEPTION"), path));
162+
throw new DirectoryNotFoundException(
163+
string.Format(
164+
CultureInfo.InvariantCulture,
165+
StringResources.Manager.GetString("COULD_NOT_FIND_PART_OF_PATH_EXCEPTION"),
166+
path));
148167
}
149168

150-
mockFileDataAccessor.AddFile(path, new MockFileData(new byte[0]));
151-
var stream = OpenWrite(path);
152-
return stream;
153-
}
154-
155-
public override Stream Create(string path, int bufferSize)
156-
{
157-
throw new NotImplementedException(StringResources.Manager.GetString("NOT_IMPLEMENTED_EXCEPTION"));
158-
}
159-
160-
public override Stream Create(string path, int bufferSize, FileOptions options)
161-
{
162-
throw new NotImplementedException(StringResources.Manager.GetString("NOT_IMPLEMENTED_EXCEPTION"));
163-
}
164-
165-
#if NET40
166-
public override Stream Create(string path, int bufferSize, FileOptions options, FileSecurity fileSecurity)
167-
{
168-
throw new NotImplementedException(StringResources.Manager.GetString("NOT_IMPLEMENTED_EXCEPTION"));
169+
var mockFileData = new MockFileData(new byte[0])
170+
{
171+
AccessControl = fileSecurity
172+
};
173+
mockFileDataAccessor.AddFile(path, mockFileData);
174+
return OpenWriteInternal(path, options);
169175
}
170-
#endif
171176

172177
public override StreamWriter CreateText(string path)
173178
{
@@ -383,7 +388,15 @@ public override Stream Open(string path, FileMode mode, FileAccess access)
383388
return Open(path, mode, access, FileShare.None);
384389
}
385390

386-
public override Stream Open(string path, FileMode mode, FileAccess access, FileShare share)
391+
public override Stream Open(string path, FileMode mode, FileAccess access, FileShare share) =>
392+
OpenInternal(path, mode, access, share, FileOptions.None);
393+
394+
private Stream OpenInternal(
395+
string path,
396+
FileMode mode,
397+
FileAccess access,
398+
FileShare share,
399+
FileOptions options)
387400
{
388401
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
389402

@@ -412,7 +425,7 @@ public override Stream Open(string path, FileMode mode, FileAccess access, FileS
412425
else if (mode == FileMode.Append)
413426
streamType = MockFileStream.StreamType.APPEND;
414427

415-
return new MockFileStream(mockFileDataAccessor, path, streamType);
428+
return new MockFileStream(mockFileDataAccessor, path, streamType, options);
416429
}
417430

418431
public override Stream OpenRead(string path)
@@ -430,11 +443,12 @@ public override StreamReader OpenText(string path)
430443
OpenRead(path));
431444
}
432445

433-
public override Stream OpenWrite(string path)
446+
public override Stream OpenWrite(string path) => OpenWriteInternal(path, FileOptions.None);
447+
448+
private Stream OpenWriteInternal(string path, FileOptions options)
434449
{
435450
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
436-
437-
return Open(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
451+
return OpenInternal(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, options);
438452
}
439453

440454
public override byte[] ReadAllBytes(string path)

System.IO.Abstractions.TestingHelpers/MockFileStream.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public class MockFileStream : MemoryStream
66
private readonly IMockFileDataAccessor mockFileDataAccessor;
77
private readonly string path;
88
private readonly bool canWrite = true;
9+
private readonly FileOptions options;
910
private bool disposed;
1011

1112
public enum StreamType
@@ -16,10 +17,23 @@ public enum StreamType
1617
TRUNCATE
1718
}
1819

19-
public MockFileStream(IMockFileDataAccessor mockFileDataAccessor, string path, StreamType streamType)
20+
public MockFileStream(
21+
IMockFileDataAccessor mockFileDataAccessor,
22+
string path,
23+
StreamType streamType)
24+
: this(mockFileDataAccessor, path, streamType, FileOptions.None)
25+
{
26+
}
27+
28+
public MockFileStream(
29+
IMockFileDataAccessor mockFileDataAccessor,
30+
string path,
31+
StreamType streamType,
32+
FileOptions options)
2033
{
2134
this.mockFileDataAccessor = mockFileDataAccessor ?? throw new ArgumentNullException(nameof(mockFileDataAccessor));
2235
this.path = path;
36+
this.options = options;
2337

2438
if (mockFileDataAccessor.FileExists(path))
2539
{
@@ -51,6 +65,7 @@ public MockFileStream(IMockFileDataAccessor mockFileDataAccessor, string path, S
5165
public override void Close()
5266
{
5367
InternalFlush();
68+
OnClose();
5469
}
5570
#else
5671
protected override void Dispose(bool disposing)
@@ -61,6 +76,7 @@ protected override void Dispose(bool disposing)
6176
}
6277
InternalFlush();
6378
base.Dispose(disposing);
79+
OnClose();
6480
disposed = true;
6581
}
6682
#endif
@@ -84,5 +100,20 @@ private void InternalFlush()
84100
mockFileData.Contents = data;
85101
}
86102
}
103+
104+
private void OnClose()
105+
{
106+
if (options.HasFlag(FileOptions.DeleteOnClose) && mockFileDataAccessor.FileExists(path))
107+
{
108+
mockFileDataAccessor.RemoveFile(path);
109+
}
110+
111+
#if NET40
112+
if (options.HasFlag(FileOptions.Encrypted) && mockFileDataAccessor.FileExists(path))
113+
{
114+
mockFileDataAccessor.FileInfo.FromFileName(path).Encrypt();
115+
}
116+
#endif
117+
}
87118
}
88119
}

System.IO.Abstractions.TestingHelpers/MockFileStreamFactory.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@ public Stream Create(string path, FileMode mode, FileAccess access, FileShare sh
2424
=> new MockFileStream(mockFileSystem, path, GetStreamType(mode, access));
2525

2626
public Stream Create(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
27-
=> new MockFileStream(mockFileSystem, path, GetStreamType(mode, access));
27+
=> new MockFileStream(mockFileSystem, path, GetStreamType(mode, access), options);
2828

2929
public Stream Create(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync)
3030
=> new MockFileStream(mockFileSystem, path, GetStreamType(mode, access));
3131

3232
#if NET40
3333
public Stream Create(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options, FileSecurity fileSecurity)
34-
=> new MockFileStream(mockFileSystem, path, GetStreamType(mode));
34+
=> new MockFileStream(mockFileSystem, path, GetStreamType(mode), options);
3535

3636
public Stream Create(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options)
37-
=> new MockFileStream(mockFileSystem, path, GetStreamType(mode));
37+
=> new MockFileStream(mockFileSystem, path, GetStreamType(mode), options);
3838
#endif
3939

4040
#if NET40 || NETSTANDARD_20

0 commit comments

Comments
 (0)