Skip to content

Commit 25e44d7

Browse files
authored
feat: adjust timestamps when accessing and modifying files (#861)
1 parent 4e6e3ac commit 25e44d7

File tree

4 files changed

+139
-8
lines changed

4 files changed

+139
-8
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ public override void Copy(string sourceFileName, string destFileName, bool overw
125125

126126
var sourceFileData = mockFileDataAccessor.GetFile(sourceFileName);
127127
sourceFileData.CheckFileAccess(sourceFileName, FileAccess.Read);
128-
mockFileDataAccessor.AddFile(destFileName, new MockFileData(sourceFileData));
128+
var destFileData = new MockFileData(sourceFileData);
129+
destFileData.CreationTime = destFileData.LastAccessTime = DateTime.Now;
130+
mockFileDataAccessor.AddFile(destFileName, destFileData);
129131
}
130132

131133
/// <inheritdoc />

src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public class MockFileStream : MemoryStream
88
private readonly string path;
99
private readonly FileAccess access = FileAccess.ReadWrite;
1010
private readonly FileOptions options;
11-
11+
private readonly MockFileData fileData;
1212
private bool disposed;
1313

1414
/// <inheritdoc />
@@ -31,7 +31,7 @@ public MockFileStream(
3131
throw CommonExceptions.FileAlreadyExists(path);
3232
}
3333

34-
var fileData = mockFileDataAccessor.GetFile(path);
34+
fileData = mockFileDataAccessor.GetFile(path);
3535
fileData.CheckFileAccess(path, access);
3636

3737
var existingContents = fileData.Contents;
@@ -40,8 +40,8 @@ public MockFileStream(
4040
mode != FileMode.Truncate && mode != FileMode.Create;
4141
if (keepExistingContents)
4242
{
43-
Write(existingContents, 0, existingContents.Length);
44-
Seek(0, mode == FileMode.Append
43+
base.Write(existingContents, 0, existingContents.Length);
44+
base.Seek(0, mode == FileMode.Append
4545
? SeekOrigin.End
4646
: SeekOrigin.Begin);
4747
}
@@ -59,7 +59,9 @@ public MockFileStream(
5959
throw CommonExceptions.FileNotFound(path);
6060
}
6161

62-
mockFileDataAccessor.AddFile(path, new MockFileData(new byte[] { }));
62+
fileData = new MockFileData(new byte[] { });
63+
fileData.CreationTime = fileData.LastWriteTime = fileData.LastAccessTime = DateTime.Now;
64+
mockFileDataAccessor.AddFile(path, fileData);
6365
}
6466

6567
this.access = access;
@@ -71,6 +73,20 @@ public MockFileStream(
7173
/// <inheritdoc />
7274
public override bool CanWrite => access.HasFlag(FileAccess.Write);
7375

76+
/// <inheritdoc />
77+
public override int Read(byte[] buffer, int offset, int count)
78+
{
79+
fileData.LastAccessTime = DateTime.Now;
80+
return base.Read(buffer, offset, count);
81+
}
82+
83+
/// <inheritdoc />
84+
public override void Write(byte[] buffer, int offset, int count)
85+
{
86+
fileData.LastWriteTime = fileData.LastAccessTime = DateTime.Now;
87+
base.Write(buffer, offset, count);
88+
}
89+
7490
/// <inheritdoc />
7591
protected override void Dispose(bool disposing)
7692
{

tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileCopyTests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@ public void MockFile_Copy_ShouldOverwriteFileWhenOverwriteFlagIsTrue()
2727
Assert.AreEqual(copyResult.Contents, sourceContents.Contents);
2828
}
2929

30+
[Test]
31+
public void MockFile_Copy_ShouldAdjustTimestampsOnDestination()
32+
{
33+
var sourceFileName = XFS.Path(@"c:\source\demo.txt");
34+
var destFileName = XFS.Path(@"c:\source\demo_copy.txt");
35+
36+
var mockFileSystem = new MockFileSystem();
37+
mockFileSystem.AddFile(sourceFileName, "Original");
38+
mockFileSystem.File.Copy(sourceFileName, destFileName);
39+
40+
var sourceFileInfo = mockFileSystem.FileInfo.FromFileName(sourceFileName);
41+
var destFileInfo = mockFileSystem.FileInfo.FromFileName(destFileName);
42+
Assert.AreEqual(sourceFileInfo.LastWriteTime, destFileInfo.LastWriteTime);
43+
Assert.LessOrEqual(DateTime.Now - destFileInfo.CreationTime, TimeSpan.FromSeconds(1));
44+
Assert.AreEqual(destFileInfo.CreationTime, destFileInfo.LastAccessTime);
45+
}
46+
3047
[Test]
3148
public void MockFile_Copy_ShouldCloneContents()
3249
{

tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileOpenTests.cs

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.Threading.Tasks;
2+
13
namespace System.IO.Abstractions.TestingHelpers.Tests
24
{
35
using Collections.Generic;
@@ -217,7 +219,7 @@ public void MockFile_OpenText_ShouldRetainLastWriteTime()
217219
}
218220

219221
[Test]
220-
public void MockFile_OpenText_ShouldRetainLastAccessTime()
222+
public void MockFile_OpenText_ShouldUpdateLastAccessTime()
221223
{
222224
// Arrange
223225
var fs = new MockFileSystem();
@@ -234,7 +236,101 @@ public void MockFile_OpenText_ShouldRetainLastAccessTime()
234236
}
235237

236238
// Assert
237-
Assert.AreEqual(lastAccessTime, fs.FileInfo.FromFileName(filepath).LastAccessTime);
239+
Assert.LessOrEqual(DateTime.Now - fs.FileInfo.FromFileName(filepath).LastAccessTime, TimeSpan.FromSeconds(1));
240+
}
241+
242+
[Test]
243+
public void MockFile_Read_ShouldRetainCreationTimeAndUpdateLastAccessTime()
244+
{
245+
// Arrange
246+
var fs = new MockFileSystem();
247+
var filepath = XFS.Path(@"C:\TestData\test.txt");
248+
var file = new MockFileData(new byte[] { 1, 2, 3 });
249+
var lastAccessTime = new DateTime(2012, 03, 21);
250+
file.LastAccessTime = lastAccessTime;
251+
var creationTime = new DateTime(2012, 03, 20);
252+
file.CreationTime = creationTime;
253+
fs.AddFile(filepath, file);
254+
255+
var fi = fs.FileInfo.FromFileName(filepath);
256+
var stream = fi.OpenRead();
257+
var buffer = new byte[16];
258+
stream.Read(buffer, 0, buffer.Length);
259+
fi.Refresh();
260+
// Assert
261+
Assert.AreEqual(creationTime, fi.CreationTime);
262+
Assert.LessOrEqual(DateTime.Now - fi.LastAccessTime, TimeSpan.FromSeconds(1));
263+
}
264+
265+
[Test]
266+
public async Task MockFile_ReadAsync_ShouldRetainCreationTimeAndUpdateLastAccessTime()
267+
{
268+
// Arrange
269+
var fs = new MockFileSystem();
270+
var filepath = XFS.Path(@"C:\TestData\test.txt");
271+
var file = new MockFileData(new byte[] { 1, 2, 3 });
272+
var lastAccessTime = new DateTime(2012, 03, 21);
273+
file.LastAccessTime = lastAccessTime;
274+
var creationTime = new DateTime(2012, 03, 20);
275+
file.CreationTime = creationTime;
276+
fs.AddFile(filepath, file);
277+
278+
var fi = fs.FileInfo.FromFileName(filepath);
279+
var stream = fi.OpenRead();
280+
var buffer = new byte[16];
281+
await stream.ReadAsync(buffer, 0, buffer.Length);
282+
fi.Refresh();
283+
// Assert
284+
Assert.AreEqual(creationTime, fi.CreationTime);
285+
Assert.LessOrEqual(DateTime.Now - fi.LastAccessTime, TimeSpan.FromSeconds(1));
286+
}
287+
288+
[Test]
289+
public void MockFile_Write_ShouldRetainCreationTimeAndUpdateLastAccessTimeAndLastWriteTime()
290+
{
291+
// Arrange
292+
var fs = new MockFileSystem();
293+
var filepath = XFS.Path(@"C:\TestData\test.txt");
294+
var file = new MockFileData(new byte[] { 1, 2, 3 });
295+
var lastAccessTime = new DateTime(2012, 03, 21);
296+
file.LastAccessTime = lastAccessTime;
297+
var creationTime = new DateTime(2012, 03, 20);
298+
file.CreationTime = creationTime;
299+
fs.AddFile(filepath, file);
300+
301+
var fi = fs.FileInfo.FromFileName(filepath);
302+
var stream = fi.OpenWrite();
303+
var buffer = new byte[16];
304+
stream.Write(buffer, 0, buffer.Length);
305+
fi.Refresh();
306+
// Assert
307+
Assert.AreEqual(creationTime, fi.CreationTime);
308+
Assert.LessOrEqual(DateTime.Now - fi.LastAccessTime, TimeSpan.FromSeconds(1));
309+
Assert.LessOrEqual(DateTime.Now - fi.LastWriteTime, TimeSpan.FromSeconds(1));
310+
}
311+
312+
[Test]
313+
public async Task MockFile_WriteAsync_ShouldRetainCreationTimeAndUpdateLastAccessTimeAndLastWriteTime()
314+
{
315+
// Arrange
316+
var fs = new MockFileSystem();
317+
var filepath = XFS.Path(@"C:\TestData\test.txt");
318+
var file = new MockFileData(new byte[] { 1, 2, 3 });
319+
var lastAccessTime = new DateTime(2012, 03, 21);
320+
file.LastAccessTime = lastAccessTime;
321+
var creationTime = new DateTime(2012, 03, 20);
322+
file.CreationTime = creationTime;
323+
fs.AddFile(filepath, file);
324+
325+
var fi = fs.FileInfo.FromFileName(filepath);
326+
var stream = fi.OpenWrite();
327+
var buffer = new byte[16];
328+
await stream.WriteAsync(buffer, 0, buffer.Length);
329+
fi.Refresh();
330+
// Assert
331+
Assert.AreEqual(creationTime, fi.CreationTime);
332+
Assert.LessOrEqual(DateTime.Now - fi.LastAccessTime, TimeSpan.FromSeconds(1));
333+
Assert.LessOrEqual(DateTime.Now - fi.LastWriteTime, TimeSpan.FromSeconds(1));
238334
}
239335

240336
[Test]

0 commit comments

Comments
 (0)