namespace SantaClausInc.Test; public sealed class StackTests { [Fact] public void Construction() { var stack = new Stack(); stack.Count.Should().Be(0); } [Fact] public void PushPop_Single() { const int Value = 6; var stack = new Stack(); stack.Push(Value); stack.Count.Should().Be(1, "one item added"); stack.Pop().Should().Be(Value, "we get back what we put in"); stack.Count.Should().Be(0, "no items remain"); } [Fact] public void PushPop_Single_DifferentType() { const bool Value = true; var stack = new Stack(); stack.Push(Value); stack.Count.Should().Be(1); stack.Pop().Should().Be(Value, "we get back what we put in"); ; stack.Count.Should().Be(0, "no items remain"); } [Fact] public void PushPop_Nullable() { var stack = new Stack(); stack.Push(null); stack.Count.Should().Be(1, "we can push null as well"); stack.Pop().Should().Be(null, "we get back what we put in, even if it was null"); stack.Count.Should().Be(0, "no items remain"); } [Fact] public void PushPop_Multiple() { const string Value1 = "foo"; const string Value2 = "bar"; var stack = new Stack(); stack.Push(Value1); stack.Push(Value2); stack.Count.Should().Be(2, "two items added"); stack.Pop().Should().Be(Value2, "last in, first out"); stack.Count.Should().Be(1, "one item remains"); stack.Pop().Should().Be(Value1); stack.Count.Should().Be(0, "all items removed"); } [Fact] public void Pop_Empty() { var stack1 = new Stack(); var stack2 = new Stack(); var stack3 = new Stack(); stack1.Pop().Should() .Be(default(long), "popping from an empty stack returns the types default") .And.Be(0L, "the default of long"); stack2.Pop().Should() .Be(default(object), "the default is dependent on the type parameter") .And.Be(null, "the default of a reference type"); stack3.Pop().Should() .Be(null, "a little more complex for nullable value types") .And.Be(null, "for which the default is null") .And.NotBe(default(long), "but cannot be inferred correctly all the time"); } [Fact] public void Peek_Simple() { const char Value = 'H'; var stack = new Stack(); stack.Push(Value); stack.Count.Should().Be(1); stack.Peek().Should().Be(Value, "we peek the top of the stack"); stack.Count.Should().Be(1, "peek does not remove element from the stack"); } [Fact] public void Peek_Multiple() { const bool Value = true; var stack = new Stack(); stack.Push(Value); stack.Push(null); stack.Count.Should().Be(2); stack.Peek().Should().Be(null, "we peek the top of the stack"); stack.Peek().Should().Be(null, "still the same element on top"); stack.Pop().Should().Be(null); stack.Peek().Should().Be(Value, "now we peek the value added first"); stack.Count.Should().Be(1, "peek does not remove elements from the stack, but pop does"); } [Fact] public void Peek_Empty() { var stack = new Stack(); stack.Peek().Should() .Be(default(object), "peeking an empty stack returns the type parameters default value"); } // ReSharper disable once ClassNeverInstantiated.Local - used as type parameter in tests private sealed record Foo; }