diff --git a/composer.lock b/composer.lock index f2748bb..5b825b9 100644 --- a/composer.lock +++ b/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "kariricode/contract", - "version": "v2.1.0", + "version": "v2.3.1", "source": { "type": "git", "url": "https://github.com/KaririCode-Framework/kariricode-contract.git", - "reference": "f8a776c083882e260e68945d8cd8f193ec2fce6f" + "reference": "619c2f472a874a59b118460d7ac55e4eaa07b636" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/KaririCode-Framework/kariricode-contract/zipball/f8a776c083882e260e68945d8cd8f193ec2fce6f", - "reference": "f8a776c083882e260e68945d8cd8f193ec2fce6f", + "url": "https://api.github.com/repos/KaririCode-Framework/kariricode-contract/zipball/619c2f472a874a59b118460d7ac55e4eaa07b636", + "reference": "619c2f472a874a59b118460d7ac55e4eaa07b636", "shasum": "" }, "require": { @@ -66,7 +66,7 @@ "issues": "https://github.com/KaririCode-Framework/kariricode-contract/issues", "source": "https://github.com/KaririCode-Framework/kariricode-contract" }, - "time": "2024-06-29T14:45:04+00:00" + "time": "2024-07-01T21:51:33+00:00" } ], "packages-dev": [ @@ -1445,16 +1445,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.0.2", + "version": "v5.1.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" + "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1", + "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1", "shasum": "" }, "require": { @@ -1465,7 +1465,7 @@ }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^9.0" }, "bin": [ "bin/php-parse" @@ -1497,9 +1497,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0" }, - "time": "2024-03-05T20:51:40+00:00" + "time": "2024-07-01T20:03:41+00:00" }, { "name": "nunomaduro/phpinsights", diff --git a/src/Collection/ArrayList.php b/src/Collection/ArrayList.php index a01433f..ef61737 100644 --- a/src/Collection/ArrayList.php +++ b/src/Collection/ArrayList.php @@ -49,17 +49,14 @@ public function remove(mixed $element): bool public function contains(mixed $element): bool { - return in_array($element, $this->elements, true); + return null !== $this->find($element); } - public function clear(): void + public function find(mixed $element): ?int { - $this->elements = []; - } + $index = array_search($element, $this->elements, true); - public function isEmpty(): bool - { - return empty($this->elements); + return false !== $index ? $index : null; } public function getItems(): array @@ -67,7 +64,12 @@ public function getItems(): array return $this->elements; } - public function count(): int + public function clear(): void + { + $this->elements = []; + } + + public function size(): int { return count($this->elements); } diff --git a/src/Collection/LinkedList.php b/src/Collection/LinkedList.php index f396c0c..fa8d99b 100644 --- a/src/Collection/LinkedList.php +++ b/src/Collection/LinkedList.php @@ -71,16 +71,21 @@ public function remove(mixed $element): bool } public function contains(mixed $element): bool + { + return null !== $this->find($element); + } + + public function find(mixed $element): ?Node { $current = $this->head; while (null !== $current) { if ($current->data === $element) { - return true; + return $current; } $current = $current->next; } - return false; + return null; } public function clear(): void @@ -107,7 +112,7 @@ public function getItems(): array return $items; } - public function count(): int + public function size(): int { return $this->size; } diff --git a/src/Map/HashMap.php b/src/Map/HashMap.php index 58739ac..b56d83a 100644 --- a/src/Map/HashMap.php +++ b/src/Map/HashMap.php @@ -4,6 +4,7 @@ namespace KaririCode\DataStructure\Map; +use KaririCode\Contract\DataStructure\Behavioral\IterableCollection; use KaririCode\Contract\DataStructure\Map; /** @@ -19,7 +20,7 @@ * * @see https://kariricode.org/ */ -class HashMap implements Map +class HashMap implements Map, IterableCollection, \IteratorAggregate { private array $map = []; @@ -68,4 +69,9 @@ public function values(): array { return array_values($this->map); } + + public function getIterator(): \Iterator + { + return new \ArrayIterator($this->map); + } } diff --git a/src/Map/TreeMap.php b/src/Map/TreeMap.php index d61555b..9ef5d3f 100644 --- a/src/Map/TreeMap.php +++ b/src/Map/TreeMap.php @@ -4,6 +4,7 @@ namespace KaririCode\DataStructure\Map; +use KaririCode\Contract\DataStructure\Behavioral\IterableCollection; use KaririCode\Contract\DataStructure\Map; use KaririCode\DataStructure\TreeMapNode; @@ -20,9 +21,10 @@ * * @see https://kariricode.org/ */ -class TreeMap implements Map +class TreeMap implements Map, IterableCollection, \IteratorAggregate { private ?TreeMapNode $root = null; + private int $size = 0; public function put(mixed $key, mixed $value): void { @@ -30,6 +32,7 @@ public function put(mixed $key, mixed $value): void if (null === $this->root) { $this->root = $newNode; $this->root->setBlack(); + ++$this->size; } else { $this->insertNode($newNode); $this->balanceAfterInsertion($newNode); @@ -41,6 +44,22 @@ public function get(mixed $key): mixed return $this->findNode($key)?->value; } + public function keys(): array + { + $keys = []; + $this->inOrderTraversalKeys($this->root, $keys); + + return $keys; + } + + public function values(): array + { + $values = []; + $this->inOrderTraversalValues($this->root, $values); + + return $values; + } + public function remove(mixed $key): bool { $node = $this->findNode($key); @@ -48,10 +67,67 @@ public function remove(mixed $key): bool return false; } $this->deleteNode($node); + --$this->size; return true; } + public function size(): int + { + return $this->size; + } + + public function clear(): void + { + $this->root = null; + $this->size = 0; + } + + public function containsKey(mixed $key): bool + { + return null !== $this->findNode($key); + } + + public function getItems(): array + { + $items = []; + $this->inOrderTraversal($this->root, $items); + + return $items; + } + + public function getIterator(): \Iterator + { + return new \ArrayIterator($this->getItems()); + } + + private function inOrderTraversalKeys(?TreeMapNode $node, array &$keys): void + { + if (null !== $node) { + $this->inOrderTraversalKeys($node->left, $keys); + $keys[] = $node->key; + $this->inOrderTraversalKeys($node->right, $keys); + } + } + + private function inOrderTraversalValues(?TreeMapNode $node, array &$values): void + { + if (null !== $node) { + $this->inOrderTraversalValues($node->left, $values); + $values[] = $node->value; + $this->inOrderTraversalValues($node->right, $values); + } + } + + private function inOrderTraversal(?TreeMapNode $node, array &$items): void + { + if (null !== $node) { + $this->inOrderTraversal($node->left, $items); + $items[$node->key] = $node->value; + $this->inOrderTraversal($node->right, $items); + } + } + private function insertNode(TreeMapNode $newNode): void { $current = $this->root; @@ -76,6 +152,8 @@ private function insertNode(TreeMapNode $newNode): void } else { $parent->right = $newNode; } + + ++$this->size; $this->balanceAfterInsertion($newNode); } diff --git a/src/Queue/ArrayDeque.php b/src/Queue/ArrayDeque.php index 792d421..98264bf 100644 --- a/src/Queue/ArrayDeque.php +++ b/src/Queue/ArrayDeque.php @@ -5,7 +5,6 @@ namespace KaririCode\DataStructure\Queue; use KaririCode\Contract\DataStructure\Deque; -use KaririCode\Contract\DataStructure\Queue; /** * ArrayDeque implementation. @@ -52,4 +51,9 @@ public function peekLast(): mixed return $this->elements[$index]; } + + public function add(mixed $element): void + { + $this->addLast($element); + } } diff --git a/src/Queue/ArrayQueue.php b/src/Queue/ArrayQueue.php index 9e39be5..a310225 100644 --- a/src/Queue/ArrayQueue.php +++ b/src/Queue/ArrayQueue.php @@ -21,5 +21,8 @@ */ class ArrayQueue extends CircularArrayQueue implements Queue { - // No additional methods required, uses methods from CircularArrayQueue + public function add(mixed $element): void + { + $this->enqueue($element); + } } diff --git a/src/Queue/CircularArrayQueue.php b/src/Queue/CircularArrayQueue.php index d54d7d5..523a227 100644 --- a/src/Queue/CircularArrayQueue.php +++ b/src/Queue/CircularArrayQueue.php @@ -88,6 +88,16 @@ public function enqueue(mixed $element): void ++$this->size; } + public function addLast(mixed $element): void + { + $this->enqueue($element); + } + + public function removeFirst(): mixed + { + return $this->dequeue(); + } + public function getItems(): array { $items = []; @@ -97,4 +107,23 @@ public function getItems(): array return $items; } + + public function remove(mixed $element): bool + { + for ($i = 0; $i < $this->size; ++$i) { + $index = ($this->front + $i) % $this->capacity; + if ($this->elements[$index] === $element) { + // Shift elements to the left to fill the gap + for ($j = $index; $j !== ($this->front + $this->size - 1) % $this->capacity; $j = ($j + 1) % $this->capacity) { + $this->elements[$j] = $this->elements[($j + 1) % $this->capacity]; + } + $this->elements[($this->front + $this->size - 1) % $this->capacity] = null; + --$this->size; + + return true; + } + } + + return false; + } } diff --git a/src/Set/TreeSet.php b/src/Set/TreeSet.php new file mode 100644 index 0000000..159ba58 --- /dev/null +++ b/src/Set/TreeSet.php @@ -0,0 +1,110 @@ + + * @license MIT + * + * @see https://kariricode.org/ + */ +class TreeSet implements Set +{ + private TreeMap $map; + + public function __construct() + { + $this->map = new TreeMap(); + } + + public function add(mixed $element): void + { + if (null === $this->map->get($element)) { + $this->map->put($element, true); + } + } + + public function remove(mixed $element): bool + { + return $this->map->remove($element); + } + + public function clear(): void + { + $this->map = new TreeMap(); + } + + public function contains(mixed $element): bool + { + return null !== $this->map->get($element); + } + + public function size(): int + { + return $this->map->size(); + } + + public function union(Set $otherSet): TreeSet + { + $resultSet = new TreeSet(); + foreach ($this->getItems() as $item) { + $resultSet->add($item); + } + foreach ($otherSet->getItems() as $item) { + $resultSet->add($item); + } + + return $resultSet; + } + + public function intersection(Set $otherSet): TreeSet + { + $resultSet = new TreeSet(); + foreach ($this->getItems() as $item) { + if ($otherSet->contains($item)) { + $resultSet->add($item); + } + } + + return $resultSet; + } + + public function difference(Set $otherSet): TreeSet + { + $resultSet = new TreeSet(); + foreach ($this->getItems() as $item) { + if (! $otherSet->contains($item)) { + $resultSet->add($item); + } + } + + return $resultSet; + } + + public function find(mixed $element): mixed + { + return $this->contains($element) ? $element : null; + } + + public function getItems(): array + { + $elements = []; + foreach ($this->map as $key => $value) { + $elements[] = $key; + } + + return $elements; + } +} diff --git a/src/Tree/TreeSet.php b/src/Tree/TreeSet.php deleted file mode 100644 index e69de29..0000000 diff --git a/tests/Collection/ArrayListTest.php b/tests/Collection/ArrayListTest.php index bddc9de..2d7727e 100644 --- a/tests/Collection/ArrayListTest.php +++ b/tests/Collection/ArrayListTest.php @@ -59,7 +59,7 @@ public function testClearElementsRemovesAllElementsFromList(): void $list->add(1); $list->clear(); - $this->assertTrue($list->isEmpty()); + $this->assertTrue($list->size() <= 0); $this->assertSame([], $list->getItems()); } @@ -67,10 +67,10 @@ public function testClearElementsRemovesAllElementsFromList(): void public function testIsEmptyReturnsTrueIfListIsEmpty(): void { $list = new ArrayList(); - $this->assertTrue($list->isEmpty()); + $this->assertTrue($list->size() <= 0); $list->add(1); - $this->assertFalse($list->isEmpty()); + $this->assertFalse($list->size() <= 0); } // Test getting all items from the list @@ -87,11 +87,11 @@ public function testGetItemsReturnsAllElementsInList(): void public function testCountElementsReturnsNumberOfElementsInList(): void { $list = new ArrayList(); - $this->assertSame(0, $list->count()); + $this->assertSame(0, $list->size()); $list->add(1); $list->add(2); - $this->assertSame(2, $list->count()); + $this->assertSame(2, $list->size()); } // Test getting an element by its index @@ -164,13 +164,13 @@ public function testMassAddAndRemoveHandlesLargeNumberOfElements(): void $list->add($i); } - $this->assertSame(1000, $list->count()); + $this->assertSame(1000, $list->size()); for ($i = 0; $i < 1000; ++$i) { $list->remove($i); } - $this->assertTrue($list->isEmpty()); + $this->assertTrue($list->size() <= 0); } // Test index consistency after removing an element diff --git a/tests/Collection/LinkedListTest.php b/tests/Collection/LinkedListTest.php index 9df1aa8..b502a42 100644 --- a/tests/Collection/LinkedListTest.php +++ b/tests/Collection/LinkedListTest.php @@ -87,11 +87,11 @@ public function testGetItemsReturnsAllElementsInList(): void public function testCountElementsReturnsNumberOfElementsInList(): void { $list = new LinkedList(); - $this->assertSame(0, $list->count()); + $this->assertSame(0, $list->size()); $list->add(1); $list->add(2); - $this->assertSame(2, $list->count()); + $this->assertSame(2, $list->size()); } // Test getting an element by its index @@ -164,7 +164,7 @@ public function testMassAddAndRemoveHandlesLargeNumberOfElements(): void $list->add($i); } - $this->assertSame(1000, $list->count()); + $this->assertSame(1000, $list->size()); for ($i = 0; $i < 1000; ++$i) { $list->remove($i); diff --git a/tests/Map/HashMapTest.php b/tests/Map/HashMapTest.php index a43f7f8..6aa56d3 100644 --- a/tests/Map/HashMapTest.php +++ b/tests/Map/HashMapTest.php @@ -9,6 +9,14 @@ final class HashMapTest extends TestCase { + private HashMap $hashMap; + + protected function setUp(): void + { + parent::setUp(); + $this->hashMap = new HashMap(); + } + // Test adding a key-value pair to the map public function testPutAddsKeyValuePairToMap(): void { @@ -104,4 +112,25 @@ public function testPutReplacesValueForExistingKey(): void $map->put('key1', 'value2'); $this->assertSame('value2', $map->get('key1')); } + + // Test for the getIterator method + public function testGetIterator(): void + { + $this->hashMap->put(1, 'one'); + $this->hashMap->put(2, 'two'); + $this->hashMap->put(3, 'three'); + + $items = []; + foreach ($this->hashMap as $key => $value) { + $items[$key] = $value; + } + + $expectedItems = [ + 1 => 'one', + 2 => 'two', + 3 => 'three', + ]; + + $this->assertSame($expectedItems, $items); + } } diff --git a/tests/Map/TreeMapTest.php b/tests/Map/TreeMapTest.php index 97ef270..6be16e2 100644 --- a/tests/Map/TreeMapTest.php +++ b/tests/Map/TreeMapTest.php @@ -137,6 +137,43 @@ public function testBalancingAfterRemoval(): void $this->assertStringContainsString('15:fifteen [RED]', $treeStructure); } + // test size + public function testSize(): void + { + $this->assertSame(0, $this->treeMap->size(), 'Initial size should be 0'); + + $this->treeMap->put(1, 'one'); + $this->assertSame(1, $this->treeMap->size(), 'Size should be 1 after adding one element'); + + $this->treeMap->put(2, 'two'); + $this->assertSame(2, $this->treeMap->size(), 'Size should be 2 after adding another element'); + + $this->treeMap->put(1, 'one updated'); + $this->assertSame(2, $this->treeMap->size(), 'Size should remain 2 after updating an existing element'); + + $this->treeMap->remove(1); + $this->assertSame(1, $this->treeMap->size(), 'Size should be 1 after removing one element'); + + $this->treeMap->remove(2); + $this->assertSame(0, $this->treeMap->size(), 'Size should be 0 after removing all elements'); + } + + // Test getting all items from the TreeMap + public function testGetItems(): void + { + $this->treeMap->put(10, 'ten'); + $this->treeMap->put(5, 'five'); + $this->treeMap->put(20, 'twenty'); + + $expectedItems = [ + 5 => 'five', + 10 => 'ten', + 20 => 'twenty', + ]; + + $this->assertSame($expectedItems, $this->treeMap->getItems()); + } + // Test complex operations on the tree. public function testComplexOperations(): void { @@ -291,6 +328,73 @@ public function testDeleteRootNodeWithSingleChild(): void $this->assertNull($newRoot->parent); } + // Teste para verificar a existĂȘncia de uma chave. + public function testContainsKey(): void + { + $this->treeMap->put(10, 'ten'); + $this->treeMap->put(20, 'twenty'); + $this->assertTrue($this->treeMap->containsKey(10)); + $this->assertTrue($this->treeMap->containsKey(20)); + $this->assertFalse($this->treeMap->containsKey(30)); + } + + // Teste para obter todas as chaves do mapa. + public function testKeys(): void + { + $this->treeMap->put(10, 'ten'); + $this->treeMap->put(5, 'five'); + $this->treeMap->put(20, 'twenty'); + + $expectedKeys = [5, 10, 20]; + $this->assertSame($expectedKeys, $this->treeMap->keys()); + } + + // Teste para obter todos os valores do mapa. + public function testValues(): void + { + $this->treeMap->put(10, 'ten'); + $this->treeMap->put(5, 'five'); + $this->treeMap->put(20, 'twenty'); + + $expectedValues = ['five', 'ten', 'twenty']; + $this->assertSame($expectedValues, $this->treeMap->values()); + } + + // Teste para limpar o mapa. + public function testClear(): void + { + $this->treeMap->put(10, 'ten'); + $this->treeMap->put(5, 'five'); + $this->treeMap->put(20, 'twenty'); + + $this->treeMap->clear(); + $this->assertSame(0, $this->treeMap->size()); + $this->assertNull($this->treeMap->get(10)); + $this->assertNull($this->treeMap->get(5)); + $this->assertNull($this->treeMap->get(20)); + } + + // Teste para obter o iterador. + public function testGetIterator(): void + { + $this->treeMap->put(10, 'ten'); + $this->treeMap->put(5, 'five'); + $this->treeMap->put(20, 'twenty'); + + $items = []; + foreach ($this->treeMap as $key => $value) { + $items[$key] = $value; + } + + $expectedItems = [ + 5 => 'five', + 10 => 'ten', + 20 => 'twenty', + ]; + + $this->assertSame($expectedItems, $items); + } + // Helper method to get the root node of the tree. private function getRootNode(): ?TreeMapNode { diff --git a/tests/Queue/ArrayDequeTest.php b/tests/Queue/ArrayDequeTest.php index ce85f39..6996d98 100644 --- a/tests/Queue/ArrayDequeTest.php +++ b/tests/Queue/ArrayDequeTest.php @@ -9,6 +9,18 @@ final class ArrayDequeTest extends TestCase { + // Teste adicionar elementos com add + public function testAddAddsElementToEndOfDeque(): void + { + $deque = new ArrayDeque(); + $deque->add(1); + $deque->add(2); + $deque->add(3); + + $this->assertSame(1, $deque->peek()); + $this->assertSame([1, 2, 3], $deque->getItems()); + } + // Test enqueuing elements public function testEnqueueAddsElementToEndOfDeque(): void { @@ -237,4 +249,26 @@ public function testGetItemsReturnsAllElementsInCorrectOrder(): void $deque->enqueue(3); $this->assertSame([1, 2, 3], $deque->getItems()); } + + // Test remove method + public function testRemove(): void + { + $deque = new ArrayDeque(); + $deque->enqueue(1); + $deque->enqueue(2); + $deque->enqueue(3); + $this->assertTrue($deque->remove(2)); + $this->assertFalse($deque->remove(4)); + $this->assertSame([1, 3], $deque->getItems()); + } + + // Test getItems method + public function testGetItems(): void + { + $deque = new ArrayDeque(); + $deque->enqueue(1); + $deque->enqueue(2); + $deque->enqueue(3); + $this->assertSame([1, 2, 3], $deque->getItems()); + } } diff --git a/tests/Queue/ArrayQueueTest.php b/tests/Queue/ArrayQueueTest.php index 073a5f4..2f7ba25 100644 --- a/tests/Queue/ArrayQueueTest.php +++ b/tests/Queue/ArrayQueueTest.php @@ -9,6 +9,37 @@ final class ArrayQueueTest extends TestCase { + private ArrayQueue $queue; + + protected function setUp(): void + { + parent::setUp(); + $this->queue = new ArrayQueue(); + } + + // Test adding elements to the queue + public function testAdd(): void + { + $this->queue->add(1); + $this->queue->add(2); + $this->queue->add(3); + + $this->assertSame(1, $this->queue->peek()); + $this->assertSame([1, 2, 3], $this->queue->getItems()); + } + + // Test removing elements from the queue + public function testRemoveFirst(): void + { + $this->queue->add(1); + $this->queue->add(2); + $this->queue->add(3); + + $this->assertSame(1, $this->queue->removeFirst()); + $this->assertSame(2, $this->queue->peek()); + $this->assertSame([2, 3], $this->queue->getItems()); + } + // Test enqueuing elements public function testEnqueueAddsElementToEndOfQueue(): void { @@ -137,4 +168,26 @@ public function testGetItemsReturnsAllElementsInCorrectOrder(): void $queue->enqueue(3); $this->assertSame([1, 2, 3], $queue->getItems()); } + + // Test remove method + public function testRemove(): void + { + $queue = new ArrayQueue(); + $queue->enqueue(1); + $queue->enqueue(2); + $queue->enqueue(3); + $this->assertTrue($queue->remove(2)); + $this->assertFalse($queue->remove(4)); + $this->assertSame([1, 3], $queue->getItems()); + } + + // Test getItems method + public function testGetItems(): void + { + $queue = new ArrayQueue(); + $queue->enqueue(1); + $queue->enqueue(2); + $queue->enqueue(3); + $this->assertSame([1, 2, 3], $queue->getItems()); + } } diff --git a/tests/Set/TreeSetTest.php b/tests/Set/TreeSetTest.php new file mode 100644 index 0000000..2d77753 --- /dev/null +++ b/tests/Set/TreeSetTest.php @@ -0,0 +1,195 @@ +set = new TreeSet(); + } + + // Test adding elements to the set + public function testAddElement(): void + { + $this->set->add(1); + $this->assertTrue($this->set->contains(1)); + $this->set->add(1); // Duplicate element + $this->assertEquals(1, $this->set->size()); // Size should still be 1 + } + + // Test removing elements from the set + public function testRemoveElement(): void + { + $this->set->add(1); + $this->assertTrue($this->set->remove(1)); + $this->assertFalse($this->set->contains(1)); + $this->assertFalse($this->set->remove(1)); // Removing non-existing element + } + + // Test checking if an element exists in the set + public function testContainsElement(): void + { + $this->set->add(1); + $this->assertTrue($this->set->contains(1)); + $this->assertFalse($this->set->contains(2)); // Non-existing element + } + + // Test clearing the set + public function testClearSet(): void + { + $this->set->add(1); + $this->set->add(2); + $this->set->clear(); + $this->assertTrue($this->set->size() <= 0); + } + + // Test getting the size of the set + public function testSizeOfSet(): void + { + $this->assertSame(0, $this->set->size()); + $this->set->add(1); + $this->assertSame(1, $this->set->size()); + } + + // Test converting the set to an array + public function testToArray(): void + { + $this->set->add(1); + $this->set->add(2); + $this->assertSame([1, 2], $this->set->getItems()); + } + + // Test adding various data types to the set + public function testSetWithVariousDataTypes(): void + { + $obj = new \stdClass(); + + $this->set->add(123); + $this->set->add('string'); + $this->set->add([1, 2, 3]); + $this->set->add($obj); + + $this->assertTrue($this->set->contains(123)); + $this->assertTrue($this->set->contains('string')); + $this->assertTrue($this->set->contains([1, 2, 3])); + $this->assertTrue($this->set->contains($obj)); + } + + // Test set behavior after mixed operations + public function testSetBehaviorAfterMixedOperations(): void + { + $this->set->add(1); + $this->set->add(2); + $this->set->remove(1); + $this->set->add(3); + $this->set->clear(); + $this->set->add(4); + + $this->assertFalse($this->set->contains(1)); + $this->assertFalse($this->set->contains(2)); + $this->assertFalse($this->set->contains(3)); + $this->assertTrue($this->set->contains(4)); + } + + // Test adding and removing a large data set + public function testLargeDataSet(): void + { + $data = range(1, 1000); + foreach ($data as $element) { + $this->set->add($element); + } + + $this->assertSame(1000, $this->set->size()); + + foreach ($data as $element) { + $this->assertTrue($this->set->contains($element)); + } + + foreach ($data as $element) { + $this->set->remove($element); + } + + $this->assertTrue($this->set->size() <= 0); + } + + // Test union of two sets + public function testUnion(): void + { + $set1 = new TreeSet(); + $set2 = new TreeSet(); + + $set1->add(1); + $set1->add(2); + + $set2->add(2); + $set2->add(3); + + $resultSet = $set1->union($set2); + + $this->assertTrue($resultSet->contains(1)); + $this->assertTrue($resultSet->contains(2)); + $this->assertTrue($resultSet->contains(3)); + } + + // Test intersection of two sets + public function testIntersection(): void + { + $set1 = new TreeSet(); + $set2 = new TreeSet(); + + $set1->add(1); + $set1->add(2); + $set1->add(3); + + $set2->add(2); + $set2->add(3); + $set2->add(4); + + $resultSet = $set1->intersection($set2); + + $this->assertFalse($resultSet->contains(1)); + $this->assertTrue($resultSet->contains(2)); + $this->assertTrue($resultSet->contains(3)); + $this->assertFalse($resultSet->contains(4)); + } + + // Test difference of two sets + public function testDifference(): void + { + $set1 = new TreeSet(); + $set2 = new TreeSet(); + + $set1->add(1); + $set1->add(2); + $set1->add(3); + + $set2->add(2); + $set2->add(3); + $set2->add(4); + + $resultSet = $set1->difference($set2); + + $this->assertTrue($resultSet->contains(1)); + $this->assertFalse($resultSet->contains(2)); + $this->assertFalse($resultSet->contains(3)); + $this->assertFalse($resultSet->contains(4)); + } + + // Test find method + public function testFind(): void + { + $this->set->add(1); + $this->set->add(2); + $this->assertSame(1, $this->set->find(1)); + $this->assertNull($this->set->find(3)); // Non-existing element + } +}