packages/sql-catalog/tests/Unit/Core/Catalog/StatementPartTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Core\Catalog;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlCatalog\Core\Catalog\StatementPart;
11use SqlCatalog\Core\Text\LiteralText;
12use SqlCatalog\Core\Text\Origin;
13use SqlCatalog\Core\Text\TextHole;
14use SqlCatalog\Core\Text\TextPattern;
15use SqlCatalog\Core\Type\TypeShape;
16
17#[CoversClass(StatementPart::class)]
18#[UsesClass(LiteralText::class)]
19#[UsesClass(Origin::class)]
20#[UsesClass(TextHole::class)]
21#[UsesClass(TextPattern::class)]
22#[UsesClass(TypeShape::class)]
23final class StatementPartTest extends TestCase
24{
25 public function testOfKeepsAKnownRunAsTheTextItIs(): void
26 {
27 $parts = StatementPart::of(TextPattern::fromText('SELECT 1'));
28
29 self::assertCount(1, $parts);
30 self::assertSame('SELECT 1', $parts[0]->text);
31 self::assertFalse($parts[0]->isGap);
32 self::assertSame('', $parts[0]->origin);
33 }
34
35 public function testOfKeepsWhatIsKnownAboutAGap(): void
36 {
37 $parts = StatementPart::of(TextPattern::fromHole(
38 new TextHole(Origin::External, TypeShape::unknown(), '$_GET["id"]', '$id'),
39 ));
40
41 self::assertCount(1, $parts);
42 self::assertTrue($parts[0]->isGap);
43 self::assertSame('', $parts[0]->text);
44 self::assertSame('external', $parts[0]->origin);
45 self::assertSame('external input', $parts[0]->reason);
46 self::assertSame('$_GET["id"]', $parts[0]->expression);
47 self::assertSame('$id', $parts[0]->variable);
48 }
49
50 public function testOfKeepsTheRunsAndTheGapsInOrder(): void
51 {
52 $parts = StatementPart::of(TextPattern::fromSegments([
53 new LiteralText('SELECT * FROM '),
54 new TextHole(Origin::Property, TypeShape::unknown()),
55 new LiteralText(' WHERE id = 1'),
56 ]));
57
58 self::assertSame(
59 ['SELECT * FROM ', '', ' WHERE id = 1'],
60 array_map(static fn (StatementPart $part): string => $part->text, $parts),
61 );
62 self::assertSame([false, true, false], array_map(static fn (StatementPart $part): bool => $part->isGap, $parts));
63 }
64
65 public function testOfHasNothingToSayAboutAnEmptyStatement(): void
66 {
67 self::assertSame([], StatementPart::of(TextPattern::empty()));
68 }
69}
70