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