From f8cb521a1e2ec22df54793aaf2d27212bf6c437b Mon Sep 17 00:00:00 2001 From: dbuechel Date: Thu, 21 Feb 2019 13:39:45 +0100 Subject: [PATCH] SEBWIN-296: Implemented unit tests for substream. --- ...ExamBrowser.Configuration.UnitTests.csproj | 1 + .../SubStreamTests.cs | 186 ++++++++++++++++++ SafeExamBrowser.Configuration/SubStream.cs | 1 - 3 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 SafeExamBrowser.Configuration.UnitTests/SubStreamTests.cs diff --git a/SafeExamBrowser.Configuration.UnitTests/SafeExamBrowser.Configuration.UnitTests.csproj b/SafeExamBrowser.Configuration.UnitTests/SafeExamBrowser.Configuration.UnitTests.csproj index 4d9e254a..de04bb25 100644 --- a/SafeExamBrowser.Configuration.UnitTests/SafeExamBrowser.Configuration.UnitTests.csproj +++ b/SafeExamBrowser.Configuration.UnitTests/SafeExamBrowser.Configuration.UnitTests.csproj @@ -96,6 +96,7 @@ + diff --git a/SafeExamBrowser.Configuration.UnitTests/SubStreamTests.cs b/SafeExamBrowser.Configuration.UnitTests/SubStreamTests.cs new file mode 100644 index 00000000..6e6b83f8 --- /dev/null +++ b/SafeExamBrowser.Configuration.UnitTests/SubStreamTests.cs @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.IO; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace SafeExamBrowser.Configuration.UnitTests +{ + [TestClass] + public class SubStreamTests + { + private Mock stream; + + [TestInitialize] + public void Initialize() + { + stream = new Mock(); + + stream.SetupGet(s => s.CanRead).Returns(true); + stream.SetupGet(s => s.CanSeek).Returns(true); + stream.SetupGet(s => s.Length).Returns(1000); + } + + [TestMethod] + public void MustSetPropertiesCorrectly() + { + var sut = new SubStream(stream.Object, 100, 200); + + Assert.IsTrue(sut.CanRead); + Assert.IsTrue(sut.CanSeek); + Assert.IsFalse(sut.CanWrite); + Assert.AreEqual(200, sut.Length); + Assert.AreEqual(0, sut.Position); + } + + [TestMethod] + public void MustReadCorrectly() + { + var position = 750L; + var sut = new SubStream(stream.Object, 100, 200); + + stream.SetupGet(s => s.Position).Returns(position); + stream.SetupSet(s => s.Position = It.IsAny()).Callback(p => position = p); + stream.Setup(s => s.Read(It.IsAny(), It.IsAny(), It.IsAny())).Returns((a, o, c) => c); + sut.Position = 50; + + var bytesRead = sut.Read(new byte[25], 0, 25); + + stream.Verify(s => s.Read(It.IsAny(), 0, 25), Times.Once); + + Assert.AreEqual(25, bytesRead); + Assert.AreEqual(75, sut.Position); + Assert.AreEqual(750, position); + + sut.Position = 150; + bytesRead = sut.Read(new byte[75], 0, 75); + + stream.Verify(s => s.Read(It.IsAny(), 0, 50), Times.Once); + + Assert.AreEqual(50, bytesRead); + Assert.AreEqual(200, sut.Position); + Assert.AreEqual(750, position); + } + + [TestMethod] + public void MustNotReadOutsideOfBounds() + { + var sut = new SubStream(stream.Object, 100, 200); + + sut.Position = -1; + + var bytesRead = sut.Read(new byte[0], 0, 0); + + Assert.AreEqual(0, bytesRead); + stream.Verify(s => s.ReadByte(), Times.Never); + stream.Verify(s => s.Read(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); + + sut.Position = 500; + bytesRead = sut.Read(new byte[0], 0, 0); + + Assert.AreEqual(0, bytesRead); + stream.Verify(s => s.ReadByte(), Times.Never); + stream.Verify(s => s.Read(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); + } + + [TestMethod] + public void MustReadByteCorrectly() + { + var sut = new SubStream(stream.Object, 100, 200); + + stream.SetupGet(s => s.Position).Returns(-100); + Assert.AreEqual(-1, sut.ReadByte()); + + stream.SetupGet(s => s.Position).Returns(200); + Assert.AreEqual(-1, sut.ReadByte()); + + stream.SetupGet(s => s.Position).Returns(25); + sut.ReadByte(); + stream.Verify(s => s.Read(It.IsAny(), It.IsAny(), It.IsAny()), Times.AtLeastOnce); + } + + [TestMethod] + public void MustSeekCorrectly() + { + var sut = new SubStream(stream.Object, 100, 200); + + sut.Seek(10, SeekOrigin.Begin); + Assert.AreEqual(10, sut.Position); + + sut.Seek(15, SeekOrigin.Current); + Assert.AreEqual(25, sut.Position); + + sut.Seek(-5, SeekOrigin.Current); + Assert.AreEqual(20, sut.Position); + + sut.Seek(-50, SeekOrigin.End); + Assert.AreEqual(150, sut.Position); + + sut.Seek(10, SeekOrigin.End); + Assert.AreEqual(210, sut.Position); + + sut.Seek(-10, SeekOrigin.Begin); + Assert.AreEqual(-10, sut.Position); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentException))] + public void MustNotAllowNonReadableStream() + { + stream.SetupGet(s => s.CanRead).Returns(false); + + new SubStream(stream.Object, 0, 0); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentException))] + public void MustNotAllowNonSeekableStream() + { + stream.SetupGet(s => s.CanSeek).Returns(false); + + new SubStream(stream.Object, 0, 0); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public void MustNotAllowOffsetSmallerThanZero() + { + new SubStream(stream.Object, -1, 100); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public void MustNotAllowLengthSmallerThanOne() + { + new SubStream(stream.Object, 100, 0); + } + + [TestMethod] + [ExpectedException(typeof(NotSupportedException))] + public void MustNotSupportFlushing() + { + new SubStream(stream.Object, 100, 100).Flush(); + } + + [TestMethod] + [ExpectedException(typeof(NotSupportedException))] + public void MustNotSupportChangingLength() + { + new SubStream(stream.Object, 100, 100).SetLength(100); + } + + [TestMethod] + [ExpectedException(typeof(NotSupportedException))] + public void MustNotSupportWriting() + { + new SubStream(stream.Object, 100, 100).Write(new byte[0], 0, 0); + } + } +} diff --git a/SafeExamBrowser.Configuration/SubStream.cs b/SafeExamBrowser.Configuration/SubStream.cs index 3cdda622..20e947d4 100644 --- a/SafeExamBrowser.Configuration/SubStream.cs +++ b/SafeExamBrowser.Configuration/SubStream.cs @@ -13,7 +13,6 @@ namespace SafeExamBrowser.Configuration { /// /// A read-only wrapper for a subsection of another, larger stream. - /// TODO: Unit Test! /// internal class SubStream : Stream {