packages/sql-catalog/tests/Unit/Reporter/Html/SearchIndexTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Reporter\Html;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlCatalog\Core\Catalog\CallSite;
11use SqlCatalog\Core\Catalog\Catalog;
12use SqlCatalog\Core\Catalog\CatalogEntry;
13use SqlCatalog\Core\Catalog\Resolution;
14use SqlCatalog\Core\Sql\StatementKind;
15use SqlCatalog\Core\Text\LiteralText;
16use SqlCatalog\Core\Text\TextPattern;
17use SqlCatalog\Reporter\Html\CatalogIndex;
18use SqlCatalog\Reporter\Html\CatalogStatistics;
19use SqlCatalog\Reporter\Html\HtmlText;
20use SqlCatalog\Reporter\Html\ReportSite;
21use SqlCatalog\Reporter\Html\Scope;
22use SqlCatalog\Reporter\Html\SearchIndex;
23
24#[CoversClass(SearchIndex::class)]
25#[UsesClass(CallSite::class)]
26#[UsesClass(Catalog::class)]
27#[UsesClass(CatalogEntry::class)]
28#[UsesClass(CatalogIndex::class)]
29#[UsesClass(CatalogStatistics::class)]
30#[UsesClass(HtmlText::class)]
31#[UsesClass(ReportSite::class)]
32#[UsesClass(Resolution::class)]
33#[UsesClass(Scope::class)]
34#[UsesClass(StatementKind::class)]
35#[UsesClass(LiteralText::class)]
36#[UsesClass(TextPattern::class)]
37#[UsesClass(\SqlCatalog\Core\Catalog\StatementPart::class)]
38#[UsesClass(\SqlCatalog\Reporter\Html\SqlHighlighter::class)]
39#[UsesClass(\SqlCatalog\Core\Text\TextHole::class)]
40#[UsesClass(\SqlCatalog\Core\Text\Origin::class)]
41#[UsesClass(\SqlCatalog\Core\Type\TypeShape::class)]
42final class SearchIndexTest extends TestCase
43{
44    public function testRenderWritesTheIndexAsAScriptThePagesLoad(): void
45    {
46        $catalog = new Catalog([
47            new CatalogEntry('a1', StatementKind::Select, TextPattern::fromText('SELECT 1'), [], [], new CallSite('a.php', 1, 'f', 'pdo.query'), []),
48        ]);
49
50        self::assertSame(
51            'window.__CATALOG_INDEX__ = [{"q":"SELECT 1","w":"a.php:1","f":"f","t":"","u":"statements/a1.html","k":"SELECT","r":"resolved"}];' . "\n",
52            (new SearchIndex())->render(new ReportSite($catalog, formatter: \SqlCatalog\Facade\Builtins::sqlFormatter())),
53        );
54        self::assertSame("window.__CATALOG_INDEX__ = [];\n", (new SearchIndex())->render(new ReportSite(new Catalog(), formatter: \SqlCatalog\Facade\Builtins::sqlFormatter())));
55    }
56
57    public function testEntryToArrayCarriesWhatTheSearchReads(): void
58    {
59        $entry = new CatalogEntry('a1', StatementKind::Delete, TextPattern::fromText("DELETE FROM users\n WHERE id = 1"), ['users'], [], new CallSite('a.php', 3, 'App\\R::gone', 'pdo.query'), []);
60
61        self::assertSame(
62            ['q' => 'DELETE FROM users WHERE id = 1', 'w' => 'a.php:3', 'f' => 'App\\R::gone', 't' => 'users', 'u' => 'statements/a1.html', 'k' => 'DELETE', 'r' => 'resolved'],
63            (new SearchIndex())->entryToArray(new ReportSite(new Catalog([$entry]), formatter: \SqlCatalog\Facade\Builtins::sqlFormatter()), $entry),
64        );
65    }
66    public function testEntryToArrayMakesTheVariableNameSearchable(): void
67    {
68        $entry = new CatalogEntry('q', StatementKind::Unknown, TextPattern::fromHole(
69            new \SqlCatalog\Core\Text\TextHole(\SqlCatalog\Core\Text\Origin::Parameter, \SqlCatalog\Core\Type\TypeShape::unknown(), '$sql'),
70        ), [], [], new CallSite('query.php', 4, 'f', 'pdo.prepare'), []);
71
72        self::assertSame('{$sql}', (new SearchIndex())->entryToArray(new ReportSite(new Catalog([$entry]), formatter: \SqlCatalog\Facade\Builtins::sqlFormatter()), $entry)['q']);
73    }
74
75}
76