<commit_before><?php

namespace Tests;

use Onion\Framework\Hydrator\Interfaces\HydratableInterface;
use Onion\Framework\Hydrator\PropertyHydrator;
use Onion\Framework\Rest\Interfaces\EntityInterface;
use \Onion\Framework\Rest\Transformer;
use \Tests\Stubs\Serializer\A;

class TransformerTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var Transformer
     */
    private $testable;

    public function setUp()
    {
        $this->testable = new Transformer([
            A::class => [
                'rel' => 'a',
                'links' => [
                    ['rel' => 'self', 'href' => '/entity/id'],
                ],
                'fields' => ['id']
            ]
        ]);
    }

    public function testSimpleSerialization()
    {
        $this->assertInstanceOf(EntityInterface::class,$this->testable->transform(new A()));
        $entity = $this->testable->transform(new A());
    }

    public function testExceptionWHenNoMappingDefined()
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->testable->transform(new class implements HydratableInterface {
            use PropertyHydrator;
        });
    }
}<commit_msg>Added tests to cover the transformer<commit_after><?php

namespace Tests;

use Onion\Framework\Hydrator\Interfaces\HydratableInterface;
use Onion\Framework\Hydrator\PropertyHydrator;
use Onion\Framework\Rest\Interfaces\EntityInterface;
use Onion\Framework\Rest\Interfaces\SerializableInterface;
use \Onion\Framework\Rest\Transformer;
use Psr\Link\LinkInterface;
use \Tests\Stubs\Serializer\A;

class TransformerTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var Transformer
     */
    private $testable;

    public function setUp()
    {
        $this->testable = new Transformer([
            A::class => [
                'rel' => 'a',
                'links' => [
                    ['rel' => 'self', 'href' => '/entity/id'],
                ],
                'fields' => ['id']
            ]
        ]);
    }

    public function testSimpleSerialization()
    {
        $this->assertInstanceOf(EntityInterface::class,$this->testable->transform(new A()));
        $entity = $this->testable->transform(new A());
        $this->assertSame('a', $entity->getRel());
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinksByRel('self'));
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinks());
        $this->assertArrayHasKey('id', $entity->getData());
    }

    public function testExceptionWhenNoMappingDefined()
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->testable->transform(new class implements HydratableInterface {
            use PropertyHydrator;
        });
    }

    public function testSelfDefiningObjects()
    {
        $entity = new class implements SerializableInterface {
            use PropertyHydrator;

            public $id = 5;

            public function getMappings(): array
            {
                return [
                    'rel' => 'a',
                    'links' => [
                        ['rel' => 'self', 'href' => '/entity/id', 'name' => 'test'],
                    ],
                    'fields' => ['id']
                ];
            }
        };

        $this->assertInstanceOf(EntityInterface::class,$this->testable->transform($entity));
        $entity = $this->testable->transform($entity);
        $this->assertSame('a', $entity->getRel());
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinksByRel('self'));
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinks());
        $this->assertArrayHasKey('id', $entity->getData());
    }

    public function testObjectWithRelations()
    {
        $entity = new class implements SerializableInterface {
            use PropertyHydrator;

            public $id = 5;

            public function stubs(): array
            {
                return [
                    new class implements SerializableInterface {
                        use PropertyHydrator;

                        public $name = 'Smith';

                        public function getMappings(): array
                        {
                            return [
                                'rel' => 'b',
                                'fields' => ['name'],
                                'links' => [
                                    ['rel' => 'self', 'href' => '/']
                                ]
                            ];
                        }
                    }
                ];
            }

            public function getMappings(): array
            {
                return [
                    'rel' => 'a',
                    'links' => [
                        ['rel' => 'self', 'href' => '/entity/id', 'name' => 'test'],
                    ],
                    'fields' => ['id'],
                    'relations' => [
                        'children' => 'stubs'
                    ]
                ];
            }
        };

        $this->assertInstanceOf(EntityInterface::class,$this->testable->transform($entity));
        $entity = $this->testable->transform($entity);
        $this->assertSame('a', $entity->getRel());
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinksByRel('self'));
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinks());
        $this->assertArrayHasKey('id', $entity->getData());
        $this->assertArrayHasKey('children', $entity->getEmbedded());
        $this->assertContainsOnlyInstancesOf(EntityInterface::class, $entity->getEmbedded()['children']);
    }

    public function testObjectWithRelationsReturningHydratable()
    {
        $entity = new class implements SerializableInterface {
            use PropertyHydrator;

            public $id = 5;

            public function stub(): HydratableInterface
            {
                return new class implements SerializableInterface {
                    use PropertyHydrator;

                    public $name = 'Smith';

                    public function getMappings(): array
                    {
                        return [
                            'rel' => 'b',
                            'fields' => ['name'],
                            'links' => [
                                ['rel' => 'self', 'href' => '/']
                            ]
                        ];
                    }
                };
            }

            public function getMappings(): array
            {
                return [
                    'rel' => 'a',
                    'links' => [
                        ['rel' => 'self', 'href' => '/entity/id', 'name' => 'test'],
                    ],
                    'fields' => ['id'],
                    'relations' => [
                        'child' => 'stub'
                    ]
                ];
            }
        };

        $this->assertInstanceOf(EntityInterface::class,$this->testable->transform($entity));
        $entity = $this->testable->transform($entity);
        $this->assertSame('a', $entity->getRel());
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinksByRel('self'));
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinks());
        $this->assertArrayHasKey('id', $entity->getData());
        $this->assertArrayHasKey('child', $entity->getEmbedded());
        $this->assertInstanceOf(EntityInterface::class, $entity->getEmbedded()['child']);
    }

    public function testObjectWithPropertyValueImplementingHydratable()
    {
        $entity = new class implements SerializableInterface {
            use PropertyHydrator;

            public $id = 5;

            public $stubs;

            public function __construct()
            {
                $this->stubs = [
                    new class implements SerializableInterface {
                        use PropertyHydrator;

                        public $name = 'Smith';

                        public function getMappings(): array
                        {
                            return [
                                'rel' => 'b',
                                'fields' => ['name'],
                                'links' => [
                                    ['rel' => 'self', 'href' => '/']
                                ]
                            ];
                        }
                    }
                ];
            }

            public function getMappings(): array
            {
                return [
                    'rel' => 'a',
                    'links' => [
                        ['rel' => 'self', 'href' => '/entity/id', 'name' => 'test'],
                    ],
                    'fields' => ['id', 'stubs'],
                ];
            }
        };

        $this->assertInstanceOf(EntityInterface::class,$this->testable->transform($entity));
        $entity = $this->testable->transform($entity);
        $this->assertSame('a', $entity->getRel());
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinksByRel('self'));
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinks());
        $this->assertArrayHasKey('id', $entity->getData());
        $this->assertArrayHasKey('stubs', $entity->getEmbedded());
        $this->assertNotContains('stubs', $entity->getData());
        $this->assertTrue(is_array($entity->getEmbedded()['stubs']));
        $this->assertContainsOnlyInstancesOf(EntityInterface::class, $entity->getEmbedded()['stubs']);
    }

    public function testObjectWithPropertyValuesImplementingHydratable()
    {
        $entity = new class implements SerializableInterface {
            use PropertyHydrator;

            public $id = 5;

            public $stubs;

            public function __construct()
            {
                $this->stubs = [
                    new class implements SerializableInterface {
                        use PropertyHydrator;

                        public $name = 'Smith';

                        public function getMappings(): array
                        {
                            return [
                                'rel' => 'b',
                                'fields' => ['name'],
                                'links' => [
                                    ['rel' => 'self', 'href' => '/']
                                ]
                            ];
                        }
                    },
                    new class implements SerializableInterface {
                        use PropertyHydrator;

                        public $name = 'Smith';

                        public function getMappings(): array
                        {
                            return [
                                'rel' => 'b',
                                'fields' => ['name'],
                                'links' => [
                                    ['rel' => 'self', 'href' => '/']
                                ]
                            ];
                        }
                    }
                ];
            }

            public function getMappings(): array
            {
                return [
                    'rel' => 'a',
                    'links' => [
                        ['rel' => 'self', 'href' => '/entity/id', 'name' => 'test'],
                    ],
                    'fields' => ['id', 'stubs'],
                ];
            }
        };

        $this->assertInstanceOf(EntityInterface::class, $this->testable->transform($entity));
        $entity = $this->testable->transform($entity);
        $this->assertSame('a', $entity->getRel());
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinksByRel('self'));
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinks());
        $this->assertArrayHasKey('id', $entity->getData());
        $this->assertArrayHasKey('stubs', $entity->getEmbedded());
        $this->assertNotContains('stubs', $entity->getData());
        $this->assertTrue(is_array($entity->getEmbedded()['stubs']));
        $this->assertContainsOnlyInstancesOf(EntityInterface::class, $entity->getEmbedded()['stubs']);
        $this->assertCount(2, $entity->getEmbedded()['stubs']);
    }

    public function testObjectWithPropertyValueIsHydratable()
    {
        $entity = new class implements SerializableInterface {
            use PropertyHydrator;

            public $id = 5;

            public $stub;

            public function __construct()
            {
                $this->stub = new class implements SerializableInterface {
                    use PropertyHydrator;

                    public $name = 'Smith';

                    public function getMappings(): array
                    {
                        return [
                            'rel' => 'b',
                            'fields' => ['name'],
                            'links' => [
                                ['rel' => 'self', 'href' => '/']
                            ]
                        ];
                    }
                };
            }

            public function getMappings(): array
            {
                return [
                    'rel' => 'a',
                    'links' => [
                        ['rel' => 'self', 'href' => '/entity/id', 'name' => 'test'],
                    ],
                    'fields' => ['id', 'stub'],
                ];
            }
        };

        $this->assertInstanceOf(EntityInterface::class, $this->testable->transform($entity));
        $entity = $this->testable->transform($entity);
        $this->assertSame('a', $entity->getRel());
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinksByRel('self'));
        $this->assertContainsOnlyInstancesOf(LinkInterface::class, $entity->getLinks());
        $this->assertArrayHasKey('id', $entity->getData());
        $this->assertArrayHasKey('stub', $entity->getEmbedded());
        $this->assertNotContains('stub', $entity->getData());
        $this->assertInstanceOf(EntityInterface::class, $entity->getEmbedded()['stub']);
    }

}
{'fraction_non_alphanumeric': 0.13705478025411372, 'fraction_numerical': 0.0004860098590571409, 'mean_word_length': 1.4086956521739131, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 224, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3918612', 'n_tokens_mistral': 3581, 'n_tokens_neox': 3392, 'n_words': 568}