From e90ba72236b723f28db29e199bcdc3976c6a4111 Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 25 Oct 2023 16:40:08 +0200 Subject: [PATCH] Add parameter types in AccessKey, fix deprecates PHPUnit method --- src/Helper/AccessKey.php | 25 ++++-------- src/Helper/AccessableTrait.php | 19 ++++++--- tests/Fixtures/AccessableTraitMock.php | 16 ++++++++ tests/Fixtures/HelperTrait.php | 15 ++++++++ tests/Unit/Helper/AccessableTraitTest.php | 47 +++++++++++++++-------- tests/Unit/V1/ErrorCollectionTest.php | 6 +-- tests/Unit/V1/ResourceCollectionTest.php | 5 ++- 7 files changed, 90 insertions(+), 43 deletions(-) create mode 100644 tests/Fixtures/AccessableTraitMock.php diff --git a/src/Helper/AccessKey.php b/src/Helper/AccessKey.php index bed0120..fbc7a31 100644 --- a/src/Helper/AccessKey.php +++ b/src/Helper/AccessKey.php @@ -22,31 +22,20 @@ final class AccessKey extends SplStack /** * Transforms the Key to a string * - * @param int|string $key - * * @return AccessKey */ - public static function create($key): AccessKey + public static function create(string $key): AccessKey { - // Ignore arrays and objects - if (is_object($key) or is_array($key)) { - $key = ''; - } - - $key_string = strval($key); - - $key = new self(); - $key->raw = $key_string; - - $keys = explode('.', $key_string); + $accessKey = new self(); + $accessKey->raw = $key; - foreach ($keys as $value) { - $key->push($value); + foreach (explode('.', $key) as $value) { + $accessKey->push($value); } - $key->rewind(); + $accessKey->rewind(); - return $key; + return $accessKey; } /** diff --git a/src/Helper/AccessableTrait.php b/src/Helper/AccessableTrait.php index 6cee963..95a78af 100644 --- a/src/Helper/AccessableTrait.php +++ b/src/Helper/AccessableTrait.php @@ -62,6 +62,8 @@ final public function has($key): bool gettype($key), AccessKey::class ), \E_USER_DEPRECATED); + + $key = ''; } $key = $this->parseKey($key); @@ -97,6 +99,17 @@ final public function has($key): bool */ public function get($key) { + if (! is_int($key) && ! is_string($key) && (! is_object($key) || ! $key instanceof AccessKey)) { + trigger_error(sprintf( + '%s::get(): 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 = ''; + } + $key = $this->parseKey($key); $string = $key->shift(); @@ -136,8 +149,6 @@ private function getValue(string $key) * Parse a dot.notated.key to an object * * @param int|string|AccessKey $key The key - * - * @return AccessKey The parsed key */ private function parseKey($key): AccessKey { @@ -145,8 +156,6 @@ private function parseKey($key): AccessKey return $key; } - $key = AccessKey::create($key); - - return $key; + return AccessKey::create(strval($key)); } } diff --git a/tests/Fixtures/AccessableTraitMock.php b/tests/Fixtures/AccessableTraitMock.php new file mode 100644 index 0000000..3a1c797 --- /dev/null +++ b/tests/Fixtures/AccessableTraitMock.php @@ -0,0 +1,16 @@ +> + */ + public static function jsonValuesProviderWithoutStringAndInt(): array + { + $data = static::jsonValuesProvider(); + + unset($data[2]); + unset($data[3]); + + return array_values($data); + } + /** * Json Values as string Provider * diff --git a/tests/Unit/Helper/AccessableTraitTest.php b/tests/Unit/Helper/AccessableTraitTest.php index cda7d40..9083e20 100644 --- a/tests/Unit/Helper/AccessableTraitTest.php +++ b/tests/Unit/Helper/AccessableTraitTest.php @@ -8,22 +8,29 @@ namespace Art4\JsonApiClient\Tests\Unit\Helper; -use Art4\JsonApiClient\Helper\AccessableTrait; -use Art4\JsonApiClient\Accessable; +use Art4\JsonApiClient\Exception\AccessException; +use Art4\JsonApiClient\Tests\Fixtures\AccessableTraitMock; +use Art4\JsonApiClient\Tests\Fixtures\HelperTrait; use PHPUnit\Framework\TestCase; class AccessableTraitTest extends TestCase { - public function testHasWithObjectAsKeyTriggersException(): void + use HelperTrait; + + /** + * @dataProvider jsonValuesProviderWithoutStringAndInt + * + * @param mixed $key + */ + public function testHasWithInvalidKeyTypeTriggersDeprecationError($key): void { - /** @var Accessable */ - $resource = $this->getMockForTrait(AccessableTrait::class); + $resource = new AccessableTraitMock(); // 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.', + function ($errno, $errstr) use ($key): bool { + $this->assertSame( + 'Art4\JsonApiClient\Tests\Fixtures\AccessableTraitMock::has(): Providing Argument #1 ($key) as '.gettype($key).' is deprecated since 1.2.0, please provide as int|string|Art4\JsonApiClient\Helper\AccessKey instead.', $errstr ); @@ -33,19 +40,23 @@ function ($errno, $errstr): bool { E_USER_DEPRECATED ); - $resource->has(new \stdClass()); + $resource->has($key); } - public function testHasWithArrayAsKeyTriggersException(): void + /** + * @dataProvider jsonValuesProviderWithoutStringAndInt + * + * @param mixed $key + */ + public function testGetWithInvalidKeyTypeTriggersDeprecationError($key): void { - /** @var Accessable */ - $resource = $this->getMockForTrait(AccessableTrait::class); + $resource = new AccessableTraitMock(); // 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.', + function ($errno, $errstr) use ($key): bool { + $this->assertSame( + 'Art4\JsonApiClient\Tests\Fixtures\AccessableTraitMock::get(): Providing Argument #1 ($key) as '.gettype($key).' is deprecated since 1.2.0, please provide as int|string|Art4\JsonApiClient\Helper\AccessKey instead.', $errstr ); @@ -55,6 +66,10 @@ function ($errno, $errstr): bool { E_USER_DEPRECATED ); - $resource->has([]); + try { + $resource->get($key); + } catch (AccessException $th) { + // ignore AccessException + } } } diff --git a/tests/Unit/V1/ErrorCollectionTest.php b/tests/Unit/V1/ErrorCollectionTest.php index eadff7d..e6fc4a1 100644 --- a/tests/Unit/V1/ErrorCollectionTest.php +++ b/tests/Unit/V1/ErrorCollectionTest.php @@ -49,15 +49,15 @@ public function testCreate(): void $this->assertSame($collection->getKeys(), [0, 1]); $this->assertFalse($collection->has('string')); - - $this->assertTrue($collection->has(AccessKey::create(0))); - + $this->assertTrue($collection->has(AccessKey::create('0'))); $this->assertTrue($collection->has(0)); + $error = $collection->get(0); $this->assertInstanceOf(Accessable::class, $error); $this->assertTrue($collection->has(1)); + $error = $collection->get(1); $this->assertInstanceOf(Accessable::class, $error); diff --git a/tests/Unit/V1/ResourceCollectionTest.php b/tests/Unit/V1/ResourceCollectionTest.php index aed1f05..9955a9d 100644 --- a/tests/Unit/V1/ResourceCollectionTest.php +++ b/tests/Unit/V1/ResourceCollectionTest.php @@ -45,7 +45,7 @@ public function testCreateWithEmptyArray(): void // Test get() with various key types $this->assertFalse($collection->has(0)); - $this->assertFalse($collection->has(AccessKey::create(0))); + $this->assertFalse($collection->has(AccessKey::create('0'))); $this->assertFalse($collection->has('string')); } @@ -95,6 +95,9 @@ public function testCreateWithIdentifierAndMeta(): void $this->assertInstanceOf(Accessable::class, $resource); + $this->assertSame($resource, $collection->get('0')); + $this->assertSame($resource, $collection->get(AccessKey::create('0'))); + $this->assertTrue($collection->has(1)); $resource = $collection->get(1);