Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.4.2
### Fixed
- PHP 8.4 deprecation notices: the optional parameters of `getBool()`, `getFloat()`, `getInt()`, `getString()` and of the exception constructors are declared as explicit nullable types

## 0.4.1
### Fixed
- Suppress Symfony deprecations
Expand Down
1 change: 1 addition & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertDeprecationsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
Expand Down
6 changes: 4 additions & 2 deletions src/Exception/InvalidItemException.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@

namespace Paysera\Component\ObjectWrapper\Exception;

class InvalidItemException extends \Exception
use Exception;

class InvalidItemException extends Exception
{
private $key;

public function __construct(string $key, string $message = null, \Exception $previous = null)
public function __construct(string $key, ?string $message = null, ?Exception $previous = null)
{
parent::__construct($message ?? sprintf('Invalid key "%s"', $key), 0, $previous);
$this->key = $key;
Expand Down
4 changes: 3 additions & 1 deletion src/Exception/InvalidItemTypeException.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@

namespace Paysera\Component\ObjectWrapper\Exception;

use Exception;

class InvalidItemTypeException extends InvalidItemException
{
private $expectedType;
private $givenType;

public function __construct(string $expectedType, string $givenType, string $key, \Exception $previous = null)
public function __construct(string $expectedType, string $givenType, string $key, ?Exception $previous = null)
{
parent::__construct(
$key,
Expand Down
4 changes: 3 additions & 1 deletion src/Exception/MissingItemException.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

namespace Paysera\Component\ObjectWrapper\Exception;

use Exception;

class MissingItemException extends InvalidItemException
{
public function __construct(string $key, \Exception $previous = null)
public function __construct(string $key, ?Exception $previous = null)
{
parent::__construct($key, sprintf('Missing required key "%s"', $key), $previous);
}
Expand Down
8 changes: 4 additions & 4 deletions src/ObjectWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public function getRequiredBool(string $key): bool
* @param bool|null $default
* @return bool|null
*/
public function getBool(string $key, bool $default = null)
public function getBool(string $key, ?bool $default = null)
{
return $this->getOfType($key, 'boolean', $default);
}
Expand All @@ -118,7 +118,7 @@ public function getRequiredFloat(string $key): float
* @param float|null $default
* @return float|null
*/
public function getFloat(string $key, float $default = null)
public function getFloat(string $key, ?float $default = null)
{
return $this->getOfType($key, 'float', $default);
}
Expand All @@ -133,7 +133,7 @@ public function getRequiredInt(string $key): int
* @param int|null $default
* @return int|null
*/
public function getInt(string $key, int $default = null)
public function getInt(string $key, ?int $default = null)
{
return $this->getOfType($key, 'integer', $default);
}
Expand Down Expand Up @@ -162,7 +162,7 @@ public function getRequiredString(string $key): string
* @param string|null $default
* @return string|null
*/
public function getString(string $key, string $default = null)
public function getString(string $key, ?string $default = null)
{
return $this->getOfType($key, 'string', $default);
}
Expand Down
118 changes: 118 additions & 0 deletions tests/Exception/InvalidItemExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php
declare(strict_types=1);

namespace Paysera\Component\ObjectWrapper\Tests\Exception;

use Exception;
use Paysera\Component\ObjectWrapper\Exception\InvalidItemException;
use Paysera\Component\ObjectWrapper\Exception\InvalidItemTypeException;
use Paysera\Component\ObjectWrapper\Exception\MissingItemException;
use PHPUnit\Framework\TestCase;

class InvalidItemExceptionTest extends TestCase
Comment thread
vinayak-iyer-paysera marked this conversation as resolved.
{
/**
* @dataProvider exceptionProvider
* @param array<string, mixed> $expected
*/
public function testExceptionDescribesTheItem(callable $createException, array $expected): void
{
$exception = $createException();

$this->assertSame($expected, [
'class' => get_class($exception),
'message' => $exception->getMessage(),
'key' => $exception->getKey(),
'expectedType' => $exception instanceof InvalidItemTypeException ? $exception->getExpectedType() : null,
'givenType' => $exception instanceof InvalidItemTypeException ? $exception->getGivenType() : null,
'previous' => $exception->getPrevious(),
]);
}

/**
* @return array<string, array{callable, array<string, mixed>}>
*/
public static function exceptionProvider(): array
{
$previous = new Exception('x');

return [
'invalid item with null message and previous' => [
static function () {
return new InvalidItemException('a.b', null, null);
},
self::expected(InvalidItemException::class, 'Invalid key "a.b"', 'a.b'),
],
'invalid item type with a null previous exception' => [
static function () {
return new InvalidItemTypeException('string', 'integer', 'a.b', null);
},
self::expected(
InvalidItemTypeException::class,
'Expected string but got integer for key "a.b"',
'a.b',
'string',
'integer'
),
],
'missing item with a null previous exception' => [
static function () {
return new MissingItemException('a.b', null);
},
self::expected(MissingItemException::class, 'Missing required key "a.b"', 'a.b'),
],
'invalid item with a custom message' => [
static function () {
return new InvalidItemException('a.b', 'Custom message');
},
self::expected(InvalidItemException::class, 'Custom message', 'a.b'),
],
'invalid item with a previous exception' => [
static function () use ($previous) {
return new InvalidItemException('a.b', null, $previous);
},
self::expected(InvalidItemException::class, 'Invalid key "a.b"', 'a.b', null, null, $previous),
],
'invalid item type with a previous exception' => [
static function () use ($previous) {
return new InvalidItemTypeException('string', 'integer', 'a.b', $previous);
},
self::expected(
InvalidItemTypeException::class,
'Expected string but got integer for key "a.b"',
'a.b',
'string',
'integer',
$previous
),
],
'missing item with a previous exception' => [
static function () use ($previous) {
return new MissingItemException('a.b', $previous);
},
self::expected(MissingItemException::class, 'Missing required key "a.b"', 'a.b', null, null, $previous),
],
];
}

/**
* @return array<string, mixed>
*/
private static function expected(
string $class,
string $message,
string $key,
?string $expectedType = null,
?string $givenType = null,
?Exception $previous = null
): array {
return [
'class' => $class,
'message' => $message,
'key' => $key,
'expectedType' => $expectedType,
'givenType' => $givenType,
'previous' => $previous,
];
}
}
24 changes: 24 additions & 0 deletions tests/ObjectWrapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,30 @@ public function testGetOriginalDataAsArray()
$this->assertDeepEquals($expectedArray, $originalData);
}

/**
* @dataProvider optionalGetterProvider
* @param mixed $value
*/
public function testOptionalGettersAcceptAnExplicitNullDefault(string $method, $value): void
{
$object = new ObjectWrapper((object)['present' => $value]);

$this->assertSame([$value, null], [$object->$method('present', null), $object->$method('absent', null)]);
}

/**
* @return array<string, array{string, mixed}>
*/
public static function optionalGetterProvider(): array
{
return [
'getBool' => ['getBool', true],
'getFloat' => ['getFloat', 1.5],
'getInt' => ['getInt', 7],
'getString' => ['getString', 'text'],
];
}

private function assertDeepEquals($expectedData, $dataWithWrappers)
{
$this->assertEquals($expectedData, $this->unwrap($dataWithWrappers));
Expand Down
Loading