packages/ztd-query-pdo-adapter/tests/Unit/Session/ParameterBinderTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Session;
6
7use PDO;
8use PHPUnit\Framework\Attributes\CoversClass;
9use PHPUnit\Framework\TestCase;
10use ZtdQuery\Adapter\Pdo\Session\ParameterBinder;
11use ZtdQuery\Adapter\Pdo\Session\ParameterKind;
12
13#[CoversClass(ParameterBinder::class)]
14#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Adapter\Pdo\ZtdPdoException::class)]
15#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Adapter\Pdo\ZtdPdoStatement::class)]
16#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Adapter\Pdo\ZtdPdo::class)]
17#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Adapter\Pdo\Driver\PdoConnection::class)]
18#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Adapter\Pdo\Driver\PdoStatement::class)]
19#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Adapter\Pdo\Session\StatementExecution::class)]
20#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Adapter\Pdo\Session\Bindings::class)]
21#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Adapter\Pdo\Session\BufferedRow::class)]
22#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Adapter\Pdo\Session\DriverSessionFactory::class)]
23#[\PHPUnit\Framework\Attributes\UsesClass(ParameterKind::class)]
24#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Adapter\Pdo\Session\PreparedQuery::class)]
25#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Adapter\Pdo\Session\ConnectionExecution::class)]
26final class ParameterBinderTest extends TestCase
27{
28    public function testExecuteBindsEachValueAsTheKindPdoReadsItAs(): void
29    {
30        $pdo = new PDO('sqlite::memory:');
31        $statement = $pdo->prepare('SELECT typeof(?), typeof(?), typeof(?)');
32        self::assertNotFalse($statement);
33
34        self::assertTrue((new ParameterBinder())->execute($statement, [1, null, '1']));
35        self::assertSame(['integer', 'null', 'text'], $statement->fetch(PDO::FETCH_NUM));
36    }
37
38    public function testExecuteBindsEveryKindAndNamesEveryNamedPlaceholder(): void
39    {
40        $pdo = new PDO('sqlite::memory:');
41        $statement = $pdo->prepare(
42            'SELECT typeof(?), typeof(?), typeof(?), typeof(?), typeof(:name), typeof(:ratio)',
43        );
44        self::assertNotFalse($statement);
45        $resource = fopen('php://memory', 'r');
46        self::assertIsResource($resource);
47
48        self::assertTrue((new ParameterBinder())->execute($statement, [
49            null,
50            true,
51            7,
52            $resource,
53            'name' => 'text',
54            ':ratio' => 2.5,
55        ]));
56
57        self::assertSame(
58            ['null', 'integer', 'integer', 'blob', 'text', 'text'],
59            $statement->fetch(PDO::FETCH_NUM),
60        );
61        fclose($resource);
62    }
63    public function testExecuteRunsWhatIsAlreadyBoundWhereItIsGivenNothing(): void
64    {
65        $pdo = new PDO('sqlite::memory:');
66        $statement = $pdo->prepare('SELECT 1');
67        self::assertNotFalse($statement);
68
69        self::assertTrue((new ParameterBinder())->execute($statement, null));
70    }
71
72    public function testParameterNameWritesAPlainNameAsAPlaceholder(): void
73    {
74        self::assertSame(':name', (new ParameterBinder())->parameterName('name'));
75    }
76
77    public function testParameterNameLeavesANameThatIsAlreadyAPlaceholderAlone(): void
78    {
79        self::assertSame(':name', (new ParameterBinder())->parameterName(':name'));
80    }
81}
82