Skip to content

Commit 1ce9d56

Browse files
committed
[Toolkit] Add functional tests to render all Kit components usage codes (from their documentation), with a snapshot system
1 parent 4314322 commit 1ce9d56

File tree

79 files changed

+1873
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+1873
-5
lines changed

.github/workflows/test.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ jobs:
116116
working-directory: "src/${{ matrix.component }}"
117117
dependency-versions: ${{ matrix.dependency-version }}
118118

119+
- name: Install specific packages for Toolkit when PHP >=8.2
120+
if: ${{ matrix.component == 'Toolkit' && matrix.php-version != '8.1' }}
121+
run:
122+
composer require --dev tales-from-a-dev/twig-tailwind-extra
123+
working-directory: "src/${{ matrix.component }}"
124+
119125
- name: ${{ matrix.component }} Tests
120126
working-directory: "src/${{ matrix.component }}"
121127
run: vendor/bin/simple-phpunit

src/Toolkit/composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@
4545
"symfony/http-client": "6.4|^7.0",
4646
"symfony/stopwatch": "^6.4|^7.0",
4747
"symfony/phpunit-bridge": "^6.4|^7.0",
48-
"vincentlanglet/twig-cs-fixer": "^3.5"
48+
"vincentlanglet/twig-cs-fixer": "^3.5",
49+
"spatie/phpunit-snapshot-assertions": "^4.2.17",
50+
"symfony/ux-icons": "^2.18"
4951
},
5052
"bin": [
5153
"bin/ux-toolkit-kit-create",

src/Toolkit/tests/Fixtures/Kernel.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,34 @@
1616
use Symfony\Bundle\TwigBundle\TwigBundle;
1717
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
1818
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
19+
use Symfony\UX\Icons\UXIconsBundle;
1920
use Symfony\UX\Toolkit\UXToolkitBundle;
2021
use Symfony\UX\TwigComponent\TwigComponentBundle;
22+
use TalesFromADev\Twig\Extra\Tailwind\Bridge\Symfony\Bundle\TalesFromADevTwigExtraTailwindBundle;
23+
use Twig\Extra\TwigExtraBundle\TwigExtraBundle;
2124

2225
final class Kernel extends BaseKernel
2326
{
2427
use MicroKernelTrait;
2528

2629
public function registerBundles(): iterable
2730
{
28-
return [
31+
$bundles = [
2932
new FrameworkBundle(),
3033
new TwigBundle(),
3134
new TwigComponentBundle(),
35+
new TwigExtraBundle(),
36+
new UXIconsBundle(),
3237
new UXToolkitBundle(),
3338
];
39+
40+
if (class_exists(TalesFromADevTwigExtraTailwindBundle::class)) {
41+
$bundles[] = new TalesFromADevTwigExtraTailwindBundle();
42+
} elseif (\PHP_VERSION_ID >= 80200) {
43+
throw new \RuntimeException('The dependency "tales-from-a-dev/twig-tailwind-extra" must be installed when using PHP 8.2+.');
44+
}
45+
46+
return $bundles;
3447
}
3548

3649
protected function configureContainer(ContainerConfigurator $container): void
@@ -69,6 +82,9 @@ protected function configureContainer(ContainerConfigurator $container): void
6982

7083
->alias('ux_toolkit.registry.registry_factory', '.ux_toolkit.registry.registry_factory')
7184
->public()
85+
86+
->alias('ux_toolkit.registry.local', '.ux_toolkit.registry.local')
87+
->public()
7288
;
7389
}
7490
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\UX\Toolkit\Tests\Functional;
13+
14+
use Spatie\Snapshots\Drivers\HtmlDriver;
15+
use Spatie\Snapshots\MatchesSnapshots;
16+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
17+
use Symfony\Component\Filesystem\Path;
18+
use Symfony\Component\Finder\Finder;
19+
use Symfony\UX\Toolkit\Asset\Component;
20+
use Symfony\UX\Toolkit\Kit\Kit;
21+
use Symfony\UX\Toolkit\Kit\KitFactory;
22+
use Symfony\UX\Toolkit\Registry\LocalRegistry;
23+
24+
class ComponentsRenderingTest extends WebTestCase
25+
{
26+
use MatchesSnapshots;
27+
28+
private const KITS_DIR = __DIR__.'/../../kits';
29+
30+
/**
31+
* @return iterable<string, string, string>
32+
*/
33+
public static function provideTestComponentRendering(): iterable
34+
{
35+
foreach (LocalRegistry::getAvailableKitsName() as $kitName) {
36+
$kitDir = Path::join(__DIR__, '../../kits', $kitName, 'docs/components');
37+
$docsFinder = (new Finder())->files()->name('*.md')->in($kitDir)->depth(0);
38+
39+
foreach ($docsFinder as $docFile) {
40+
$componentName = $docFile->getFilenameWithoutExtension();
41+
42+
$codeBlockMatchesResult = preg_match_all('/```twig.*?\n(?P<code>.+?)```/s', $docFile->getContents(), $codeBlockMatches);
43+
if (false === $codeBlockMatchesResult || 0 === $codeBlockMatchesResult) {
44+
throw new \RuntimeException(\sprintf('No Twig code blocks found in file "%s"', $docFile->getRelativePathname()));
45+
}
46+
47+
foreach ($codeBlockMatches['code'] as $i => $code) {
48+
yield \sprintf('Kit %s, component %s, code #%d', $kitName, $componentName, $i + 1) => [$kitName, $componentName, $code];
49+
}
50+
}
51+
}
52+
}
53+
54+
/**
55+
* @dataProvider provideTestComponentRendering
56+
*/
57+
public function testComponentRendering(string $kitName, string $componentName, string $code): void
58+
{
59+
$twig = self::getContainer()->get('twig');
60+
$kitContextRunner = self::getContainer()->get('ux_toolkit.kit.kit_context_runner');
61+
62+
$kit = $this->instantiateKit($kitName);
63+
$template = $twig->createTemplate($code);
64+
65+
try {
66+
$renderedCode = $kitContextRunner->runForKit($kit, fn () => $template->render());
67+
} catch (\Twig\Error\SyntaxError $e) {
68+
if (\PHP_VERSION < 80200 && str_contains($e->getMessage(), 'Unknown "tailwind_merge" filter')) {
69+
$this->markTestSkipped('Filter "tailwind_merge" is not supported on PHP <8.2.');
70+
}
71+
72+
throw $e;
73+
}
74+
75+
$this->assertCodeRenderedMatchesHtmlSnapshot($kit, $kit->getComponent($componentName), $code, $renderedCode);
76+
}
77+
78+
private function instantiateKit(string $kitName): Kit
79+
{
80+
$kitFactory = self::getContainer()->get('ux_toolkit.kit.kit_factory');
81+
82+
self::assertInstanceOf(KitFactory::class, $kitFactory);
83+
84+
return $kitFactory->createKitFromAbsolutePath(Path::join(__DIR__, '../../kits', $kitName));
85+
}
86+
87+
private function assertCodeRenderedMatchesHtmlSnapshot(Kit $kit, Component $component, string $code, string $renderedCode): void
88+
{
89+
$info = \sprintf(<<<HTML
90+
<!--
91+
- Kit: %s
92+
- Component: %s
93+
- Code:
94+
```twig
95+
%s
96+
```
97+
- Rendered code (prettified for testing purposes, run "php vendor/bin/phpunit -d --update-snapshots" to update snapshots): -->
98+
HTML,
99+
$kit->name,
100+
$component->name,
101+
trim($code)
102+
);
103+
104+
$this->assertMatchesSnapshot($renderedCode, new class($info) extends HtmlDriver {
105+
public function __construct(private string $info)
106+
{
107+
}
108+
109+
public function serialize($data): string
110+
{
111+
$serialized = parent::serialize($data);
112+
$serialized = str_replace(['<html><body>', '</body></html>'], '', $serialized);
113+
$serialized = trim($serialized);
114+
115+
return $this->info."\n".$serialized;
116+
}
117+
});
118+
}
119+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!--
2+
- Kit: Shadcn UI
3+
- Component: Alert
4+
- Code:
5+
```twig
6+
<twig:Alert class="max-w-lg">
7+
<twig:ux:icon name="tabler:terminal" class="h-4 w-4" />
8+
<twig:Alert:Title>Heads up!</twig:Alert:Title>
9+
<twig:Alert:Description>
10+
You can add components to your app using the cli.
11+
</twig:Alert:Description>
12+
</twig:Alert>
13+
```
14+
- Rendered code (prettified for testing purposes, run "php vendor/bin/phpunit -d --update-snapshots" to update snapshots): -->
15+
<div class="relative w-full rounded-lg border p-4 [&amp;&gt;svg~*]:pl-7 [&amp;&gt;svg+div]:translate-y-[-3px] [&amp;&gt;svg]:absolute [&amp;&gt;svg]:left-4 [&amp;&gt;svg]:top-4 [&amp;&gt;svg]:text-foreground bg-background text-foreground max-w-lg" role="alert">
16+
<svg xmlns="https://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="currentColor" class="h-4 w-4" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m5 7l5 5l-5 5m7 2h7"></path></svg>
17+
<h5 class="mb-1 font-medium leading-none tracking-tight ">Heads up!</h5>
18+
<p class="text-sm [&amp;_p]:leading-relaxed ">You can add components to your app using the cli.
19+
</p>
20+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!--
2+
- Kit: Shadcn UI
3+
- Component: Alert
4+
- Code:
5+
```twig
6+
<twig:Alert class="max-w-lg">
7+
<twig:ux:icon name="tabler:terminal" class="h-4 w-4" />
8+
<twig:Alert:Title>Heads up!</twig:Alert:Title>
9+
<twig:Alert:Description>
10+
You can add components to your app using the cli.
11+
</twig:Alert:Description>
12+
</twig:Alert>
13+
```
14+
- Rendered code (prettified for testing purposes, run "php vendor/bin/phpunit -d --update-snapshots" to update snapshots): -->
15+
<div class="relative w-full rounded-lg border p-4 [&amp;&gt;svg~*]:pl-7 [&amp;&gt;svg+div]:translate-y-[-3px] [&amp;&gt;svg]:absolute [&amp;&gt;svg]:left-4 [&amp;&gt;svg]:top-4 [&amp;&gt;svg]:text-foreground bg-background text-foreground max-w-lg" role="alert">
16+
<svg xmlns="https://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="currentColor" class="h-4 w-4" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m5 7l5 5l-5 5m7 2h7"></path></svg>
17+
<h5 class="mb-1 font-medium leading-none tracking-tight ">Heads up!</h5>
18+
<p class="text-sm [&amp;_p]:leading-relaxed ">You can add components to your app using the cli.
19+
</p>
20+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!--
2+
- Kit: Shadcn UI
3+
- Component: Alert
4+
- Code:
5+
```twig
6+
<twig:Alert variant="destructive" class="max-w-lg">
7+
<twig:ux:icon name="tabler:alert-circle" class="h-4 w-4" />
8+
<twig:Alert:Title>Error</twig:Alert:Title>
9+
<twig:Alert:Description>
10+
Your session has expired. Please log in again.
11+
</twig:Alert:Description>
12+
</twig:Alert>
13+
```
14+
- Rendered code (prettified for testing purposes, run "php vendor/bin/phpunit -d --update-snapshots" to update snapshots): -->
15+
<div class="relative w-full rounded-lg border p-4 [&amp;&gt;svg~*]:pl-7 [&amp;&gt;svg+div]:translate-y-[-3px] [&amp;&gt;svg]:absolute [&amp;&gt;svg]:left-4 [&amp;&gt;svg]:top-4 border-destructive/50 text-destructive dark:border-destructive [&amp;&gt;svg]:text-destructive max-w-lg" role="alert">
16+
<svg xmlns="https://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="currentColor" class="h-4 w-4" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0m9-4v4m0 4h.01"></path></svg>
17+
<h5 class="mb-1 font-medium leading-none tracking-tight ">Error</h5>
18+
<p class="text-sm [&amp;_p]:leading-relaxed ">Your session has expired. Please log in again.
19+
</p>
20+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!--
2+
- Kit: Shadcn UI
3+
- Component: AspectRatio
4+
- Code:
5+
```twig
6+
<twig:AspectRatio ratio="1 / 1" class="max-w-[300px]">
7+
<img
8+
src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&amp;dpr=2&amp;q=80"
9+
alt="Landscape photograph by Tobias Tullius"
10+
class="h-full w-full rounded-md object-cover"
11+
/>
12+
</twig:AspectRatio>
13+
```
14+
- Rendered code (prettified for testing purposes, run "php vendor/bin/phpunit -d --update-snapshots" to update snapshots): -->
15+
<div style="aspect-ratio: 1 / 1; " class="max-w-[300px]">
16+
<img src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&amp;dpr=2&amp;q=80" alt="Landscape photograph by Tobias Tullius" class="h-full w-full rounded-md object-cover">
17+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!--
2+
- Kit: Shadcn UI
3+
- Component: AspectRatio
4+
- Code:
5+
```twig
6+
<twig:AspectRatio ratio="1 / 1" class="max-w-[350px]">
7+
<img
8+
src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&amp;dpr=2&amp;q=80"
9+
alt="Landscape photograph by Tobias Tullius"
10+
class="h-full w-full rounded-md object-cover"
11+
/>
12+
</twig:AspectRatio>
13+
```
14+
- Rendered code (prettified for testing purposes, run "php vendor/bin/phpunit -d --update-snapshots" to update snapshots): -->
15+
<div style="aspect-ratio: 1 / 1; " class="max-w-[350px]">
16+
<img src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&amp;dpr=2&amp;q=80" alt="Landscape photograph by Tobias Tullius" class="h-full w-full rounded-md object-cover">
17+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!--
2+
- Kit: Shadcn UI
3+
- Component: AspectRatio
4+
- Code:
5+
```twig
6+
<twig:AspectRatio ratio="16 / 9" class="max-w-[350px]">
7+
<img
8+
src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&amp;dpr=2&amp;q=80"
9+
alt="Landscape photograph by Tobias Tullius"
10+
class="h-full w-full rounded-md object-cover"
11+
/>
12+
</twig:AspectRatio>
13+
```
14+
- Rendered code (prettified for testing purposes, run "php vendor/bin/phpunit -d --update-snapshots" to update snapshots): -->
15+
<div style="aspect-ratio: 16 / 9; " class="max-w-[350px]">
16+
<img src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&amp;dpr=2&amp;q=80" alt="Landscape photograph by Tobias Tullius" class="h-full w-full rounded-md object-cover">
17+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!--
2+
- Kit: Shadcn UI
3+
- Component: Avatar
4+
- Code:
5+
```twig
6+
<twig:Avatar>
7+
<twig:Avatar:Image src="https://github.com/symfony.png" alt="@symfony" />
8+
</twig:Avatar>
9+
```
10+
- Rendered code (prettified for testing purposes, run "php vendor/bin/phpunit -d --update-snapshots" to update snapshots): -->
11+
<span class="relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full "><img class="aspect-square h-full w-full " alt="@symfony" src="https://github.com/symfony.png">
12+
13+
</span>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!--
2+
- Kit: Shadcn UI
3+
- Component: Avatar
4+
- Code:
5+
```twig
6+
<twig:Avatar>
7+
<twig:Avatar:Image src="https://github.com/symfony.png" alt="@symfony" />
8+
</twig:Avatar>
9+
```
10+
- Rendered code (prettified for testing purposes, run "php vendor/bin/phpunit -d --update-snapshots" to update snapshots): -->
11+
<span class="relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full "><img class="aspect-square h-full w-full " alt="@symfony" src="https://github.com/symfony.png">
12+
13+
</span>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!--
2+
- Kit: Shadcn UI
3+
- Component: Avatar
4+
- Code:
5+
```twig
6+
<div class="flex gap-1">
7+
<twig:Avatar>
8+
<twig:Avatar:Text>FP</twig:Avatar:Text>
9+
</twig:Avatar>
10+
<twig:Avatar>
11+
<twig:Avatar:Text class="bg-red-500 text-red-50">FP</twig:Avatar:Text>
12+
</twig:Avatar>
13+
</div>
14+
```
15+
- Rendered code (prettified for testing purposes, run "php vendor/bin/phpunit -d --update-snapshots" to update snapshots): -->
16+
<div class="flex gap-1">
17+
<span class="relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full "><span class="flex h-full w-full items-center justify-center rounded-full bg-muted ">FP</span>
18+
</span>
19+
<span class="relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full "><span class="flex h-full w-full items-center justify-center rounded-full bg-muted bg-red-500 text-red-50">FP</span>
20+
</span>
21+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!--
2+
- Kit: Shadcn UI
3+
- Component: Avatar
4+
- Code:
5+
```twig
6+
<div class="flex -space-x-2">
7+
<twig:Avatar>
8+
<twig:Avatar:Image src="https://github.com/symfony.png" alt="@symfony" />
9+
</twig:Avatar>
10+
<twig:Avatar>
11+
<twig:Avatar:Text>FP</twig:Avatar:Text>
12+
</twig:Avatar>
13+
<twig:Avatar>
14+
<twig:Avatar:Text class="bg-red-500 text-red-50">FP</twig:Avatar:Text>
15+
</twig:Avatar>
16+
</div>
17+
```
18+
- Rendered code (prettified for testing purposes, run "php vendor/bin/phpunit -d --update-snapshots" to update snapshots): -->
19+
<div class="flex -space-x-2">
20+
<span class="relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full "><img class="aspect-square h-full w-full " alt="@symfony" src="https://github.com/symfony.png">
21+
22+
</span>
23+
<span class="relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full "><span class="flex h-full w-full items-center justify-center rounded-full bg-muted ">FP</span>
24+
</span>
25+
<span class="relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full "><span class="flex h-full w-full items-center justify-center rounded-full bg-muted bg-red-500 text-red-50">FP</span>
26+
</span>
27+
</div>

0 commit comments

Comments
 (0)