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

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Session;
6
7use PDO;
8use PDOStatement;
9use PHPUnit\Framework\Attributes\CoversClass;
10use PHPUnit\Framework\TestCase;
11use ZtdQuery\Adapter\Pdo\Session\Bindings;
12
13#[CoversClass(Bindings::class)]
14final class BindingsTest extends TestCase
15{
16    public function testApplyReplaysLatestValuesAndNativeFetchOptions(): void
17    {
18        $native = new PDO('sqlite::memory:');
19        $bindings = new Bindings();
20        $bindings->parameter(1, static fn (PDOStatement $statement): bool => $statement->bindValue(1, 7, PDO::PARAM_INT));
21        $bindings->parameter(1, static fn (PDOStatement $statement): bool => $statement->bindValue(1, 9, PDO::PARAM_INT));
22        $bindings->fetch(static fn (PDOStatement $statement): bool => $statement->setFetchMode(PDO::FETCH_COLUMN, 1));
23        $statement = $native->prepare('SELECT 1, ?');
24        $bindings->apply($statement);
25        self::assertTrue($statement->execute());
26        self::assertSame(9, $statement->fetch());
27    }
28
29    public function testParameterReferencesKeepTheirCurrentValueAcrossStatements(): void
30    {
31        $native = new PDO('sqlite::memory:');
32        $bindings = new Bindings();
33        $value = 4;
34        $bindings->parameter(':value', static function (PDOStatement $statement) use (&$value): bool {
35            return $statement->bindParam(':value', $value, PDO::PARAM_INT);
36        });
37        $first = $native->prepare('SELECT :value');
38        $bindings->apply($first);
39        self::assertTrue($first->execute());
40        self::assertSame(4, $first->fetchColumn());
41        $value = 8;
42        $second = $native->prepare('SELECT :value');
43        $bindings->apply($second);
44        self::assertTrue($second->execute());
45        self::assertSame(8, $second->fetchColumn());
46    }
47
48    public function testFetchDefaultsLeaveNativeDefaultsIntact(): void
49    {
50        $statement = (new PDO('sqlite::memory:'))->prepare('SELECT 3 AS value');
51        (new Bindings())->apply($statement);
52        self::assertTrue($statement->execute());
53        self::assertSame(['value' => 3, 0 => 3], $statement->fetch());
54    }
55}
56