public void StructuredDocumentLogsWithCorrectDepth(string logEntry, int depth)
        {
            //Arrange
            var fileSystem         = new Mock <IFileSystem>();
            var fileBase           = new Mock <FileBase>();
            var stream             = new TestMemoryStream();
            var structuredDocument = new StructuredTextDocument <string>(@"x:\log.log", Id, Id);

            fileSystem.Setup(f => f.File).Returns(fileBase.Object);

            fileBase.Setup(f => f.Open(It.IsAny <string>(), It.IsAny <FileMode>(), It.IsAny <FileAccess>(), It.IsAny <FileShare>()))
            .Returns(stream);
            FileSystemHelpers.Instance = fileSystem.Object;

            //Act
            structuredDocument.Write(logEntry, depth);

            //Assert
            Assert.True(stream.Position > 0, "must write data");
            stream.Position = 0;
            var result       = new StreamReader(stream).ReadToEnd();
            var writtenDepth = StructuredTextDocument.GetEntryDepth(result);

            Assert.Equal(depth, writtenDepth);
            Assert.Equal(string.Concat(logEntry, System.Environment.NewLine), result.Substring(writtenDepth));
            stream.RealDispose();
        }
예제 #2
0
        public Stream OpenAppend()
        {
            var stream = new TestMemoryStream(this);

            stream.Write(_content, 0, _content.Length);
            return(stream);
        }
예제 #3
0
    private void Test()
    {
        TestEnity _t = new TestEnity();

        return;

        TestMemoryStream.TestWrite();
    }
예제 #4
0
        public void Can_compress_short_block()
        {
            var compressedStream = new TestMemoryStream();
            var huffmanStream    = new HuffmanStream(compressedStream);

            huffmanStream.Write(new byte[] { 0xB9, 0x80, 0x1F }, 0, 3);

            compressedStream.ActualBytes.Should().BeEquivalentTo(new byte[] { 0xB3, 0x32, 0x98, 0xDA });
        }
예제 #5
0
        public void Can_compress_long_block()
        {
            var actualCompressedStream = new TestMemoryStream();
            var huffmanStream          = new HuffmanStream(actualCompressedStream);

            huffmanStream.Write(decompressed, 0, decompressed.Length);

            actualCompressedStream.ActualBytes.Should().BeEquivalentTo(compressed);
        }
        public async Task WriteCharArrayAsync_WritesToStream(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new ProtoResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            using (writer)
                await writer.WriteAsync((new string('a', byteLength)).ToCharArray());

            // Assert
            Assert.Equal(byteLength, stream.Length);
        }
        public void NoDataWritten_Flush_DoesNotFlushUnderlyingStream()
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new ProtoResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            writer.Flush();

            // Assert
            Assert.Equal(0, stream.FlushCallCount);
            Assert.Equal(0, stream.Length);
        }
        public async Task DoesNotClose_UnderlyingStream_OnDisposingWriter()
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            await writer.WriteAsync("Hello");
            writer.Close();

            // Assert
            Assert.Equal(0, stream.CloseCallCount);
        }
예제 #9
0
        public async Task NoDataWritten_FlushAsync_DoesNotFlushUnderlyingStream()
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            await writer.FlushAsync();

            // Assert
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(0, stream.Length);
        }
예제 #10
0
        public async Task FlushesBuffer_OnFlushAsync(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);
            await writer.WriteAsync(new string('a', byteLength));

            // Act
            await writer.FlushAsync();

            // Assert
            Assert.Equal(1, stream.FlushAsyncCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
예제 #11
0
        public async Task DoesNotDispose_UnderlyingStream_OnDisposingWriter()
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            await writer.WriteAsync("Hello world");

            writer.Dispose();

            // Assert
            Assert.Equal(0, stream.DisposeCallCount);
        }
예제 #12
0
        public void FlushesBuffer_OnFlush(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            writer.Write(new string('a', byteLength));

            // Act
            writer.Flush();

            // Assert
            Assert.Equal(1, stream.FlushCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
예제 #13
0
        public void WriteCharArray_WritesToStream(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            using (writer)
            {
                writer.Write((new string('a', byteLength)).ToCharArray());
            }

            // Assert
            Assert.Equal(byteLength, stream.Length);
        }
예제 #14
0
        public async Task WriteReadOnlyMemoryAsync_TokenCanceled_ReturnsCanceledTask()
        {
            // Arrange
            var stream = new TestMemoryStream();

            using var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);
            var memory            = new ReadOnlyMemory <char>(new char[] { 'a' });
            var cancellationToken = new CancellationToken(true);

            // Act
            await Assert.ThrowsAsync <TaskCanceledException>(async() => await writer.WriteAsync(memory, cancellationToken));

            // Assert
            Assert.Equal(0, stream.Length);
        }
예제 #15
0
        public async Task DoesNotFlush_UnderlyingStream_OnClosingWriter()
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            await writer.WriteAsync("Hello");

            writer.Close();

            // Assert
            Assert.Equal(0, stream.FlushCallCount);
            Assert.Equal(0, stream.FlushAsyncCallCount);
        }
        public async Task WriteCharAsync_WritesToStream(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new ProtoResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            using (writer)
                for (var i = 0; i < byteLength; i++)
                {
                    await writer.WriteAsync('a');
                }

            // Assert
            Assert.Equal(byteLength, stream.Length);
        }
예제 #17
0
        public void WriteReadOnlySpanChar_WritesToStream(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            using (writer)
            {
                var array = new string('a', byteLength).ToCharArray();
                var span  = new ReadOnlySpan <char>(array);
                writer.Write(span);
            }

            // Assert
            Assert.Equal(byteLength, stream.Length);
        }
예제 #18
0
        public async Task WriteReadOnlyMemoryAsync_WritesToStream(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            using (writer)
            {
                var array  = new string('a', byteLength).ToCharArray();
                var memory = new ReadOnlyMemory <char>(array);
                await writer.WriteAsync(memory);
            }

            // Assert
            Assert.Equal(byteLength, stream.Length);
        }
예제 #19
0
        public async Task FlushesBuffer_ButNotStream_OnFlushAsync(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);
            await writer.WriteAsync(new string('a', byteLength));

            var expectedWriteCount = Math.Ceiling((double)byteLength / HttpResponseStreamWriter.DefaultBufferSize);

            // Act
            await writer.FlushAsync();

            // Assert
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(expectedWriteCount, stream.WriteAsyncCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
예제 #20
0
        public void StructuredTextLoggerLogFunction(string message, LogEntryType type)
        {
            //Arrange
            var fileSystem = new Mock<IFileSystem>();
            var fileBase = new Mock<FileBase>();
            var stream = new TestMemoryStream();
            var analytics = new Mock<IAnalytics>();
            var logger = new StructuredTextLogger(@"x:\log.log", analytics.Object);

            fileSystem.Setup(f => f.File).Returns(fileBase.Object);

            fileBase.Setup(f => f.Open(It.IsAny<string>(), It.IsAny<FileMode>(), It.IsAny<FileAccess>(), It.IsAny<FileShare>()))
                    .Returns(stream);
            fileBase.Setup(f => f.OpenRead(It.IsAny<string>()))
                    .Returns((string path) => 
                    {
                        stream.Position = 0;
                        return stream;
                    });
            fileBase.Setup(f => f.ReadAllText(It.IsAny<string>()))
                    .Returns((string path) =>
                    {
                        using (var reader = new StreamReader(fileBase.Object.OpenRead(path)))
                        {
                            return reader.ReadToEnd();
                        }
                    });
            fileBase.Setup(f => f.ReadAllLines(It.IsAny<string>()))
                    .Returns((string path) =>
                    {
                        return fileBase.Object.ReadAllText(path).Split(new[] { System.Environment.NewLine }, StringSplitOptions.None);
                    });

            FileSystemHelpers.Instance = fileSystem.Object;

            //Act
            logger.Log(message, type);
            var entries = logger.GetLogEntries();

            //Assert
            Assert.Equal(1, entries.Count());
            Assert.Equal(message, entries.First().Message);
            Assert.Equal(type, entries.First().Type);
            stream.RealDispose();
        }
    public async Task WriteLineAsyncCharArray_OnlyWritesNewLineToStream_ForZeroCount(int newLineLength)
    {
        // Arrange
        var content = new char[1];
        var stream  = new TestMemoryStream();
        var writer  = new HttpResponseStreamWriter(stream, Encoding.UTF8);

        writer.NewLine = new string('\n', newLineLength);

        // Act
        using (writer)
        {
            await writer.WriteLineAsync(content, 0, 0);
        }

        // Assert
        Assert.Equal(newLineLength, stream.Length);
    }
예제 #22
0
        public void DisposesWhenEnumerationIsCompleted()
        {
            var disposable   = new TestDisposable();
            var memoryStream = new TestMemoryStream(Encoding.Default.GetBytes("line1\r\nline2\r\nline3"));
            var streamReader = new TestStreamReader(memoryStream);
            var enumerable   = new StreamReaderEnumerable(streamReader, disposable);

            // complete enumeration
            var lines = enumerable.ToList();

            Assert.IsTrue(streamReader.DisposeCalled);
            Assert.IsTrue(streamReader.DisposeCalledDisposingValue);

            Assert.IsTrue(memoryStream.DisposeCalled);
            Assert.IsTrue(memoryStream.DisposeCalledDisposingValue);

            Assert.IsTrue(disposable.DisposeCalled);
        }
    public async Task WriteLineAsyncString_WritesToStream(int charCount, int newLineLength)
    {
        // Arrange
        var content = new string('a', charCount);
        var stream  = new TestMemoryStream();
        var writer  = new HttpResponseStreamWriter(stream, Encoding.UTF8);

        writer.NewLine = new string('\n', newLineLength);

        // Act
        using (writer)
        {
            await writer.WriteLineAsync(content);
        }

        // Assert
        Assert.Equal(charCount + newLineLength, stream.Length);
    }
예제 #24
0
        public void WriteChar_WritesToStream(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            using (writer)
            {
                for (var i = 0; i < byteLength; i++)
                {
                    writer.Write('a');
                }
            }

            // Assert
            Assert.Equal(byteLength, stream.Length);
        }
    public async Task WriteLineAsyncString_OnlyWritesNewLineToStream_ForNullArgument(int newLineLength)
    {
        // Arrange
        string?content = null;
        var    stream  = new TestMemoryStream();
        var    writer  = new HttpResponseStreamWriter(stream, Encoding.UTF8);

        writer.NewLine = new string('\n', newLineLength);

        // Act
        using (writer)
        {
            await writer.WriteLineAsync(content);
        }

        // Assert
        Assert.Equal(newLineLength, stream.Length);
    }
        public void FlushesBuffer_ButNotStream_OnFlush(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new ProtoResponseStreamWriter(stream, Encoding.UTF8);

            writer.Write(new string('a', byteLength));

            var expectedWriteCount = Math.Ceiling((double)byteLength / ProtoResponseStreamWriter.DefaultBufferSize);

            // Act
            writer.Flush();

            // Assert
            Assert.Equal(0, stream.FlushCallCount);
            Assert.Equal(expectedWriteCount, stream.WriteCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
예제 #27
0
        public async Task FlushesBuffer_OnClose(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);
            await writer.WriteAsync(new string('a', byteLength));

            // Act
#if NET451
            writer.Close();
#else
            writer.Dispose();
#endif

            // Assert
            Assert.Equal(0, stream.FlushCallCount);
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
예제 #28
0
        public async Task HttpResponseStreamWriter_WritesDataCorrectly_ForCharactersHavingSurrogatePairs(int characterSize)
        {
            // Arrange
            // Here "𐐀" (called Deseret Long I) actually represents 2 characters. Try to make this character split across
            // the boundary
            var content = new string('a', characterSize - 1) + "𐐀";
            var stream  = new TestMemoryStream();
            var writer  = new HttpResponseStreamWriter(stream, Encoding.Unicode);

            // Act
            await writer.WriteAsync(content);

            await writer.FlushAsync();

            // Assert
            stream.Seek(0, SeekOrigin.Begin);
            var streamReader  = new StreamReader(stream, Encoding.Unicode);
            var actualContent = await streamReader.ReadToEndAsync();

            Assert.Equal(content, actualContent);
        }
예제 #29
0
        public async Task FlushWriteThrows_DontFlushInDispose(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream()
            {
                ThrowOnWrite = true
            };
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            await writer.WriteAsync(new string('a', byteLength));

            await Assert.ThrowsAsync <IOException>(() => writer.FlushAsync());

            // Act
            writer.Dispose();

            // Assert
            Assert.Equal(1, stream.WriteAsyncCallCount);
            Assert.Equal(0, stream.WriteCallCount);
            Assert.Equal(0, stream.FlushCallCount);
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(0, stream.Length);
        }
        internal static FileSystemInfo GetTextLoggerMockFileSystem()
        {
            var fileSystem = new Mock <IFileSystem>();
            var fileBase   = new Mock <FileBase>();
            var stream     = new TestMemoryStream();

            fileSystem.Setup(f => f.File).Returns(fileBase.Object);

            fileBase.Setup(f => f.Open(It.IsAny <string>(), It.IsAny <FileMode>(), It.IsAny <FileAccess>(), It.IsAny <FileShare>()))
            .Returns(stream);
            fileBase.Setup(f => f.OpenRead(It.IsAny <string>()))
            .Returns((string path) =>
            {
                stream.Position = 0;
                return(stream);
            });
            fileBase.Setup(f => f.ReadAllText(It.IsAny <string>()))
            .Returns((string path) =>
            {
                using (var reader = new StreamReader(fileBase.Object.OpenRead(path)))
                {
                    return(reader.ReadToEnd());
                }
            });
            fileBase.Setup(f => f.ReadAllLines(It.IsAny <string>()))
            .Returns((string path) =>
            {
                return(fileBase.Object.ReadAllText(path).Split(new[] { System.Environment.NewLine }, StringSplitOptions.None));
            });

            return(new FileSystemInfo
            {
                FileSystem = fileSystem.Object,
                MemoryStream = stream
            });
        }
        internal static FileSystemInfo GetTextLoggerMockFileSystem()
        {
            var fileSystem = new Mock<IFileSystem>();
            var fileBase = new Mock<FileBase>();
            var stream = new TestMemoryStream();

            fileSystem.Setup(f => f.File).Returns(fileBase.Object);

            fileBase.Setup(f => f.Open(It.IsAny<string>(), It.IsAny<FileMode>(), It.IsAny<FileAccess>(), It.IsAny<FileShare>()))
                    .Returns(stream);
            fileBase.Setup(f => f.OpenRead(It.IsAny<string>()))
                    .Returns((string path) => 
                    {
                        stream.Position = 0;
                        return stream;
                    });
            fileBase.Setup(f => f.ReadAllText(It.IsAny<string>()))
                    .Returns((string path) =>
                    {
                        using (var reader = new StreamReader(fileBase.Object.OpenRead(path)))
                        {
                            return reader.ReadToEnd();
                        }
                    });
            fileBase.Setup(f => f.ReadAllLines(It.IsAny<string>()))
                    .Returns((string path) =>
                    {
                        return fileBase.Object.ReadAllText(path).Split(new[] { System.Environment.NewLine }, StringSplitOptions.None);
                    });

            return new FileSystemInfo
            {
                FileSystem = fileSystem.Object,
                MemoryStream = stream
            };
        }
        public async Task WriteCharArrayAsync_WritesToStream(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            using (writer)
            {
                await writer.WriteAsync((new string('a', byteLength)).ToCharArray());
            }

            // Assert
            Assert.Equal(byteLength, stream.Length);
        }
예제 #33
0
        public void FlushesBuffer_OnFlush(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);
            writer.Write(new string('a', byteLength));

            // Act
            writer.Flush();

            // Assert
            Assert.Equal(1, stream.FlushCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
        public async Task FlushesBuffer_ButNotStream_OnFlushAsync(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);
            await writer.WriteAsync(new string('a', byteLength));

            var expectedWriteCount = Math.Ceiling((double)byteLength / HttpResponseStreamWriter.DefaultBufferSize);

            // Act
            await writer.FlushAsync();

            // Assert
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(expectedWriteCount, stream.WriteAsyncCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
        public async Task WriteCharAsync_WritesToStream(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            using (writer)
            {
                for (var i = 0; i < byteLength; i++)
                {
                    await writer.WriteAsync('a');
                }
            }

            // Assert
            Assert.Equal(byteLength, stream.Length);
        }
        public async Task NoDataWritten_FlushAsync_DoesNotFlushUnderlyingStream()
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            await writer.FlushAsync();

            // Assert
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(0, stream.Length);
        }
        public async Task FlushesBuffer_OnDispose(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);
            await writer.WriteAsync(new string('a', byteLength));

            // Act
            writer.Dispose();

            // Assert
            Assert.Equal(0, stream.FlushCallCount);
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
예제 #38
0
        private void BuildFileSystemMock(Action <Mock <IFileSystem> > action)
        {
            var fileSystemMock       = new Mock <IFileSystem>();
            var fileBaseMock         = new Mock <FileBase>();
            var fileInfoFactoryMoack = new Mock <IFileInfoFactory>();
            var fileInfoMock         = new Mock <FileInfoBase>();
            var directoryBaseMock    = new Mock <DirectoryBase>();
            var files = new Dictionary <string, TestMemoryStream>();

            fileSystemMock.SetupGet(fs => fs.File)
            .Returns(fileBaseMock.Object);

            fileSystemMock.SetupGet(fs => fs.FileInfo)
            .Returns(fileInfoFactoryMoack.Object);

            fileInfoFactoryMoack.Setup(f => f.FromFileName(It.IsAny <string>()))
            .Returns(fileInfoMock.Object);

            fileSystemMock.SetupGet(fs => fs.Directory)
            .Returns(directoryBaseMock.Object);

            fileBaseMock.Setup(f => f.Exists(It.IsAny <string>())).Returns(true);
            fileBaseMock.Setup(f => f.Open(It.IsAny <string>(), FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
            .Returns((string path, FileMode fileMode, FileAccess fileAccess, FileShare fileShare) =>
            {
                TestMemoryStream stream;
                if (!files.TryGetValue(path, out stream))
                {
                    stream = new TestMemoryStream();
                    byte[] contentInBytes = Encoding.UTF8.GetBytes("{}");
                    if (string.Equals(@"x:\bad-content.json", path))
                    {
                        contentInBytes = Encoding.UTF8.GetBytes(@"{
                                                                            ""AzureDriveEnabled"": true,
                                                                            ""AzureDriveTraceLevel"": 2,
                                                                            ""AzureTableEnabled"": true,
                                                                            ""AzureTableTraceLevel"": 8,
                                                                            ""AzureBlobEnabled"": true,
                                                                            ""AzureBlobTraceLevel"": 16
                                                                          }");
                    }
                    stream.WriteAsync(contentInBytes, 0, contentInBytes.Length);
                }

                stream.Position = 0;
                return(stream);
            });

            fileBaseMock.Setup(f => f.Open(It.IsAny <string>(), FileMode.Create, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete))
            .Returns((string path, FileMode fileMode, FileAccess fileAccess, FileShare fileShare) =>
            {
                files[path] = new TestMemoryStream();
                return(files[path]);
            });

            directoryBaseMock.Setup(d => d.Exists(It.IsAny <string>())).Returns(true);

            try
            {
                action(fileSystemMock);
            }
            finally
            {
                foreach (var f in files)
                {
                    f.Value.RealDispose();
                }
            }
        }
        public async Task FlushWriteThrows_DontFlushInDispose(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream() { ThrowOnWrite = true };
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            await writer.WriteAsync(new string('a', byteLength));
            await Assert.ThrowsAsync<IOException>(() =>  writer.FlushAsync());

            // Act
            writer.Dispose();

            // Assert
            Assert.Equal(1, stream.WriteAsyncCallCount);
            Assert.Equal(0, stream.WriteCallCount);
            Assert.Equal(0, stream.FlushCallCount);
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(0, stream.Length);
        }
        private void BuildFileSystemMock(Action<Mock<IFileSystem>> action)
        {
            var fileSystemMock = new Mock<IFileSystem>();
            var fileBaseMock = new Mock<FileBase>();
            var fileInfoFactoryMoack = new Mock<IFileInfoFactory>();
            var fileInfoMock = new Mock<FileInfoBase>();
            var directoryBaseMock = new Mock<DirectoryBase>();
            var files = new Dictionary<string, TestMemoryStream>();

            fileSystemMock.SetupGet(fs => fs.File)
                      .Returns(fileBaseMock.Object);

            fileSystemMock.SetupGet(fs => fs.FileInfo)
                      .Returns(fileInfoFactoryMoack.Object);

            fileInfoFactoryMoack.Setup(f => f.FromFileName(It.IsAny<string>()))
                                .Returns(fileInfoMock.Object);

            fileSystemMock.SetupGet(fs => fs.Directory)
                      .Returns(directoryBaseMock.Object);

            fileBaseMock.Setup(f => f.Exists(It.IsAny<string>())).Returns(true);
            fileBaseMock.Setup(f => f.Open(It.IsAny<string>(), FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
                    .Returns((string path, FileMode fileMode, FileAccess fileAccess, FileShare fileShare) =>
                    {
                        TestMemoryStream stream;
                        if (!files.TryGetValue(path, out stream))
                        {
                            stream = new TestMemoryStream();
                            byte[] contentInBytes = Encoding.UTF8.GetBytes("{}");
                            if (string.Equals(@"x:\bad-content.json", path))
                            {
                                contentInBytes = Encoding.UTF8.GetBytes(@"{
                                                                            ""AzureDriveEnabled"": true,
                                                                            ""AzureDriveTraceLevel"": 2,
                                                                            ""AzureTableEnabled"": true,
                                                                            ""AzureTableTraceLevel"": 8,
                                                                            ""AzureBlobEnabled"": true,
                                                                            ""AzureBlobTraceLevel"": 16
                                                                          }");
                            }
                            stream.WriteAsync(contentInBytes, 0, contentInBytes.Length);
                        }

                        stream.Position = 0;
                        return stream;
                    });

            fileBaseMock.Setup(f => f.Open(It.IsAny<string>(), FileMode.Create, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete))
                    .Returns((string path, FileMode fileMode, FileAccess fileAccess, FileShare fileShare) =>
                    {
                        files[path] = new TestMemoryStream();
                        return files[path];
                    });

            directoryBaseMock.Setup(d => d.Exists(It.IsAny<string>())).Returns(true);

            try
            {
                action(fileSystemMock);
            }
            finally
            {
                foreach (var f in files)
                {
                    f.Value.RealDispose();
                }
            }
        }