AssertHtmlTest.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  5. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  6. *
  7. * Licensed under The MIT License
  8. * For full copyright and license information, please see the LICENSE.txt
  9. * Redistributions of files must retain the above copyright notice.
  10. *
  11. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  12. * @link https://cakephp.org CakePHP(tm) Project
  13. * @since 3.0.0
  14. * @license https://opensource.org/licenses/mit-license.php MIT License
  15. */
  16. namespace Cake\Test\TestCase\TestSuite;
  17. use Cake\TestSuite\TestCase;
  18. use PHPUnit\Framework\ExpectationFailedException;
  19. /**
  20. * This class helps in indirectly testing the functionality of TestCase::assertHtml
  21. */
  22. class AssertHtmlTest extends TestCase
  23. {
  24. /**
  25. * Test whitespace after HTML tags
  26. */
  27. public function testAssertHtmlWhitespaceAfter(): void
  28. {
  29. $input = <<<HTML
  30. <div class="wrapper">
  31. <h4 class="widget-title">Popular tags
  32. <i class="i-icon"></i>
  33. </h4>
  34. </div>
  35. HTML;
  36. $pattern = [
  37. 'div' => ['class' => 'wrapper'],
  38. 'h4' => ['class' => 'widget-title'], 'Popular tags',
  39. 'i' => ['class' => 'i-icon'], '/i',
  40. '/h4',
  41. '/div',
  42. ];
  43. $this->assertHtml($pattern, $input);
  44. }
  45. /**
  46. * Test whitespace inside HTML tags
  47. */
  48. public function testAssertHtmlInnerWhitespace(): void
  49. {
  50. $input = <<<HTML
  51. <div class="widget">
  52. <div class="widget-content">
  53. A custom widget
  54. </div>
  55. </div>
  56. HTML;
  57. $expected = [
  58. ['div' => ['class' => 'widget']],
  59. ['div' => ['class' => 'widget-content']],
  60. 'A custom widget',
  61. '/div',
  62. '/div',
  63. ];
  64. $this->assertHtml($expected, $input);
  65. }
  66. /**
  67. * test assertHtml works with single and double quotes
  68. */
  69. public function testAssertHtmlQuoting(): void
  70. {
  71. $input = '<a href="/test.html" class="active">My link</a>';
  72. $pattern = [
  73. 'a' => ['href' => '/test.html', 'class' => 'active'],
  74. 'My link',
  75. '/a',
  76. ];
  77. $this->assertHtml($pattern, $input);
  78. $input = "<a href='/test.html' class='active'>My link</a>";
  79. $pattern = [
  80. 'a' => ['href' => '/test.html', 'class' => 'active'],
  81. 'My link',
  82. '/a',
  83. ];
  84. $this->assertHtml($pattern, $input);
  85. $input = "<a href='/test.html' class='active'>My link</a>";
  86. $pattern = [
  87. 'a' => ['href' => 'preg:/.*\.html/', 'class' => 'active'],
  88. 'My link',
  89. '/a',
  90. ];
  91. $this->assertHtml($pattern, $input);
  92. $input = '<span><strong>Text</strong></span>';
  93. $pattern = [
  94. '<span',
  95. '<strong',
  96. 'Text',
  97. '/strong',
  98. '/span',
  99. ];
  100. $this->assertHtml($pattern, $input);
  101. $input = "<span class='active'><strong>Text</strong></span>";
  102. $pattern = [
  103. 'span' => ['class'],
  104. '<strong',
  105. 'Text',
  106. '/strong',
  107. '/span',
  108. ];
  109. $this->assertHtml($pattern, $input);
  110. }
  111. /**
  112. * Test that assertHtml runs quickly.
  113. */
  114. public function testAssertHtmlRuntimeComplexity(): void
  115. {
  116. $pattern = [
  117. 'div' => [
  118. 'attr1' => 'val1',
  119. 'attr2' => 'val2',
  120. 'attr3' => 'val3',
  121. 'attr4' => 'val4',
  122. 'attr5' => 'val5',
  123. 'attr6' => 'val6',
  124. 'attr7' => 'val7',
  125. 'attr8' => 'val8',
  126. ],
  127. 'My div',
  128. '/div',
  129. ];
  130. $input = '<div attr8="val8" attr6="val6" attr4="val4" attr2="val2"' .
  131. ' attr1="val1" attr3="val3" attr5="val5" attr7="val7" />' .
  132. 'My div' .
  133. '</div>';
  134. $this->assertHtml($pattern, $input);
  135. }
  136. /**
  137. * test that assertHtml knows how to handle correct quoting.
  138. */
  139. public function testAssertHtmlQuotes(): void
  140. {
  141. $input = '<a href="/test.html" class="active">My link</a>';
  142. $pattern = [
  143. 'a' => ['href' => '/test.html', 'class' => 'active'],
  144. 'My link',
  145. '/a',
  146. ];
  147. $this->assertHtml($pattern, $input);
  148. $input = "<a href='/test.html' class='active'>My link</a>";
  149. $pattern = [
  150. 'a' => ['href' => '/test.html', 'class' => 'active'],
  151. 'My link',
  152. '/a',
  153. ];
  154. $this->assertHtml($pattern, $input);
  155. $input = "<a href='/test.html' class='active'>My link</a>";
  156. $pattern = [
  157. 'a' => ['href' => 'preg:/.*\.html/', 'class' => 'active'],
  158. 'My link',
  159. '/a',
  160. ];
  161. $this->assertHtml($pattern, $input);
  162. }
  163. /**
  164. * testNumericValuesInExpectationForAssertHtml
  165. */
  166. public function testNumericValuesInExpectationForAssertHtml(): void
  167. {
  168. $value = 220985;
  169. $input = '<p><strong>' . $value . '</strong></p>';
  170. $pattern = [
  171. '<p',
  172. '<strong',
  173. $value,
  174. '/strong',
  175. '/p',
  176. ];
  177. $this->assertHtml($pattern, $input);
  178. $input = '<p><strong>' . $value . '</strong></p><p><strong>' . $value . '</strong></p>';
  179. $pattern = [
  180. '<p',
  181. '<strong',
  182. $value,
  183. '/strong',
  184. '/p',
  185. '<p',
  186. '<strong',
  187. $value,
  188. '/strong',
  189. '/p',
  190. ];
  191. $this->assertHtml($pattern, $input);
  192. $input = '<p><strong>' . $value . '</strong></p><p id="' . $value . '"><strong>' . $value . '</strong></p>';
  193. $pattern = [
  194. '<p',
  195. '<strong',
  196. $value,
  197. '/strong',
  198. '/p',
  199. 'p' => ['id' => $value],
  200. '<strong',
  201. $value,
  202. '/strong',
  203. '/p',
  204. ];
  205. $this->assertHtml($pattern, $input);
  206. }
  207. /**
  208. * test assertions fail when attributes are wrong.
  209. */
  210. public function testBadAssertHtmlInvalidAttribute(): void
  211. {
  212. $input = '<a href="/test.html" class="active">My link</a>';
  213. $pattern = [
  214. 'a' => ['hRef' => '/test.html', 'clAss' => 'active'],
  215. 'My link2',
  216. '/a',
  217. ];
  218. try {
  219. $this->assertHtml($pattern, $input);
  220. $this->fail('Assertion should fail');
  221. } catch (ExpectationFailedException $e) {
  222. $this->assertStringContainsString(
  223. 'Attribute did not match. Was expecting Attribute `clAss` == `active`',
  224. $e->getMessage()
  225. );
  226. }
  227. }
  228. /**
  229. * test assertion failure on incomplete HTML
  230. */
  231. public function testBadAssertHtmlMissingTags(): void
  232. {
  233. $input = '<a href="/test.html" class="active">My link</a>';
  234. $pattern = [
  235. '<a' => ['href' => '/test.html', 'class' => 'active'],
  236. 'My link',
  237. '/a',
  238. ];
  239. try {
  240. $this->assertHtml($pattern, $input);
  241. } catch (ExpectationFailedException $e) {
  242. $this->assertStringContainsString(
  243. 'Item #1 / regex #0 failed: Open <a tag',
  244. $e->getMessage()
  245. );
  246. }
  247. }
  248. }