packages/sql-faker/tests/Unit/Grammar/Resource/SqlVersionRegistryTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Grammar\Resource;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use RuntimeException;
11use SqlFaker\Grammar\Resource\SqlVersion;
12use SqlFaker\Grammar\Resource\SqlVersionRegistry;
13
14#[CoversClass(SqlVersionRegistry::class)]
15#[UsesClass(SqlVersion::class)]
16final class SqlVersionRegistryTest extends TestCase
17{
18    public function testResolveAnswersTheDefaultReleaseOfADialect(): void
19    {
20        $version = (new SqlVersionRegistry())->resolve('mysql');
21
22        self::assertSame('mysql', $version->dialect);
23        self::assertSame('mysql-8.4.7', $version->name);
24        self::assertFileExists($version->astPath);
25    }
26
27    public function testResolveRejectsADialectThePackageDoesNotShip(): void
28    {
29        $this->expectException(RuntimeException::class);
30        $this->expectExceptionMessage('Unknown SQL dialect: oracle');
31
32        (new SqlVersionRegistry())->resolve('oracle');
33    }
34
35    public function testResolveRejectsAReleaseThePackageDoesNotShip(): void
36    {
37        $this->expectException(RuntimeException::class);
38        $this->expectExceptionMessage('Unsupported mysql version: mysql-999.0.0');
39
40        (new SqlVersionRegistry())->resolve('mysql', 'mysql-999.0.0');
41    }
42
43    public function testNamesEnumeratesTheReleasesOfOneDialect(): void
44    {
45        self::assertSame(
46            [
47                'mysql-5.6.51',
48                'mysql-5.7.44',
49                'mysql-8.0.44',
50                'mysql-8.1.0',
51                'mysql-8.2.0',
52                'mysql-8.3.0',
53                'mysql-8.4.7',
54                'mysql-9.0.1',
55                'mysql-9.1.0',
56            ],
57            (new SqlVersionRegistry())->names('mysql'),
58        );
59    }
60
61    public function testNamesRejectsADialectThePackageDoesNotShip(): void
62    {
63        $this->expectException(RuntimeException::class);
64        $this->expectExceptionMessage('Unknown SQL dialect: oracle');
65
66        (new SqlVersionRegistry())->names('oracle');
67    }
68
69    public function testAllEnumeratesEveryReleaseOfEveryDialect(): void
70    {
71        self::assertCount(11, (new SqlVersionRegistry())->all());
72    }
73
74    public function testEntriesReadsTheRecordOfGeneratedReleases(): void
75    {
76        self::assertSame(['mysql', 'postgresql', 'sqlite'], array_keys((new SqlVersionRegistry())->entries()));
77    }
78
79    public function testPathResolvesARecordedPathAgainstTheResourceDirectory(): void
80    {
81        $registry = new SqlVersionRegistry();
82
83        self::assertSame($registry->directory() . '/mysql/ast.php', $registry->path('mysql/ast.php'));
84    }
85
86    public function testPathRejectsAPathThatClimbsOutOfTheResourceDirectory(): void
87    {
88        $this->expectException(RuntimeException::class);
89        $this->expectExceptionMessage('Invalid SQL version resource path: ../composer.json');
90
91        (new SqlVersionRegistry())->path('../composer.json');
92    }
93
94    public function testDirectoryAnswersWhereGeneratedArtifactsAreCommitted(): void
95    {
96        self::assertDirectoryExists((new SqlVersionRegistry())->directory());
97    }
98}
99