packages/sql-catalog/tests/Unit/Reporter/Html/HtmlTextTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Reporter\Html;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use SqlCatalog\Reporter\Html\HtmlText;
10
11#[CoversClass(HtmlText::class)]
12final class HtmlTextTest extends TestCase
13{
14 public function testEscapeMakesTextSafeForTheDocument(): void
15 {
16 self::assertSame('<a href="x">'', (new HtmlText())->escape('<a href="x">\''));
17 }
18
19 public function testChipCarriesItsRoleAndTitle(): void
20 {
21 self::assertSame('<span class="chip tone-blue" title="What it does">SELECT</span>', (new HtmlText())->chip('SELECT', 'tone-blue', 'What it does'));
22 self::assertSame('<span class="chip">plain</span>', (new HtmlText())->chip('plain'));
23 }
24
25 public function testChipLinkIsAChipThatLeadsSomewhere(): void
26 {
27 self::assertSame(
28 '<a class="chip chip-ghost" href="tables/posts.html" title="t">posts</a>',
29 (new HtmlText())->chipLink('posts', 'tables/posts.html', 'chip-ghost', 't'),
30 );
31 }
32
33 public function testLinkEscapesItsTextAndAddress(): void
34 {
35 self::assertSame('<a class="mono" href="a.html?q=1&b=2">A & B</a>', (new HtmlText())->link('A & B', 'a.html?q=1&b=2', 'mono'));
36 self::assertSame('<a href="a.html">A</a>', (new HtmlText())->link('A', 'a.html'));
37 }
38
39 public function testNumberIsWrittenForScanning(): void
40 {
41 self::assertSame('1,234', (new HtmlText())->number(1234));
42 }
43
44 public function testPluralAgreesWithTheCount(): void
45 {
46 self::assertSame('1 table', (new HtmlText())->plural(1, 'table'));
47 self::assertSame('2 tables', (new HtmlText())->plural(2, 'table'));
48 }
49
50 public function testPercentIsWholeAndSafeOnZero(): void
51 {
52 self::assertSame('33%', (new HtmlText())->percent(1, 3));
53 self::assertSame('0%', (new HtmlText())->percent(1, 0));
54 }
55
56 public function testChipCountCarriesHowManyTheChipStandsFor(): void
57 {
58 self::assertSame(
59 '<a class="chip chip-ghost" href="tables/posts.html">posts<span class="facet-count">1,234</span></a>',
60 (new HtmlText())->chipCount('posts', 'tables/posts.html', 1234, 'chip-ghost'),
61 );
62 self::assertSame('<a class="chip" href="a.html">A & B<span class="facet-count">0</span></a>', (new HtmlText())->chipCount('A & B', 'a.html', 0));
63 }
64
65 public function testNounAgreesWithTheCount(): void
66 {
67 self::assertSame('table', (new HtmlText())->noun(1, 'table'));
68 self::assertSame('tables', (new HtmlText())->noun(0, 'table'));
69 }
70
71 public function testSlugIsWritableAsAnIdentifier(): void
72 {
73 self::assertSame('app-users-find', (new HtmlText())->slug('App\\Users::find'));
74 }
75
76 public function testCollapseWritesEveryRunOfWhitespaceAsOneSpace(): void
77 {
78 self::assertSame('a b c', (new HtmlText())->collapse(" a\n\t b c "));
79 }
80
81 public function testTruncateCollapsesAndCuts(): void
82 {
83 self::assertSame('SELECT…', (new HtmlText())->truncate("SELECT 1\nFROM t", 7));
84 self::assertSame('SELECT 1', (new HtmlText())->truncate('SELECT 1', 8));
85 }
86
87 public function testMarkedMarksEveryGapInAName(): void
88 {
89 self::assertSame(
90 '<span class="hole tone-warn" title="A part of this name the analysis could not pin down">{$}</span>posts & more',
91 (new HtmlText())->marked('{$}posts & more'),
92 );
93 }
94
95 public function testCountIsWrittenBesideAHeading(): void
96 {
97 self::assertSame('<span class="count">3 tables</span>', (new HtmlText())->count(3, 'table'));
98 self::assertSame('<span class="count">3</span>', (new HtmlText())->count(3));
99 }
100}
101