Improve export of enums
This commit improves the export of enumerations (see https://wiki.php.net/rfc/enumerations). This change is backwards-compatible with PHP 8.0. Previously, enums would be exported as objects (which they are internally), for instance: ``` SebastianBergmann\Exporter\ExampleEnum Object #%d ( 'name' => 'Value' )" ``` This commit changes that behaviour and improves the export for both backed and non-backed enums: Unit enum: SebastianBergmann\Exporter\ExampleEnum Enum #%d (Value) Backed enum: SebastianBergmann\Exporter\ExampleBackedEnum Enum #%d (Value, 'value')
This commit is contained in:
parent
2d3ded59e9
commit
ba5c2c83da
|
|
@ -11,5 +11,9 @@
|
|||
<code>$hash</code>
|
||||
<code>$key</code>
|
||||
</InvalidScalarArgument>
|
||||
<NoInterfaceProperties occurrences="6">
|
||||
<code>$value->name</code>
|
||||
<code>$value->value</code>
|
||||
</NoInterfaceProperties>
|
||||
</file>
|
||||
</files>
|
||||
|
|
|
|||
|
|
@ -48,6 +48,11 @@
|
|||
"src/"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"classmap": [
|
||||
"tests/"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.0-dev"
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use function get_class;
|
|||
use function get_resource_type;
|
||||
use function gettype;
|
||||
use function implode;
|
||||
use function interface_exists;
|
||||
use function is_array;
|
||||
use function is_float;
|
||||
use function is_object;
|
||||
|
|
@ -28,8 +29,10 @@ use function sprintf;
|
|||
use function str_repeat;
|
||||
use function str_replace;
|
||||
use function var_export;
|
||||
use BackedEnum;
|
||||
use SebastianBergmann\RecursionContext\Context;
|
||||
use SplObjectStorage;
|
||||
use UnitEnum;
|
||||
|
||||
/**
|
||||
* A nifty utility for visualizing PHP variables.
|
||||
|
|
@ -115,6 +118,26 @@ final class Exporter
|
|||
return $string;
|
||||
}
|
||||
|
||||
// FIXME: Remove 'interface_exists' check once we drop support for PHP 8.0
|
||||
if (interface_exists('\UnitEnum')) {
|
||||
if ($value instanceof BackedEnum) {
|
||||
return sprintf(
|
||||
'%s Enum (%s, %s)',
|
||||
get_class($value),
|
||||
$value->name,
|
||||
$this->export($value->value)
|
||||
);
|
||||
}
|
||||
|
||||
if ($value instanceof UnitEnum) {
|
||||
return sprintf(
|
||||
'%s Enum (%s)',
|
||||
get_class($value),
|
||||
$value->name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_object($value)) {
|
||||
return sprintf(
|
||||
'%s Object (%s)',
|
||||
|
|
@ -217,6 +240,28 @@ final class Exporter
|
|||
);
|
||||
}
|
||||
|
||||
// FIXME: Remove 'interface_exists' check once we drop support for PHP 8.0
|
||||
if (interface_exists('\UnitEnum')) {
|
||||
if ($value instanceof BackedEnum) {
|
||||
return sprintf(
|
||||
'%s Enum #%d (%s, %s)',
|
||||
get_class($value),
|
||||
spl_object_id($value),
|
||||
$value->name,
|
||||
$this->export($value->value, $indentation)
|
||||
);
|
||||
}
|
||||
|
||||
if ($value instanceof UnitEnum) {
|
||||
return sprintf(
|
||||
'%s Enum #%d (%s)',
|
||||
get_class($value),
|
||||
spl_object_id($value),
|
||||
$value->name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_string($value)) {
|
||||
// Match for most non printable chars somewhat taking multibyte chars into account
|
||||
if (preg_match('/[^\x09-\x0d\x1b\x20-\xff]/', $value)) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/exporter.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Exporter;
|
||||
|
||||
/*
|
||||
* Helper to test export of enums.
|
||||
*/
|
||||
enum ExampleEnum
|
||||
{
|
||||
case Value;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/exporter.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Exporter;
|
||||
|
||||
/*
|
||||
* Helper to test export of backed enums.
|
||||
*/
|
||||
enum ExampleIntegerBackedEnum: int
|
||||
{
|
||||
case Value = 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/exporter.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Exporter;
|
||||
|
||||
/*
|
||||
* Helper to test export of backed enums.
|
||||
*/
|
||||
enum ExampleStringBackedEnum: string
|
||||
{
|
||||
case Value = 'value';
|
||||
}
|
||||
|
|
@ -365,6 +365,50 @@ EOF;
|
|||
mb_language($oldMbLanguage);
|
||||
}
|
||||
|
||||
public function enumProvider()
|
||||
{
|
||||
return [
|
||||
'export enum' => [ExampleEnum::Value, 'SebastianBergmann\Exporter\ExampleEnum Enum #%d (Value)'],
|
||||
'export backed enum' => [ExampleStringBackedEnum::Value, 'SebastianBergmann\Exporter\ExampleStringBackedEnum Enum #%d (Value, \'value\')'],
|
||||
'shortened export integer backed enum' => [ExampleIntegerBackedEnum::Value, 'SebastianBergmann\Exporter\ExampleIntegerBackedEnum Enum #%d (Value, 0)'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 8.1
|
||||
* @dataProvider enumProvider
|
||||
*/
|
||||
public function testEnumExport($value, $expected): void
|
||||
{
|
||||
// FIXME: Merge test into testExport once we drop support for PHP 8.0
|
||||
$this->assertStringMatchesFormat(
|
||||
$expected,
|
||||
$this->trimNewline($this->exporter->export($value))
|
||||
);
|
||||
}
|
||||
|
||||
public function enumShortenedProvider()
|
||||
{
|
||||
return [
|
||||
'shortened export enum' => [ExampleEnum::Value, 'SebastianBergmann\Exporter\ExampleEnum Enum (Value)'],
|
||||
'shortened export string backed enum' => [ExampleStringBackedEnum::Value, 'SebastianBergmann\Exporter\ExampleStringBackedEnum Enum (Value, \'value\')'],
|
||||
'shortened export integer backed enum' => [ExampleIntegerBackedEnum::Value, 'SebastianBergmann\Exporter\ExampleIntegerBackedEnum Enum (Value, 0)'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 8.1
|
||||
* @dataProvider enumShortenedProvider
|
||||
*/
|
||||
public function testEnumShortenedExport($value, $expected): void
|
||||
{
|
||||
// FIXME: Merge test into testShortenedExport once we drop support for PHP 8.0
|
||||
$this->assertStringMatchesFormat(
|
||||
$expected,
|
||||
$this->trimNewline($this->exporter->shortenedExport($value))
|
||||
);
|
||||
}
|
||||
|
||||
public function provideNonBinaryMultibyteStrings(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
|||
Loading…
Reference in New Issue