PageRenderTime 44ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/core/modules/system/src/Tests/Theme/FunctionsTest.php

http://github.com/drupal/drupal
PHP | 518 lines | 397 code | 42 blank | 79 comment | 0 complexity | f9cd09ee1915d1c260de7c9f3d564dac MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. namespace Drupal\system\Tests\Theme;
  3. use Drupal\Component\Serialization\Json;
  4. use Drupal\Component\Utility\Html;
  5. use Drupal\Component\Utility\SafeMarkup;
  6. use Drupal\Core\Session\UserSession;
  7. use Drupal\Core\Url;
  8. use Drupal\simpletest\WebTestBase;
  9. /**
  10. * Tests for common theme functions.
  11. *
  12. * @group Theme
  13. */
  14. class FunctionsTest extends WebTestBase {
  15. /**
  16. * Modules to enable.
  17. *
  18. * @var array
  19. */
  20. public static $modules = array('router_test');
  21. /**
  22. * Tests item-list.html.twig.
  23. */
  24. function testItemList() {
  25. // Verify that empty items produce no output.
  26. $variables = array();
  27. $expected = '';
  28. $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback generates no output.');
  29. // Verify that empty items with title produce no output.
  30. $variables = array();
  31. $variables['title'] = 'Some title';
  32. $expected = '';
  33. $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback with title generates no output.');
  34. // Verify that empty items produce the empty string.
  35. $variables = array();
  36. $variables['empty'] = 'No items found.';
  37. $expected = '<div class="item-list">No items found.</div>';
  38. $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback generates empty string.');
  39. // Verify that empty items produce the empty string with title.
  40. $variables = array();
  41. $variables['title'] = 'Some title';
  42. $variables['empty'] = 'No items found.';
  43. $expected = '<div class="item-list"><h3>Some title</h3>No items found.</div>';
  44. $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback generates empty string with title.');
  45. // Verify that title set to 0 is output.
  46. $variables = array();
  47. $variables['title'] = 0;
  48. $variables['empty'] = 'No items found.';
  49. $expected = '<div class="item-list"><h3>0</h3>No items found.</div>';
  50. $this->assertThemeOutput('item_list', $variables, $expected, '%callback with title set to 0 generates a title.');
  51. // Verify that title set to a render array is output.
  52. $variables = array();
  53. $variables['title'] = array(
  54. '#markup' => '<span>Render array</span>',
  55. );
  56. $variables['empty'] = 'No items found.';
  57. $expected = '<div class="item-list"><h3><span>Render array</span></h3>No items found.</div>';
  58. $this->assertThemeOutput('item_list', $variables, $expected, '%callback with title set to a render array generates a title.');
  59. // Verify that empty text is not displayed when there are list items.
  60. $variables = array();
  61. $variables['title'] = 'Some title';
  62. $variables['empty'] = 'No items found.';
  63. $variables['items'] = array('Un', 'Deux', 'Trois');
  64. $expected = '<div class="item-list"><h3>Some title</h3><ul><li>Un</li><li>Deux</li><li>Trois</li></ul></div>';
  65. $this->assertThemeOutput('item_list', $variables, $expected, '%callback does not print empty text when there are list items.');
  66. // Verify nested item lists.
  67. $variables = array();
  68. $variables['title'] = 'Some title';
  69. $variables['attributes'] = array(
  70. 'id' => 'parentlist',
  71. );
  72. $variables['items'] = array(
  73. // A plain string value forms an own item.
  74. 'a',
  75. // Items can be fully-fledged render arrays with their own attributes.
  76. array(
  77. '#wrapper_attributes' => array(
  78. 'id' => 'item-id-b',
  79. ),
  80. '#markup' => 'b',
  81. 'childlist' => array(
  82. '#theme' => 'item_list',
  83. '#attributes' => array('id' => 'blist'),
  84. '#list_type' => 'ol',
  85. '#items' => array(
  86. 'ba',
  87. array(
  88. '#markup' => 'bb',
  89. '#wrapper_attributes' => array('class' => array('item-class-bb')),
  90. ),
  91. ),
  92. ),
  93. ),
  94. // However, items can also be child #items.
  95. array(
  96. '#markup' => 'c',
  97. 'childlist' => array(
  98. '#attributes' => array('id' => 'clist'),
  99. 'ca',
  100. array(
  101. '#markup' => 'cb',
  102. '#wrapper_attributes' => array('class' => array('item-class-cb')),
  103. 'children' => array(
  104. 'cba',
  105. 'cbb',
  106. ),
  107. ),
  108. 'cc',
  109. ),
  110. ),
  111. // Use #markup to be able to specify #wrapper_attributes.
  112. array(
  113. '#markup' => 'd',
  114. '#wrapper_attributes' => array('id' => 'item-id-d'),
  115. ),
  116. // An empty item with attributes.
  117. array(
  118. '#wrapper_attributes' => array('id' => 'item-id-e'),
  119. ),
  120. // Lastly, another plain string item.
  121. 'f',
  122. );
  123. $inner_b = '<div class="item-list"><ol id="blist">';
  124. $inner_b .= '<li>ba</li>';
  125. $inner_b .= '<li class="item-class-bb">bb</li>';
  126. $inner_b .= '</ol></div>';
  127. $inner_cb = '<div class="item-list"><ul>';
  128. $inner_cb .= '<li>cba</li>';
  129. $inner_cb .= '<li>cbb</li>';
  130. $inner_cb .= '</ul></div>';
  131. $inner_c = '<div class="item-list"><ul id="clist">';
  132. $inner_c .= '<li>ca</li>';
  133. $inner_c .= '<li class="item-class-cb">cb' . $inner_cb . '</li>';
  134. $inner_c .= '<li>cc</li>';
  135. $inner_c .= '</ul></div>';
  136. $expected = '<div class="item-list">';
  137. $expected .= '<h3>Some title</h3>';
  138. $expected .= '<ul id="parentlist">';
  139. $expected .= '<li>a</li>';
  140. $expected .= '<li id="item-id-b">b' . $inner_b . '</li>';
  141. $expected .= '<li>c' . $inner_c . '</li>';
  142. $expected .= '<li id="item-id-d">d</li>';
  143. $expected .= '<li id="item-id-e"></li>';
  144. $expected .= '<li>f</li>';
  145. $expected .= '</ul></div>';
  146. $this->assertThemeOutput('item_list', $variables, $expected);
  147. }
  148. /**
  149. * Tests links.html.twig.
  150. */
  151. function testLinks() {
  152. // Turn off the query for the
  153. // \Drupal\Core\Utility\LinkGeneratorInterface::generate() method to compare
  154. // the active link correctly.
  155. $original_query = \Drupal::request()->query->all();
  156. \Drupal::request()->query->replace(array());
  157. // Verify that empty variables produce no output.
  158. $variables = array();
  159. $expected = '';
  160. $this->assertThemeOutput('links', $variables, $expected, 'Empty %callback generates no output.');
  161. $variables = array();
  162. $variables['heading'] = 'Some title';
  163. $expected = '';
  164. $this->assertThemeOutput('links', $variables, $expected, 'Empty %callback with heading generates no output.');
  165. // Verify that a list of links is properly rendered.
  166. $variables = array();
  167. $variables['attributes'] = array('id' => 'somelinks');
  168. $variables['links'] = array(
  169. 'a link' => array(
  170. 'title' => 'A <link>',
  171. 'url' => Url::fromUri('base:a/link'),
  172. ),
  173. 'plain text' => array(
  174. 'title' => 'Plain "text"',
  175. ),
  176. 'html text' => array(
  177. 'title' => SafeMarkup::format('<span class="unescaped">@text</span>', array('@text' => 'potentially unsafe text that <should> be escaped')),
  178. ),
  179. 'front page' => array(
  180. 'title' => 'Front page',
  181. 'url' => Url::fromRoute('<front>'),
  182. ),
  183. 'router-test' => array(
  184. 'title' => 'Test route',
  185. 'url' => Url::fromRoute('router_test.1'),
  186. ),
  187. 'query-test' => array(
  188. 'title' => 'Query test route',
  189. 'url' => Url::fromRoute('router_test.1'),
  190. 'query' => array(
  191. 'key' => 'value',
  192. )
  193. ),
  194. );
  195. $expected_links = '';
  196. $expected_links .= '<ul id="somelinks">';
  197. $expected_links .= '<li class="a-link"><a href="' . Url::fromUri('base:a/link')->toString() . '">' . Html::escape('A <link>') . '</a></li>';
  198. $expected_links .= '<li class="plain-text">' . Html::escape('Plain "text"') . '</li>';
  199. $expected_links .= '<li class="html-text"><span class="unescaped">' . Html::escape('potentially unsafe text that <should> be escaped') . '</span></li>';
  200. $expected_links .= '<li class="front-page"><a href="' . Url::fromRoute('<front>')->toString() . '">' . Html::escape('Front page') . '</a></li>';
  201. $expected_links .= '<li class="router-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . Html::escape('Test route') . '</a></li>';
  202. $query = array('key' => 'value');
  203. $expected_links .= '<li class="query-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1', $query) . '">' . Html::escape('Query test route') . '</a></li>';
  204. $expected_links .= '</ul>';
  205. // Verify that passing a string as heading works.
  206. $variables['heading'] = 'Links heading';
  207. $expected_heading = '<h2>Links heading</h2>';
  208. $expected = $expected_heading . $expected_links;
  209. $this->assertThemeOutput('links', $variables, $expected);
  210. // Restore the original request's query.
  211. \Drupal::request()->query->replace($original_query);
  212. // Verify that passing an array as heading works (core support).
  213. $variables['heading'] = array(
  214. 'text' => 'Links heading',
  215. 'level' => 'h3',
  216. 'attributes' => array('class' => array('heading')),
  217. );
  218. $expected_heading = '<h3 class="heading">Links heading</h3>';
  219. $expected = $expected_heading . $expected_links;
  220. $this->assertThemeOutput('links', $variables, $expected);
  221. // Verify that passing attributes for the heading works.
  222. $variables['heading'] = array('text' => 'Links heading', 'level' => 'h3', 'attributes' => array('id' => 'heading'));
  223. $expected_heading = '<h3 id="heading">Links heading</h3>';
  224. $expected = $expected_heading . $expected_links;
  225. $this->assertThemeOutput('links', $variables, $expected);
  226. // Verify that passing attributes for the links work.
  227. $variables['links']['plain text']['attributes'] = array(
  228. 'class' => array('a/class'),
  229. );
  230. $expected_links = '';
  231. $expected_links .= '<ul id="somelinks">';
  232. $expected_links .= '<li class="a-link"><a href="' . Url::fromUri('base:a/link')->toString() . '">' . Html::escape('A <link>') . '</a></li>';
  233. $expected_links .= '<li class="plain-text"><span class="a/class">' . Html::escape('Plain "text"') . '</span></li>';
  234. $expected_links .= '<li class="html-text"><span class="unescaped">' . Html::escape('potentially unsafe text that <should> be escaped') . '</span></li>';
  235. $expected_links .= '<li class="front-page"><a href="' . Url::fromRoute('<front>')->toString() . '">' . Html::escape('Front page') . '</a></li>';
  236. $expected_links .= '<li class="router-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . Html::escape('Test route') . '</a></li>';
  237. $query = array('key' => 'value');
  238. $expected_links .= '<li class="query-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1', $query) . '">' . Html::escape('Query test route') . '</a></li>';
  239. $expected_links .= '</ul>';
  240. $expected = $expected_heading . $expected_links;
  241. $this->assertThemeOutput('links', $variables, $expected);
  242. // Verify the data- attributes for setting the "active" class on links.
  243. \Drupal::currentUser()->setAccount(new UserSession(array('uid' => 1)));
  244. $variables['set_active_class'] = TRUE;
  245. $expected_links = '';
  246. $expected_links .= '<ul id="somelinks">';
  247. $expected_links .= '<li class="a-link"><a href="' . Url::fromUri('base:a/link')->toString() . '">' . Html::escape('A <link>') . '</a></li>';
  248. $expected_links .= '<li class="plain-text"><span class="a/class">' . Html::escape('Plain "text"') . '</span></li>';
  249. $expected_links .= '<li class="html-text"><span class="unescaped">' . Html::escape('potentially unsafe text that <should> be escaped') . '</span></li>';
  250. $expected_links .= '<li data-drupal-link-system-path="&lt;front&gt;" class="front-page"><a href="' . Url::fromRoute('<front>')->toString() . '" data-drupal-link-system-path="&lt;front&gt;">' . Html::escape('Front page') . '</a></li>';
  251. $expected_links .= '<li data-drupal-link-system-path="router_test/test1" class="router-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '" data-drupal-link-system-path="router_test/test1">' . Html::escape('Test route') . '</a></li>';
  252. $query = array('key' => 'value');
  253. $encoded_query = Html::escape(Json::encode($query));
  254. $expected_links .= '<li data-drupal-link-query="' . $encoded_query . '" data-drupal-link-system-path="router_test/test1" class="query-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1', $query) . '" data-drupal-link-query="' . $encoded_query . '" data-drupal-link-system-path="router_test/test1">' . Html::escape('Query test route') . '</a></li>';
  255. $expected_links .= '</ul>';
  256. $expected = $expected_heading . $expected_links;
  257. $this->assertThemeOutput('links', $variables, $expected);
  258. }
  259. /**
  260. * Tests links.html.twig using links with indexed keys.
  261. */
  262. function testIndexedKeyedLinks() {
  263. // Turn off the query for the
  264. // \Drupal\Core\Utility\LinkGeneratorInterface::generate() method to compare
  265. // the active link correctly.
  266. $original_query = \Drupal::request()->query->all();
  267. \Drupal::request()->query->replace([]);
  268. // Verify that empty variables produce no output.
  269. $variables = [];
  270. $expected = '';
  271. $this->assertThemeOutput('links', $variables, $expected, 'Empty %callback generates no output.');
  272. $variables = [];
  273. $variables['heading'] = 'Some title';
  274. $expected = '';
  275. $this->assertThemeOutput('links', $variables, $expected, 'Empty %callback with heading generates no output.');
  276. // Verify that a list of links is properly rendered.
  277. $variables = [];
  278. $variables['attributes'] = ['id' => 'somelinks'];
  279. $variables['links'] = array(
  280. array(
  281. 'title' => 'A <link>',
  282. 'url' => Url::fromUri('base:a/link'),
  283. ),
  284. array(
  285. 'title' => 'Plain "text"',
  286. ),
  287. array(
  288. 'title' => SafeMarkup::format('<span class="unescaped">@text</span>', array('@text' => 'potentially unsafe text that <should> be escaped')),
  289. ),
  290. array(
  291. 'title' => 'Front page',
  292. 'url' => Url::fromRoute('<front>'),
  293. ),
  294. array(
  295. 'title' => 'Test route',
  296. 'url' => Url::fromRoute('router_test.1'),
  297. ),
  298. array(
  299. 'title' => 'Query test route',
  300. 'url' => Url::fromRoute('router_test.1'),
  301. 'query' => array(
  302. 'key' => 'value',
  303. )
  304. ),
  305. );
  306. $expected_links = '';
  307. $expected_links .= '<ul id="somelinks">';
  308. $expected_links .= '<li><a href="' . Url::fromUri('base:a/link')->toString() . '">' . Html::escape('A <link>') . '</a></li>';
  309. $expected_links .= '<li>' . Html::escape('Plain "text"') . '</li>';
  310. $expected_links .= '<li><span class="unescaped">' . Html::escape('potentially unsafe text that <should> be escaped') . '</span></li>';
  311. $expected_links .= '<li><a href="' . Url::fromRoute('<front>')->toString() . '">' . Html::escape('Front page') . '</a></li>';
  312. $expected_links .= '<li><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . Html::escape('Test route') . '</a></li>';
  313. $query = ['key' => 'value'];
  314. $expected_links .= '<li><a href="' . \Drupal::urlGenerator()->generate('router_test.1', $query) . '">' . Html::escape('Query test route') . '</a></li>';
  315. $expected_links .= '</ul>';
  316. // Verify that passing a string as heading works.
  317. $variables['heading'] = 'Links heading';
  318. $expected_heading = '<h2>Links heading</h2>';
  319. $expected = $expected_heading . $expected_links;
  320. $this->assertThemeOutput('links', $variables, $expected);
  321. // Restore the original request's query.
  322. \Drupal::request()->query->replace($original_query);
  323. // Verify that passing an array as heading works (core support).
  324. $variables['heading'] = [
  325. 'text' => 'Links heading',
  326. 'level' => 'h3',
  327. 'attributes' => ['class' => ['heading']],
  328. ];
  329. $expected_heading = '<h3 class="heading">Links heading</h3>';
  330. $expected = $expected_heading . $expected_links;
  331. $this->assertThemeOutput('links', $variables, $expected);
  332. // Verify that passing attributes for the heading works.
  333. $variables['heading'] = ['text' => 'Links heading', 'level' => 'h3', 'attributes' => ['id' => 'heading']];
  334. $expected_heading = '<h3 id="heading">Links heading</h3>';
  335. $expected = $expected_heading . $expected_links;
  336. $this->assertThemeOutput('links', $variables, $expected);
  337. // Verify that passing attributes for the links work.
  338. $variables['links'][1]['attributes'] = [
  339. 'class' => ['a/class'],
  340. ];
  341. $expected_links = '';
  342. $expected_links .= '<ul id="somelinks">';
  343. $expected_links .= '<li><a href="' . Url::fromUri('base:a/link')->toString() . '">' . Html::escape('A <link>') . '</a></li>';
  344. $expected_links .= '<li><span class="a/class">' . Html::escape('Plain "text"') . '</span></li>';
  345. $expected_links .= '<li><span class="unescaped">' . Html::escape('potentially unsafe text that <should> be escaped') . '</span></li>';
  346. $expected_links .= '<li><a href="' . Url::fromRoute('<front>')->toString() . '">' . Html::escape('Front page') . '</a></li>';
  347. $expected_links .= '<li><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . Html::escape('Test route') . '</a></li>';
  348. $query = ['key' => 'value'];
  349. $expected_links .= '<li><a href="' . \Drupal::urlGenerator()->generate('router_test.1', $query) . '">' . Html::escape('Query test route') . '</a></li>';
  350. $expected_links .= '</ul>';
  351. $expected = $expected_heading . $expected_links;
  352. $this->assertThemeOutput('links', $variables, $expected);
  353. // Verify the data- attributes for setting the "active" class on links.
  354. \Drupal::currentUser()->setAccount(new UserSession(array('uid' => 1)));
  355. $variables['set_active_class'] = TRUE;
  356. $expected_links = '';
  357. $expected_links .= '<ul id="somelinks">';
  358. $expected_links .= '<li><a href="' . Url::fromUri('base:a/link')->toString() . '">' . Html::escape('A <link>') . '</a></li>';
  359. $expected_links .= '<li><span class="a/class">' . Html::escape('Plain "text"') . '</span></li>';
  360. $expected_links .= '<li><span class="unescaped">' . Html::escape('potentially unsafe text that <should> be escaped') . '</span></li>';
  361. $expected_links .= '<li data-drupal-link-system-path="&lt;front&gt;"><a href="' . Url::fromRoute('<front>')->toString() . '" data-drupal-link-system-path="&lt;front&gt;">' . Html::escape('Front page') . '</a></li>';
  362. $expected_links .= '<li data-drupal-link-system-path="router_test/test1"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '" data-drupal-link-system-path="router_test/test1">' . Html::escape('Test route') . '</a></li>';
  363. $query = ['key' => 'value'];
  364. $encoded_query = Html::escape(Json::encode($query));
  365. $expected_links .= '<li data-drupal-link-query="' . $encoded_query . '" data-drupal-link-system-path="router_test/test1"><a href="' . \Drupal::urlGenerator()->generate('router_test.1', $query) . '" data-drupal-link-query="' . $encoded_query . '" data-drupal-link-system-path="router_test/test1">' . Html::escape('Query test route') . '</a></li>';
  366. $expected_links .= '</ul>';
  367. $expected = $expected_heading . $expected_links;
  368. $this->assertThemeOutput('links', $variables, $expected);
  369. }
  370. /**
  371. * Test the use of drupal_pre_render_links() on a nested array of links.
  372. */
  373. function testDrupalPreRenderLinks() {
  374. // Define the base array to be rendered, containing a variety of different
  375. // kinds of links.
  376. $base_array = array(
  377. '#theme' => 'links',
  378. '#pre_render' => array('drupal_pre_render_links'),
  379. '#links' => array(
  380. 'parent_link' => array(
  381. 'title' => 'Parent link original',
  382. 'url' => Url::fromRoute('router_test.1'),
  383. ),
  384. ),
  385. 'first_child' => array(
  386. '#theme' => 'links',
  387. '#links' => array(
  388. // This should be rendered if 'first_child' is rendered separately,
  389. // but ignored if the parent is being rendered (since it duplicates
  390. // one of the parent's links).
  391. 'parent_link' => array(
  392. 'title' => 'Parent link copy',
  393. 'url' => Url::fromRoute('router_test.6'),
  394. ),
  395. // This should always be rendered.
  396. 'first_child_link' => array(
  397. 'title' => 'First child link',
  398. 'url' => Url::fromRoute('router_test.7'),
  399. ),
  400. ),
  401. ),
  402. // This should always be rendered as part of the parent.
  403. 'second_child' => array(
  404. '#theme' => 'links',
  405. '#links' => array(
  406. 'second_child_link' => array(
  407. 'title' => 'Second child link',
  408. 'url' => Url::fromRoute('router_test.8'),
  409. ),
  410. ),
  411. ),
  412. // This should never be rendered, since the user does not have access to
  413. // it.
  414. 'third_child' => array(
  415. '#theme' => 'links',
  416. '#links' => array(
  417. 'third_child_link' => array(
  418. 'title' => 'Third child link',
  419. 'url' => Url::fromRoute('router_test.9'),
  420. ),
  421. ),
  422. '#access' => FALSE,
  423. ),
  424. );
  425. // Start with a fresh copy of the base array, and try rendering the entire
  426. // thing. We expect a single <ul> with appropriate links contained within
  427. // it.
  428. $render_array = $base_array;
  429. $html = \Drupal::service('renderer')->renderRoot($render_array);
  430. $dom = new \DOMDocument();
  431. $dom->loadHTML($html);
  432. $this->assertEqual($dom->getElementsByTagName('ul')->length, 1, 'One "ul" tag found in the rendered HTML.');
  433. $list_elements = $dom->getElementsByTagName('li');
  434. $this->assertEqual($list_elements->length, 3, 'Three "li" tags found in the rendered HTML.');
  435. $this->assertEqual($list_elements->item(0)->nodeValue, 'Parent link original', 'First expected link found.');
  436. $this->assertEqual($list_elements->item(1)->nodeValue, 'First child link', 'Second expected link found.');
  437. $this->assertEqual($list_elements->item(2)->nodeValue, 'Second child link', 'Third expected link found.');
  438. $this->assertIdentical(strpos($html, 'Parent link copy'), FALSE, '"Parent link copy" link not found.');
  439. $this->assertIdentical(strpos($html, 'Third child link'), FALSE, '"Third child link" link not found.');
  440. // Now render 'first_child', followed by the rest of the links, and make
  441. // sure we get two separate <ul>'s with the appropriate links contained
  442. // within each.
  443. $render_array = $base_array;
  444. $child_html = \Drupal::service('renderer')->renderRoot($render_array['first_child']);
  445. $parent_html = \Drupal::service('renderer')->renderRoot($render_array);
  446. // First check the child HTML.
  447. $dom = new \DOMDocument();
  448. $dom->loadHTML($child_html);
  449. $this->assertEqual($dom->getElementsByTagName('ul')->length, 1, 'One "ul" tag found in the rendered child HTML.');
  450. $list_elements = $dom->getElementsByTagName('li');
  451. $this->assertEqual($list_elements->length, 2, 'Two "li" tags found in the rendered child HTML.');
  452. $this->assertEqual($list_elements->item(0)->nodeValue, 'Parent link copy', 'First expected link found.');
  453. $this->assertEqual($list_elements->item(1)->nodeValue, 'First child link', 'Second expected link found.');
  454. // Then check the parent HTML.
  455. $dom = new \DOMDocument();
  456. $dom->loadHTML($parent_html);
  457. $this->assertEqual($dom->getElementsByTagName('ul')->length, 1, 'One "ul" tag found in the rendered parent HTML.');
  458. $list_elements = $dom->getElementsByTagName('li');
  459. $this->assertEqual($list_elements->length, 2, 'Two "li" tags found in the rendered parent HTML.');
  460. $this->assertEqual($list_elements->item(0)->nodeValue, 'Parent link original', 'First expected link found.');
  461. $this->assertEqual($list_elements->item(1)->nodeValue, 'Second child link', 'Second expected link found.');
  462. $this->assertIdentical(strpos($parent_html, 'First child link'), FALSE, '"First child link" link not found.');
  463. $this->assertIdentical(strpos($parent_html, 'Third child link'), FALSE, '"Third child link" link not found.');
  464. }
  465. /**
  466. * Tests theme_image().
  467. */
  468. function testImage() {
  469. // Test that data URIs work with theme_image().
  470. $variables = array();
  471. $variables['uri'] = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
  472. $variables['alt'] = 'Data URI image of a red dot';
  473. $expected = '<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Data URI image of a red dot" />' . "\n";
  474. $this->assertThemeOutput('image', $variables, $expected);
  475. }
  476. }