From d3e2710cf309e23ef240b7cf2b798725d2ac5b49 Mon Sep 17 00:00:00 2001 From: Art4 Date: Thu, 19 Oct 2023 16:44:30 +0200 Subject: [PATCH] Using Accessable::has() with object or array is deprecated --- src/Accessable.php | 4 +- src/Helper/AccessableTrait.php | 9 ++++ src/V1/ResourceNull.php | 9 ++++ tests/Unit/Helper/AccessableTraitTest.php | 57 +++++++++++++++++++++++ tests/Unit/V1/ErrorCollectionTest.php | 5 +- tests/Unit/V1/ResourceCollectionTest.php | 6 +-- tests/Unit/V1/ResourceNullTest.php | 50 ++++++++++++++++++++ 7 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 tests/Unit/Helper/AccessableTraitTest.php diff --git a/src/Accessable.php b/src/Accessable.php index 069da12..cf63145 100644 --- a/src/Accessable.php +++ b/src/Accessable.php @@ -18,7 +18,7 @@ interface Accessable /** * Get a value by a key * - * @param int|string|AccessKey $key The key + * @param mixed $key The key * * @return mixed */ @@ -29,7 +29,7 @@ public function get($key); * * @deprecated `\Art4\JsonApiClient\Accessable::has()` will add `bool` as a native return type declaration in v2.0. Do the same in your implementation now to avoid errors. * - * @param int|string|AccessKey $key The key + * @param mixed $key The key * * @return bool */ diff --git a/src/Helper/AccessableTrait.php b/src/Helper/AccessableTrait.php index d9d690a..6cee963 100644 --- a/src/Helper/AccessableTrait.php +++ b/src/Helper/AccessableTrait.php @@ -55,6 +55,15 @@ final public function getKeys(): array */ final public function has($key): bool { + if (! is_int($key) && ! is_string($key) && (! is_object($key) || ! $key instanceof AccessKey)) { + trigger_error(sprintf( + '%s::has(): Providing Argument #1 ($key) as %s is deprecated since 1.2.0, please provide as int|string|%s instead.', + get_class($this), + gettype($key), + AccessKey::class + ), \E_USER_DEPRECATED); + } + $key = $this->parseKey($key); $string = $key->shift(); diff --git a/src/V1/ResourceNull.php b/src/V1/ResourceNull.php index 7876367..3065002 100644 --- a/src/V1/ResourceNull.php +++ b/src/V1/ResourceNull.php @@ -47,6 +47,15 @@ public function __construct($data, Manager $manager, Accessable $parent) */ public function has($key) { + if (! is_int($key) && ! is_string($key) && (! is_object($key) || ! $key instanceof AccessKey)) { + trigger_error(sprintf( + '%s::has(): Providing Argument #1 ($key) as %s is deprecated since 1.2.0, please provide as int|string|%s instead.', + get_class($this), + gettype($key), + AccessKey::class + ), \E_USER_DEPRECATED); + } + return false; } diff --git a/tests/Unit/Helper/AccessableTraitTest.php b/tests/Unit/Helper/AccessableTraitTest.php new file mode 100644 index 0000000..af512b3 --- /dev/null +++ b/tests/Unit/Helper/AccessableTraitTest.php @@ -0,0 +1,57 @@ +getMockForTrait(AccessableTrait::class); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertStringEndsWith( + '::has(): Providing Argument #1 ($key) as object is deprecated since 1.2.0, please provide as int|string|Art4\JsonApiClient\Helper\AccessKey instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $resource->has(new \stdClass()); + } + + public function testHasWithArrayAsKeyTriggersException(): void + { + $resource = $this->getMockForTrait(AccessableTrait::class); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertStringEndsWith( + '::has(): Providing Argument #1 ($key) as array is deprecated since 1.2.0, please provide as int|string|Art4\JsonApiClient\Helper\AccessKey instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $resource->has([]); + } +} diff --git a/tests/Unit/V1/ErrorCollectionTest.php b/tests/Unit/V1/ErrorCollectionTest.php index 31b2731..eadff7d 100644 --- a/tests/Unit/V1/ErrorCollectionTest.php +++ b/tests/Unit/V1/ErrorCollectionTest.php @@ -11,6 +11,7 @@ use Art4\JsonApiClient\Accessable; use Art4\JsonApiClient\Exception\AccessException; use Art4\JsonApiClient\Exception\ValidationException; +use Art4\JsonApiClient\Helper\AccessKey; use Art4\JsonApiClient\Tests\Fixtures\HelperTrait; use Art4\JsonApiClient\V1\ErrorCollection; use PHPUnit\Framework\TestCase; @@ -47,10 +48,10 @@ public function testCreate(): void $this->assertSame($collection->getKeys(), [0, 1]); - $this->assertFalse($collection->has(new \stdClass())); - $this->assertFalse($collection->has([])); $this->assertFalse($collection->has('string')); + $this->assertTrue($collection->has(AccessKey::create(0))); + $this->assertTrue($collection->has(0)); $error = $collection->get(0); diff --git a/tests/Unit/V1/ResourceCollectionTest.php b/tests/Unit/V1/ResourceCollectionTest.php index 67d00e1..aed1f05 100644 --- a/tests/Unit/V1/ResourceCollectionTest.php +++ b/tests/Unit/V1/ResourceCollectionTest.php @@ -11,6 +11,7 @@ use Art4\JsonApiClient\Accessable; use Art4\JsonApiClient\Exception\AccessException; use Art4\JsonApiClient\Exception\ValidationException; +use Art4\JsonApiClient\Helper\AccessKey; use Art4\JsonApiClient\Tests\Fixtures\HelperTrait; use Art4\JsonApiClient\V1\ResourceCollection; use PHPUnit\Framework\TestCase; @@ -41,11 +42,10 @@ public function testCreateWithEmptyArray(): void $this->assertInstanceOf(Accessable::class, $collection); $this->assertSame($collection->getKeys(), []); - $this->assertFalse($collection->has(0)); // Test get() with various key types - $this->assertFalse($collection->has(new \stdClass())); - $this->assertFalse($collection->has([])); + $this->assertFalse($collection->has(0)); + $this->assertFalse($collection->has(AccessKey::create(0))); $this->assertFalse($collection->has('string')); } diff --git a/tests/Unit/V1/ResourceNullTest.php b/tests/Unit/V1/ResourceNullTest.php index cbaf377..b59c69e 100644 --- a/tests/Unit/V1/ResourceNullTest.php +++ b/tests/Unit/V1/ResourceNullTest.php @@ -64,4 +64,54 @@ public function testGetThrowsException(): void $resource->get('something'); } + + public function testHasWithObjectAsKeyTriggersException(): void + { + $resource = new ResourceNull( + null, + $this->manager, + $this->parent + ); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + 'Art4\JsonApiClient\V1\ResourceNull::has(): Providing Argument #1 ($key) as object is deprecated since 1.2.0, please provide as int|string|Art4\JsonApiClient\Helper\AccessKey instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $resource->has(new \stdClass()); + } + + public function testHasWithArrayAsKeyTriggersException(): void + { + $resource = new ResourceNull( + null, + $this->manager, + $this->parent + ); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + 'Art4\JsonApiClient\V1\ResourceNull::has(): Providing Argument #1 ($key) as array is deprecated since 1.2.0, please provide as int|string|Art4\JsonApiClient\Helper\AccessKey instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $resource->has([]); + } }