packages/ztd-query-core/tests/Unit/RewriteRefusalTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use ZtdQuery\Config\UnknownSchemaBehavior;
11use ZtdQuery\Config\UnsupportedSqlBehavior;
12use ZtdQuery\Config\ZtdConfig;
13use ZtdQuery\Connection\Exception\DatabaseException;
14use ZtdQuery\Exception\UnknownSchemaException;
15use ZtdQuery\Exception\UnsupportedSqlException;
16use ZtdQuery\Rewrite\QueryKind;
17use ZtdQuery\Rewrite\RewritePlan;
18use ZtdQuery\RewriteRefusal;
19
20#[CoversClass(RewriteRefusal::class)]
21#[UsesClass(ZtdConfig::class)]
22#[UsesClass(RewritePlan::class)]
23#[UsesClass(UnsupportedSqlException::class)]
24#[UsesClass(UnknownSchemaException::class)]
25#[UsesClass(DatabaseException::class)]
26final class RewriteRefusalTest extends TestCase
27{
28 public function testForUnsupportedRaisesWhereTheCallerAskedToBeTold(): void
29 {
30 $refusals = new RewriteRefusal(new ZtdConfig(unsupportedBehavior: UnsupportedSqlBehavior::Exception));
31
32 $this->expectException(DatabaseException::class);
33
34 $refusals->forUnsupported(new UnsupportedSqlException('SELECT 1', 'why'), 'SELECT 1');
35 }
36
37 public function testForUnsupportedAnswersAPlanThatDoesNothingWhereTheCallerAllowsThat(): void
38 {
39 $refusals = new RewriteRefusal(new ZtdConfig(unsupportedBehavior: UnsupportedSqlBehavior::Ignore));
40
41 $plan = $refusals->forUnsupported(new UnsupportedSqlException('SELECT 1', 'why'), 'SELECT 1');
42
43 self::assertSame([QueryKind::SKIPPED, 'SELECT 1'], [$plan->kind(), $plan->sql()]);
44 }
45
46 public function testForUnsupportedSaysSomethingWhereTheCallerAskedToBeNoticed(): void
47 {
48 $refusals = new RewriteRefusal(new ZtdConfig(unsupportedBehavior: UnsupportedSqlBehavior::Notice));
49 $said = null;
50 set_error_handler(static function (int $level, string $message) use (&$said): bool {
51 $said = $message;
52
53 return true;
54 }, E_USER_NOTICE);
55
56 try {
57 $refusals->forUnsupported(new UnsupportedSqlException('SELECT 1', 'why'), 'SELECT 1');
58 } finally {
59 restore_error_handler();
60 }
61
62 self::assertSame('[ZTD Notice] Unsupported SQL ignored: SELECT 1', $said);
63 }
64
65 public function testForUnknownSchemaRaisesWhereTheCallerAskedToBeTold(): void
66 {
67 $refusals = new RewriteRefusal(new ZtdConfig(unknownSchemaBehavior: UnknownSchemaBehavior::Exception));
68
69 $this->expectException(DatabaseException::class);
70
71 $refusals->forUnknownSchema(new UnknownSchemaException('SELECT 1', 't'), 'SELECT 1', 'SELECT 1 WHERE 0');
72 }
73
74 public function testForUnknownSchemaLetsTheStatementThroughWhereTheCallerAsksForThat(): void
75 {
76 $refusals = new RewriteRefusal(new ZtdConfig(unknownSchemaBehavior: UnknownSchemaBehavior::Passthrough));
77
78 $plan = $refusals->forUnknownSchema(new UnknownSchemaException('SELECT 1', 't'), 'SELECT 1', 'SELECT 1 WHERE 0');
79
80 self::assertSame([QueryKind::READ, 'SELECT 1'], [$plan->kind(), $plan->sql()]);
81 }
82
83 public function testForUnknownSchemaReadsNothingBackWhereTheCallerAsksForThat(): void
84 {
85 $refusals = new RewriteRefusal(new ZtdConfig(unknownSchemaBehavior: UnknownSchemaBehavior::EmptyResult));
86
87 $plan = $refusals->forUnknownSchema(new UnknownSchemaException('SELECT 1', 't'), 'SELECT 1', 'SELECT 1 WHERE 0');
88
89 self::assertSame([QueryKind::READ, 'SELECT 1 WHERE 0'], [$plan->kind(), $plan->sql()]);
90 }
91
92 public function testForUnknownSchemaSaysSomethingWhereTheCallerAskedToBeNoticed(): void
93 {
94 $refusals = new RewriteRefusal(new ZtdConfig(unknownSchemaBehavior: UnknownSchemaBehavior::Notice));
95 $said = null;
96 set_error_handler(static function (int $level, string $message) use (&$said): bool {
97 $said = $message;
98
99 return true;
100 }, E_USER_NOTICE);
101
102 try {
103 $refusals->forUnknownSchema(new UnknownSchemaException('SELECT 1', 't'), 'SELECT 1', 'SELECT 1 WHERE 0');
104 } finally {
105 restore_error_handler();
106 }
107
108 self::assertSame('[ZTD Notice] Unknown table referenced: t', $said);
109 }
110}
111