From 821ecb84ae6011dfff1112ec54ec05eb9ae29559 Mon Sep 17 00:00:00 2001 From: DumbergerL Date: Tue, 9 Jan 2024 16:51:28 +0100 Subject: [PATCH] test implementation of collection objects --- src/Models/AbstractCollection.php | 139 ++++++++++++++++++ .../Groups/Group/GroupTypeCollection.php | 13 ++ src/Models/Groups/Group/GroupTypeRequest.php | 4 +- .../GroupMember/GroupMemberCollection.php | 26 ++++ src/Models/Groups/Person/PersonCollection.php | 13 ++ tests/Unit/Models/Collection/Car.php | 17 +++ .../Unit/Models/Collection/CarCollection.php | 18 +++ .../Unit/Models/Collection/CollectionTest.php | 136 +++++++++++++++++ 8 files changed, 364 insertions(+), 2 deletions(-) create mode 100644 src/Models/AbstractCollection.php create mode 100644 src/Models/Groups/Group/GroupTypeCollection.php create mode 100644 src/Models/Groups/GroupMember/GroupMemberCollection.php create mode 100644 src/Models/Groups/Person/PersonCollection.php create mode 100644 tests/Unit/Models/Collection/Car.php create mode 100644 tests/Unit/Models/Collection/CarCollection.php create mode 100644 tests/Unit/Models/Collection/CollectionTest.php diff --git a/src/Models/AbstractCollection.php b/src/Models/AbstractCollection.php new file mode 100644 index 00000000..f7ec8567 --- /dev/null +++ b/src/Models/AbstractCollection.php @@ -0,0 +1,139 @@ +validateValue($value); + } + $this->arrayObject = new ArrayObject($array); + } + + protected abstract function getClassType(): string; + + protected abstract function createInstance(array $data): AbstractCollection; + + private function validateValue(mixed $value): void + { + $classType = $this->getClassType(); + if(!is_a($value, $classType)){ + $valueType = is_object($value) ? get_class($value) : gettype($value); + throw new \InvalidArgumentException("Value from type " . $valueType . " is not assignable to Collection from type " . get_class($this)); + } + } + + /** + * Alias for append. + * @param object $value + * @return void + */ + public function push(object $value): void + { + $this->append($value); + } + public function append(object $value): void + { + $this->validateValue($value); + $this->arrayObject[] = $value; + } + + public function first(): ?object + { + $iterator = $this->arrayObject->getIterator(); + return $iterator->current(); + } + + public function filter(callable $callback, int $mode = 0): self + { + $filtered = array_filter((array) $this->arrayObject, $callback, $mode); + return $this->createInstance($filtered); + } + + public function map(callable $callback): self + { + $filtered = array_map($callback, (array) $this->arrayObject); + return $this->createInstance($filtered); + } + + public function count(): int + { + return $this->arrayObject->count(); + } + + /** + * Sort the entries by value + * @param int $flags + * @return bool + */ + public function asort(int $flags = SORT_REGULAR): bool + { + return $this->arrayObject->asort($flags); + } + + /** + * Sort the entries by key + * @param int $flags + * @return bool + */ + public function ksort(int $flags = SORT_REGULAR): bool + { + return $this->arrayObject->ksort($flags); + } + + /** + * Sort the entries with a user-defined comparison function and maintain key association + * @param callable $callback + * @return bool + */ + public function uasort(callable $callback): bool + { + return $this->arrayObject->uasort($callback); + } + + public function getIterator(): Traversable + { + return $this->arrayObject->getIterator(); + } + + public function offsetExists(mixed $offset): bool + { + return $this->arrayObject->offsetExists($offset); + } + + public function offsetGet(mixed $offset): mixed + { + return $this->arrayObject->offsetGet($offset); + } + + public function offsetSet(mixed $offset, mixed $value): void + { + $this->validateValue($value); + $this->arrayObject->offsetSet($offset, $value); + } + + public function offsetUnset(mixed $offset): void + { + $this->arrayObject->offsetUnset($offset); + $this->filterNullableEntries(); + } + + private function filterNullableEntries(): void + { + $withoutNullable = array_filter($this->arrayObject->getArrayCopy(), function($element){ + return isset($element); + }); + $this->arrayObject->exchangeArray(array_values($withoutNullable)); + } +} \ No newline at end of file diff --git a/src/Models/Groups/Group/GroupTypeCollection.php b/src/Models/Groups/Group/GroupTypeCollection.php new file mode 100644 index 00000000..b8f384a5 --- /dev/null +++ b/src/Models/Groups/Group/GroupTypeCollection.php @@ -0,0 +1,13 @@ +all(); + return new GroupTypeCollection((new GroupTypeRequestBuilder())->all()); } public static function where(string $key, $value): GroupTypeRequestBuilder diff --git a/src/Models/Groups/GroupMember/GroupMemberCollection.php b/src/Models/Groups/GroupMember/GroupMemberCollection.php new file mode 100644 index 00000000..4b08929a --- /dev/null +++ b/src/Models/Groups/GroupMember/GroupMemberCollection.php @@ -0,0 +1,26 @@ +getPersonId(); + }, $this); + + return PersonRequest::where('ids', $ids)->get(); + } + +} \ No newline at end of file diff --git a/src/Models/Groups/Person/PersonCollection.php b/src/Models/Groups/Person/PersonCollection.php new file mode 100644 index 00000000..06e90094 --- /dev/null +++ b/src/Models/Groups/Person/PersonCollection.php @@ -0,0 +1,13 @@ +append(new Car("bmw")); + $carCollection[] = new Car("daimler"); + + $this->assertEquals(3, sizeof($carCollection)); + } + + public function testAddCollection_TypeCheck() + { + $this->expectException(\InvalidArgumentException::class); + $carCollection = new CarCollection(); + $carCollection[] = new Car("mercedes"); + $carCollection[] = "awidon"; + } + + public function testCreateCollection() + { + $car1 = new Car("mercedes"); + $car2 = new Car("bmw"); + $carCollection = new CarCollection([$car1, $car2]); + $this->assertEquals(2, sizeof($carCollection)); + } + + public function testCreateCollection_TypeCheck() + { + $this->expectException(\InvalidArgumentException::class); + $carCollection = new CarCollection(["test"]); + } + + public function testGetSpecificElement() + { + $car1 = new Car("mercedes"); + $car2 = new Car("bmw"); + $carCollection = new CarCollection([$car1, $car2]); + + $car = $carCollection->offsetGet(1); + $this->assertEquals($car->brand, "bmw"); + + $car = $carCollection[0]; + $this->assertEquals($car->brand, "mercedes"); + } + + public function testRemoveElement() + { + $car1 = new Car("mercedes"); + $car2 = new Car("bmw"); + $car3 = new Car("daimler"); + $carCollection = new CarCollection([$car1, $car2, $car3]); + + $carCollection->offsetUnset(1); + $this->assertEquals(2, sizeof($carCollection)); + } + + public function testRemoveElementInLoop() + { + $car1 = new Car("mercedes"); + $car2 = new Car("bmw"); + $car3 = new Car("daimler"); + + $carCollection = new CarCollection([$car1, $car2, $car3]); + + $numberOfIterations = 0; + foreach($carCollection as $car) + { + echo "\n". $car->brand; + if($car->brand === "bmw"){ + $carCollection->offsetUnset(1); + } + $numberOfIterations++; + } + $this->assertEquals(3, $numberOfIterations); + } + + public function testGetFirstElement() + { + $car1 = new Car("mercedes"); + $car2 = new Car("bmw"); + $car3 = new Car("daimler"); + + $carCollection = new CarCollection([$car1, $car2, $car3]); + + foreach($carCollection as $carIterator){ + $car = $carCollection->first(); + $this->assertEquals("mercedes", $car->brand); + } + } + + public function testGetFirstElement_Empty() + { + $carCollection = new CarCollection(); + $this->assertNull($carCollection->first()); + } + + public function testGetFirstElement_FirstUnset() + { + $carCollection = new CarCollection([Car::fromBrand("mercedes"), Car::fromBrand("audi")]); + $this->assertNotNull($carCollection->first()); + $this->assertEquals("mercedes", $carCollection->first()->brand); + + $carCollection->offsetUnset(0); + $this->assertNotNull($carCollection->first()); + $this->assertEquals("audi", $carCollection->first()->brand); + } + + public function testFilter() + { + $car1 = new Car("mercedes"); + $car2 = new Car("bmw"); + $car3 = new Car("daimler"); + + $carCollection = new CarCollection([$car1, $car2, $car3]); + + + $carCollectionFiltered = $carCollection->filter(function($test){ + return $test->brand === "bmw"; + }); + + $this->assertEquals(sizeof($carCollectionFiltered), 1); + } + +} \ No newline at end of file