packages/ztd-query-mysqli-adapter/tests/Unit/Driver/MysqliResultColumnExtractorTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Driver;
6
7use Container\MySql80Container;
8use Container\MySql84Container;
9use mysqli;
10use mysqli_result;
11use PHPUnit\Framework\Attributes\CoversClass;
12use PHPUnit\Framework\Attributes\Large;
13use PHPUnit\Framework\TestCase;
14use Testcontainers\Testcontainers;
15use ZtdQuery\Adapter\Mysqli\Driver\MysqliResultColumnExtractor;
16use ZtdQuery\Platform\ResultColumnTypeResolver;
17use ZtdQuery\Schema\ColumnType;
18use ZtdQuery\Schema\ColumnTypeFamily;
19
20#[CoversClass(MysqliResultColumnExtractor::class)]
21#[Large]
22final class MysqliResultColumnExtractorTest extends TestCase
23{
24 public function testExtractPassesNativeFieldMetadataToTheTypeResolver(): void
25 {
26 $container = Testcontainers::run(getenv('MYSQL_VERSION') === '8.4.7' ? MySql84Container::class : MySql80Container::class);
27 try {
28 $connection = new mysqli(str_replace('localhost', '127.0.0.1', $container->getHost()), 'root', 'root', 'test', $container->getMappedPort(3306));
29 $connection->set_charset('utf8mb4');
30 $result = $connection->query('SELECT CAST(7 AS SIGNED) AS value');
31 self::assertInstanceOf(mysqli_result::class, $result);
32 $resolver = self::createMock(ResultColumnTypeResolver::class);
33 $resolver->expects(self::once())->method('resolve')->with(self::callback(
34 static fn (array $metadata): bool => $metadata['name'] === 'value'
35 && $metadata['type'] === MYSQLI_TYPE_LONGLONG && $metadata['charsetnr'] === 63,
36 ))->willReturn(new ColumnType(ColumnTypeFamily::INTEGER, 'BIGINT'));
37 $columns = MysqliResultColumnExtractor::extract($result, $resolver);
38 self::assertSame('value', $columns[0]->name);
39 self::assertSame(ColumnTypeFamily::INTEGER, $columns[0]->type->family);
40 $connection->close();
41 } finally {
42 $container->stop();
43 }
44 }
45
46 public function testExtractPreservesEveryColumnAndItsOrder(): void
47 {
48 $container = Testcontainers::run(getenv('MYSQL_VERSION') === '8.4.7' ? MySql84Container::class : MySql80Container::class);
49 try {
50 $connection = new mysqli(str_replace('localhost', '127.0.0.1', $container->getHost()), 'root', 'root', 'test', $container->getMappedPort(3306));
51 $connection->set_charset('utf8mb4');
52 $result = $connection->query("SELECT 1 AS id, 'Alice' AS name");
53 self::assertInstanceOf(mysqli_result::class, $result);
54 $resolver = self::createStub(ResultColumnTypeResolver::class);
55 $resolver->method('resolve')->willReturn(new ColumnType(ColumnTypeFamily::STRING, 'TEXT'));
56 $columns = MysqliResultColumnExtractor::extract($result, $resolver);
57 self::assertSame(['id', 'name'], array_column($columns, 'name'));
58 $connection->close();
59 } finally {
60 $container->stop();
61 }
62 }
63
64}
65