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