3 namespace Drupal\KernelTests\Core\Render\Element;
5 use Drupal\Component\Utility\Html;
7 use Drupal\KernelTests\KernelTestBase;
10 * Tests the markup of core render element types passed to drupal_render().
14 class RenderElementTypesTest extends KernelTestBase {
21 public static $modules = ['system', 'router_test'];
23 protected function setUp() {
25 $this->installConfig(['system']);
26 \Drupal::service('router.builder')->rebuild();
30 * Asserts that an array of elements is rendered properly.
32 * @param array $elements
33 * The render element array to test.
34 * @param string $expected_html
35 * The expected markup.
36 * @param string $message
39 protected function assertElements(array $elements, $expected_html, $message) {
40 $actual_html = (string) \Drupal::service('renderer')->renderRoot($elements);
43 $out .= '<td valign="top"><pre>' . Html::escape($expected_html) . '</pre></td>';
44 $out .= '<td valign="top"><pre>' . Html::escape($actual_html) . '</pre></td>';
45 $out .= '</tr></table>';
48 $this->assertIdentical($actual_html, $expected_html, Html::escape($message));
52 * Tests system #type 'container'.
54 public function testContainer() {
55 // Basic container with no attributes.
56 $this->assertElements([
57 '#type' => 'container',
59 ], "<div>foo</div>\n", "#type 'container' with no HTML attributes");
61 // Container with a class.
62 $this->assertElements([
63 '#type' => 'container',
68 ], '<div class="bar">foo</div>' . "\n", "#type 'container' with a class HTML attribute");
70 // Container with children.
71 $this->assertElements([
72 '#type' => 'container',
76 ], "<div>foo</div>\n", "#type 'container' with child elements");
80 * Tests system #type 'html_tag'.
82 public function testHtmlTag() {
84 $this->assertElements([
85 '#type' => 'html_tag',
87 '#value' => 'ignored',
89 'name' => 'description',
90 'content' => 'Drupal test',
92 ], '<meta name="description" content="Drupal test" />' . "\n", "#type 'html_tag', void element renders properly");
94 // Test non-void element.
95 $this->assertElements([
96 '#type' => 'html_tag',
100 'class' => ['unicorns'],
102 ], '<section class="unicorns">value</section>' . "\n", "#type 'html_tag', non-void element renders properly");
104 // Test empty void element tag.
105 $this->assertElements([
106 '#type' => 'html_tag',
108 ], "<link />\n", "#type 'html_tag' empty void element renders properly");
110 // Test empty non-void element tag.
111 $this->assertElements([
112 '#type' => 'html_tag',
114 ], "<section></section>\n", "#type 'html_tag' empty non-void element renders properly");
118 * Tests system #type 'more_link'.
120 public function testMoreLink() {
123 'name' => "#type 'more_link' anchor tag generation without extra classes",
125 '#type' => 'more_link',
126 '#url' => Url::fromUri('https://www.drupal.org'),
128 'expected' => '//div[@class="more-link"]/a[@href="https://www.drupal.org" and text()="More"]',
131 'name' => "#type 'more_link' anchor tag generation with different link text",
133 '#type' => 'more_link',
134 '#url' => Url::fromUri('https://www.drupal.org'),
135 '#title' => 'More Titles',
137 'expected' => '//div[@class="more-link"]/a[@href="https://www.drupal.org" and text()="More Titles"]',
140 'name' => "#type 'more_link' anchor tag generation with attributes on wrapper",
142 '#type' => 'more_link',
143 '#url' => Url::fromUri('https://www.drupal.org'),
144 '#theme_wrappers' => [
147 'title' => 'description',
148 'class' => ['more-link', 'drupal', 'test'],
153 'expected' => '//div[@title="description" and contains(@class, "more-link") and contains(@class, "drupal") and contains(@class, "test")]/a[@href="https://www.drupal.org" and text()="More"]',
156 'name' => "#type 'more_link' anchor tag with a relative path",
158 '#type' => 'more_link',
159 '#url' => Url::fromRoute('router_test.1'),
161 'expected' => '//div[@class="more-link"]/a[@href="' . Url::fromRoute('router_test.1')->toString() . '" and text()="More"]',
164 'name' => "#type 'more_link' anchor tag with a route",
166 '#type' => 'more_link',
167 '#url' => Url::fromRoute('router_test.1'),
169 'expected' => '//div[@class="more-link"]/a[@href="' . \Drupal::urlGenerator()->generate('router_test.1') . '" and text()="More"]',
172 'name' => "#type 'more_link' anchor tag with an absolute path",
174 '#type' => 'more_link',
175 '#url' => Url::fromRoute('system.admin_content'),
176 '#options' => ['absolute' => TRUE],
178 'expected' => '//div[@class="more-link"]/a[@href="' . Url::fromRoute('system.admin_content')->setAbsolute()->toString() . '" and text()="More"]',
181 'name' => "#type 'more_link' anchor tag to the front page",
183 '#type' => 'more_link',
184 '#url' => Url::fromRoute('<front>'),
186 'expected' => '//div[@class="more-link"]/a[@href="' . Url::fromRoute('<front>')->toString() . '" and text()="More"]',
190 foreach ($elements as $element) {
191 $xml = new \SimpleXMLElement(\Drupal::service('renderer')->renderRoot($element['value']));
192 $result = $xml->xpath($element['expected']);
193 $this->assertTrue($result, '"' . $element['name'] . '" input rendered correctly by drupal_render().');
198 * Tests system #type 'system_compact_link'.
200 public function testSystemCompactLink() {
203 'name' => "#type 'system_compact_link' when admin compact mode is off",
205 '#type' => 'system_compact_link',
207 'expected' => '//div[@class="compact-link"]/a[contains(@href, "admin/compact/on?") and text()="Hide descriptions"]',
210 'name' => "#type 'system_compact_link' when adding extra attributes",
212 '#type' => 'system_compact_link',
214 'class' => ['kittens-rule'],
217 'expected' => '//div[@class="compact-link"]/a[contains(@href, "admin/compact/on?") and @class="kittens-rule" and text()="Hide descriptions"]',
221 foreach ($elements as $element) {
222 $xml = new \SimpleXMLElement(\Drupal::service('renderer')->renderRoot($element['value']));
223 $result = $xml->xpath($element['expected']);
224 $this->assertTrue($result, '"' . $element['name'] . '" is rendered correctly by drupal_render().');
227 // Set admin compact mode on for additional tests.
228 \Drupal::request()->cookies->set('Drupal_visitor_admin_compact_mode', TRUE);
231 'name' => "#type 'system_compact_link' when admin compact mode is on",
233 '#type' => 'system_compact_link',
235 'expected' => '//div[@class="compact-link"]/a[contains(@href, "admin/compact?") and text()="Show descriptions"]',
238 $xml = new \SimpleXMLElement(\Drupal::service('renderer')->renderRoot($element['value']));
239 $result = $xml->xpath($element['expected']);
240 $this->assertTrue($result, '"' . $element['name'] . '" is rendered correctly by drupal_render().');