packages/sql-catalog/tests/Unit/Extension/Doctrine/DoctrineExtensionTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Extension\Doctrine;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlCatalog\Core\Extension\SinkRole;
11use SqlCatalog\Core\Extension\SinkSpec;
12use SqlCatalog\Core\Sql\StatementKind;
13use SqlCatalog\Extension\Doctrine\DoctrineExtension;
14
15#[CoversClass(DoctrineExtension::class)]
16#[UsesClass(SinkSpec::class)]
17final class DoctrineExtensionTest extends TestCase
18{
19    public function testNameIsHowTheCommandLineSelectsIt(): void
20    {
21        self::assertSame('doctrine', (new DoctrineExtension())->name());
22    }
23
24    public function testDescriptionMentionsWhatItCovers(): void
25    {
26        self::assertStringContainsString('Doctrine', (new DoctrineExtension())->description());
27    }
28
29    public function testSinksCoverPreparingBindingAndQuerying(): void
30    {
31        $roles = array_map(static fn (SinkSpec $sink): SinkRole => $sink->role, (new DoctrineExtension())->sinks());
32        self::assertContains(SinkRole::Prepare, $roles);
33        self::assertContains(SinkRole::Bind, $roles);
34        self::assertContains(SinkRole::Query, $roles);
35    }
36
37    public function testPreparingHandsBackADoctrineStatement(): void
38    {
39        $prepare = array_values(array_filter(
40            (new DoctrineExtension())->sinks(),
41            static fn (SinkSpec $sink): bool => $sink->id === 'doctrine.prepare',
42        ));
43        self::assertSame('Doctrine\\DBAL\\Statement', $prepare[0]->handleType);
44    }
45
46    public function testMethodsNameTheKindTheFetchCallsImply(): void
47    {
48        $methods = (new DoctrineExtension())->methods();
49        self::assertSame(StatementKind::Select, $methods['fetchAllAssociative']);
50        self::assertNull($methods['executeStatement']);
51    }
52    public function testEverySinkIsDescribedExactly(): void
53    {
54        $described = array_map(
55            static fn (SinkSpec $sink): string => implode('|', [
56                $sink->id,
57                $sink->callKind->value,
58                $sink->receiverType ?? '-',
59                $sink->name,
60                $sink->role->value,
61                $sink->sqlParameter ?? '-',
62                $sink->valuesParameter ?? '-',
63                $sink->valuesFrom ?? '-',
64                $sink->nameParameter ?? '-',
65                $sink->valueParameter ?? '-',
66                ($sink->kind === null ? '-' : $sink->kind->value) . '/' . ($sink->handleType ?? '-'),
67            ]),
68            (new DoctrineExtension())->sinks(),
69        );
70
71        self::assertSame(
72            [
73            'doctrine.prepare|method|Doctrine\DBAL\Connection|prepare|prepare|0|-|-|-|-|-/Doctrine\DBAL\Statement',
74            'doctrine.statement.bindValue|method|Doctrine\DBAL\Statement|bindValue|bind|-|-|-|0|1|-/-',
75            'doctrine.statement.executeQuery|method|Doctrine\DBAL\Statement|executeQuery|execute|-|0|-|-|-|-/-',
76            'doctrine.executeQuery|method|Doctrine\DBAL\Connection|executeQuery|query|0|1|-|-|-|-/-',
77            'doctrine.executeStatement|method|Doctrine\DBAL\Connection|executeStatement|query|0|1|-|-|-|-/-',
78            'doctrine.executeCacheQuery|method|Doctrine\DBAL\Connection|executeCacheQuery|query|0|1|-|-|-|select/-',
79            'doctrine.fetchAllAssociative|method|Doctrine\DBAL\Connection|fetchAllAssociative|query|0|1|-|-|-|select/-',
80            'doctrine.fetchAllKeyValue|method|Doctrine\DBAL\Connection|fetchAllKeyValue|query|0|1|-|-|-|select/-',
81            'doctrine.fetchAllNumeric|method|Doctrine\DBAL\Connection|fetchAllNumeric|query|0|1|-|-|-|select/-',
82            'doctrine.fetchAssociative|method|Doctrine\DBAL\Connection|fetchAssociative|query|0|1|-|-|-|select/-',
83            'doctrine.fetchNumeric|method|Doctrine\DBAL\Connection|fetchNumeric|query|0|1|-|-|-|select/-',
84            'doctrine.fetchFirstColumn|method|Doctrine\DBAL\Connection|fetchFirstColumn|query|0|1|-|-|-|select/-',
85            'doctrine.fetchOne|method|Doctrine\DBAL\Connection|fetchOne|query|0|1|-|-|-|select/-',
86            'doctrine.iterateAssociative|method|Doctrine\DBAL\Connection|iterateAssociative|query|0|1|-|-|-|select/-',
87            ],
88            $described,
89        );
90    }
91
92    public function testGlobalsAreEmptyBecauseTheHandleIsNotReachedThroughOne(): void
93    {
94        self::assertSame([], (new DoctrineExtension())->globals());
95    }
96}
97