packages/sql-catalog/tests/Unit/Facade/ConfigurationSchemaTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Facade;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\Attributes\UsesClass;
10use PHPUnit\Framework\TestCase;
11use SqlCatalog\Facade\ConfigurationSchema;
12use SqlCatalog\Facade\InvalidConfigurationException;
13use stdClass;
14
15#[CoversClass(ConfigurationSchema::class)]
16#[UsesClass(InvalidConfigurationException::class)]
17final class ConfigurationSchemaTest extends TestCase
18{
19 public function testOptionsPreservesListsAndResolvesOnlyFilesystemPaths(): void
20 {
21 $options = ConfigurationSchema::options((object) ['paths' => ['src'], 'exclude' => ['*.tmp', 'vendor'], 'root' => '/project', 'kind' => ['select'], 'function-models' => new stdClass()], '/config');
22 self::assertSame(['paths' => ['/config/src'], 'exclude' => ['*.tmp', 'vendor'], 'root' => ['/project'], 'kind' => ['select']], $options);
23 self::assertSame(['extension' => [], 'root' => ['/config']], ConfigurationSchema::options((object) ['extensions' => []], '/config'));
24 }
25
26 #[DataProvider('providerInvalidOptions')]
27 public function testOptionsRejectsInvalidSettings(stdClass $data): void
28 {
29 $this->expectException(InvalidConfigurationException::class);
30 ConfigurationSchema::options($data, '/config');
31 }
32
33 /**
34 * @return list<array{stdClass}>
35 */
36 public static function providerInvalidOptions(): array
37 {
38 return [
39 [(object) ['unknown' => 'value']],
40 [(object) ['reporter' => []]],
41 [(object) ['reporter' => '']],
42 [(object) ['paths' => 'src']],
43 [(object) ['paths' => ['x' => 'src']]],
44 [(object) ['paths' => [1]]],
45 [(object) ['paths' => ['']]],
46 ];
47 }
48
49 public function testModelsReadsAMappingAndAllowsNoRegistrations(): void
50 {
51 self::assertSame([], ConfigurationSchema::models(new stdClass()));
52 self::assertSame([], ConfigurationSchema::models((object) ['function-models' => new stdClass()]));
53 self::assertSame(['array_fill' => 'App\\Model'], ConfigurationSchema::models((object) ['function-models' => (object) ['array_fill' => 'App\\Model']]));
54 }
55
56 #[DataProvider('providerInvalidModels')]
57 public function testModelsRejectsMalformedRegistrations(stdClass $data): void
58 {
59 $this->expectException(InvalidConfigurationException::class);
60 ConfigurationSchema::models($data);
61 }
62
63 /**
64 * @return list<array{stdClass}>
65 */
66 public static function providerInvalidModels(): array
67 {
68 return [
69 [(object) ['function-models' => []]],
70 [(object) ['function-models' => null]],
71 [(object) ['function-models' => (object) ['' => 'Model']]],
72 [(object) ['function-models' => (object) ['foo' => '']]],
73 [(object) ['function-models' => (object) ['foo' => false]]],
74 ];
75 }
76
77 #[DataProvider('providerPaths')]
78 public function testAbsolutePreservesAbsolutePathsAndResolvesRelativePaths(string $path, string $expected): void
79 {
80 self::assertSame($expected, ConfigurationSchema::absolute($path, '/config'));
81 }
82
83 /**
84 * @return list<array{string, string}>
85 */
86 public static function providerPaths(): array
87 {
88 return [['src', '/config/src'], ['/src', '/src'], ['C:/src', 'C:/src'], ['C:\\src', 'C:\\src'], ['\\\\server\\src', '\\\\server\\src']];
89 }
90}
91