Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
2 changes: 1 addition & 1 deletion src/Exception/InvalidItemException.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ 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)
Comment thread
vinayak-iyer-paysera marked this conversation as resolved.
Outdated
{
parent::__construct($message ?? sprintf('Invalid key "%s"', $key), 0, $previous);
$this->key = $key;
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/InvalidItemTypeException.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ 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
2 changes: 1 addition & 1 deletion src/Exception/MissingItemException.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

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
49 changes: 49 additions & 0 deletions tests/ClassLoadingTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);

namespace Paysera\Component\ObjectWrapper\Tests;

use PHPUnit\Framework\TestCase;

class ClassLoadingTest extends TestCase
Comment thread
vinayak-iyer-paysera marked this conversation as resolved.
Outdated
{
public function testClassesLoadWithoutDeprecations(): void
{
$script = strtr(
<<<'PHP'
set_error_handler(function ($type, $message, $file) {
if (strpos((string)realpath($file), SOURCE_DIRECTORY . DIRECTORY_SEPARATOR) === 0) {
echo $message, PHP_EOL;
}

return true;
});
require AUTOLOAD_FILE;
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(SOURCE_DIRECTORY, FilesystemIterator::SKIP_DOTS));
foreach ($files as $file) {
if ($file->getExtension() !== 'php') {
continue;
}
$class = 'Paysera\Component\ObjectWrapper\\'
. strtr(substr($file->getPathname(), strlen(SOURCE_DIRECTORY) + 1, -4), DIRECTORY_SEPARATOR, '\\');
if (!class_exists($class) && !interface_exists($class, false) && !trait_exists($class, false)) {
echo 'Not loaded: ', $class, PHP_EOL;
}
}
PHP
,
[
'SOURCE_DIRECTORY' => var_export(realpath(dirname(__DIR__) . '/src'), true),
'AUTOLOAD_FILE' => var_export(dirname(__DIR__) . '/vendor/autoload.php', true),
]
);

exec(
sprintf('%s -n -d error_reporting=-1 -r %s 2>&1', escapeshellarg(PHP_BINARY), escapeshellarg($script)),
$output,
$exitCode
);

$this->assertSame(['exitCode' => 0, 'output' => []], ['exitCode' => $exitCode, 'output' => $output]);
}
}
83 changes: 83 additions & 0 deletions tests/Exception/InvalidItemExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php
declare(strict_types=1);

namespace Paysera\Component\ObjectWrapper\Tests\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
{
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'),
],
];
}

/**
* @return array<string, mixed>
*/
private static function expected(
string $class,
string $message,
string $key,
?string $expectedType = null,
?string $givenType = null
): array {
return [
'class' => $class,
'message' => $message,
'key' => $key,
'expectedType' => $expectedType,
'givenType' => $givenType,
'previous' => null,
];
}
}
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