Skip to content

Commit 8c0ca89

Browse files
authored
Move property mock logic to Twig compiler (#42)
1 parent a4a2385 commit 8c0ca89

25 files changed

+329
-168
lines changed

composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@
3232
"symfony/css-selector": "^6.4|^7.0",
3333
"symfony/framework-bundle": "^6.4|^7.0",
3434
"symfony/phpunit-bridge": "^6.4|^7.0",
35-
"symfony/stimulus-bundle": "^2.16",
36-
"symfony/ux-live-component": "^2.16",
37-
"symfony/ux-twig-component": "2.16",
35+
"symfony/stimulus-bundle": "^2.21",
36+
"symfony/ux-live-component": "^2.21",
37+
"symfony/ux-twig-component": "^2.21",
3838
"symfonycasts/sass-bundle": "^0.5.1",
3939
"symfonycasts/tailwind-bundle": "^0.5.0"
4040
},

sandbox/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"symfony/stimulus-bundle": "^2.17",
2020
"symfony/twig-bundle": "7.0.*",
2121
"symfony/ux-live-component": "^2.17",
22-
"symfony/ux-twig-component": "2.16",
22+
"symfony/ux-twig-component": "^2.16",
2323
"symfony/yaml": "7.0.*",
2424
"twig/extra-bundle": "^2.12|^3.0",
2525
"twig/twig": "^2.12|^3.0"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
import ProductTable from './ProductTable.html.twig';
2+
import {twig} from "@sensiolabs/storybook-symfony-webpack5";
23

34
export default {
45
component: ProductTable,
56
};
67

78
export const Default = {
89
}
10+
11+
export const EmbeddedRender = {
12+
render: () => ({
13+
components: { ProductTable },
14+
template: twig`<twig:ProductTable></twig:ProductTable>`,
15+
}),
16+
}

src/DependencyInjection/StorybookExtension.php

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,26 @@
99
use Storybook\Command\StorybookInitCommand;
1010
use Storybook\Controller\StorybookController;
1111
use Storybook\DependencyInjection\Compiler\ComponentMockPass;
12-
use Storybook\EventListener\ComponentMockSubscriber;
1312
use Storybook\EventListener\ProxyRequestListener;
1413
use Storybook\Exception\UnauthorizedStoryException;
1514
use Storybook\Mock\ComponentProxyFactory;
1615
use Storybook\StoryRenderer;
16+
use Storybook\Twig\StorybookEnvironment;
1717
use Storybook\Twig\StorybookEnvironmentConfigurator;
18+
use Storybook\Twig\StoryExtension;
1819
use Storybook\Twig\TwigComponentSubscriber;
1920
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
2021
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
2122
use Symfony\Component\Config\Definition\ConfigurationInterface;
2223
use Symfony\Component\Config\Definition\Processor;
2324
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
25+
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
2426
use Symfony\Component\DependencyInjection\ChildDefinition;
2527
use Symfony\Component\DependencyInjection\ContainerBuilder;
2628
use Symfony\Component\DependencyInjection\Extension\Extension;
2729
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
2830
use Symfony\Component\DependencyInjection\Reference;
31+
use Twig\Extension\SandboxExtension;
2932
use Twig\Sandbox\SecurityPolicy;
3033

3134
/**
@@ -97,14 +100,35 @@ static function (ChildDefinition $definition, AsComponentMock $attributeInstance
97100
->setArgument(4, $sandboxConfig['allowedFunctions'])
98101
;
99102

103+
// Storybook Twig extensions
104+
$container->setDefinition('storybook.twig', new ChildDefinition('twig'))
105+
->setClass(StorybookEnvironment::class)
106+
->addMethodCall('setComponentRuntime', [new Reference('storybook.twig.component_runtime')])
107+
->setConfigurator([new Reference('storybook.twig.environment_configurator'), 'configure'])
108+
;
109+
110+
$container->register('storybook.twig.extension.sandbox', SandboxExtension::class)
111+
->setArgument(0, new Reference('storybook.twig.security_policy'))
112+
->addTag('storybook.twig.extension')
113+
;
114+
115+
$container->register('storybook.twig.extension.story', StoryExtension::class)
116+
->setArgument(0, new Reference('storybook.component_proxy_factory'))
117+
->addTag('storybook.twig.extension')
118+
;
119+
100120
$container->register('storybook.twig.environment_configurator', StorybookEnvironmentConfigurator::class)
101121
->setArgument(0, new Reference('twig.configurator.environment'))
102-
->setArgument(1, new Reference('storybook.twig.security_policy'))
122+
->setArgument(1, new TaggedIteratorArgument('storybook.twig.extension'))
103123
->setArgument(2, $config['cache'] ?? false)
104124
;
105125

106-
$container->setDefinition('storybook.twig', new ChildDefinition('twig'))
107-
->setConfigurator([new Reference('storybook.twig.environment_configurator'), 'configure'])
126+
$container->setDefinition('storybook.twig.component_runtime', new ChildDefinition('.ux.twig_component.twig.component_runtime'))
127+
->replaceArgument(0, new Reference('storybook.twig.component_renderer'))
128+
;
129+
130+
$container->setDefinition('storybook.twig.component_renderer', new ChildDefinition('ux.twig_component.component_renderer'))
131+
->replaceArgument(0, new Reference('storybook.twig'))
108132
;
109133

110134
$container->register('storybook.story_renderer', StoryRenderer::class)
@@ -135,10 +159,6 @@ static function (ChildDefinition $definition, AsComponentMock $attributeInstance
135159
->setArgument(0, new Reference('request_stack'))
136160
->setArgument(1, new Reference('event_dispatcher'))
137161
->addTag('kernel.event_subscriber');
138-
139-
$container->register('storybook.component_mock_subscriber', ComponentMockSubscriber::class)
140-
->setArgument(0, new Reference('storybook.component_proxy_factory'))
141-
->addTag('kernel.event_subscriber');
142162
}
143163

144164
public function getConfigTreeBuilder(): TreeBuilder

src/EventListener/ComponentMockSubscriber.php

Lines changed: 0 additions & 45 deletions
This file was deleted.

src/Mock/MockedPropertiesProxy.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
*/
1616
final class MockedPropertiesProxy
1717
{
18-
public function __construct(private readonly object $component, private readonly object $provider, private readonly array $mockedMethods)
19-
{
18+
public function __construct(
19+
private readonly object $component,
20+
private readonly object $provider,
21+
private readonly array $mockedMethods,
22+
) {
2023
}
2124

2225
public function __call(string $name, array $args)

src/StoryRenderer.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,10 @@ public function render(Story $story): string
2121
{
2222
$storyTemplateName = \sprintf('story_%s.html.twig', $story->getId());
2323

24-
// Name included template with a hash to avoid reusing an already loaded template class
25-
$templateName = \sprintf('%s.html.twig', hash('xxh128', $story->getTemplate()));
26-
2724
$loader = new ChainLoader([
2825
new ArrayLoader([
29-
$templateName => $story->getTemplate(),
30-
$storyTemplateName => \sprintf("{%% sandbox %%} {%%- include '%s' -%%} {%% endsandbox %%}", $templateName),
26+
$story->getTemplateName() => $story->getTemplate(),
27+
$storyTemplateName => \sprintf("{%% sandbox %%} {%%- include '%s' -%%} {%% endsandbox %%}", $story->getTemplateName()),
3128
]),
3229
$originalLoader = $this->twig->getLoader(),
3330
]);

src/Twig/Sandbox/Node/BypassCheckSecurityCallNode.php renamed to src/Twig/Node/BypassCheckSecurityCallNode.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?php
22

3-
namespace Storybook\Twig\Sandbox\Node;
3+
namespace Storybook\Twig\Node;
44

5+
use Twig\Attribute\YieldReady;
56
use Twig\Compiler;
67
use Twig\Node\Node;
78

@@ -12,7 +13,7 @@
1213
*
1314
* @internal
1415
*/
15-
// #[YieldReady]
16+
#[YieldReady]
1617
class BypassCheckSecurityCallNode extends Node
1718
{
1819
public function compile(Compiler $compiler): void

src/Twig/Node/MockContextNode.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Storybook\Twig\Node;
4+
5+
use Storybook\Twig\StoryExtension;
6+
use Twig\Attribute\YieldReady;
7+
use Twig\Compiler;
8+
use Twig\Node\Node;
9+
10+
/**
11+
* Mock context array with provided Storybook context helper if available.
12+
*
13+
* @author Nicolas Rigaud <squrious@protonmail.com>
14+
*
15+
* @internal
16+
*/
17+
#[YieldReady]
18+
final class MockContextNode extends Node
19+
{
20+
public function compile(Compiler $compiler): void
21+
{
22+
$storybookExtension = $compiler->getVarName();
23+
24+
$compiler
25+
->write('if (isset($context["__storybook"])) {')
26+
->raw("\n")
27+
->indent()
28+
->write(\sprintf('$%s = $this->env->getExtension(', $storybookExtension))
29+
->string(StoryExtension::class)
30+
->raw(");\n")
31+
->write(\sprintf('$%s->prepareContext($context);', $storybookExtension))
32+
->raw("\n")
33+
->outdent()
34+
->write('}')
35+
->raw("\n\n")
36+
;
37+
}
38+
}
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?php
22

3-
namespace Storybook\Twig\Sandbox\Node;
3+
namespace Storybook\Twig\Node;
44

5+
use Twig\Attribute\YieldReady;
56
use Twig\Compiler;
67
use Twig\Node\BodyNode;
78

@@ -12,12 +13,12 @@
1213
*
1314
* @internal
1415
*/
15-
// #[YieldReady]
16+
#[YieldReady]
1617
class SafeBodyNode extends BodyNode
1718
{
1819
public function __construct(BodyNode $body)
1920
{
20-
parent::__construct($body->nodes, $body->attributes, $body->lineno, $body->tag);
21+
parent::__construct($body->nodes, $body->attributes, $body->lineno);
2122
}
2223

2324
public function compile(Compiler $compiler): void

0 commit comments

Comments
 (0)