3 namespace Drupal\Tests\Core\Render;
6 * @coversDefaultClass \Drupal\Core\Render\Renderer
9 class RendererRecursionTest extends RendererTestBase {
11 protected function setUpRenderRecursionComplexElements() {
12 $complex_child_markup = '<p>Imagine this is a render array for an entity.</p>';
13 $parent_markup = '<p>Rendered!</p>';
15 $complex_child_template = [
21 '#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', [$this->getRandomGenerator()->string()]],
22 '#create_placeholder' => TRUE,
25 return [$complex_child_markup, $parent_markup, $complex_child_template];
29 * ::renderRoot() may not be called inside of another ::renderRoot() call.
31 * @covers ::renderRoot
35 public function testRenderRecursionWithNestedRenderRoot() {
36 list($complex_child_markup, $parent_markup, $complex_child_template) = $this->setUpRenderRecursionComplexElements();
37 $renderer = $this->renderer;
38 $this->setUpRequest();
40 $complex_child = $complex_child_template;
41 $callable = function () use ($renderer, $complex_child) {
42 $this->setExpectedException(\LogicException::class);
43 $renderer->renderRoot($complex_child);
51 '#suffix' => $parent_markup,
54 $renderer->renderRoot($page);
58 * ::render() may be called from anywhere.
60 * Including from inside of another ::renderRoot() call. Bubbling must be
63 * @covers ::renderRoot
67 public function testRenderRecursionWithNestedRender() {
68 list($complex_child_markup, $parent_markup, $complex_child_template) = $this->setUpRenderRecursionComplexElements();
69 $renderer = $this->renderer;
70 $this->setUpRequest();
72 $callable = function ($markup) use ($renderer, $complex_child_template) {
73 $this->assertTrue(strpos($markup, '<drupal-render-placeholder') === 0, 'Rendered complex child output as expected, without the placeholder replaced, i.e. with just the placeholder.');
79 'complex_child' => $complex_child_template,
83 '#suffix' => $parent_markup,
86 $output = $renderer->renderRoot($page);
88 $this->assertEquals('<p>This is a rendered placeholder!</p><p>Rendered!</p>', $output, 'Rendered output as expected, with the placeholder replaced.');
89 $this->assertTrue(in_array('test:complex_child', $page['#cache']['tags']), 'Cache tag bubbling performed.');
90 $this->assertTrue(in_array('dynamic_animal', array_keys($page['#attached']['drupalSettings'])), 'Asset bubbling performed.');
94 * ::renderPlain() may be called from anywhere.
96 * Including from inside of another ::renderRoot() call.
98 * @covers ::renderRoot
99 * @covers ::renderPlain
101 public function testRenderRecursionWithNestedRenderPlain() {
102 list($complex_child_markup, $parent_markup, $complex_child_template) = $this->setUpRenderRecursionComplexElements();
103 $renderer = $this->renderer;
104 $this->setUpRequest();
106 $complex_child = $complex_child_template;
108 $callable = function ($elements) use ($renderer, $complex_child, $parent_markup) {
109 $elements['#markup'] = $renderer->renderPlain($complex_child);
110 $this->assertEquals('<p>This is a rendered placeholder!</p>', $elements['#markup'], 'Rendered complex child output as expected, with the placeholder replaced.');
119 '#suffix' => $parent_markup,
122 $output = $renderer->renderRoot($page);
123 $this->assertEquals('<p>This is a rendered placeholder!</p>' . $parent_markup, $output, 'Rendered output as expected, with the placeholder replaced.');
124 $this->assertFalse(in_array('test:complex_child', $page['#cache']['tags']), 'Cache tag bubbling not performed.');
125 $this->assertTrue(empty($page['#attached']), 'Asset bubbling not performed.');