[TASK] Add unit tests for HtmlParser->splitIntoBlock()
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Html / HtmlParserTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Html;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Html\HtmlParser;
18
19 /**
20 * Testcase for \TYPO3\CMS\Core\Html\HtmlParser
21 */
22 class HtmlParserTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
23
24 /**
25 * @var \TYPO3\CMS\Core\Html\HtmlParser
26 */
27 protected $subject = NULL;
28
29 protected function setUp() {
30 $this->subject = new HtmlParser();
31 }
32
33 /**
34 * Data provider for getSubpart
35 *
36 * @return array
37 */
38 public function getSubpartDataProvider() {
39 return array(
40 'No start marker' => array(
41 '<body>text</body>',
42 '###SUBPART###',
43 ''
44 ),
45 'No stop marker' => array(
46 '<body>
47 <!-- ###SUBPART### Start -->
48 text
49 </body>',
50 '###SUBPART###',
51 ''
52 ),
53 'Start and stop marker in HTML comment' => array(
54 '<body>
55 <!-- ###SUBPART### Start -->
56 text
57 <!-- ###SUBPART### End -->
58 </body>',
59 '###SUBPART###',
60 '
61 text
62 '
63 ),
64 'Stop marker in HTML comment' => array(
65 '<body>
66 ###SUBPART###
67 text
68 <!-- ###SUBPART### End -->
69 </body>',
70 '###SUBPART###',
71 '
72 text
73 '
74 ),
75 'Start marker in HTML comment' => array(
76 '<body>
77 <!-- ###SUBPART### Start -->
78 text
79 ###SUBPART###
80 </body>',
81 '###SUBPART###',
82 '
83 text
84 '
85 ),
86 'Start and stop marker direct' => array(
87 '<body>
88 ###SUBPART###
89 text
90 ###SUBPART###
91 </body>',
92 '###SUBPART###',
93 '
94 text
95 '
96 ),
97 );
98 }
99
100 /**
101 * @test
102 * @param string $content
103 * @param string $marker
104 * @param string $expected
105 * @dataProvider getSubpartDataProvider
106 */
107 public function getSubpart($content, $marker, $expected) {
108 $this->assertSame($expected, HtmlParser::getSubpart($content, $marker));
109 }
110
111 /**
112 * Data provider for substituteSubpart
113 *
114 * @return array
115 */
116 public function substituteSubpartDataProvider() {
117 return array(
118 'No start marker' => array(
119 '<body>text</body>',
120 '###SUBPART###',
121 'hello',
122 FALSE,
123 FALSE,
124 '<body>text</body>'
125 ),
126 'No stop marker' => array(
127 '<body>
128 <!-- ###SUBPART### Start -->
129 text
130 </body>',
131 '###SUBPART###',
132 'hello',
133 FALSE,
134 FALSE,
135 '<body>
136 <!-- ###SUBPART### Start -->
137 text
138 </body>',
139 ),
140 'Start and stop marker in HTML comment' => array(
141 '<body>
142 <!-- ###SUBPART### Start -->
143 text
144 <!-- ###SUBPART### End -->
145 </body>',
146 '###SUBPART###',
147 'hello',
148 FALSE,
149 FALSE,
150 '<body>
151 hello
152 </body>'
153 ),
154 'Recursive subpart' => array(
155 '<body>
156 <!-- ###SUBPART### Start -->text1<!-- ###SUBPART### End -->
157 <!-- ###SUBPART### Start -->text2<!-- ###SUBPART### End -->
158 </body>',
159 '###SUBPART###',
160 'hello',
161 TRUE,
162 FALSE,
163 '<body>
164 hello
165 hello
166 </body>'
167 ),
168 'Keep HTML marker' => array(
169 '<body>
170 <!-- ###SUBPART### Start -->text<!-- ###SUBPART### End -->
171 </body>',
172 '###SUBPART###',
173 'hello',
174 FALSE,
175 TRUE,
176 '<body>
177 <!-- ###SUBPART### Start -->hello<!-- ###SUBPART### End -->
178 </body>'
179 ),
180 'Keep HTML begin marker' => array(
181 '<body>
182 <!-- ###SUBPART### Start -->text###SUBPART###
183 </body>',
184 '###SUBPART###',
185 'hello',
186 FALSE,
187 TRUE,
188 '<body>
189 <!-- ###SUBPART### Start -->hello###SUBPART###
190 </body>'
191 ),
192 'Keep HTML end marker' => array(
193 '<body>
194 ###SUBPART###text<!-- ###SUBPART### End -->
195 </body>',
196 '###SUBPART###',
197 'hello',
198 FALSE,
199 TRUE,
200 '<body>
201 ###SUBPART###hello<!-- ###SUBPART### End -->
202 </body>'
203 ),
204 'Keep plain marker' => array(
205 '<body>
206 ###SUBPART###text###SUBPART###
207 </body>',
208 '###SUBPART###',
209 'hello',
210 FALSE,
211 TRUE,
212 '<body>
213 ###SUBPART###hello###SUBPART###
214 </body>'
215 ),
216 'Wrap around' => array(
217 '<body>
218 ###SUBPART###text###SUBPART###
219 </body>',
220 '###SUBPART###',
221 array('before-', '-after'),
222 FALSE,
223 TRUE,
224 '<body>
225 ###SUBPART###before-text-after###SUBPART###
226 </body>'
227 ),
228 );
229 }
230
231 /**
232 * @test
233 * @param string $content
234 * @param string $marker
235 * @param array $subpartContent
236 * @param bool $recursive
237 * @param bool $keepMarker
238 * @param string $expected
239 * @dataProvider substituteSubpartDataProvider
240 */
241 public function substituteSubpart($content, $marker, $subpartContent, $recursive, $keepMarker, $expected) {
242 $this->assertSame($expected, HtmlParser::substituteSubpart($content, $marker, $subpartContent, $recursive, $keepMarker));
243 }
244
245 /**
246 * Data provider for substituteMarkerArray
247 */
248 public function substituteMarkerArrayDataProvider() {
249 return array(
250 'Upper case marker' => array(
251 'This is ###MARKER1### and this is ###MARKER2###',
252 array('###MARKER1###' => 'marker 1',
253 '###MARKER2###' => 'marker 2'),
254 '',
255 FALSE,
256 FALSE,
257 'This is marker 1 and this is marker 2'
258 ),
259 'Lower case marker' => array(
260 'This is ###MARKER1### and this is ###MARKER2###',
261 array('###marker1###' => 'marker 1',
262 '###marker2###' => 'marker 2'),
263 '',
264 TRUE,
265 FALSE,
266 'This is marker 1 and this is marker 2'
267 ),
268 'Upper case marker without hash mark' => array(
269 'This is ###MARKER1### and this is ###MARKER2###',
270 array('MARKER1' => 'marker 1',
271 'MARKER2' => 'marker 2'),
272 '###|###',
273 FALSE,
274 FALSE,
275 'This is marker 1 and this is marker 2'
276 ),
277 'Upper case marker with another hash mark' => array(
278 'This is *MARKER1* and this is *MARKER2*',
279 array('MARKER1' => 'marker 1',
280 'MARKER2' => 'marker 2'),
281 '*|*',
282 FALSE,
283 FALSE,
284 'This is marker 1 and this is marker 2'
285 ),
286 'Upper case marker with unused marker' => array(
287 'This is ###MARKER1### and this is ###MARKER2### ###UNUSED###',
288 array('###MARKER1###' => 'marker 1',
289 '###MARKER2###' => 'marker 2'),
290 '',
291 FALSE,
292 FALSE,
293 'This is marker 1 and this is marker 2 ###UNUSED###'
294 ),
295 'Upper case marker with unused marker deleted' => array(
296 'This is ###MARKER1### and this is ###MARKER2### ###UNUSED###',
297 array('###MARKER1###' => 'marker 1',
298 '###MARKER2###' => 'marker 2'),
299 '',
300 FALSE,
301 TRUE,
302 'This is marker 1 and this is marker 2 '
303 ),
304 );
305 }
306
307 /**
308 * @test
309 * @dataProvider substituteMarkerArrayDataProvider
310 * @param string $content The content stream, typically HTML template content.
311 * @param array $markContentArray The array of key/value pairs being marker/content values used in the substitution. For each element in this array the function will substitute a marker in the content stream with the content.
312 * @param string $wrap A wrap value - [part 1] | [part 2] - for the markers before substitution
313 * @param bool $uppercase If set, all marker string substitution is done with upper-case markers.
314 * @param bool $deleteUnused If set, all unused marker are deleted.
315 * @param string $expected
316 */
317 public function substituteMarkerArray($content, $markContentArray, $wrap, $uppercase, $deleteUnused, $expected) {
318 $this->assertSame($expected, HtmlParser::substituteMarkerArray($content, $markContentArray, $wrap, $uppercase, $deleteUnused));
319 }
320
321 /**
322 * Data provider for substituteMarker
323 */
324 public function substituteMarkerDataProvider() {
325 return array(
326 'Single marker' => array(
327 'This is a ###SAMPLE### text',
328 '###SAMPLE###',
329 'simple',
330 'This is a simple text'
331 ),
332 'Double marker' => array(
333 'This is a ###SAMPLE### text with a ###SAMPLE### content',
334 '###SAMPLE###',
335 'simple',
336 'This is a simple text with a simple content'
337 ),
338 );
339 }
340
341 /**
342 * @dataProvider substituteMarkerDataProvider
343 * @param string $content The content stream, typically HTML template content.
344 * @param string $marker The marker string, typically on the form "###[the marker string]###
345 * @param mixed $markContent The content to insert instead of the marker string found.
346 * @param string $expected The expected result of the substitution
347 */
348 public function substituteMarker($content, $marker, $markContent, $expected) {
349 $this->assertSame($expected, HtmlParser::substituteMarker($content, $marker, $markContent));
350 }
351
352 /**
353 * Data provider for substituteSubpartArray
354 *
355 * @return array
356 */
357 public function substituteSubpartArrayDataProvider() {
358 return array(
359 'Substitute multiple subparts at once with plain marker' => array(
360 '<body>
361 ###SUBPART1###text1###SUBPART1###
362 ###SUBPART2###text2###SUBPART2###
363 </body>',
364 array ('###SUBPART1###' => 'hello',
365 '###SUBPART2###' => 'world'),
366 '<body>
367 hello
368 world
369 </body>'
370 ),
371 );
372 }
373
374 /**
375 * @test
376 * @param string $content
377 * @param array $subpartsContent
378 * @param string $expected
379 * @dataProvider substituteSubpartArrayDataProvider
380 */
381 public function substituteSubpartArray($content, array $subpartsContent, $expected) {
382 $this->assertSame($expected, HtmlParser::substituteSubpartArray($content, $subpartsContent));
383 }
384
385 /**
386 * Data provider for substituteMarkerAndSubpartArrayRecursiveResolvesMarkersAndSubpartsArray
387 *
388 * @return array
389 */
390 public function substituteMarkerAndSubpartArrayRecursiveResolvesMarkersAndSubpartsArrayDataProvider() {
391 $template = '###SINGLEMARKER1###
392 <!-- ###FOO### begin -->
393 <!-- ###BAR### begin -->
394 ###SINGLEMARKER2###
395 <!-- ###BAR### end -->
396 <!-- ###FOOTER### begin -->
397 ###SINGLEMARKER3###
398 <!-- ###FOOTER### end -->
399 <!-- ###FOO### end -->';
400
401 $expected ='Value 1
402
403
404 Value 2.1
405
406 Value 2.2
407
408
409 Value 3.1
410
411 Value 3.2
412
413 ';
414
415 return array(
416 'Single marker' => array(
417 '###SINGLEMARKER###',
418 array(
419 '###SINGLEMARKER###' => 'Value 1'
420 ),
421 '',
422 FALSE,
423 FALSE,
424 'Value 1'
425 ),
426 'Subpart marker' => array(
427 $template,
428 array(
429 '###SINGLEMARKER1###' => 'Value 1',
430 '###FOO###' => array(
431 array(
432 '###BAR###' => array(
433 array(
434 '###SINGLEMARKER2###' => 'Value 2.1'
435 ),
436 array(
437 '###SINGLEMARKER2###' => 'Value 2.2'
438 )
439 ),
440 '###FOOTER###' => array(
441 array(
442 '###SINGLEMARKER3###' => 'Value 3.1'
443 ),
444 array(
445 '###SINGLEMARKER3###' => 'Value 3.2'
446 )
447 )
448 )
449 )
450 ),
451 '',
452 FALSE,
453 FALSE,
454 $expected
455 ),
456 'Subpart marker with wrap' => array(
457 $template,
458 array(
459 'SINGLEMARKER1' => 'Value 1',
460 'FOO' => array(
461 array(
462 'BAR' => array(
463 array(
464 'SINGLEMARKER2' => 'Value 2.1'
465 ),
466 array(
467 'SINGLEMARKER2' => 'Value 2.2'
468 )
469 ),
470 'FOOTER' => array(
471 array(
472 'SINGLEMARKER3' => 'Value 3.1'
473 ),
474 array(
475 'SINGLEMARKER3' => 'Value 3.2'
476 )
477 )
478 )
479 )
480 ),
481 '###|###',
482 FALSE,
483 FALSE,
484 $expected
485 ),
486 'Subpart marker with lower marker array keys' => array(
487 $template,
488 array(
489 '###singlemarker1###' => 'Value 1',
490 '###foo###' => array(
491 array(
492 '###bar###' => array(
493 array(
494 '###singlemarker2###' => 'Value 2.1'
495 ),
496 array(
497 '###singlemarker2###' => 'Value 2.2'
498 )
499 ),
500 '###footer###' => array(
501 array(
502 '###singlemarker3###' => 'Value 3.1'
503 ),
504 array(
505 '###singlemarker3###' => 'Value 3.2'
506 )
507 )
508 )
509 )
510 ),
511 '',
512 TRUE,
513 FALSE,
514 $expected
515 ),
516 'Subpart marker with unused markers' => array(
517 $template,
518 array(
519 '###FOO###' => array(
520 array(
521 '###BAR###' => array(
522 array(
523 '###SINGLEMARKER2###' => 'Value 2.1'
524 )
525 ),
526 '###FOOTER###' => array(
527 array(
528 '###SINGLEMARKER3###' => 'Value 3.1'
529 )
530 )
531 )
532 )
533 ),
534 '',
535 FALSE,
536 TRUE,
537 '
538
539
540 Value 2.1
541
542
543 Value 3.1
544
545 '
546 ),
547 'Subpart marker with empty subpart' => array(
548 $template,
549 array(
550 '###SINGLEMARKER1###' => 'Value 1',
551 '###FOO###' => array(
552 array(
553 '###BAR###' => array(
554 array(
555 '###SINGLEMARKER2###' => 'Value 2.1'
556 ),
557 array(
558 '###SINGLEMARKER2###' => 'Value 2.2'
559 )
560 ),
561 '###FOOTER###' => array()
562 )
563 )
564 ),
565 '',
566 FALSE,
567 FALSE,
568 'Value 1
569
570
571 Value 2.1
572
573 Value 2.2
574
575
576 '
577 )
578 );
579 }
580
581 /**
582 * @test
583 * @param string $template
584 * @param array $markersAndSubparts
585 * @param string $wrap
586 * @param bool $uppercase
587 * @param bool $deleteUnused
588 * @param string $expected
589 * @dataProvider substituteMarkerAndSubpartArrayRecursiveResolvesMarkersAndSubpartsArrayDataProvider
590 */
591 public function substituteMarkerAndSubpartArrayRecursiveResolvesMarkersAndSubpartsArray($template, $markersAndSubparts, $wrap, $uppercase, $deleteUnused, $expected) {
592 $this->assertSame($expected, HtmlParser::substituteMarkerAndSubpartArrayRecursive($template, $markersAndSubparts, $wrap, $uppercase, $deleteUnused));
593 }
594
595 /**
596 * @return array
597 */
598 public function cDataWillRemainUnmodifiedDataProvider() {
599 return array(
600 'single-line CDATA' => array(
601 '/*<![CDATA[*/ <hello world> /*]]>*/',
602 '/*<![CDATA[*/ <hello world> /*]]>*/',
603 ),
604 'multi-line CDATA #1' => array(
605 '/*<![CDATA[*/' . LF . '<hello world> /*]]>*/',
606 '/*<![CDATA[*/' . LF . '<hello world> /*]]>*/',
607 ),
608 'multi-line CDATA #2' => array(
609 '/*<![CDATA[*/ <hello world>' . LF . '/*]]>*/',
610 '/*<![CDATA[*/ <hello world>' . LF . '/*]]>*/',
611 ),
612 'multi-line CDATA #3' => array(
613 '/*<![CDATA[*/' . LF . '<hello world>' . LF . '/*]]>*/',
614 '/*<![CDATA[*/' . LF . '<hello world>' . LF . '/*]]>*/',
615 ),
616 );
617 }
618
619 /**
620 * Data provider for splitIntoBlock
621 *
622 * @return array
623 */
624 public function splitIntoBlockDataProvider() {
625 return array(
626 'splitBlock' => array(
627 'h1,span',
628 '<body><h1>Title</h1><span>Note</span></body>',
629 FALSE,
630 array('<body>',
631 '<h1>Title</h1>',
632 '',
633 '<span>Note</span>',
634 '</body>')
635 ),
636 'splitBlock br' => array(
637 'h1,span',
638 '<body><h1>Title</h1><br /><span>Note</span><br /></body>',
639 FALSE,
640 array('<body>',
641 '<h1>Title</h1>',
642 '<br />',
643 '<span>Note</span>',
644 '<br /></body>')
645 ),
646 'splitBlock with attribute' => array(
647 'h1,span',
648 '<body><h1 class="title">Title</h1><span>Note</span></body>',
649 FALSE,
650 array('<body>',
651 '<h1 class="title">Title</h1>',
652 '',
653 '<span>Note</span>',
654 '</body>')
655 ),
656 'splitBlock span with attribute' => array(
657 'span',
658 '<body><h1>Title</h1><span class="title">Note</span></body>',
659 FALSE,
660 array('<body><h1>Title</h1>',
661 '<span class="title">Note</span>',
662 '</body>')
663 ),
664 'splitBlock without extra end tags' => array(
665 'h1,span,div',
666 '<body><h1>Title</h1><span>Note</span></body></div>',
667 TRUE,
668 array('<body>',
669 '<h1>Title</h1>',
670 '',
671 '<span>Note</span>',
672 '</body>')
673 ),
674 );
675 }
676
677 /**
678 * @test
679 * @param string $tag List of tags, comma separated.
680 * @param string $content HTML-content
681 * @param bool $eliminateExtraEndTags If set, excessive end tags are ignored - you should probably set this in most cases.
682 * @param array $expected The expected result
683 * @dataProvider splitIntoBlockDataProvider
684 */
685 public function splitIntoBlock($tag, $content, $eliminateExtraEndTags, $expected) {
686 $this->assertSame($expected, $this->subject->splitIntoBlock($tag, $content, $eliminateExtraEndTags));
687 }
688
689 /**
690 * @test
691 * @param string $source
692 * @param string $expected
693 * @dataProvider cDataWillRemainUnmodifiedDataProvider
694 */
695 public function xHtmlCleaningDoesNotModifyCDATA($source, $expected) {
696 $result = $this->subject->XHTML_clean($source);
697 $this->assertSame($expected, $result);
698 }
699
700 /**
701 * Data provider for spanTagCorrectlyRemovedWhenRmTagIfNoAttribIsConfigured
702 */
703 public static function spanTagCorrectlyRemovedWhenRmTagIfNoAttribIsConfiguredDataProvider() {
704 return array(
705 'Span tag with no attrib' => array(
706 '<span>text</span>',
707 'text'
708 ),
709 'Span tag with allowed id attrib' => array(
710 '<span id="id">text</span>',
711 '<span id="id">text</span>'
712 ),
713 'Span tag with disallowed style attrib' => array(
714 '<span style="line-height: 12px;">text</span>',
715 'text'
716 )
717 );
718 }
719
720 /**
721 * @test
722 * @param string $content
723 * @param string $expectedResult
724 * @dataProvider spanTagCorrectlyRemovedWhenRmTagIfNoAttribIsConfiguredDataProvider
725 */
726 public function tagCorrectlyRemovedWhenRmTagIfNoAttribIsConfigured($content, $expectedResult) {
727 $tsConfig = array(
728 'allowTags' => 'span',
729 'tags.' => array(
730 'span.' => array(
731 'allowedAttribs' => 'id',
732 'rmTagIfNoAttrib' => 1
733 )
734 )
735 );
736 $this->assertEquals($expectedResult, $this->parseConfigAndCleanHtml($tsConfig, $content));
737 }
738
739 /**
740 * @test
741 */
742 public function rmTagIfNoAttribIsConfiguredDoesNotChangeNestingType() {
743 $tsConfig = array(
744 'allowTags' => 'div,span',
745 'rmTagIfNoAttrib' => 'span',
746 'globalNesting' => 'div,span'
747 );
748 $content = '<span></span><span id="test"><div></span></div>';
749 $expectedResult = '<span id="test"></span>';
750 $this->assertEquals($expectedResult, $this->parseConfigAndCleanHtml($tsConfig, $content));
751 }
752
753 /**
754 * Data provider for localNestingCorrectlyRemovesInvalidTags
755 *
756 * @return array
757 */
758 public static function localNestingCorrectlyRemovesInvalidTagsDataProvider() {
759 return array(
760 'Valid nesting is untouched' => array(
761 '<B><I></B></I>',
762 '<B><I></B></I>'
763 ),
764 'Valid nesting with content is untouched' => array(
765 'testa<B>test1<I>test2</B>test3</I>testb',
766 'testa<B>test1<I>test2</B>test3</I>testb'
767 ),
768 'Superflous tags are removed' => array(
769 '</B><B><I></B></I></B>',
770 '<B><I></B></I>'
771 ),
772 'Superflous tags with content are removed' => array(
773 'test1</B>test2<B>test3<I>test4</B>test5</I>test6</B>test7',
774 'test1test2<B>test3<I>test4</B>test5</I>test6test7'
775 ),
776 'Another valid nesting test' => array(
777 '<span><div></span></div>',
778 '<span><div></span></div>',
779 ),
780 );
781 }
782
783 /**
784 * @test
785 * @dataProvider localNestingCorrectlyRemovesInvalidTagsDataProvider
786 * @param string $content
787 * @param string $expectedResult
788 */
789 public function localNestingCorrectlyRemovesInvalidTags($content, $expectedResult) {
790 $tsConfig = array(
791 'allowTags' => 'div,span,b,i',
792 'localNesting' => 'div,span,b,i',
793 );
794 $this->assertEquals($expectedResult, $this->parseConfigAndCleanHtml($tsConfig, $content));
795 }
796
797 /**
798 * Data provider for globalNestingCorrectlyRemovesInvalidTags
799 *
800 * @return array
801 */
802 public static function globalNestingCorrectlyRemovesInvalidTagsDataProvider() {
803 return array(
804 'Valid nesting is untouched' => array(
805 '<B><I></I></B>',
806 '<B><I></I></B>'
807 ),
808 'Valid nesting with content is untouched' => array(
809 'testa<B>test1<I>test2</I>test3</B>testb',
810 'testa<B>test1<I>test2</I>test3</B>testb'
811 ),
812 'Invalid nesting is cleaned' => array(
813 '</B><B><I></B></I></B>',
814 '<B></B>'
815 ),
816 'Invalid nesting with content is cleaned' => array(
817 'test1</B>test2<B>test3<I>test4</B>test5</I>test6</B>test7',
818 'test1test2<B>test3test4</B>test5test6test7'
819 ),
820 'Another invalid nesting test' => array(
821 '<span><div></span></div>',
822 '<span></span>',
823 ),
824 );
825 }
826
827 /**
828 * @test
829 * @dataProvider globalNestingCorrectlyRemovesInvalidTagsDataProvider
830 * @param string $content
831 * @param string $expectedResult
832 */
833 public function globalNestingCorrectlyRemovesInvalidTags($content, $expectedResult) {
834 $tsConfig = array(
835 'allowTags' => 'span,div,b,i',
836 'globalNesting' => 'span,div,b,i',
837 );
838 $this->assertEquals($expectedResult, $this->parseConfigAndCleanHtml($tsConfig, $content));
839 }
840
841 /**
842 * @return array
843 */
844 public function emptyTagsDataProvider() {
845 return array(
846 array(0 , NULL, FALSE, '<h1></h1>', '<h1></h1>'),
847 array(1 , NULL, FALSE, '<h1></h1>', ''),
848 array(1 , NULL, FALSE, '<h1>hallo</h1>', '<h1>hallo</h1>'),
849 array(1 , NULL, FALSE, '<h1 class="something"></h1>', ''),
850 array(1 , NULL, FALSE, '<h1 class="something"></h1><h2></h2>', ''),
851 array(1 , 'h2', FALSE, '<h1 class="something"></h1><h2></h2>', '<h1 class="something"></h1>'),
852 array(1 , 'h2, h1', FALSE, '<h1 class="something"></h1><h2></h2>', ''),
853 array(1 , NULL, FALSE, '<div><p></p></div>', ''),
854 array(1 , NULL, FALSE, '<div><p>&nbsp;</p></div>', '<div><p>&nbsp;</p></div>'),
855 array(1 , NULL, TRUE, '<div><p>&nbsp;&nbsp;</p></div>', ''),
856 array(1 , NULL, TRUE, '<div>&nbsp;&nbsp;<p></p></div>', ''),
857 array(1 , NULL, FALSE, '<div>Some content<p></p></div>', '<div>Some content</div>'),
858 array(1 , NULL, TRUE, '<div>Some content<p></p></div>', '<div>Some content</div>'),
859 array(1 , NULL, FALSE, '<div>Some content</div>', '<div>Some content</div>'),
860 array(1 , NULL, TRUE, '<div>Some content</div>', '<div>Some content</div>'),
861 array(1 , NULL, FALSE, '<a href="#skiplinks">Skiplinks </a><b></b>', '<a href="#skiplinks">Skiplinks </a>'),
862 array(1 , NULL, TRUE, '<a href="#skiplinks">Skiplinks </a><b></b>', '<a href="#skiplinks">Skiplinks </a>'),
863 );
864 }
865
866 /**
867 * @test
868 * @dataProvider emptyTagsDataProvider
869 * @param bool $stripOn TRUE if stripping should be activated.
870 * @param string $tagList Comma seperated list of tags that should be stripped.
871 * @param bool $treatNonBreakingSpaceAsEmpty If TRUE &nbsp; will be considered empty.
872 * @param string $content The HTML code that should be modified.
873 * @param string $expectedResult The expected HTML code result.
874 */
875 public function stripEmptyTags($stripOn, $tagList, $treatNonBreakingSpaceAsEmpty, $content, $expectedResult) {
876 $tsConfig = array(
877 'keepNonMatchedTags' => 1,
878 'stripEmptyTags' => $stripOn,
879 'stripEmptyTags.' => array(
880 'tags' => $tagList,
881 'treatNonBreakingSpaceAsEmpty' => $treatNonBreakingSpaceAsEmpty
882 ),
883 );
884
885 $result = $this->parseConfigAndCleanHtml($tsConfig, $content);
886 $this->assertEquals($expectedResult, $result);
887 }
888
889 /**
890 * Calls HTMLparserConfig() and passes the generated config to the HTMLcleaner() method on the current subject.
891 *
892 * @param array $tsConfig The TypoScript that should be used to generate the HTML parser config.
893 * @param string $content The content that should be parsed by the HTMLcleaner.
894 * @return string The parsed content.
895 */
896 protected function parseConfigAndCleanHtml(array $tsConfig, $content) {
897 $config = $this->subject->HTMLparserConfig($tsConfig);
898 return $this->subject->HTMLcleaner($content, $config[0], $config[1], $config[2], $config[3]);
899 }
900
901 /**
902 * @return array
903 */
904 public function removeFirstAndLastTagDataProvider() {
905 return array(
906 array('<span>Wrapper<div>Some content</div></span>', 'Wrapper<div>Some content</div>'),
907 array('<td><tr>Some content</tr></td>', '<tr>Some content</tr>'),
908 array('Something before<span>Wrapper<div>Some content</div></span>Something after', 'Wrapper<div>Some content</div>'),
909 array('<span class="hidden">Wrapper<div>Some content</div></span>', 'Wrapper<div>Some content</div>'),
910 array('<span>Wrapper<div class="hidden">Some content</div></span>', 'Wrapper<div class="hidden">Some content</div>'),
911 );
912 }
913
914 /**
915 * Removes the first and last tag in the string
916 * Anything before the first and after the last tags respectively is also removed
917 *
918 * @test
919 * @dataProvider removeFirstAndLastTagDataProvider
920 * @param string $str String to process
921 * @param string $expectedResult
922 */
923 public function removeFirstAndLastTag($str, $expectedResult) {
924 $this->assertEquals($expectedResult, $this->subject->removeFirstAndLastTag($str));
925 }
926 }