packages/sql-fixture/tests/Unit/Platform/PlatformFactoryTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Platform;
6
7use PDO;
8use PHPUnit\Framework\Attributes\CoversClass;
9use PHPUnit\Framework\Attributes\Test;
10use PHPUnit\Framework\Attributes\UsesClass;
11use PHPUnit\Framework\TestCase;
12use SqlFixture\Platform\MySql\MySqlSchemaFetcher;
13use SqlFixture\Platform\MySql\MySqlSchemaParser;
14use SqlFixture\Platform\MySql\MySqlTypeMapper;
15use SqlFixture\Platform\PlatformFactory;
16use SqlFixture\Platform\PostgreSql\PostgreSqlSchemaFetcher;
17use SqlFixture\Platform\PostgreSql\PostgreSqlSchemaParser;
18use SqlFixture\Platform\PostgreSql\PostgreSqlTypeMapper;
19use SqlFixture\Platform\Sqlite\SqliteSchemaFetcher;
20use SqlFixture\Platform\Sqlite\SqliteSchemaParser;
21use SqlFixture\Platform\Sqlite\SqliteTypeMapper;
22
23#[CoversClass(PlatformFactory::class)]
24#[UsesClass(SqliteSchemaFetcher::class)]
25#[UsesClass(PostgreSqlSchemaFetcher::class)]
26#[UsesClass(MySqlSchemaFetcher::class)]
27#[UsesClass(MySqlSchemaParser::class)]
28#[UsesClass(MySqlTypeMapper::class)]
29#[UsesClass(PostgreSqlSchemaParser::class)]
30#[UsesClass(PostgreSqlTypeMapper::class)]
31#[UsesClass(SqliteSchemaParser::class)]
32#[UsesClass(SqliteTypeMapper::class)]
33#[UsesClass(\SqlFixture\Schema\ColumnDefinition::class)]
34#[UsesClass(\SqlFixture\Schema\SchemaFetcherInterface::class)]
35#[UsesClass(\SqlFixture\Schema\SchemaParseException::class)]
36#[UsesClass(\SqlFixture\Schema\SchemaParserInterface::class)]
37#[UsesClass(\SqlFixture\Schema\TableSchema::class)]
38#[UsesClass(\SqlFixture\TypeMapper\TypeMapperInterface::class)]
39#[UsesClass(\SqlFixture\Platform\MySql\Schema\ColumnParser::class)]
40#[UsesClass(\SqlFixture\Platform\MySql\Schema\CreateTableQuery::class)]
41#[UsesClass(\SqlFixture\Platform\MySql\Schema\DefaultExpression::class)]
42#[UsesClass(\SqlFixture\Platform\MySql\Schema\DefinitionIntegrity::class)]
43#[UsesClass(\SqlFixture\Platform\MySql\Schema\IdentifierQuoter::class)]
44#[UsesClass(\SqlFixture\Platform\MySql\Schema\TableDefinition::class)]
45#[UsesClass(\SqlFixture\Platform\MySql\Schema\TypeParameters::class)]
46#[UsesClass(\SqlFixture\Platform\MySql\Value\ColumnGenerator::class)]
47#[UsesClass(\SqlFixture\Platform\MySql\Value\DecimalGenerator::class)]
48#[UsesClass(\SqlFixture\Platform\MySql\Value\GeometryGenerator::class)]
49#[UsesClass(\SqlFixture\Platform\MySql\Value\IntegerGenerator::class)]
50#[UsesClass(\SqlFixture\Platform\MySql\Value\NumericGenerator::class)]
51#[UsesClass(\SqlFixture\Platform\MySql\Value\SpatialGenerator::class)]
52#[UsesClass(\SqlFixture\Platform\MySql\Value\StringGenerator::class)]
53#[UsesClass(\SqlFixture\Platform\MySql\Value\TextGenerator::class)]
54#[UsesClass(\SqlFixture\Platform\PostgreSql\Schema\CatalogColumn::class)]
55#[UsesClass(\SqlFixture\Platform\PostgreSql\Schema\CatalogDdl::class)]
56#[UsesClass(\SqlFixture\Platform\PostgreSql\Schema\CatalogQuery::class)]
57#[UsesClass(\SqlFixture\Platform\PostgreSql\Schema\CatalogSchema::class)]
58#[UsesClass(\SqlFixture\Platform\PostgreSql\Schema\ColumnParser::class)]
59#[UsesClass(\SqlFixture\Platform\PostgreSql\Schema\DefaultExpression::class)]
60#[UsesClass(\SqlFixture\Platform\PostgreSql\Schema\DefinitionList::class)]
61#[UsesClass(\SqlFixture\Platform\PostgreSql\Schema\TableSyntax::class)]
62#[UsesClass(\SqlFixture\Platform\PostgreSql\Schema\TypeDeclaration::class)]
63#[UsesClass(\SqlFixture\Platform\PostgreSql\Value\ColumnGenerator::class)]
64#[UsesClass(\SqlFixture\Platform\PostgreSql\Value\DecimalGenerator::class)]
65#[UsesClass(\SqlFixture\Platform\PostgreSql\Value\NumericGenerator::class)]
66#[UsesClass(\SqlFixture\Platform\PostgreSql\Value\StringGenerator::class)]
67#[UsesClass(\SqlFixture\Platform\PostgreSql\Value\StructuredGenerator::class)]
68#[UsesClass(\SqlFixture\Platform\PostgreSql\Value\TemporalGenerator::class)]
69#[UsesClass(\SqlFixture\Platform\Sqlite\Schema\ColumnParser::class)]
70#[UsesClass(\SqlFixture\Platform\Sqlite\Schema\CreateTableQuery::class)]
71#[UsesClass(\SqlFixture\Platform\Sqlite\Schema\DefaultExpression::class)]
72#[UsesClass(\SqlFixture\Platform\Sqlite\Schema\DefinitionList::class)]
73#[UsesClass(\SqlFixture\Platform\Sqlite\Schema\PragmaColumn::class)]
74#[UsesClass(\SqlFixture\Platform\Sqlite\Schema\PragmaSchema::class)]
75#[UsesClass(\SqlFixture\Platform\Sqlite\Schema\TableSyntax::class)]
76#[UsesClass(\SqlFixture\Platform\Sqlite\Schema\TypeDeclaration::class)]
77#[UsesClass(\SqlFixture\Platform\Sqlite\Value\ColumnGenerator::class)]
78#[UsesClass(\SqlFixture\Platform\Sqlite\Value\TypeAffinity::class)]
79#[UsesClass(\SqlFixture\Schema\DefinitionSegments::class)]
80#[UsesClass(\SqlFixture\Schema\TypeShape::class)]
81#[UsesClass(\SqlFixture\TypeMapper\ParagraphGenerator::class)]
82#[UsesClass(\SqlFixture\Platform\MySql\Schema\TableDefinitionInput::class)]
83#[UsesClass(\SqlFixture\Schema\Exception\InvalidSqlException::class)]
84#[UsesClass(\SqlFixture\Schema\Exception\ExpectedCreateTableException::class)]
85#[UsesClass(\SqlFixture\Schema\Exception\MissingColumnDefinitionsException::class)]
86#[UsesClass(\SqlFixture\TypeMapper\IntegerRange::class)]
87#[UsesClass(\SqlFixture\TypeMapper\IntegerWidth::class)]
88#[UsesClass(\SqlFixture\TypeMapper\DecimalRange::class)]
89#[\PHPUnit\Framework\Attributes\Medium]
90final class PlatformFactoryTest extends TestCase
91{
92    #[Test]
93    public function testCreateSchemaParserForMysql(): void
94    {
95        $parser = PlatformFactory::createSchemaParser(PlatformFactory::DRIVER_MYSQL);
96
97        self::assertInstanceOf(MySqlSchemaParser::class, $parser);
98    }
99
100    #[Test]
101    public function testCreateSchemaParserForSqlite(): void
102    {
103        $parser = PlatformFactory::createSchemaParser(PlatformFactory::DRIVER_SQLITE);
104
105        self::assertInstanceOf(SqliteSchemaParser::class, $parser);
106    }
107
108    #[Test]
109    public function testCreateSchemaParserForPgsql(): void
110    {
111        $parser = PlatformFactory::createSchemaParser(PlatformFactory::DRIVER_PGSQL);
112
113        self::assertInstanceOf(PostgreSqlSchemaParser::class, $parser);
114    }
115
116    #[Test]
117    public function testCreateTypeMapperForMysql(): void
118    {
119        $mapper = PlatformFactory::createTypeMapper(PlatformFactory::DRIVER_MYSQL);
120
121        self::assertInstanceOf(MySqlTypeMapper::class, $mapper);
122    }
123
124    #[Test]
125    public function testCreateTypeMapperForSqlite(): void
126    {
127        $mapper = PlatformFactory::createTypeMapper(PlatformFactory::DRIVER_SQLITE);
128
129        self::assertInstanceOf(SqliteTypeMapper::class, $mapper);
130    }
131
132    #[Test]
133    public function testCreateTypeMapperForPgsql(): void
134    {
135        $mapper = PlatformFactory::createTypeMapper(PlatformFactory::DRIVER_PGSQL);
136
137        self::assertInstanceOf(PostgreSqlTypeMapper::class, $mapper);
138    }
139
140    #[Test]
141    public function testCreateSchemaFetcherForMysql(): void
142    {
143        $fetcher = PlatformFactory::createSchemaFetcher(PlatformFactory::DRIVER_MYSQL);
144
145        self::assertInstanceOf(MySqlSchemaFetcher::class, $fetcher);
146    }
147
148    #[Test]
149    public function testCreateSchemaFetcherForSqlite(): void
150    {
151        $fetcher = PlatformFactory::createSchemaFetcher(PlatformFactory::DRIVER_SQLITE);
152
153        self::assertInstanceOf(SqliteSchemaFetcher::class, $fetcher);
154    }
155
156    #[Test]
157    public function testCreateSchemaFetcherForPgsql(): void
158    {
159        $fetcher = PlatformFactory::createSchemaFetcher(PlatformFactory::DRIVER_PGSQL);
160
161        self::assertInstanceOf(PostgreSqlSchemaFetcher::class, $fetcher);
162    }
163
164    #[Test]
165    public function testDetectDriverForSqlite(): void
166    {
167        $pdo = new PDO('sqlite::memory:');
168
169        $driver = PlatformFactory::detectDriver($pdo);
170
171        self::assertSame(PlatformFactory::DRIVER_SQLITE, $driver);
172    }
173
174    #[Test]
175    public function testGetSupportedDrivers(): void
176    {
177        $drivers = PlatformFactory::getSupportedDrivers();
178
179        self::assertContains(PlatformFactory::DRIVER_MYSQL, $drivers);
180        self::assertContains(PlatformFactory::DRIVER_SQLITE, $drivers);
181        self::assertContains(PlatformFactory::DRIVER_PGSQL, $drivers);
182    }
183
184    #[\PHPUnit\Framework\Attributes\DataProvider('providerDatabaseDrivers')]
185    public function testDetectDriverReadsTheNativeConnection(string $prefix, string $expected): void
186    {
187        $pdo = new PDO(
188            (string) getenv($prefix . '_DSN'),
189            (string) getenv($prefix . '_USER'),
190            (string) getenv($prefix . '_PASSWORD'),
191            [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false],
192        );
193        self::assertSame($expected, PlatformFactory::detectDriver($pdo));
194    }
195
196    /**
197     * @return iterable<string, array{string, string}>
198     */
199    public static function providerDatabaseDrivers(): iterable
200    {
201        yield 'mysql' => ['SQL_FIXTURE_MYSQL', 'mysql'];
202        yield 'postgres' => ['SQL_FIXTURE_PGSQL', 'pgsql'];
203    }
204}
205