-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathSlotParameterTest.php
210 lines (188 loc) · 9.12 KB
/
SlotParameterTest.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
<?php
declare(strict_types=1);
namespace SMS\FluidComponents\Tests\Functional;
use SMS\FluidComponents\Exception\InvalidArgumentException;
use SMS\FluidComponents\Utility\ComponentLoader;
use TYPO3\CMS\Core\Http\ServerRequest;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters;
use TYPO3\CMS\Extbase\Mvc\Request;
use TYPO3\CMS\Fluid\View\TemplateView;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
class SlotParameterTest extends FunctionalTestCase
{
protected bool $initializeDatabase = false;
protected array $testExtensionsToLoad = [
'typo3conf/ext/fluid_components'
];
public function setUp(): void
{
parent::setUp();
$componentLoader = GeneralUtility::makeInstance(ComponentLoader::class);
$componentLoader->addNamespace(
'SMS\\FluidComponents\\Tests\\Fixtures\\Functional\\Components',
realpath(dirname(__FILE__) . '/../Fixtures/Functional/Components/')
);
}
public function renderDataProvider(): \Generator
{
// Check override order of slot content
yield 'parameter, named slot and tag content provided' => [
'<test:contentSlot content="from parameter"><fc:content>from named</fc:content>from children</test:contentSlot>',
"from parameter\n"
];
yield 'named slot and tag content provided' => [
'<test:contentSlot><fc:content>from named</fc:content>from children</test:contentSlot>',
"from named\n"
];
yield 'tag content provided' => [
'<test:contentSlot>from children</test:contentSlot>',
"from children\n"
];
// Check if different ways of providing slot content don't interfere between components
yield 'two component calls with tag content as slot value' => [
'<test:contentSlot><b>some html</b></test:contentSlot><test:contentSlot><b>other html</b></test:contentSlot>',
"<b>some html</b>\n<b>other html</b>\n"
];
yield 'two component calls with named slots' => [
'<test:contentSlot><fc:content><b>some html</b></fc:content></test:contentSlot><test:contentSlot><fc:content><b>other html</b></fc:content></test:contentSlot>',
"<b>some html</b>\n<b>other html</b>\n"
];
yield 'first component with tag content, second with named slot' => [
'<test:contentSlot><b>some html</b></test:contentSlot><test:contentSlot><fc:content><b>other html</b></fc:content></test:contentSlot>',
"<b>some html</b>\n<b>other html</b>\n"
];
yield 'first component with named slot, second with tag content' => [
'<test:contentSlot><fc:content><b>some html</b></fc:content></test:contentSlot><test:contentSlot><b>other html</b></test:contentSlot>',
"<b>some html</b>\n<b>other html</b>\n"
];
yield 'two nested component calls with named slots' => [
'<test:contentSlot><b>some html</b><test:contentSlot><fc:content><b>other html</b></fc:content></test:contentSlot></test:contentSlot>',
"<b>some html</b><b>other html</b>\n"
];
yield 'two different nested component calls with named slots' => [
'<test:contentSlot><fc:content><b>some html</b><test:twoSlotsAndContent><fc:content slot="slot1"><b>slot 1 html</b></fc:content><fc:content slot="slot2"><b>slot 2 html</b></fc:content>slot content</test:twoSlotsAndContent></fc:content></test:contentSlot>',
"<b>some html</b><b>slot 1 html</b>|<b>slot 2 html</b>|slot content\n"
];
// Check if slot object behaves correct for if statements
yield 'unspecified slot parameter' => [
'<test:slotParameterCheck />',
"undefined\n"
];
yield 'empty slot parameter' => [
'<test:slotParameterCheck slot="" />',
"undefined\n"
];
yield 'specified slot parameter' => [
'<test:slotParameterCheck slot="content" />',
"defined\n"
];
yield 'only whitespace as parameter value' => [
'<test:slotParameterCheck slot=" " />',
"defined\n"
];
// Check behavior of optional slot parameter
yield 'provide content to optional slot parameter' => [
'<test:optionalSlotParameter slot="content" />',
"content\n"
];
yield 'no error for optional slot parameter' => [
'<test:optionalSlotParameter />',
"\n"
];
// Check behavior of multiple slot parameters
yield 'component with two slots, ordered named slots' => [
'<test:TwoSlotsAndContent><fc:content slot="slot1">content in slot 1</fc:content><fc:content slot="slot2">content in slot 2</fc:content></test:TwoSlotsAndContent>',
"content in slot 1|content in slot 2|\n"
];
yield 'component with two slots, unordered named slots' => [
'<test:TwoSlotsAndContent><fc:content slot="slot2">content in slot 2</fc:content><fc:content slot="slot1">content in slot 1</fc:content></test:TwoSlotsAndContent>',
"content in slot 1|content in slot 2|\n"
];
yield 'component with two slots, unordered named slots with content slot' => [
'<test:TwoSlotsAndContent><fc:content slot="slot2">content in slot 2</fc:content><fc:content>some more content</fc:content><fc:content slot="slot1">content in slot 1</fc:content></test:TwoSlotsAndContent>',
"content in slot 1|content in slot 2|some more content\n"
];
yield 'component with two slots, unordered named slots with tag content' => [
'<test:TwoSlotsAndContent><fc:content slot="slot2">content in slot 2</fc:content><fc:content slot="slot1">content in slot 1</fc:content>some more content</test:TwoSlotsAndContent>',
"content in slot 1|content in slot 2|some more content\n"
];
}
/**
* @test
* @dataProvider renderDataProvider
*/
public function render(string $template, string $expected): void
{
$view = new TemplateView();
$view->getRenderingContext()->setRequest(
new Request(
(new ServerRequest)->withAttribute(
'extbase',
new ExtbaseRequestParameters
)
)
);
$view->getRenderingContext()->getViewHelperResolver()->addNamespace('fc', 'SMS\\FluidComponents\\ViewHelpers');
$view->getRenderingContext()->getViewHelperResolver()->addNamespace('test', 'SMS\\FluidComponents\\Tests\\Fixtures\\Functional\\Components');
$view->getRenderingContext()->getTemplatePaths()->setTemplateSource($template);
// Test without cache
self::assertSame($expected, $view->render());
// Test with cache
self::assertSame($expected, $view->render());
}
/**
* @test
*/
public function unspecifiedRequiredSlot(): void
{
$template = '<test:slotParameter />';
$view = new TemplateView();
$view->getRenderingContext()->setRequest(
new Request(
(new ServerRequest)->withAttribute(
'extbase',
new ExtbaseRequestParameters
)
)
);
$view->getRenderingContext()->getViewHelperResolver()->addNamespace('fc', 'SMS\\FluidComponents\\ViewHelpers');
$view->getRenderingContext()->getViewHelperResolver()->addNamespace('test', 'SMS\\FluidComponents\\Tests\\Fixtures\\Functional\\Components');
$view->getRenderingContext()->getTemplatePaths()->setTemplateSource($template);
// Test without cache
self::expectException(\InvalidArgumentException::class);
self::expectExceptionCode(1681728555);
$view->render();
// Test with cache
self::expectException(\InvalidArgumentException::class);
self::expectExceptionCode(1681728555);
$view->render();
}
/**
* @test
*/
public function undefinedSlot(): void
{
$template = '<test:slotParameter><fc:content slot="slot">content</fc:content><fc:content slot="invalidSlot">more content</fc:content></test:slotParameter>';
$view = new TemplateView();
$view->getRenderingContext()->setRequest(
new Request(
(new ServerRequest)->withAttribute(
'extbase',
new ExtbaseRequestParameters
)
)
);
$view->getRenderingContext()->getViewHelperResolver()->addNamespace('fc', 'SMS\\FluidComponents\\ViewHelpers');
$view->getRenderingContext()->getViewHelperResolver()->addNamespace('test', 'SMS\\FluidComponents\\Tests\\Fixtures\\Functional\\Components');
$view->getRenderingContext()->getTemplatePaths()->setTemplateSource($template);
// Test without cache
self::expectException(\InvalidArgumentException::class);
self::expectExceptionCode(1681832624);
$view->render();
// Test with cache
self::expectException(\InvalidArgumentException::class);
self::expectExceptionCode(1681832624);
$view->render();
}
}