// // Copyright (c) Quamotion. All rights reserved. // using System; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using Xunit; namespace plistcil.test { /// /// A which writes its output to a and validates that the data which /// is being written to the output stream matches the data in a reference stream. /// class ValidatingStream : Stream { Stream expectedOutput; Stream output; /// /// Initializes a new instance of the class. /// /// /// The to which to write data. /// /// /// The reference stream for . /// public ValidatingStream(Stream output, Stream expectedOutput) { this.output = output ?? throw new ArgumentNullException(nameof(output)); this.expectedOutput = expectedOutput ?? throw new ArgumentNullException(nameof(expectedOutput)); } /// public override bool CanRead => false; /// public override bool CanSeek => false; /// public override bool CanWrite => true; /// public override long Length => output.Length; /// public override long Position { get => output.Position; set => throw new NotImplementedException(); } /// public override void Flush() { output.Flush(); } /// public override int Read(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } /// public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { throw new NotSupportedException(); } /// public override long Seek(long offset, SeekOrigin origin) { throw new NotImplementedException(); } /// public override void SetLength(long value) { throw new NotImplementedException(); } /// public override void Write(byte[] buffer, int offset, int count) { byte[] expected = new byte[buffer.Length]; expectedOutput.Read(expected, offset, count); byte[] bufferChunk = buffer.Skip(offset).Take(count).ToArray(); byte[] expectedChunk = expected.Skip(offset).Take(count).ToArray(); // Make sure the data being writen matches the data which was written to the expected stream. // This will detect any errors as the invalid data is being written out - as opposed to post- // test binary validation. Assert.Equal(expectedChunk, bufferChunk); output.Write(buffer, offset, count); } /// public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { byte[] expected = new byte[buffer.Length]; await expectedOutput.ReadAsync(expected, offset, count, cancellationToken).ConfigureAwait(false); byte[] bufferChunk = buffer.Skip(offset).Take(count).ToArray(); byte[] expectedChunk = expected.Skip(offset).Take(count).ToArray(); // Make sure the data being writen matches the data which was written to the expected stream. // This will detect any errors as the invalid data is being written out - as opposed to post- // test binary validation. Assert.Equal(expectedChunk, bufferChunk); await output.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); } } }