packages/sql-fixture/tests/Unit/Platform/Sqlite/SqliteSchemaFetcherTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Platform\Sqlite;
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\Sqlite\SqliteSchemaFetcher;
13use SqlFixture\Platform\Sqlite\SqliteSchemaParser;
14use SqlFixture\Schema\ColumnDefinition;
15use SqlFixture\Schema\TableSchema;
16
17#[CoversClass(SqliteSchemaFetcher::class)]
18#[UsesClass(SqliteSchemaParser::class)]
19#[UsesClass(ColumnDefinition::class)]
20#[UsesClass(TableSchema::class)]
21#[CoversClass(\SqlFixture\Platform\Sqlite\Schema\CreateTableQuery::class)]
22#[CoversClass(\SqlFixture\Platform\Sqlite\Schema\PragmaColumn::class)]
23#[CoversClass(\SqlFixture\Platform\Sqlite\Schema\PragmaSchema::class)]
24#[UsesClass(\SqlFixture\Schema\SchemaFetcherInterface::class)]
25#[UsesClass(\SqlFixture\Schema\SchemaParseException::class)]
26#[UsesClass(\SqlFixture\Schema\SchemaParserInterface::class)]
27#[UsesClass(\SqlFixture\Platform\Sqlite\Schema\ColumnParser::class)]
28#[UsesClass(\SqlFixture\Platform\Sqlite\Schema\DefaultExpression::class)]
29#[UsesClass(\SqlFixture\Platform\Sqlite\Schema\DefinitionList::class)]
30#[UsesClass(\SqlFixture\Platform\Sqlite\Schema\TableSyntax::class)]
31#[UsesClass(\SqlFixture\Platform\Sqlite\Schema\TypeDeclaration::class)]
32#[UsesClass(\SqlFixture\Schema\DefinitionSegments::class)]
33#[UsesClass(\SqlFixture\Schema\TypeShape::class)]
34#[UsesClass(\SqlFixture\Schema\Exception\InvalidSqlException::class)]
35#[UsesClass(\SqlFixture\Schema\Exception\ExpectedCreateTableException::class)]
36#[UsesClass(\SqlFixture\Schema\Exception\MissingColumnDefinitionsException::class)]
37final class SqliteSchemaFetcherTest extends TestCase
38{
39 #[Test]
40 public function testFetchSchemaFromSqliteTable(): void
41 {
42 $pdo = new PDO('sqlite::memory:');
43 $pdo->exec('CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT NOT NULL, price REAL)');
44
45 $fetcher = new SqliteSchemaFetcher();
46 $schema = $fetcher->fetchSchema($pdo, 'products');
47
48 self::assertSame('products', $schema->tableName);
49 self::assertTrue($schema->hasColumn('id'));
50 self::assertTrue($schema->hasColumn('name'));
51 self::assertTrue($schema->hasColumn('price'));
52 }
53
54 #[Test]
55 public function testFetchSchemaWithVarcharLength(): void
56 {
57 $pdo = new PDO('sqlite::memory:');
58 $pdo->exec('CREATE TABLE items (id INTEGER PRIMARY KEY, name VARCHAR(100) NOT NULL)');
59
60 $fetcher = new SqliteSchemaFetcher();
61 $schema = $fetcher->fetchSchema($pdo, 'items');
62
63 self::assertSame('VARCHAR', $schema->columns['name']->type);
64 self::assertSame(100, $schema->columns['name']->length);
65 self::assertFalse($schema->columns['name']->nullable);
66 }
67
68 #[Test]
69 public function testFetchSchemaWithDecimalPrecisionScale(): void
70 {
71 $pdo = new PDO('sqlite::memory:');
72 $pdo->exec('CREATE TABLE money (id INTEGER PRIMARY KEY, amount DECIMAL(10, 2))');
73
74 $fetcher = new SqliteSchemaFetcher();
75 $schema = $fetcher->fetchSchema($pdo, 'money');
76
77 self::assertSame('DECIMAL', $schema->columns['amount']->type);
78 self::assertSame(10, $schema->columns['amount']->precision);
79 self::assertSame(2, $schema->columns['amount']->scale);
80 }
81
82 #[Test]
83 public function testFetchSchemaWithDefaultValues(): void
84 {
85 $pdo = new PDO('sqlite::memory:');
86 $pdo->exec("CREATE TABLE defaults (
87 id INTEGER PRIMARY KEY,
88 count INTEGER DEFAULT 42,
89 name TEXT DEFAULT 'hello',
90 nullable TEXT DEFAULT NULL,
91 price REAL DEFAULT 9.99
92 )");
93
94 $fetcher = new SqliteSchemaFetcher();
95 $schema = $fetcher->fetchSchema($pdo, 'defaults');
96
97 self::assertSame(42, $schema->columns['count']->default);
98 self::assertSame('hello', $schema->columns['name']->default);
99 self::assertNull($schema->columns['nullable']->default);
100 self::assertSame(9.99, $schema->columns['price']->default);
101 }
102
103 #[Test]
104 public function testFetchSchemaWithNullableColumns(): void
105 {
106 $pdo = new PDO('sqlite::memory:');
107 $pdo->exec('CREATE TABLE test (id INTEGER NOT NULL, name TEXT)');
108
109 $fetcher = new SqliteSchemaFetcher();
110 $schema = $fetcher->fetchSchema($pdo, 'test');
111
112 self::assertFalse($schema->columns['id']->nullable);
113 self::assertTrue($schema->columns['name']->nullable);
114 }
115
116 #[Test]
117 public function testFetchSchemaWithAutoincrement(): void
118 {
119 $pdo = new PDO('sqlite::memory:');
120 $pdo->exec('CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)');
121
122 $fetcher = new SqliteSchemaFetcher();
123 $schema = $fetcher->fetchSchema($pdo, 'test');
124
125 self::assertTrue($schema->columns['id']->autoIncrement);
126 }
127
128 #[Test]
129 public function testFetchSchemaWithCustomParser(): void
130 {
131 $pdo = new PDO('sqlite::memory:');
132 $pdo->exec('CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)');
133
134 $parser = new SqliteSchemaParser();
135 $fetcher = new SqliteSchemaFetcher($parser);
136 $schema = $fetcher->fetchSchema($pdo, 'test');
137
138 self::assertSame('test', $schema->tableName);
139 }
140
141 #[Test]
142 public function testFetchSchemaWithDefaultCurrentTimestamp(): void
143 {
144 $pdo = new PDO('sqlite::memory:');
145 $pdo->exec('CREATE TABLE test (id INTEGER PRIMARY KEY, created_at TEXT DEFAULT CURRENT_TIMESTAMP)');
146
147 $fetcher = new SqliteSchemaFetcher();
148 $schema = $fetcher->fetchSchema($pdo, 'test');
149
150 self::assertSame('CURRENT_TIMESTAMP', $schema->columns['created_at']->default);
151 }
152}
153