diff --git a/src/ArrayCollection.php b/src/ArrayCollection.php index 532ee1c..40ba415 100644 --- a/src/ArrayCollection.php +++ b/src/ArrayCollection.php @@ -21,7 +21,7 @@ use function Sauls\Component\Helper\array_set_value; use Sauls\Component\Helper\Exception\PropertyNotAccessibleException; -class ArrayCollection implements Collection +class ArrayCollection implements Collection, \Serializable { /** * @var array @@ -74,7 +74,7 @@ public function removeKey($key) return array_remove_key($this->elements, $key, false); } - public function removeElement($element) + public function removeValue($element) { return array_remove_value($this->elements, $element); } @@ -104,16 +104,50 @@ public function map(\Closure $function) return \array_map($function, $this->elements); } - public function hasKey($key): bool + public function keyOrValueExists($keyOrValue): bool + { + if ($this->keyExists($keyOrValue)) { + return true; + } + + return $this->valueExists($keyOrValue); + } + + public function keyOrValueDoesNotExists($keyOrValue): bool + { + return false === $this->keyOrValueExists($keyOrValue); + } + + public function keyExists($key): bool { return array_key_exists($this->elements, $key); } - public function hasValue($value): bool + public function keyDoesNotExists($key): bool + { + return false === $this->keyExists($key); + } + + public function valueExists($value): bool { return empty(array_deep_search($this->elements, $value)) ? false : true; } + public function valueDoesNotExists($value): bool + { + return false === $this->valueExists($value); + } + + public function valueIsNull($key): bool + { + return null === $this->get($key); + } + + public function valueIsNotNull($key): bool + { + return false === $this->valueIsNull($key); + } + public function isEmpty(): bool { return empty($this->elements); @@ -121,9 +155,23 @@ public function isEmpty(): bool public function __toString(): string { - return __CLASS__ . '@' . spl_object_hash($this); + return __CLASS__ . '#' . $this->getHash(); } + public function getHash(): string + { + return md5($this->serialize()); + } + + /** + * @return string + */ + public function getSplHash(): string + { + return \spl_object_hash($this); + } + + public function getIterator() { return new \ArrayIterator($this->elements); @@ -131,7 +179,7 @@ public function getIterator() public function offsetExists($offset) { - return $this->hasKey($offset); + return $this->keyExists($offset); } /** @@ -157,12 +205,13 @@ public function count(): int return \count($this->elements); } - public function has($keyOrValue): bool + public function serialize(): string { - if ($this->hasKey($keyOrValue)) { - return true; - } + return \serialize($this->elements); + } - return $this->hasValue($keyOrValue); + public function unserialize($value): void + { + $this->elements = \unserialize($value); } } diff --git a/src/Collection.php b/src/Collection.php index 18716fc..5a76f61 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -21,15 +21,22 @@ public function get($key, $default = null); public function merge(array $elements): void; public function replace(array $elements): void; public function removeKey($key); - public function removeElement($element); + public function removeValue($element); public function slice($offset, $length = null): array; public function clear(): void; public function all(): array; public function filter(\Closure $function); public function map(\Closure $function); - public function has($keyOrValue): bool; - public function hasKey($key): bool; - public function hasValue($value): bool; + public function keyOrValueExists($keyOrValue): bool; + public function keyOrValueDoesNotExists($keyOrValue): bool; + public function keyExists($key): bool; + public function keyDoesNotExists($key): bool; + public function valueExists($value): bool; + public function valueDoesNotExists($value): bool; + public function valueIsNull($key): bool; + public function valueIsNotNull($key): bool; public function isEmpty(): bool; public function __toString(): string; + public function getHash(): string; + public function getSplHash(): string; } diff --git a/src/ImmutableArrayCollection.php b/src/ImmutableArrayCollection.php index 9cbad2f..019d670 100644 --- a/src/ImmutableArrayCollection.php +++ b/src/ImmutableArrayCollection.php @@ -67,10 +67,40 @@ public function removeKey($key) /** * @throws \Sauls\Component\Collection\Exception\UnsupportedOperationException */ - public function removeElement($element) + public function removeValue($element) { throw new UnsupportedOperationException(); } + /** + * @throws \Sauls\Component\Collection\Exception\UnsupportedOperationException + */ + public function unserialize($value): void + { + throw new UnsupportedOperationException(); + } + + /** + * @throws \Sauls\Component\Collection\Exception\UnsupportedOperationException + */ + public function map(\Closure $function) + { + throw new UnsupportedOperationException(); + } + /** + * @throws \Sauls\Component\Collection\Exception\UnsupportedOperationException + */ + public function offsetSet($offset, $value) + { + throw new UnsupportedOperationException(); + } + + /** + * @throws \Sauls\Component\Collection\Exception\UnsupportedOperationException + */ + public function offsetUnset($offset) + { + throw new UnsupportedOperationException(); + } } diff --git a/tests/ArrayCollectionTest.php b/tests/ArrayCollectionTest.php index 4423edc..13401b5 100644 --- a/tests/ArrayCollectionTest.php +++ b/tests/ArrayCollectionTest.php @@ -13,6 +13,7 @@ namespace Sauls\Component\Collection; use Sauls\Component\Collection\Exception\UnsupportedOperationException; +use Sauls\Component\Collection\Stubs\SimpleObject; use function Sauls\Component\Helper\array_multiple_keys_exists; use Sauls\Component\Helper\Exception\PropertyNotAccessibleException; @@ -44,7 +45,7 @@ public function should_set_array_value() $arrayCollection->set('test', 11); $arrayCollection->set('test.nested.key', 11); - $this->assertArrayHasKey('test', $arrayCollection->all()); + $this->assertTrue($arrayCollection->keyExists('test')); $this->assertSame(11, $arrayCollection->get('test.nested.key')); } @@ -108,7 +109,7 @@ public function should_remove_array_key() $arrayCollection = $this->createArrayCollection($this->getTestArray()); $arrayCollection->removeKey('key1'); - $this->assertArrayNotHasKey('key1', $arrayCollection->all()); + $this->assertTrue($arrayCollection->keyDoesNotExists('key1')); $arrayCollection->removeKey('key2.x.p2'); $this->assertFalse($arrayCollection->get('key2.x.p2', false)); @@ -122,12 +123,12 @@ public function should_remove_array_element() $array = $this->getTestArray(); $arrayCollection = $this->createArrayCollection($array); - $result = $arrayCollection->removeElement('x'); + $result = $arrayCollection->removeValue('x'); $this->assertInternalType('array', $result); $this->assertEmpty($result); $this->assertSame($array, $arrayCollection->all()); - $result = $arrayCollection->removeElement(1); + $result = $arrayCollection->removeValue(1); $this->assertInternalType('array', $result); $this->assertNotEmpty($result); @@ -149,8 +150,8 @@ public function should_add_given_array() ], ]); - $this->assertTrue($arrayCollection->hasKey('p1')); - $this->assertTrue($arrayCollection->hasKey('pn.b1')); + $this->assertTrue($arrayCollection->keyExists('p1')); + $this->assertTrue($arrayCollection->keyExists('pn.b1')); } /** @@ -170,7 +171,30 @@ public function should_clear_array() public function should_return_array_collection_as_string() { $arrayCollection = $this->createArrayCollection($this->getTestArray()); - $this->assertContains('@', $arrayCollection->__toString()); + + $this->assertContains('#', $arrayCollection->__toString()); + } + + /** + * @test + */ + public function should_return_array_cellection_hash() + { + $arrayCollection = $this->createArrayCollection($this->getTestArray()); + + $this->assertSame( + 'd9947bc8febb07f84b611a6218ba8c1f', + $arrayCollection->getHash() + ); + } + + /** + * @test + */ + public function should_return_array_collection_spl_hash() + { + $arrayCollection = $this->createArrayCollection($this->getTestArray()); + $this->assertInternalType('string', $arrayCollection->getSplHash()); } /** @@ -218,11 +242,11 @@ public function should_make_offset_set() { $arrayCollection = $this->createArrayCollection($this->getTestArray()); - $this->assertFalse($arrayCollection->hasKey('key11')); + $this->assertFalse($arrayCollection->keyExists('key11')); $arrayCollection['key11'] = 1; $this->assertSame(1, $arrayCollection->get('key11')); - $this->assertFalse($arrayCollection->hasKey('k.b.n')); + $this->assertFalse($arrayCollection->keyExists('k.b.n')); $arrayCollection['k.b.n'] = 'works'; $this->assertSame('works', $arrayCollection->get('k.b.n')); } @@ -234,13 +258,13 @@ public function should_maked_offset_unset() { $arrayCollection = $this->createArrayCollection($this->getTestArray()); - $this->assertTrue($arrayCollection->hasKey('key1')); + $this->assertTrue($arrayCollection->keyExists('key1')); unset($arrayCollection['key1']); - $this->assertFalse($arrayCollection->hasKey('key1')); + $this->assertFalse($arrayCollection->keyExists('key1')); - $this->assertTrue($arrayCollection->hasKey('key2.x.p1')); + $this->assertTrue($arrayCollection->keyExists('key2.x.p1')); unset($arrayCollection['key2.x.p1']); - $this->assertFalse($arrayCollection->hasKey('key2.x.p1')); + $this->assertFalse($arrayCollection->keyExists('key2.x.p1')); } /** @@ -316,7 +340,7 @@ public function should_map_values() { $arrayCollection = $this->createArrayCollection($this->getTestArray()); - $result = $arrayCollection->map(function($value) { + $result = $arrayCollection->map(function ($value) { return \is_int($value) ? $value * 25 : $value; }); @@ -329,10 +353,10 @@ public function should_map_values() public function should_check_if_element_exists() { $arrayCollection = $this->createArrayCollection($this->getTestArray()); - $this->assertTrue($arrayCollection->hasValue(1)); - $this->assertTrue($arrayCollection->hasValue(22)); - $this->assertTrue($arrayCollection->hasValue(11)); - $this->assertFalse($arrayCollection->hasValue(9)); + $this->assertTrue($arrayCollection->valueExists(1)); + $this->assertTrue($arrayCollection->valueExists(22)); + $this->assertTrue($arrayCollection->valueExists(11)); + $this->assertFalse($arrayCollection->valueExists(9)); } /** @@ -342,17 +366,17 @@ public function should_return_existence_of_key_or_value() { $arrayCollection = $this->createArrayCollection($this->getTestArray()); - $this->assertFalse($arrayCollection->has('test1')); - $this->assertTrue($arrayCollection->has('key2')); - $this->assertTrue($arrayCollection->has(22)); - $this->assertTrue($arrayCollection->has('key2.z')); - $this->assertFalse($arrayCollection->has('key2.b')); + $this->assertFalse($arrayCollection->keyOrValueExists('test1')); + $this->assertTrue($arrayCollection->keyOrValueExists('key2')); + $this->assertTrue($arrayCollection->keyOrValueExists(22)); + $this->assertTrue($arrayCollection->keyOrValueExists('key2.z')); + $this->assertFalse($arrayCollection->keyOrValueExists('key2.b')); } /** * @test */ - public function should_throw_unsupported_method_operation_when_trying_to_set_immutable_array_collection(): void + public function should_throw_unsupported_operation_when_trying_to_set_immutable_array_collection(): void { $this->expectException(UnsupportedOperationException::class); $immutableCollection = new ImmutableArrayCollection([ @@ -365,7 +389,7 @@ public function should_throw_unsupported_method_operation_when_trying_to_set_imm /** * @test */ - public function should_throw_unsupported_method_operation_when_trying_to_add_immutable_array_collection(): void + public function should_throw_unsupported_operation_when_trying_to_add_immutable_array_collection(): void { $this->expectException(UnsupportedOperationException::class); $immutableCollection = new ImmutableArrayCollection([ @@ -378,7 +402,7 @@ public function should_throw_unsupported_method_operation_when_trying_to_add_imm /** * @test */ - public function should_throw_unsupported_method_operation_when_trying_to_merge_immutable_array_collection(): void + public function should_throw_unsupported_operation_when_trying_to_merge_immutable_array_collection(): void { $this->expectException(UnsupportedOperationException::class); $immutableCollection = new ImmutableArrayCollection([ @@ -391,7 +415,7 @@ public function should_throw_unsupported_method_operation_when_trying_to_merge_i /** * @test */ - public function should_throw_unsupported_method_operation_when_trying_to_replace_immutable_array_collection(): void + public function should_throw_unsupported_operation_when_trying_to_replace_immutable_array_collection(): void { $this->expectException(UnsupportedOperationException::class); $immutableCollection = new ImmutableArrayCollection([ @@ -404,7 +428,7 @@ public function should_throw_unsupported_method_operation_when_trying_to_replace /** * @test */ - public function should_throw_unsupported_method_operation_when_trying_to_clear_immutable_array_collection(): void + public function should_throw_unsupported_operation_when_trying_to_clear_immutable_array_collection(): void { $this->expectException(UnsupportedOperationException::class); $immutableCollection = new ImmutableArrayCollection([ @@ -417,7 +441,8 @@ public function should_throw_unsupported_method_operation_when_trying_to_clear_i /** * @test */ - public function should_throw_unsupported_method_operation_when_trying_to_remove_key_from_immutable_array_collection(): void + public function should_throw_unsupported_operation_when_trying_to_remove_key_from_immutable_array_collection( + ): void { $this->expectException(UnsupportedOperationException::class); $immutableCollection = new ImmutableArrayCollection([ @@ -430,14 +455,15 @@ public function should_throw_unsupported_method_operation_when_trying_to_remove_ /** * @test */ - public function should_throw_unsupported_method_operation_when_trying_to_remove_element_from_immutable_array_collection(): void + public function should_throw_unsupported_operation_when_trying_to_remove_element_from_immutable_array_collection( + ): void { $this->expectException(UnsupportedOperationException::class); $immutableCollection = new ImmutableArrayCollection([ 'test' => 11, ]); - $immutableCollection->removeElement(11); + $immutableCollection->removeValue(11); } /** @@ -452,7 +478,149 @@ public function should_create_immutable_array(): void $this->assertSame($array, $immutableArrayCollection->all()); $immutableArrayCollection->set('a', 'b'); + } + + /** + * @test + */ + public function should_return_that_array_value_is_not_null() + { + $arrayCollection = new ArrayCollection([ + 'test' => 1, + 't2' => [ + 'b' => 11, + 'c' => [ + 'd' => 135, + ], + ], + ]); + $this->assertTrue($arrayCollection->valueIsNotNull('test')); + $this->assertTrue($arrayCollection->valueIsNotNull('t2.b')); + $this->assertTrue($arrayCollection->valueIsNotNull('t2.c.d')); + } + + /** + * @test + */ + public function should_not_contain_key() + { + $arrayCollection = new ArrayCollection([ + 'test' => 1, + ]); + + $this->assertTrue($arrayCollection->keyDoesNotExists('test2')); + } + + /** + * @test + */ + public function should_not_contain_value() + { + $arrayCollection = new ArrayCollection([ + 'test' => 1, + ]); + + $this->assertTrue($arrayCollection->valueDoesNotExists('2')); + } + + /** + * @test + */ + public function should_not_contain_key_or_value() + { + $arrayCollection = new ArrayCollection([ + 'test' => 1, + ]); + + $this->assertTrue($arrayCollection->keyOrValueDoesNotExists('test2')); + $this->assertTrue($arrayCollection->keyOrValueDoesNotExists(11)); + } + + /** + * @test + */ + public function should_serialize_array(): void + { + $arrayCollection = new ArrayCollection([ + 'test' => 1, + 'obj' => new SimpleObject(), + ]); + + $this->assertSame( + 'a:2:{s:4:"test";i:1;s:3:"obj";O:45:"Sauls\Component\Collection\Stubs\SimpleObject":1:{s:9:"property1";s:5:"prop1";}}', + $arrayCollection->serialize() + ); + } + + /** + * @test + */ + public function should_unserialize_array(): void + { + $arrayCollection = new ArrayCollection([ + 'key' => 1, + ]); + + $arrayCollection->unserialize('a:2:{s:4:"test";i:1;s:3:"obj";O:45:"Sauls\Component\Collection\Stubs\SimpleObject":1:{s:9:"property1";s:5:"prop1";}}'); + + $this->assertTrue($arrayCollection->keyExists('test')); + $this->assertTrue($arrayCollection->keyDoesNotExists('key')); + $this->assertSame('prop1', $arrayCollection->get('obj.property1')); + } + + /** + * @test + */ + public function should_throw_unsupported_operation_when_trying_to_unset_element_from_immutable_array_collection( + ): void + { + $this->expectException(UnsupportedOperationException::class); + $immutableCollection = new ImmutableArrayCollection([ + 'test' => 11, + ]); + + unset($immutableCollection['test']); + } + + /** + * @test + */ + public function should_throw_unsupported_operation_when_trying_to_array_set_element_from_immutable_array_collection(): void + { + $this->expectException(UnsupportedOperationException::class); + $immutableCollection = new ImmutableArrayCollection([ + 'test' => 11, + ]); + + $immutableCollection['test'] = 25; + } + + /** + * @test + */ + public function should_throw_unsupported_operation_when_trying_to_map_elements_from_immutable_array_collection(): void + { + $this->expectException(UnsupportedOperationException::class); + $immutableCollection = new ImmutableArrayCollection([ + 'test' => 11, + ]); + + $immutableCollection->map(function ($v) { + return $v * 15; + }); + } + + /** + * @test + */ + public function should_throw_unsupported_operation_when_trying_to_unserialize_elements_from_immutable_array_collection(): void + { + $this->expectException(UnsupportedOperationException::class); + $immutableCollection = new ImmutableArrayCollection([ + 'test' => 11, + ]); + $immutableCollection->unserialize('a:2:{s:4:"test";i:1;s:3:"obj";O:45:"Sauls\Component\Collection\Stubs\SimpleObject":1:{s:9:"property1";s:5:"prop1";}}'); } } diff --git a/tests/Stubs/SimpleObject.php b/tests/Stubs/SimpleObject.php new file mode 100644 index 0000000..f00252a --- /dev/null +++ b/tests/Stubs/SimpleObject.php @@ -0,0 +1,18 @@ + + * @link http://saulius.vaiceliunas.lt + * @copyright 2018 + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sauls\Component\Collection\Stubs; + +class SimpleObject +{ + public $property1 = 'prop1'; +}