‪TYPO3CMS  ‪main
MarkerBasedTemplateServiceTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use PHPUnit\Framework\Attributes\DataProvider;
21 use PHPUnit\Framework\Attributes\Test;
24 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
25 
29 final class ‪MarkerBasedTemplateServiceTest extends UnitTestCase
30 {
32 
33  protected bool ‪$resetSingletonInstances = true;
34 
35  protected function ‪setUp(): void
36  {
37  parent::setUp();
38  $cacheFrontendMock = $this->createMock(FrontendInterface::class);
39  $this->templateService = new ‪MarkerBasedTemplateService($cacheFrontendMock, $cacheFrontendMock);
40  }
41 
45  public static function ‪getSubpartDataProvider(): array
46  {
47  return [
48  'No start marker' => [
49  '<body>text</body>',
50  '###SUBPART###',
51  '',
52  ],
53  'No stop marker' => [
54  '<body>
55 <!-- ###SUBPART### Start -->
56 text
57 </body>',
58  '###SUBPART###',
59  '',
60  ],
61  'Start and stop marker in HTML comment' => [
62  '<body>
63 <!-- ###SUBPART### Start -->
64 text
65 <!-- ###SUBPART### End -->
66 </body>',
67  '###SUBPART###',
68  '
69 text
70 ',
71  ],
72  'Stop marker in HTML comment' => [
73  '<body>
74 ###SUBPART###
75 text
76 <!-- ###SUBPART### End -->
77 </body>',
78  '###SUBPART###',
79  '
80 text
81 ',
82  ],
83  'Start marker in HTML comment' => [
84  '<body>
85 <!-- ###SUBPART### Start -->
86 text
87 ###SUBPART###
88 </body>',
89  '###SUBPART###',
90  '
91 text
92 ',
93  ],
94  'Start and stop marker direct' => [
95  '<body>
96 ###SUBPART###
97 text
98 ###SUBPART###
99 </body>',
100  '###SUBPART###',
101  '
102 text
103 ',
104  ],
105  ];
106  }
107 
108  #[DataProvider('getSubpartDataProvider')]
109  #[Test]
110  public function ‪getSubpart(string $content, string $marker, string $expected): void
111  {
112  self::assertSame($expected, $this->templateService->getSubpart($content, $marker));
113  }
114 
118  public static function ‪substituteSubpartDataProvider(): array
119  {
120  return [
121  'No start marker' => [
122  '<body>text</body>',
123  '###SUBPART###',
124  'hello',
125  false,
126  false,
127  '<body>text</body>',
128  ],
129  'No stop marker' => [
130  '<body>
131 <!-- ###SUBPART### Start -->
132 text
133 </body>',
134  '###SUBPART###',
135  'hello',
136  false,
137  false,
138  '<body>
139 <!-- ###SUBPART### Start -->
140 text
141 </body>',
142  ],
143  'Start and stop marker in HTML comment' => [
144  '<body>
145 <!-- ###SUBPART### Start -->
146 text
147 <!-- ###SUBPART### End -->
148 </body>',
149  '###SUBPART###',
150  'hello',
151  false,
152  false,
153  '<body>
154 hello
155 </body>',
156  ],
157  'Recursive subpart' => [
158  '<body>
159 <!-- ###SUBPART### Start -->text1<!-- ###SUBPART### End -->
160 <!-- ###SUBPART### Start -->text2<!-- ###SUBPART### End -->
161 </body>',
162  '###SUBPART###',
163  'hello',
164  true,
165  false,
166  '<body>
167 hello
168 hello
169 </body>',
170  ],
171  'Keep HTML marker' => [
172  '<body>
173 <!-- ###SUBPART### Start -->text<!-- ###SUBPART### End -->
174 </body>',
175  '###SUBPART###',
176  'hello',
177  false,
178  true,
179  '<body>
180 <!-- ###SUBPART### Start -->hello<!-- ###SUBPART### End -->
181 </body>',
182  ],
183  'Keep HTML begin marker' => [
184  '<body>
185 <!-- ###SUBPART### Start -->text###SUBPART###
186 </body>',
187  '###SUBPART###',
188  'hello',
189  false,
190  true,
191  '<body>
192 <!-- ###SUBPART### Start -->hello###SUBPART###
193 </body>',
194  ],
195  'Keep HTML end marker' => [
196  '<body>
197 ###SUBPART###text<!-- ###SUBPART### End -->
198 </body>',
199  '###SUBPART###',
200  'hello',
201  false,
202  true,
203  '<body>
204 ###SUBPART###hello<!-- ###SUBPART### End -->
205 </body>',
206  ],
207  'Keep plain marker' => [
208  '<body>
209 ###SUBPART###text###SUBPART###
210 </body>',
211  '###SUBPART###',
212  'hello',
213  false,
214  true,
215  '<body>
216 ###SUBPART###hello###SUBPART###
217 </body>',
218  ],
219  'Wrap around' => [
220  '<body>
221 ###SUBPART###text###SUBPART###
222 </body>',
223  '###SUBPART###',
224  ['before-', '-after'],
225  false,
226  true,
227  '<body>
228 ###SUBPART###before-text-after###SUBPART###
229 </body>',
230  ],
231  ];
232  }
233 
237  #[DataProvider('substituteSubpartDataProvider')]
238  #[Test]
239  public function ‪substituteSubpart(
240  string $content,
241  string $marker,
242  $subpartContent,
243  bool $recursive,
244  bool $keepMarker,
245  string $expected
246  ): void {
247  self::assertSame(
248  $expected,
249  $this->templateService->substituteSubpart($content, $marker, $subpartContent, $recursive, $keepMarker)
250  );
251  }
252 
256  public static function ‪substituteMarkerArrayDataProvider(): array
257  {
258  return [
259  'Upper case marker' => [
260  'This is ###MARKER1### and this is ###MARKER2###',
261  [
262  '###MARKER1###' => 'marker 1',
263  '###MARKER2###' => 'marker 2',
264  ],
265  '',
266  false,
267  false,
268  'This is marker 1 and this is marker 2',
269  ],
270  'Lower case marker' => [
271  'This is ###MARKER1### and this is ###MARKER2###',
272  [
273  '###marker1###' => 'marker 1',
274  '###marker2###' => 'marker 2',
275  ],
276  '',
277  true,
278  false,
279  'This is marker 1 and this is marker 2',
280  ],
281  'Upper case marker without hash mark' => [
282  'This is ###MARKER1### and this is ###MARKER2###',
283  [
284  'MARKER1' => 'marker 1',
285  'MARKER2' => 'marker 2',
286  ],
287  '###|###',
288  false,
289  false,
290  'This is marker 1 and this is marker 2',
291  ],
292  'Upper case marker with another hash mark' => [
293  'This is *MARKER1* and this is *MARKER2*',
294  [
295  'MARKER1' => 'marker 1',
296  'MARKER2' => 'marker 2',
297  ],
298  '*|*',
299  false,
300  false,
301  'This is marker 1 and this is marker 2',
302  ],
303  'Upper case marker with unused marker' => [
304  'This is ###MARKER1### and this is ###MARKER2### ###UNUSED###',
305  [
306  '###MARKER1###' => 'marker 1',
307  '###MARKER2###' => 'marker 2',
308  ],
309  '',
310  false,
311  false,
312  'This is marker 1 and this is marker 2 ###UNUSED###',
313  ],
314  'Upper case marker with unused marker deleted' => [
315  'This is ###MARKER1### and this is ###MARKER2### ###UNUSED###',
316  [
317  '###MARKER1###' => 'marker 1',
318  '###MARKER2###' => 'marker 2',
319  ],
320  '',
321  false,
322  true,
323  'This is marker 1 and this is marker 2 ',
324  ],
325  ];
326  }
327 
335  #[DataProvider('substituteMarkerArrayDataProvider')]
336  #[Test]
337  public function ‪substituteMarkerArray(
338  string $content,
339  array $markContentArray,
340  string $wrap,
341  bool $uppercase,
342  bool $deleteUnused,
343  string $expected
344  ): void {
345  self::assertSame(
346  $expected,
347  $this->templateService->substituteMarkerArray($content, $markContentArray, $wrap, $uppercase, $deleteUnused)
348  );
349  }
350 
354  public static function ‪substituteMarkerDataProvider(): array
355  {
356  return [
357  'Single marker' => [
358  'This is a ###SAMPLE### text',
359  '###SAMPLE###',
360  'simple',
361  'This is a simple text',
362  ],
363  'Double marker' => [
364  'This is a ###SAMPLE### text with a ###SAMPLE### content',
365  '###SAMPLE###',
366  'simple',
367  'This is a simple text with a simple content',
368  ],
369  ];
370  }
371 
378  #[DataProvider('substituteMarkerDataProvider')]
379  public function ‪substituteMarker(string $content, string $marker, $markContent, string $expected): void
380  {
381  self::assertSame($expected, $this->templateService->substituteMarker($content, $marker, $markContent));
382  }
383 
387  public static function ‪substituteSubpartArrayDataProvider(): array
388  {
389  return [
390  'Substitute multiple subparts at once with plain marker' => [
391  '<body>
392 ###SUBPART1###text1###SUBPART1###
393 ###SUBPART2###text2###SUBPART2###
394 </body>',
395  [
396  '###SUBPART1###' => 'hello',
397  '###SUBPART2###' => 'world',
398  ],
399  '<body>
400 hello
401 world
402 </body>',
403  ],
404  ];
405  }
406 
407  #[DataProvider('substituteSubpartArrayDataProvider')]
408  #[Test]
409  public function ‪substituteSubpartArray(string $content, array $subpartsContent, string $expected): void
410  {
411  self::assertSame($expected, $this->templateService->substituteSubpartArray($content, $subpartsContent));
412  }
413 
418  {
419  $template = '###SINGLEMARKER1###
420 <!-- ###FOO### begin -->
421 <!-- ###BAR### begin -->
422 ###SINGLEMARKER2###
423 <!-- ###BAR### end -->
424 <!-- ###FOOTER### begin -->
425 ###SINGLEMARKER3###
426 <!-- ###FOOTER### end -->
427 <!-- ###FOO### end -->';
428 
429  $expected = 'Value 1
430 
431 
432 Value 2.1
433 
434 Value 2.2
435 
436 
437 Value 3.1
438 
439 Value 3.2
440 
441 ';
442 
443  return [
444  'Single marker' => [
445  '###SINGLEMARKER###',
446  [
447  '###SINGLEMARKER###' => 'Value 1',
448  ],
449  '',
450  false,
451  false,
452  'Value 1',
453  ],
454  'Subpart marker' => [
455  $template,
456  [
457  '###SINGLEMARKER1###' => 'Value 1',
458  '###FOO###' => [
459  [
460  '###BAR###' => [
461  [
462  '###SINGLEMARKER2###' => 'Value 2.1',
463  ],
464  [
465  '###SINGLEMARKER2###' => 'Value 2.2',
466  ],
467  ],
468  '###FOOTER###' => [
469  [
470  '###SINGLEMARKER3###' => 'Value 3.1',
471  ],
472  [
473  '###SINGLEMARKER3###' => 'Value 3.2',
474  ],
475  ],
476  ],
477  ],
478  ],
479  '',
480  false,
481  false,
482  $expected,
483  ],
484  'Subpart marker with wrap' => [
485  $template,
486  [
487  'SINGLEMARKER1' => 'Value 1',
488  'FOO' => [
489  [
490  'BAR' => [
491  [
492  'SINGLEMARKER2' => 'Value 2.1',
493  ],
494  [
495  'SINGLEMARKER2' => 'Value 2.2',
496  ],
497  ],
498  'FOOTER' => [
499  [
500  'SINGLEMARKER3' => 'Value 3.1',
501  ],
502  [
503  'SINGLEMARKER3' => 'Value 3.2',
504  ],
505  ],
506  ],
507  ],
508  ],
509  '###|###',
510  false,
511  false,
512  $expected,
513  ],
514  'Subpart marker with lower marker array keys' => [
515  $template,
516  [
517  '###singlemarker1###' => 'Value 1',
518  '###foo###' => [
519  [
520  '###bar###' => [
521  [
522  '###singlemarker2###' => 'Value 2.1',
523  ],
524  [
525  '###singlemarker2###' => 'Value 2.2',
526  ],
527  ],
528  '###footer###' => [
529  [
530  '###singlemarker3###' => 'Value 3.1',
531  ],
532  [
533  '###singlemarker3###' => 'Value 3.2',
534  ],
535  ],
536  ],
537  ],
538  ],
539  '',
540  true,
541  false,
542  $expected,
543  ],
544  'Subpart marker with unused markers' => [
545  $template,
546  [
547  '###FOO###' => [
548  [
549  '###BAR###' => [
550  [
551  '###SINGLEMARKER2###' => 'Value 2.1',
552  ],
553  ],
554  '###FOOTER###' => [
555  [
556  '###SINGLEMARKER3###' => 'Value 3.1',
557  ],
558  ],
559  ],
560  ],
561  ],
562  '',
563  false,
564  true,
565  '
566 
567 
568 Value 2.1
569 
570 
571 Value 3.1
572 
573 ',
574  ],
575  'Subpart marker with empty subpart' => [
576  $template,
577  [
578  '###SINGLEMARKER1###' => 'Value 1',
579  '###FOO###' => [
580  [
581  '###BAR###' => [
582  [
583  '###SINGLEMARKER2###' => 'Value 2.1',
584  ],
585  [
586  '###SINGLEMARKER2###' => 'Value 2.2',
587  ],
588  ],
589  '###FOOTER###' => [],
590  ],
591  ],
592  ],
593  '',
594  false,
595  false,
596  'Value 1
597 
598 
599 Value 2.1
600 
601 Value 2.2
602 
603 
604 ',
605  ],
606  ];
607  }
608 
609  #[DataProvider('substituteMarkerAndSubpartArrayRecursiveResolvesMarkersAndSubpartsArrayDataProvider')]
610  #[Test]
612  string $template,
613  array $markersAndSubparts,
614  string $wrap,
615  bool $uppercase,
616  bool $deleteUnused,
617  string $expected
618  ): void {
619  self::assertSame(
620  $expected,
621  $this->templateService->substituteMarkerAndSubpartArrayRecursive(
622  $template,
623  $markersAndSubparts,
624  $wrap,
625  $uppercase,
626  $deleteUnused
627  )
628  );
629  }
630 
632  {
633  return [
634  'no markers defined' => [
635  'dummy content with ###UNREPLACED### marker',
636  [],
637  [],
638  [],
639  'dummy content with ###UNREPLACED### marker',
640  ],
641  'no markers used' => [
642  'dummy content with no marker',
643  [
644  '###REPLACED###' => '_replaced_',
645  ],
646  [],
647  [],
648  'dummy content with no marker',
649  ],
650  'one marker' => [
651  'dummy content with ###REPLACED### marker',
652  [
653  '###REPLACED###' => '_replaced_',
654  ],
655  [],
656  [],
657  'dummy content with _replaced_ marker',
658  ],
659  'one marker with lots of chars' => [
660  'dummy content with ###RE.:##-=_()LACED### marker',
661  [
662  '###RE.:##-=_()LACED###' => '_replaced_',
663  ],
664  [],
665  [],
666  'dummy content with _replaced_ marker',
667  ],
668  'markers which are special' => [
669  'dummy ###aa##.#######A### ######',
670  [
671  '###aa##.###' => 'content ',
672  '###A###' => 'is',
673  '######' => '-is not considered-',
674  ],
675  [],
676  [],
677  'dummy content #is ######',
678  ],
679  'two markers in content, but more defined' => [
680  'dummy ###CONTENT### with ###REPLACED### marker',
681  [
682  '###REPLACED###' => '_replaced_',
683  '###CONTENT###' => 'content',
684  '###NEVERUSED###' => 'bar',
685  ],
686  [],
687  [],
688  'dummy content with _replaced_ marker',
689  ],
690  'one subpart' => [
691  'dummy content with ###ASUBPART### around some text###ASUBPART###.',
692  [],
693  [
694  '###ASUBPART###' => 'some other text',
695  ],
696  [],
697  'dummy content with some other text.',
698  ],
699  'one wrapped subpart' => [
700  'dummy content with ###AWRAPPEDSUBPART### around some text###AWRAPPEDSUBPART###.',
701  [],
702  [],
703  [
704  '###AWRAPPEDSUBPART###' => [
705  'more content',
706  'content',
707  ],
708  ],
709  'dummy content with more content around some textcontent.',
710  ],
711  'one subpart with markers, not replaced recursively' => [
712  'dummy ###CONTENT### with ###ASUBPART### around ###SOME### text###ASUBPART###.',
713  [
714  '###CONTENT###' => 'content',
715  '###SOME###' => '-this should never make it into output-',
716  '###OTHER_NOT_REPLACED###' => '-this should never make it into output-',
717  ],
718  [
719  '###ASUBPART###' => 'some ###OTHER_NOT_REPLACED### text',
720  ],
721  [],
722  'dummy content with some ###OTHER_NOT_REPLACED### text.',
723  ],
724  ];
725  }
726 
727  #[DataProvider('substituteMarkerArrayCachedReturnsExpectedContentDataProvider')]
728  #[Test]
730  string $content,
731  array $markContentArray,
732  array $subpartContentArray,
733  array $wrappedSubpartContentArray,
734  string $expectedContent
735  ): void {
736  $resultContent = $this->templateService->substituteMarkerArrayCached(
737  $content,
738  $markContentArray,
739  $subpartContentArray,
740  $wrappedSubpartContentArray
741  );
742  self::assertSame($expectedContent, $resultContent);
743  }
744 }
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\substituteMarkerArray
‪substituteMarkerArray(string $content, array $markContentArray, string $wrap, bool $uppercase, bool $deleteUnused, string $expected)
Definition: MarkerBasedTemplateServiceTest.php:337
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\$templateService
‪MarkerBasedTemplateService $templateService
Definition: MarkerBasedTemplateServiceTest.php:31
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\substituteMarkerArrayDataProvider
‪static substituteMarkerArrayDataProvider()
Definition: MarkerBasedTemplateServiceTest.php:256
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\substituteMarkerAndSubpartArrayRecursiveResolvesMarkersAndSubpartsArray
‪substituteMarkerAndSubpartArrayRecursiveResolvesMarkersAndSubpartsArray(string $template, array $markersAndSubparts, string $wrap, bool $uppercase, bool $deleteUnused, string $expected)
Definition: MarkerBasedTemplateServiceTest.php:611
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\setUp
‪setUp()
Definition: MarkerBasedTemplateServiceTest.php:35
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\substituteSubpartDataProvider
‪static substituteSubpartDataProvider()
Definition: MarkerBasedTemplateServiceTest.php:118
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\substituteMarkerDataProvider
‪static substituteMarkerDataProvider()
Definition: MarkerBasedTemplateServiceTest.php:354
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\getSubpartDataProvider
‪static getSubpartDataProvider()
Definition: MarkerBasedTemplateServiceTest.php:45
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\substituteMarkerAndSubpartArrayRecursiveResolvesMarkersAndSubpartsArrayDataProvider
‪static substituteMarkerAndSubpartArrayRecursiveResolvesMarkersAndSubpartsArrayDataProvider()
Definition: MarkerBasedTemplateServiceTest.php:417
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest
Definition: MarkerBasedTemplateServiceTest.php:30
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\substituteMarkerArrayCachedReturnsExpectedContentDataProvider
‪static substituteMarkerArrayCachedReturnsExpectedContentDataProvider()
Definition: MarkerBasedTemplateServiceTest.php:631
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\getSubpart
‪getSubpart(string $content, string $marker, string $expected)
Definition: MarkerBasedTemplateServiceTest.php:110
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\substituteSubpart
‪substituteSubpart(string $content, string $marker, $subpartContent, bool $recursive, bool $keepMarker, string $expected)
Definition: MarkerBasedTemplateServiceTest.php:239
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\substituteSubpartArrayDataProvider
‪static substituteSubpartArrayDataProvider()
Definition: MarkerBasedTemplateServiceTest.php:387
‪TYPO3\CMS\Core\Service\MarkerBasedTemplateService
Definition: MarkerBasedTemplateService.php:27
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\substituteMarkerArrayCachedReturnsExpectedContent
‪substituteMarkerArrayCachedReturnsExpectedContent(string $content, array $markContentArray, array $subpartContentArray, array $wrappedSubpartContentArray, string $expectedContent)
Definition: MarkerBasedTemplateServiceTest.php:729
‪TYPO3\CMS\Core\Tests\Unit\Service
Definition: DependencyOrderingServiceTest.php:18
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\substituteSubpartArray
‪substituteSubpartArray(string $content, array $subpartsContent, string $expected)
Definition: MarkerBasedTemplateServiceTest.php:409
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\$resetSingletonInstances
‪bool $resetSingletonInstances
Definition: MarkerBasedTemplateServiceTest.php:33
‪TYPO3\CMS\Core\Tests\Unit\Service\MarkerBasedTemplateServiceTest\substituteMarker
‪substituteMarker(string $content, string $marker, $markContent, string $expected)
Definition: MarkerBasedTemplateServiceTest.php:379