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\Endpoint;
8use Container\MySqlRelease;
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(MySqlRelease::fromEnvironment());
27 $endpoint = $container->getData(Endpoint::class);
28 try {
29 $connection = new mysqli($endpoint->host, $endpoint->username, $endpoint->password, $endpoint->database, $endpoint->port);
30 $connection->set_charset('utf8mb4');
31 $result = $connection->query('SELECT CAST(7 AS SIGNED) AS value');
32 self::assertInstanceOf(mysqli_result::class, $result);
33 $resolver = self::createMock(ResultColumnTypeResolver::class);
34 $resolver->expects(self::once())->method('resolve')->with(self::callback(
35 static fn (array $metadata): bool => $metadata['name'] === 'value'
36 && $metadata['type'] === MYSQLI_TYPE_LONGLONG && $metadata['charsetnr'] === 63,
37 ))->willReturn(new ColumnType(ColumnTypeFamily::INTEGER, 'BIGINT'));
38 $columns = MysqliResultColumnExtractor::extract($result, $resolver);
39 self::assertSame('value', $columns[0]->name);
40 self::assertSame(ColumnTypeFamily::INTEGER, $columns[0]->type->family);
41 $connection->close();
42 } finally {
43 $container->stop();
44 }
45 }
46
47 public function testExtractPreservesEveryColumnAndItsOrder(): void
48 {
49 $container = Testcontainers::run(MySqlRelease::fromEnvironment());
50 $endpoint = $container->getData(Endpoint::class);
51 try {
52 $connection = new mysqli($endpoint->host, $endpoint->username, $endpoint->password, $endpoint->database, $endpoint->port);
53 $connection->set_charset('utf8mb4');
54 $result = $connection->query("SELECT 1 AS id, 'Alice' AS name");
55 self::assertInstanceOf(mysqli_result::class, $result);
56 $resolver = self::createStub(ResultColumnTypeResolver::class);
57 $resolver->method('resolve')->willReturn(new ColumnType(ColumnTypeFamily::STRING, 'TEXT'));
58 $columns = MysqliResultColumnExtractor::extract($result, $resolver);
59 self::assertSame(['id', 'name'], array_column($columns, 'name'));
60 $connection->close();
61 } finally {
62 $container->stop();
63 }
64 }
65
66}
67