diff --git a/src/Stack/ArrayStack.php b/src/Stack/ArrayStack.php index e69de29..40a6cca 100644 --- a/src/Stack/ArrayStack.php +++ b/src/Stack/ArrayStack.php @@ -0,0 +1,68 @@ + + * @license MIT + * + * @see https://kariricode.org/ + */ +class ArrayStack implements Stack +{ + private array $elements = []; + + public function push(mixed $element): void + { + $this->elements[] = $element; + } + + public function pop(): mixed + { + if ($this->isEmpty()) { + return null; + } + + return array_pop($this->elements); + } + + public function peek(): mixed + { + if ($this->isEmpty()) { + return null; + } + + return $this->elements[count($this->elements) - 1]; + } + + public function isEmpty(): bool + { + return empty($this->elements); + } + + public function size(): int + { + return count($this->elements); + } + + public function clear(): void + { + $this->elements = []; + } + + public function getItems(): array + { + return array_reverse($this->elements); + } +} diff --git a/tests/Stack/ArrayStackTest.php b/tests/Stack/ArrayStackTest.php new file mode 100644 index 0000000..4d41f39 --- /dev/null +++ b/tests/Stack/ArrayStackTest.php @@ -0,0 +1,134 @@ +push(1); + $this->assertSame(1, $stack->peek()); + } + + // Test popping elements from the stack + public function testPopRemovesElementFromStack(): void + { + $stack = new ArrayStack(); + $stack->push(1); + $stack->push(2); + $this->assertSame(2, $stack->pop()); + $this->assertSame(1, $stack->peek()); + } + + // Test popping from an empty stack + public function testPopFromEmptyStackReturnsNull(): void + { + $stack = new ArrayStack(); + $this->assertNull($stack->pop()); + } + + // Test peeking elements + public function testPeekReturnsElementFromTopWithoutRemovingIt(): void + { + $stack = new ArrayStack(); + $stack->push(1); + $this->assertSame(1, $stack->peek()); + $this->assertSame(1, $stack->peek()); + } + + // Test peeking from an empty stack + public function testPeekFromEmptyStackReturnsNull(): void + { + $stack = new ArrayStack(); + $this->assertNull($stack->peek()); + } + + // Test checking if stack is empty + public function testIsEmptyReturnsTrueIfStackIsEmpty(): void + { + $stack = new ArrayStack(); + $this->assertTrue($stack->isEmpty()); + $stack->push(1); + $this->assertFalse($stack->isEmpty()); + } + + // Test getting the size of the stack + public function testSizeReturnsNumberOfElementsInStack(): void + { + $stack = new ArrayStack(); + $this->assertSame(0, $stack->size()); + $stack->push(1); + $stack->push(2); + $this->assertSame(2, $stack->size()); + } + + // Test clearing the stack + public function testClearRemovesAllElementsFromStack(): void + { + $stack = new ArrayStack(); + $stack->push(1); + $stack->push(2); + $stack->clear(); + $this->assertTrue($stack->isEmpty()); + } + + // Test converting the stack to an array + public function testGetItemsReturnsAllElementsInStack(): void + { + $stack = new ArrayStack(); + $stack->push(1); + $stack->push(2); + $this->assertSame([2, 1], $stack->getItems()); + } + + // Test stack with various data types + public function testStackWithVariousDataTypes(): void + { + $stack = new ArrayStack(); + $stack->push(123); + $stack->push('string'); + $stack->push([1, 2, 3]); + $stack->push(new \stdClass()); + + $this->assertInstanceOf(\stdClass::class, $stack->pop()); + $this->assertSame([1, 2, 3], $stack->pop()); + $this->assertSame('string', $stack->pop()); + $this->assertSame(123, $stack->pop()); + } + + // Test stack behavior after mixed operations + public function testStackBehaviorAfterMixedOperations(): void + { + $stack = new ArrayStack(); + $stack->push(1); + $stack->push(2); + $stack->pop(); + $stack->push(3); + $stack->clear(); + $stack->push(4); + $stack->push(5); + + $this->assertSame(5, $stack->pop()); + $this->assertSame(4, $stack->peek()); + } + + // Test LIFO behavior + public function testStackFollowsLifoOrder(): void + { + $stack = new ArrayStack(); + $stack->push(1); + $stack->push(2); + $stack->push(3); + + $this->assertSame(3, $stack->pop()); + $this->assertSame(2, $stack->pop()); + $this->assertSame(1, $stack->pop()); + } +}