From 135166cd0bcb22e0f15ff817f37295ab03e6eae5 Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Mon, 20 Nov 2023 22:32:46 +0000 Subject: [PATCH] Added some more tests to the UnsafeStack, covering everything but `ToString` --- Arch.LowLevel.Tests/UnsafeStackTest.cs | 155 ++++++++++++++++++++++++- Arch.LowLevel/UnsafeStack.cs | 21 ++-- 2 files changed, 161 insertions(+), 15 deletions(-) diff --git a/Arch.LowLevel.Tests/UnsafeStackTest.cs b/Arch.LowLevel.Tests/UnsafeStackTest.cs index d8445b4..3523b84 100644 --- a/Arch.LowLevel.Tests/UnsafeStackTest.cs +++ b/Arch.LowLevel.Tests/UnsafeStackTest.cs @@ -9,22 +9,171 @@ namespace Arch.LowLevel.Tests; [TestFixture] public class UnsafeStackTest { - /// - /// Checks if is capable of adding itemss. + /// Checks if checks for invalid capacity on construction. + /// + [Test] + public void UnsafeStackInvalidCapacity() + { + Throws(() => new UnsafeStack(-9)); + } + + /// + /// Checks if is capable of adding items. /// [Test] public void UnsafeStackAdd() { using var stack = new UnsafeStack(8); + + That(stack.IsFull, Is.False); + That(stack.IsEmpty, Is.True); + + stack.Push(1); + stack.Push(2); + stack.Push(3); + + That(stack.IsFull, Is.False); + That(stack.IsEmpty, Is.False); + + That(stack.Count, Is.EqualTo(3)); + That(stack.Peek(), Is.EqualTo(3)); + } + + /// + /// Checks if is can be converted to a span + /// + [Test] + public void UnsafeStackAsSpan() + { + using var stack = new UnsafeStack(8); + stack.Push(1); stack.Push(2); stack.Push(3); + + var span = stack.AsSpan(); + + stack.Pop(); + stack.Push(4); + + That(span.Length, Is.EqualTo(3)); + + CollectionAssert.AreEqual(span.ToArray(), new[] { 1, 2, 4 }); + } + + /// + /// Checks if is capable of adding items even past the initial capacity + /// + [Test] + public void UnsafeStackAddBeyondCapacity() + { + using var stack = new UnsafeStack(4); + That(stack.Capacity, Is.EqualTo(4)); + + stack.Push(1); + stack.Push(2); + stack.Push(3); + stack.Push(4); + That(stack.IsFull, Is.True); + stack.Push(5); + stack.Push(6); + stack.Push(7); + + That(stack.Count, Is.EqualTo(7)); + That(stack.Peek(), Is.EqualTo(7)); + } + + /// + /// Checks if expands capacity + /// + [Test] + public void UnsafeStackEnsureCapacityExpands() + { + using var stack = new UnsafeStack(10); + That(stack.Capacity, Is.EqualTo(10)); + + stack.EnsureCapacity(11); + + That(stack.Capacity, Is.GreaterThanOrEqualTo(11)); + } + + /// + /// Checks if cannot shrink the capacity + /// + [Test] + public void UnsafeStackEnsureCapacityCannotShrink() + { + using var stack = new UnsafeStack(10); + That(stack.Capacity, Is.EqualTo(10)); + + stack.EnsureCapacity(1); + + That(stack.Capacity, Is.EqualTo(10)); + } + + /// + /// Checks if can add a massive amount of new capacity + /// + [Test] + public void UnsafeStackEnsureCapacityExpandsALot() + { + using var stack = new UnsafeStack(10); + That(stack.Capacity, Is.EqualTo(10)); + + stack.EnsureCapacity(10000); + + That(stack.Capacity, Is.GreaterThanOrEqualTo(10000)); + } + + /// + /// Checks if can remove unused capacity + /// + [Test] + public void UnsafeStackTrimExcessShrinks() + { + using var stack = new UnsafeStack(10); + That(stack.Capacity, Is.EqualTo(10)); + + stack.TrimExcess(); + + That(stack.Capacity, Is.LessThan(10)); + } + + /// + /// Checks if does not expand + /// + [Test] + public void UnsafeStackTrimExcessNeverExpands() + { + using var stack = new UnsafeStack(2); + stack.TrimExcess(); + + That(stack.Capacity, Is.LessThanOrEqualTo(2)); + } + + /// + /// Checks if is capable of being cleared. + /// + [Test] + public void UnsafeStackClear() + { + using var stack = new UnsafeStack(8); + stack.Push(1); + stack.Push(2); + stack.Push(3); + That(stack.Count, Is.EqualTo(3)); That(stack.Peek(), Is.EqualTo(3)); + + stack.Clear(); + + That(stack.Count, Is.EqualTo(0)); + Throws(() => stack.Peek()); + Throws(() => stack.Pop()); } - + /// /// Checks if is capable of peeking itemss. /// diff --git a/Arch.LowLevel/UnsafeStack.cs b/Arch.LowLevel/UnsafeStack.cs index 75878f2..4f82ece 100644 --- a/Arch.LowLevel/UnsafeStack.cs +++ b/Arch.LowLevel/UnsafeStack.cs @@ -1,8 +1,6 @@ using System.Collections; using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Text; namespace Arch.LowLevel; @@ -51,7 +49,7 @@ public UnsafeStack(int capacity = DefaultCapacity) /// /// The amount of items in the stack. /// - public int Count + public readonly int Count { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _count; @@ -60,7 +58,7 @@ public int Count /// /// The total capacity of this stack. /// - public int Capacity + public readonly int Capacity { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _capacity; @@ -69,7 +67,7 @@ public int Capacity /// /// If this stack is empty. /// - public bool IsEmpty + public readonly bool IsEmpty { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _count == 0; @@ -78,7 +76,7 @@ public bool IsEmpty /// /// If this stack is full. /// - public bool IsFull + public readonly bool IsFull { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _count >= _capacity; @@ -204,9 +202,8 @@ public void Dispose() /// Converts this instance into a . /// /// A new instance of . - [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + public readonly Span AsSpan() { return new Span(_stack, Count); } @@ -216,7 +213,7 @@ public Span AsSpan() /// /// A new . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public UnsafeReverseEnumerator GetEnumerator() + public readonly UnsafeReverseEnumerator GetEnumerator() { return new UnsafeReverseEnumerator(_stack, Count); } @@ -226,7 +223,7 @@ public UnsafeReverseEnumerator GetEnumerator() /// /// The new . [MethodImpl(MethodImplOptions.AggressiveInlining)] - IEnumerator IEnumerable.GetEnumerator() + readonly IEnumerator IEnumerable.GetEnumerator() { return new ReverseEnumerator(_stack, Count); } @@ -236,7 +233,7 @@ IEnumerator IEnumerable.GetEnumerator() /// /// The new . [MethodImpl(MethodImplOptions.AggressiveInlining)] - IEnumerator IEnumerable.GetEnumerator() + readonly IEnumerator IEnumerable.GetEnumerator() { return new ReverseEnumerator(_stack, Count); } @@ -246,7 +243,7 @@ IEnumerator IEnumerable.GetEnumerator() /// /// The string. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override string ToString() + public readonly override string ToString() { var items = new StringBuilder(); foreach (ref var item in this)