This commit is contained in:
Sebastian Bergmann 2024-06-17 09:39:18 +02:00
parent 9d93450ecd
commit d0d99db563
No known key found for this signature in database
GPG Key ID: 4AA394086372C20A
8 changed files with 2 additions and 212 deletions

View File

@ -2,12 +2,6 @@
All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
## [6.1.0] - 2024-MM-DD
### Added
* [#56](https://github.com/sebastianbergmann/exporter/pull/56): The export of objects can now be customized using `ObjectExporter` objects
## [6.0.1] - 2024-03-02
### Changed
@ -118,7 +112,6 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt
* Remove HHVM-specific code that is no longer needed
[6.1.0]: https://github.com/sebastianbergmann/exporter/compare/6.0.1...main
[6.0.1]: https://github.com/sebastianbergmann/exporter/compare/6.0.0...6.0.1
[6.0.0]: https://github.com/sebastianbergmann/exporter/compare/5.1...6.0.0
[5.1.2]: https://github.com/sebastianbergmann/exporter/compare/5.1.1...5.1.2

View File

@ -38,13 +38,6 @@ use UnitEnum;
final readonly class Exporter
{
private ?ObjectExporter $objectExporter;
public function __construct(?ObjectExporter $objectExporter = null)
{
$this->objectExporter = $objectExporter;
}
/**
* Exports a value as a string.
*
@ -341,18 +334,7 @@ final readonly class Exporter
$processed->add($value);
if ($this->objectExporter !== null && $this->objectExporter->handles($value)) {
$buffer = $this->objectExporter->export($value, $this, $indentation);
} else {
$buffer = $this->defaultObjectExport($value, $processed, $indentation);
}
return $class . ' Object #' . spl_object_id($value) . ' (' . $buffer . ')';
}
private function defaultObjectExport(object $object, RecursionContext $processed, int $indentation): string
{
$array = $this->toArray($object);
$array = $this->toArray($value);
$buffer = '';
$whitespace = str_repeat(' ', 4 * $indentation);
@ -370,6 +352,6 @@ final readonly class Exporter
$buffer = "\n" . $buffer . $whitespace;
}
return $buffer;
return $class . ' Object #' . spl_object_id($value) . ' (' . $buffer . ')';
}
}

View File

@ -1,17 +0,0 @@
<?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;
interface ObjectExporter
{
public function handles(object $object): bool;
public function export(object $object, Exporter $exporter, int $indentation): string;
}

View File

@ -1,51 +0,0 @@
<?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;
final class ObjectExporterChain implements ObjectExporter
{
/**
* @psalm-var non-empty-list<ObjectExporter>
*/
private array $exporter;
/**
* @psalm-param non-empty-list<ObjectExporter> $exporter
*/
public function __construct(array $exporter)
{
$this->exporter = $exporter;
}
public function handles(object $object): bool
{
foreach ($this->exporter as $exporter) {
if ($exporter->handles($object)) {
return true;
}
}
return false;
}
/**
* @throws ObjectNotSupportedException
*/
public function export(object $object, Exporter $exporter, int $indentation): string
{
foreach ($this->exporter as $objectExporter) {
if ($objectExporter->handles($object)) {
return $objectExporter->export($object, $exporter, $indentation);
}
}
throw new ObjectNotSupportedException;
}
}

View File

@ -1,16 +0,0 @@
<?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;
use Throwable;
interface Exception extends Throwable
{
}

View File

@ -1,16 +0,0 @@
<?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;
use RuntimeException;
final class ObjectNotSupportedException extends RuntimeException implements Exception
{
}

View File

@ -502,27 +502,6 @@ EOF;
$this->assertEquals('*RECURSION*', (new Exporter)->shortenedRecursiveExport($value, $context));
}
public function testExportOfObjectsCanBeCustomized(): void
{
$objectExporter = $this->createStub(ObjectExporter::class);
$objectExporter->method('handles')->willReturn(true);
$objectExporter->method('export')->willReturn('custom object export');
$exporter = new Exporter(new ObjectExporterChain([$objectExporter]));
$this->assertStringMatchesFormat(
<<<'EOT'
Array &0 [
0 => stdClass Object #%d (custom object export),
1 => stdClass Object #%d (custom object export),
]
EOT
,
$exporter->export([new stdClass, new stdClass]),
);
}
private function trimNewline(string $string): string
{
return preg_replace('/[ ]*\n/', "\n", $string);

View File

@ -1,64 +0,0 @@
<?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;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Small;
use PHPUnit\Framework\Attributes\UsesClass;
use PHPUnit\Framework\TestCase;
use stdClass;
#[CoversClass(ObjectExporterChain::class)]
#[UsesClass(Exporter::class)]
#[Small]
final class ObjectExporterChainTest extends TestCase
{
public function testCanBeQueriedWhetherChainedExporterHandlesAnObject(): void
{
$firstExporter = $this->createStub(ObjectExporter::class);
$firstExporter->method('handles')->willReturn(false);
$secondExporter = $this->createStub(ObjectExporter::class);
$secondExporter->method('handles')->willReturn(true);
$chain = new ObjectExporterChain([$firstExporter]);
$this->assertFalse($chain->handles(new stdClass));
$chain = new ObjectExporterChain([$firstExporter, $secondExporter]);
$this->assertTrue($chain->handles(new stdClass));
}
public function testDelegatesExportingToFirstExporterThatHandlesAnObject(): void
{
$firstExporter = $this->createStub(ObjectExporter::class);
$firstExporter->method('handles')->willReturn(false);
$firstExporter->method('export')->willThrowException(new ObjectNotSupportedException);
$secondExporter = $this->createStub(ObjectExporter::class);
$secondExporter->method('handles')->willReturn(true);
$secondExporter->method('export')->willReturn('string');
$chain = new ObjectExporterChain([$firstExporter, $secondExporter]);
$this->assertSame('string', $chain->export(new stdClass, new Exporter, 0));
}
public function testCannotExportObjectWhenNoExporterHandlesIt(): void
{
$firstExporter = $this->createStub(ObjectExporter::class);
$firstExporter->method('handles')->willReturn(false);
$chain = new ObjectExporterChain([$firstExporter]);
$this->expectException(ObjectNotSupportedException::class);
$this->assertSame('string', $chain->export(new stdClass, new Exporter, 0));
}
}