HtmlElementTest.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4. * This file is part of the league/commonmark package.
  5. *
  6. * (c) Colin O'Dell <colinodell@gmail.com>
  7. *
  8. * Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
  9. * - (c) John MacFarlane
  10. *
  11. * For the full copyright and license information, please view the LICENSE
  12. * file that was distributed with this source code.
  13. */
  14. namespace League\CommonMark\Tests\Unit\Util;
  15. use League\CommonMark\Util\HtmlElement;
  16. use PHPUnit\Framework\TestCase;
  17. final class HtmlElementTest extends TestCase
  18. {
  19. public function testConstructorOneArgument(): void
  20. {
  21. $p = new HtmlElement('p');
  22. $this->assertEquals('p', $p->getTagName());
  23. $this->assertEmpty($p->getAllAttributes());
  24. $this->assertEmpty($p->getContents());
  25. }
  26. public function testConstructorTwoArguments(): void
  27. {
  28. $img = new HtmlElement('img', ['src' => 'foo.jpg']);
  29. $this->assertEquals('img', $img->getTagName());
  30. $this->assertCount(1, $img->getAllAttributes());
  31. $this->assertEquals('foo.jpg', $img->getAttribute('src'));
  32. $this->assertEmpty($img->getContents());
  33. }
  34. public function testConstructorThreeArguments(): void
  35. {
  36. $li = new HtmlElement('li', ['class' => 'odd'], 'Foo');
  37. $this->assertEquals('li', $li->getTagName());
  38. $this->assertCount(1, $li->getAllAttributes());
  39. $this->assertEquals('odd', $li->getAttribute('class'));
  40. $this->assertEquals('Foo', $li->getContents());
  41. }
  42. public function testNonSelfClosingElement(): void
  43. {
  44. $p = new HtmlElement('p', [], '', false);
  45. $this->assertEquals('<p></p>', (string) $p);
  46. }
  47. public function testSelfClosingElement(): void
  48. {
  49. $hr = new HtmlElement('hr', [], '', true);
  50. $this->assertEquals('<hr />', (string) $hr);
  51. }
  52. public function testGetSetExistingAttribute(): void
  53. {
  54. $p = new HtmlElement('p', ['class' => 'foo']);
  55. $this->assertCount(1, $p->getAllAttributes());
  56. $this->assertEquals('foo', $p->getAttribute('class'));
  57. $p->setAttribute('class', 'bar');
  58. $this->assertCount(1, $p->getAllAttributes());
  59. $this->assertEquals('bar', $p->getAttribute('class'));
  60. }
  61. public function testGetSetNonExistingAttribute(): void
  62. {
  63. $p = new HtmlElement('p', ['class' => 'foo']);
  64. $this->assertCount(1, $p->getAllAttributes());
  65. $this->assertNull($p->getAttribute('id'));
  66. $p->setAttribute('id', 'bar');
  67. $this->assertCount(2, $p->getAllAttributes());
  68. $this->assertEquals('bar', $p->getAttribute('id'));
  69. $this->assertEquals('foo', $p->getAttribute('class'));
  70. }
  71. public function testGetSetAttributeWithStringAndArrayValues(): void
  72. {
  73. $p = new HtmlElement('p', ['class' => ['foo', 'bar']]);
  74. $this->assertCount(1, $p->getAllAttributes());
  75. $this->assertSame('foo bar', $p->getAttribute('class'));
  76. $p->setAttribute('class', 'baz');
  77. $this->assertSame('baz', $p->getAttribute('class'));
  78. $p->setAttribute('class', ['foo', 'bar', 'baz']);
  79. $this->assertSame('foo bar baz', $p->getAttribute('class'));
  80. $p->setAttribute('class', 'foo bar');
  81. $this->assertSame('foo bar', $p->getAttribute('class'));
  82. }
  83. public function testAttributesWithArrayValues(): void
  84. {
  85. $p = new HtmlElement('p', ['class' => ['a', 'b', 'a']]);
  86. $this->assertCount(1, $p->getAllAttributes());
  87. $this->assertSame('a b', $p->getAttribute('class'));
  88. $this->assertSame('<p class="a b"></p>', $p->__toString());
  89. $p->setAttribute('class', ['foo', 'bar', 'foo']);
  90. $this->assertSame('foo bar', $p->getAttribute('class'));
  91. $this->assertSame('<p class="foo bar"></p>', $p->__toString());
  92. // String attribute values do not have duplicate values removed
  93. $p->setAttribute('class', 'x y z x a');
  94. $this->assertSame('x y z x a', $p->getAttribute('class'));
  95. $this->assertSame('<p class="x y z x a"></p>', $p->__toString());
  96. }
  97. public function testAttributesWithBooleanTrueValues(): void
  98. {
  99. $checkbox = new HtmlElement('input', ['type' => 'checkbox', 'checked' => true], '', true);
  100. $this->assertSame('<input type="checkbox" checked>', $checkbox->__toString());
  101. $checkbox->setAttribute('checked', false);
  102. $this->assertSame('<input type="checkbox">', $checkbox->__toString());
  103. $checkbox->setAttribute('checked', true);
  104. $this->assertSame('<input type="checkbox" checked>', $checkbox->__toString());
  105. $checkbox->setAttribute('disabled'); // implicitly true
  106. $this->assertSame('<input type="checkbox" checked disabled>', $checkbox->__toString());
  107. }
  108. public function testToString(): void
  109. {
  110. $img = new HtmlElement('img', [], '', true);
  111. $p = new HtmlElement('p');
  112. $div = new HtmlElement('div');
  113. $div->setContents([$p, $img]);
  114. $this->assertIsString($div->getContents(true));
  115. $this->assertEquals('<p></p><img />', $div->getContents(true));
  116. $this->assertEquals('<div><p></p><img /></div>', $div->__toString());
  117. }
  118. public function testToStringWithUnescapedAttribute(): void
  119. {
  120. $element = new HtmlElement('p', ['id' => 'foo', 'class' => 'test" onclick="javascript:doBadThings();'], 'click me');
  121. $this->assertEquals('<p id="foo" class="test&quot; onclick=&quot;javascript:doBadThings();">click me</p>', $element->__toString());
  122. }
  123. public function testNullContentConstructor(): void
  124. {
  125. $img = new HtmlElement('img', [], null);
  126. $this->assertTrue($img->getContents(false) === '');
  127. }
  128. public function testNullContentSetter(): void
  129. {
  130. $img = new HtmlElement('img');
  131. $img->setContents(null);
  132. $this->assertTrue($img->getContents(false) === '');
  133. }
  134. /**
  135. * See https://github.com/thephpleague/commonmark/issues/376
  136. */
  137. public function testRegressionWith0NotBeingRendered(): void
  138. {
  139. $element = new HtmlElement('em');
  140. $element->setContents('0');
  141. $this->assertSame('0', $element->getContents());
  142. $element = new HtmlElement('em', [], '0');
  143. $this->assertSame('0', $element->getContents());
  144. }
  145. }