diff --git a/TestHelpers.Tests/MockFileDataLazyLoadContentTests.cs b/TestHelpers.Tests/MockFileDataLazyLoadContentTests.cs new file mode 100644 index 000000000..0d5c8a011 --- /dev/null +++ b/TestHelpers.Tests/MockFileDataLazyLoadContentTests.cs @@ -0,0 +1,163 @@ +using System.Linq; +using NUnit.Framework; + +namespace System.IO.Abstractions.TestingHelpers.Tests +{ + [TestFixture] + public class MockFileDataLazyLoadContentTests + { + [Test] + public void MockFileData_AcceptsFuncAndReturnsContents() + { + var contents = Enumerable.Range(0, 100).Select(_ => (byte)_).ToArray(); + var x = new MockFileData(() => contents); + Assert.AreEqual(x.Contents, contents); + } + + [Test] + public void MockFileData_LazyLoadFuncIsCalledOnDemand() + { + var contents = Enumerable.Range(19, 42).Select(_ => (byte)_).ToArray(); + var lazyLoadFuncHasBeenCalled = false; + var x = new MockFileData(() => + { + lazyLoadFuncHasBeenCalled = true; + return contents; + }); + Assert.IsFalse(lazyLoadFuncHasBeenCalled); + Assert.AreEqual(x.Contents, contents); + Assert.IsTrue(lazyLoadFuncHasBeenCalled); + } + + [Test] + public void MockFileData_FuncConstructorThrowsOnNullArgument() + { + Assert.Throws(() => new MockFileData((Func)null)); + } + + } + + [TestFixture] + public class MockFileDataLazyLoadAndDirectoryBrowsing + { + private class ContentCalledException : Exception + { + public ContentCalledException() : base("Content was called") + { + } + } + + private IFileSystem fileSystem; + + [SetUp] + public void SetUp() + { + var mockFileData = new MockFileData(() => + { + throw new ContentCalledException(); + }); + fileSystem = new MockFileSystem(); + ((MockFileSystem)fileSystem).AddFile(@"b:\thefile.useless", mockFileData); + } + + [Test] + public void TestThatFileExist() + { + Assert.IsTrue(fileSystem.File.Exists(@"b:\thefile.useless")); + } + + [Test] + public void TestThatDirectoryGetFilesDoesNotLoadContent() + { + Assert.AreEqual(1, fileSystem.Directory.GetFiles(@"B:\").Length); + } + + [Test] + public void TestThatDirectoryInfoGetFilesDoesNotLoadContent() + { + Assert.AreEqual(1, fileSystem.DirectoryInfo.FromDirectoryName(@"B:\").GetFiles().Length); + } + + [Test] + public void TestThatContentIsBeingUsedOnDemandWhenTheFileSizeIsRetrievedThruFileInfoObject() + { + var file = fileSystem.DirectoryInfo.FromDirectoryName(@"B:\").GetFiles().Single(); + long fileLength = -1; + Assert.Throws(typeof(ContentCalledException), () => fileLength = file.Length); + Assert.AreEqual(-1, fileLength); + } + + } + + [TestFixture] + public class MockFileDataInsertFileInfoObjectTests + { + private IFileSystem destinationFileSystem; + private FileInfoBase destinationFileInfo; + + private const string sourceFileName = @"a:\c.bin"; + private const string destinationFileName = @"b:\c\d.bin"; + private readonly byte[] fileContent = Enumerable.Range(3, 14).Select(_ => (byte)_).ToArray(); + private const FileAttributes attributes = FileAttributes.Hidden; + private readonly DateTime dateCreated = DateTime.Now.AddHours(-3); + private readonly DateTime dateLastWritten = DateTime.Now.AddHours(-2); + private readonly DateTime dateLastAccessed = DateTime.Now.AddHours(-1); + + [TestFixtureSetUp] + public void MockFileData_AcceptsFuncAndReturnsContents() + { + // create a file in a source file system + var sourceFileSystem = new MockFileSystem(); + sourceFileSystem.File.WriteAllBytes(sourceFileName, fileContent); + sourceFileSystem.File.SetAttributes(sourceFileName, attributes); + sourceFileSystem.File.SetCreationTime(sourceFileName, dateCreated); + sourceFileSystem.File.SetLastWriteTime(sourceFileName, dateLastWritten); + sourceFileSystem.File.SetLastAccessTime(sourceFileName, dateLastAccessed); + var sourceFile = sourceFileSystem.DirectoryInfo.FromDirectoryName(Path.GetDirectoryName(sourceFileName)).GetFiles().Single(); + + // create a new destination file system and copy the source file there + var dfs = new MockFileSystem(); + dfs.AddFile(destinationFileName, new MockFileData(sourceFileSystem, sourceFile)); + destinationFileInfo = dfs.DirectoryInfo.FromDirectoryName(Path.GetDirectoryName(destinationFileName)).GetFiles().Single(); + destinationFileSystem = dfs; + } + + [Test] + public void TestThatFileHasRightName() + { + Assert.AreEqual(destinationFileName, destinationFileInfo.FullName); + } + + [Test] + public void TestThatFileHasRightContent() + { + Assert.AreEqual(fileContent, destinationFileSystem.File.ReadAllBytes(destinationFileInfo.FullName)); + } + + [Test] + public void TestThatFileHasRightAttributes() + { + Assert.AreEqual(attributes, destinationFileInfo.Attributes); + } + + [Test] + public void TestThatFileHasRightCreationTime() + { + Assert.AreEqual(dateCreated, destinationFileInfo.CreationTime); + } + + [Test] + public void TestThatFileHasRightWriteTime() + { + Assert.AreEqual(dateLastWritten, destinationFileInfo.LastWriteTime); + } + + [Test] + public void TestThatFileHasRightAccessTime() + { + Assert.AreEqual(dateLastAccessed, destinationFileInfo.LastAccessTime); + } + + } + +} diff --git a/TestHelpers.Tests/TestHelpers.Tests.csproj b/TestHelpers.Tests/TestHelpers.Tests.csproj index 0e5cd6409..c62a17478 100644 --- a/TestHelpers.Tests/TestHelpers.Tests.csproj +++ b/TestHelpers.Tests/TestHelpers.Tests.csproj @@ -105,6 +105,7 @@ + diff --git a/TestingHelpers/MockFileData.cs b/TestingHelpers/MockFileData.cs index 4265e034e..5b956eefb 100644 --- a/TestingHelpers/MockFileData.cs +++ b/TestingHelpers/MockFileData.cs @@ -27,6 +27,7 @@ public class MockFileData /// The actual contents of the file. /// private byte[] contents; + private readonly Func lazyLoadContent; /// /// The date and time the was created. @@ -97,11 +98,47 @@ public MockFileData(byte[] contents) } /// - /// Gets or sets the byte contents of the . + /// Allows insertion of a file where the content is lazy loaded through a Func. /// + /// Func to return the file's content the first time it is requested. + public MockFileData(Func lazyLoadContent) + { + if (lazyLoadContent == null) + { + throw new ArgumentNullException("lazyLoadContent"); + } + this.lazyLoadContent = lazyLoadContent; + } + + /// + /// Allows insertion of a FileSystemInfoBase object into a new file system. Attributes and time stamps + /// are copied, and the content will be lazy loaded the first time it is touched. + /// + /// The source file system where the file info originates + /// The source file to be copied + public MockFileData(IFileSystem fileSystem, FileSystemInfoBase fileInfo) + { + if (fileSystem == null) + { + throw new ArgumentNullException("fileSystem"); + } + if (fileInfo == null) + { + throw new ArgumentNullException("fileInfo"); + } + creationTime = fileInfo.CreationTime; + lastAccessTime = fileInfo.LastAccessTime; + lastWriteTime = fileInfo.LastWriteTime; + attributes = fileInfo.Attributes; + lazyLoadContent = () => fileSystem.File.ReadAllBytes(fileInfo.FullName); + } + + /// + /// Gets or sets the byte contents of the . + /// public byte[] Contents { - get { return contents; } + get { return contents ?? (contents = lazyLoadContent()); } set { contents = value; } }