/// <summary> /// Applies Capacity+1 times the same test to the same buffer "logical" content but with /// different internal offsets each time. /// The "logical" initial buffer content is restored each time and at the end of the test. /// </summary> static void TestWithInternalOffsets <T>(FIFOBuffer <T> f, Action <FIFOBuffer <T> > testPredicate) { var saved = f.ToArray(); for (int iTry = 0; iTry <= f.Capacity; ++iTry) { f.Clear(); for (int i = 0; i < iTry; ++i) { f.Push(default(T)); } foreach (var i in saved) { f.Push(i); } while (f.Count > saved.Length) { f.Pop(); } f.SequenceEqual(saved).Should().BeTrue(); testPredicate(f); } foreach (var i in saved) { f.Push(i); } f.Truncate(saved.Length); }
public void FIFO_supports_Peek_and_PeekLast() { FIFOBuffer <int> f = new FIFOBuffer <int>(0); f.Invoking(sut => Console.Write(sut[-1])).Should().Throw <IndexOutOfRangeException>(); f.Invoking(sut => Console.Write(sut[0])).Should().Throw <IndexOutOfRangeException>(); f.Invoking(sut => sut.Peek()).Should().Throw <InvalidOperationException>(); f.Invoking(sut => sut.PeekLast()).Should().Throw <InvalidOperationException>(); f.Push(5); f.Invoking(sut => Console.Write(sut[0])).Should().Throw <IndexOutOfRangeException>(); f.Invoking(sut => sut.Peek()).Should().Throw <InvalidOperationException>(); f.Invoking(sut => sut.PeekLast()).Should().Throw <InvalidOperationException>(); f.Capacity = 1; TestWithInternalOffsets(f, b => { b.Push(5); b[0].Should().Be(5); b.Invoking(sut => Console.Write(sut[1])).Should().Throw <IndexOutOfRangeException>(); b.Peek().Should().Be(5); b.PeekLast().Should().Be(5); b.Push(6); b[0].Should().Be(6, "Only one item in it."); b.Invoking(sut => Console.Write(sut[1])).Should().Throw <IndexOutOfRangeException>(); b.Peek().Should().Be(6); b.PeekLast().Should().Be(6); }); f.Clear(); f.Invoking(sut => Console.Write(sut[0])).Should().Throw <IndexOutOfRangeException>(); f.Invoking(sut => Console.Write(sut[1])).Should().Throw <IndexOutOfRangeException>(); f.Invoking(sut => sut.Peek()).Should().Throw <InvalidOperationException>(); f.Invoking(sut => sut.PeekLast()).Should().Throw <InvalidOperationException>(); f.Capacity = 2; TestWithInternalOffsets(f, b => { b.Push(5); b[0].Should().Be(5); b.Invoking(sut => Console.Write(sut[1])).Should().Throw <IndexOutOfRangeException>(); b.Peek().Should().Be(5); b.PeekLast().Should().Be(5); b.Push(6); b[0].Should().Be(5); b[1].Should().Be(6); b.Peek().Should().Be(5); b.PeekLast().Should().Be(6); b.Pop(); b[0].Should().Be(6); b.Invoking(sut => Console.Write(sut[1])).Should().Throw <IndexOutOfRangeException>(); b.Peek().Should().Be(6); b.PeekLast().Should().Be(6); b.Pop(); b.Invoking(sut => Console.Write(sut[0])).Should().Throw <IndexOutOfRangeException>(); b.Invoking(sut => Console.Write(sut[1])).Should().Throw <IndexOutOfRangeException>(); b.Invoking(sut => sut.Peek()).Should().Throw <InvalidOperationException>(); b.Invoking(sut => sut.PeekLast()).Should().Throw <InvalidOperationException>(); b.Push(7); b.Push(8); b.Push(9); b[0].Should().Be(8); b[1].Should().Be(9); b.ToArray().SequenceEqual(new int[] { 8, 9 }).Should().BeTrue(); b.Peek().Should().Be(8); b.PeekLast().Should().Be(9); b.Pop().Should().Be(8); b.Pop().Should().Be(9); AssertEmpty(b); b.Push(10); b.Push(11); b.Push(12); b[0].Should().Be(11); b[1].Should().Be(12); b.Peek().Should().Be(11); b.PeekLast().Should().Be(12); b.PopLast().Should().Be(12); b.Peek().Should().Be(11); b.PeekLast().Should().Be(11); b.PopLast().Should().Be(11); AssertEmpty(b); }); f.Capacity = 3; TestWithInternalOffsets(f, b => { b.Push(11); b.Push(12); b.Push(13); b[0].Should().Be(11); b[1].Should().Be(12); b[2].Should().Be(13); }); f.Capacity = 4; f.Push(11); f.Push(12); f.Push(13); TestWithInternalOffsets(f, b => { b.Push(14); b[0].Should().Be(11); b[1].Should().Be(12); b[2].Should().Be(13); b[3].Should().Be(14); b.Push(15); b[0].Should().Be(12); b[1].Should().Be(13); b[2].Should().Be(14); b[3].Should().Be(15); b.Push(16); b[0].Should().Be(13); b[1].Should().Be(14); b[2].Should().Be(15); b[3].Should().Be(16); }); f.Capacity = 5; AssertContains(f, 11, 12, 13); TestWithInternalOffsets(f, b => { b.Push(14); b.Push(15); b.Push(16); b.Push(17); b[0].Should().Be(13); b[1].Should().Be(14); b[2].Should().Be(15); b[3].Should().Be(16); b[4].Should().Be(17); f.Invoking(sut => Console.Write(sut[5])).Should().Throw <IndexOutOfRangeException>(); }); }
public void FIFO_supports_removeAt() { FIFOBuffer <int> f = new FIFOBuffer <int>(0); f.Invoking(sut => sut.RemoveAt(0)).Should().Throw <IndexOutOfRangeException>(); f.Invoking(sut => sut.RemoveAt(-1)).Should().Throw <IndexOutOfRangeException>(); f.Capacity = 1; f.Push(1); TestWithInternalOffsetsAndGrowingCapacity(f, b => { AssertContains(b, 1); b.RemoveAt(0); AssertEmpty(b); }); f.Capacity = 2; f.Push(2); TestWithInternalOffsetsAndGrowingCapacity(f, b => { AssertContains(b, 1, 2); b.RemoveAt(0); AssertContains(b, 2); }); f.Capacity = 3; f.Push(3); f.Push(4); TestWithInternalOffsetsAndGrowingCapacity(f, b => { AssertContains(b, 2, 3, 4); b.RemoveAt(2); AssertContains(b, 2, 3); b.RemoveAt(1); AssertContains(b, 2); b.RemoveAt(0); AssertEmpty(b); }); f.Capacity = 4; f.Clear(); f.Push(2); f.Push(3); f.Push(4); TestWithInternalOffsetsAndGrowingCapacity(f, b => { AssertContains(b, 2, 3, 4); b.RemoveAt(2); AssertContains(b, 2, 3); b.RemoveAt(1); AssertContains(b, 2); }); f.Push(5); TestWithInternalOffsetsAndGrowingCapacity(f, b => { AssertContains(b, 2, 3, 4, 5); b.RemoveAt(2); AssertContains(b, 2, 3, 5); b.RemoveAt(1); AssertContains(b, 2, 5); b.RemoveAt(1); AssertContains(b, 2); }); f.Capacity = 5; f.Push(6); TestWithInternalOffsetsAndGrowingCapacity(f, b => { AssertContains(b, 2, 3, 4, 5, 6); b.RemoveAt(2); AssertContains(b, 2, 3, 5, 6); b.RemoveAt(1); AssertContains(b, 2, 5, 6); b.RemoveAt(2); AssertContains(b, 2, 5); b.RemoveAt(1); AssertContains(b, 2); }); }
public void FIFO_supports_Peek_and_PeekLast() { FIFOBuffer <int> f = new FIFOBuffer <int>(0); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(f[-1])); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(f[0])); Assert.Throws <InvalidOperationException>(() => f.Peek()); Assert.Throws <InvalidOperationException>(() => f.PeekLast()); f.Push(5); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(f[0])); Assert.Throws <InvalidOperationException>(() => f.Peek()); Assert.Throws <InvalidOperationException>(() => f.PeekLast()); f.Capacity = 1; TestWithInternalOffsets(f, b => { b.Push(5); Assert.That(b[0], Is.EqualTo(5)); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(b[1])); Assert.That(b.Peek(), Is.EqualTo(5)); Assert.That(b.PeekLast(), Is.EqualTo(5)); b.Push(6); Assert.That(b[0], Is.EqualTo(6), "Only one item in it."); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(b[1])); Assert.That(b.Peek(), Is.EqualTo(6)); Assert.That(b.PeekLast(), Is.EqualTo(6)); }); f.Clear(); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(f[0])); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(f[1])); Assert.Throws <InvalidOperationException>(() => f.Peek()); Assert.Throws <InvalidOperationException>(() => f.PeekLast()); f.Capacity = 2; TestWithInternalOffsets(f, b => { b.Push(5); Assert.That(b[0], Is.EqualTo(5)); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(b[1])); Assert.That(b.Peek(), Is.EqualTo(5)); Assert.That(b.PeekLast(), Is.EqualTo(5)); b.Push(6); Assert.That(b[0], Is.EqualTo(5)); Assert.That(b[1], Is.EqualTo(6)); Assert.That(b.Peek(), Is.EqualTo(5)); Assert.That(b.PeekLast(), Is.EqualTo(6)); b.Pop(); Assert.That(b[0], Is.EqualTo(6)); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(b[1])); Assert.That(b.Peek(), Is.EqualTo(6)); Assert.That(b.PeekLast(), Is.EqualTo(6)); b.Pop(); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(b[0])); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(b[1])); Assert.Throws <InvalidOperationException>(() => b.Peek()); Assert.Throws <InvalidOperationException>(() => b.PeekLast()); b.Push(7); b.Push(8); b.Push(9); Assert.That(b[0], Is.EqualTo(8)); Assert.That(b[1], Is.EqualTo(9)); CollectionAssert.AreEqual(b.ToArray(), new int[] { 8, 9 }); Assert.That(b.Peek(), Is.EqualTo(8)); Assert.That(b.PeekLast(), Is.EqualTo(9)); Assert.That(b.Pop(), Is.EqualTo(8)); Assert.That(b.Pop(), Is.EqualTo(9)); AssertEmpty(b); b.Push(10); b.Push(11); b.Push(12); Assert.That(b[0], Is.EqualTo(11)); Assert.That(b[1], Is.EqualTo(12)); Assert.That(b.Peek(), Is.EqualTo(11)); Assert.That(b.PeekLast(), Is.EqualTo(12)); Assert.That(b.PopLast(), Is.EqualTo(12)); Assert.That(b.Peek(), Is.EqualTo(11)); Assert.That(b.PeekLast(), Is.EqualTo(11)); Assert.That(b.PopLast(), Is.EqualTo(11)); AssertEmpty(b); }); f.Capacity = 3; TestWithInternalOffsets(f, b => { b.Push(11); b.Push(12); b.Push(13); Assert.That(b[0], Is.EqualTo(11)); Assert.That(b[1], Is.EqualTo(12)); Assert.That(b[2], Is.EqualTo(13)); }); f.Capacity = 4; f.Push(11); f.Push(12); f.Push(13); TestWithInternalOffsets(f, b => { b.Push(14); Assert.That(b[0], Is.EqualTo(11)); Assert.That(b[1], Is.EqualTo(12)); Assert.That(b[2], Is.EqualTo(13)); Assert.That(b[3], Is.EqualTo(14)); b.Push(15); Assert.That(b[0], Is.EqualTo(12)); Assert.That(b[1], Is.EqualTo(13)); Assert.That(b[2], Is.EqualTo(14)); Assert.That(b[3], Is.EqualTo(15)); b.Push(16); Assert.That(b[0], Is.EqualTo(13)); Assert.That(b[1], Is.EqualTo(14)); Assert.That(b[2], Is.EqualTo(15)); Assert.That(b[3], Is.EqualTo(16)); }); f.Capacity = 5; AssertContains(f, 11, 12, 13); TestWithInternalOffsets(f, b => { b.Push(14); b.Push(15); b.Push(16); b.Push(17); Assert.That(b[0], Is.EqualTo(13)); Assert.That(b[1], Is.EqualTo(14)); Assert.That(b[2], Is.EqualTo(15)); Assert.That(b[3], Is.EqualTo(16)); Assert.That(b[4], Is.EqualTo(17)); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(f[5])); }); }