diff --git a/System.IO.Abstractions.TestingHelpers.Tests/MockFileStreamTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/MockFileStreamTests.cs index 89fe72551..7393af978 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/MockFileStreamTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/MockFileStreamTests.cs @@ -76,6 +76,46 @@ public void MockFileStream_Constructor_ReadTypeNotWritable() Assert.IsFalse(stream.CanWrite); Assert.Throws(() => stream.WriteByte(1)); } + + [Test] + [TestCase(FileShare.None, MockFileStream.StreamType.READ)] + [TestCase(FileShare.None, MockFileStream.StreamType.WRITE)] + [TestCase(FileShare.None, MockFileStream.StreamType.APPEND)] + [TestCase(FileShare.None, MockFileStream.StreamType.TRUNCATE)] + [TestCase(FileShare.Read, MockFileStream.StreamType.WRITE)] + [TestCase(FileShare.Read, MockFileStream.StreamType.APPEND)] + [TestCase(FileShare.Read, MockFileStream.StreamType.TRUNCATE)] + [TestCase(FileShare.Write, MockFileStream.StreamType.READ)] + public void MockFileStream_Constructor_Insufficient_FileShare_Throws_Exception(FileShare allowedFileShare, MockFileStream.StreamType streamType) + { + var filePath = @"C:\locked.txt"; + var fileSystem = new MockFileSystem(new Dictionary + { + { filePath, new MockFileData("cannot access") { AllowedFileShare = allowedFileShare } } + }); + + Assert.Throws(() => new MockFileStream(fileSystem, filePath, streamType)); + } + + [Test] + [TestCase(FileShare.Read, MockFileStream.StreamType.READ)] + [TestCase(FileShare.Read | FileShare.Write, MockFileStream.StreamType.READ)] + [TestCase(FileShare.Read | FileShare.Write, MockFileStream.StreamType.APPEND)] + [TestCase(FileShare.Read | FileShare.Write, MockFileStream.StreamType.TRUNCATE)] + [TestCase(FileShare.ReadWrite, MockFileStream.StreamType.READ)] + [TestCase(FileShare.ReadWrite, MockFileStream.StreamType.WRITE)] + [TestCase(FileShare.ReadWrite, MockFileStream.StreamType.APPEND)] + [TestCase(FileShare.ReadWrite, MockFileStream.StreamType.TRUNCATE)] + public void MockFileStream_Constructor_Sufficient_FileShare_Does_Not_Throw_Exception(FileShare allowedFileShare, MockFileStream.StreamType streamType) + { + var filePath = @"C:\locked.txt"; + var fileSystem = new MockFileSystem(new Dictionary + { + { filePath, new MockFileData("cannot access") { AllowedFileShare = allowedFileShare } } + }); + + Assert.DoesNotThrow(() => new MockFileStream(fileSystem, filePath, streamType)); + } [Test] public void MockFileStream_Close_MultipleCallsDontThrow() diff --git a/System.IO.Abstractions.TestingHelpers/MockFileStream.cs b/System.IO.Abstractions.TestingHelpers/MockFileStream.cs index a6bee6e96..2fb38f59a 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFileStream.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFileStream.cs @@ -39,11 +39,14 @@ public MockFileStream( this.mockFileDataAccessor = mockFileDataAccessor ?? throw new ArgumentNullException(nameof(mockFileDataAccessor)); this.path = path; this.options = options; - + if (mockFileDataAccessor.FileExists(path)) { + var fileData = mockFileDataAccessor.GetFile(path); + fileData.CheckFileAccess(path, streamType != StreamType.READ ? FileAccess.Write : FileAccess.Read); + /* only way to make an expandable MemoryStream that starts with a particular content */ - var data = mockFileDataAccessor.GetFile(path).Contents; + var data = fileData.Contents; if (data != null && data.Length > 0 && streamType != StreamType.TRUNCATE) { Write(data, 0, data.Length); @@ -60,7 +63,7 @@ public MockFileStream( } mockFileDataAccessor.AddFile(path, new MockFileData(new byte[] { })); } - + canWrite = streamType != StreamType.READ; }