1<?php
2
3declare(strict_types=1);
4
5namespace JMS\Serializer\Tests\Handler;
6
7use JMS\Serializer\DeserializationContext;
8use JMS\Serializer\GraphNavigatorInterface;
9use JMS\Serializer\Handler\HandlerRegistry;
10use JMS\Serializer\Handler\IteratorHandler;
11use JMS\Serializer\SerializationContext;
12use JMS\Serializer\Visitor\DeserializationVisitorInterface;
13use JMS\Serializer\Visitor\SerializationVisitorInterface;
14use PHPUnit\Framework\TestCase;
15
16final class IteratorHandlerTest extends TestCase
17{
18    private const DATA = ['foo', 'bar'];
19
20    /**
21     * @var HandlerRegistry
22     */
23    private $handlerRegistry;
24
25    public function iteratorsProvider(): array
26    {
27        return [
28            [
29                new \ArrayIterator(self::DATA),
30            ],
31            [
32                (static function (): \Generator {
33                    yield 'foo';
34                    yield 'bar';
35                })(),
36            ],
37        ];
38    }
39
40    /**
41     * @dataProvider iteratorsProvider
42     */
43    public function testSerialize(\Iterator $iterator): void
44    {
45        $type = get_class($iterator);
46        $serializationHandler = $this->handlerRegistry->getHandler(
47            GraphNavigatorInterface::DIRECTION_SERIALIZATION,
48            $type,
49            'json'
50        );
51        self::assertIsCallable($serializationHandler);
52
53        $serialized = $serializationHandler(
54            $this->createSerializationVisitor(),
55            $iterator,
56            ['name' => $type, 'params' => []],
57            $this->getMockBuilder(SerializationContext::class)->getMock()
58        );
59        self::assertSame(self::DATA, $serialized);
60
61        $deserializationHandler = $this->handlerRegistry->getHandler(
62            GraphNavigatorInterface::DIRECTION_DESERIALIZATION,
63            $type,
64            'json'
65        );
66        self::assertIsCallable($deserializationHandler);
67
68        $deserialized = $deserializationHandler(
69            $this->createDeserializationVisitor(),
70            $serialized,
71            ['name' => $type, 'params' => []],
72            $this->getMockBuilder(DeserializationContext::class)->getMock()
73        );
74        self::assertEquals($iterator, $deserialized);
75    }
76
77    protected function setUp(): void
78    {
79        $this->handlerRegistry = new HandlerRegistry();
80        $this->handlerRegistry->registerSubscribingHandler(new IteratorHandler());
81    }
82
83    private function createDeserializationVisitor(): DeserializationVisitorInterface
84    {
85        $visitor = $this->getMockBuilder(DeserializationVisitorInterface::class)->getMock();
86        $visitor->method('visitArray')->with(self::DATA)->willReturn(self::DATA);
87        return $visitor;
88    }
89
90    private function createSerializationVisitor(): SerializationVisitorInterface
91    {
92        $visitor = $this->getMockBuilder(SerializationVisitorInterface::class)->getMock();
93        $visitor->method('visitArray')->with(self::DATA)->willReturn(self::DATA);
94        return $visitor;
95    }
96}
97