diff --git a/core/modules/system/src/Tests/Common/RenderTest.php b/core/modules/system/src/Tests/Common/RenderTest.php index 6a0f636..bc9369e 100644 --- a/core/modules/system/src/Tests/Common/RenderTest.php +++ b/core/modules/system/src/Tests/Common/RenderTest.php @@ -28,104 +28,6 @@ class RenderTest extends KernelTestBase { public static $modules = array('system', 'common_test'); /** - * Tests the output drupal_render() for some elementary input values. - */ - function testDrupalRenderBasics() { - $types = array( - // Test handling of #markup as a fallback for #theme hooks. - // Theme suggestion is not implemented, #markup should be rendered. - array( - 'name' => '#markup fallback for #theme suggestion not implemented', - 'value' => array( - '#theme' => array('suggestionnotimplemented'), - '#markup' => 'foo', - ), - 'expected' => 'foo', - ), - // Theme suggestion is not implemented, child #markup should be rendered. - array( - 'name' => '#markup fallback for child elements, #theme suggestion not implemented', - 'value' => array( - '#theme' => array('suggestionnotimplemented'), - 'child' => array( - '#markup' => 'foo', - ), - ), - 'expected' => 'foo', - ), - // Theme suggestion is implemented but returns empty string, #markup - // should not be rendered. - array( - 'name' => 'Avoid #markup if #theme is implemented but returns an empty string', - 'value' => array( - '#theme' => array('common_test_empty'), - '#markup' => 'foo', - ), - 'expected' => '', - ), - // Theme suggestion is implemented but returns empty string, children - // should not be rendered. - array( - 'name' => 'Avoid rendering child elements if #theme is implemented but returns an empty string', - 'value' => array( - '#theme' => array('common_test_empty'), - 'child' => array( - '#markup' => 'foo', - ), - ), - 'expected' => '', - ), - - // Test handling of #children and child renderable elements. - // #theme is implemented so the values of both #children and 'child' will - // be ignored - it is the responsibility of the theme hook to render these - // if appropriate. - array( - 'name' => '#theme is implemented, #children is set and array has children', - 'value' => array( - '#theme' => 'common_test_foo', - '#children' => 'baz', - 'child' => array('#markup' => 'boo'), - ), - 'expected' => 'foobar', - ), - // #theme is implemented but #render_children is TRUE. As in the case - // where #theme is not set, empty #children means child elements are - // rendered recursively. - array( - 'name' => '#theme is implemented, #render_children is TRUE, #children is empty and array has children', - 'value' => array( - '#theme' => 'common_test_foo', - '#children' => '', - '#render_children' => TRUE, - 'child' => array( - '#markup' => 'boo', - ), - ), - 'expected' => 'boo', - ), - // #theme is implemented but #render_children is TRUE. As in the case - // where #theme is not set, #children will take precedence over 'child'. - array( - 'name' => '#theme is implemented, #render_children is TRUE, #children is set and array has children', - 'value' => array( - '#theme' => 'common_test_foo', - '#children' => 'baz', - '#render_children' => TRUE, - 'child' => array( - '#markup' => 'boo', - ), - ), - 'expected' => 'baz', - ), - ); - - foreach($types as $type) { - $this->assertIdentical(drupal_render($type['value']), $type['expected'], '"' . $type['name'] . '" input rendered correctly by drupal_render().'); - } - } - - /** * Tests #attached functionality in children elements. */ function testDrupalRenderChildrenAttached() { @@ -169,24 +71,6 @@ function testDrupalRenderChildrenAttached() { } /** - * Tests passing arguments to the theme function. - */ - function testDrupalRenderThemeArguments() { - $element = array( - '#theme' => 'common_test_foo', - ); - // Test that defaults work. - $this->assertEqual(drupal_render($element), 'foobar', 'Defaults work'); - $element = array( - '#theme' => 'common_test_foo', - '#foo' => $this->randomMachineName(), - '#bar' => $this->randomMachineName(), - ); - // Tests that passing arguments to the theme function works. - $this->assertEqual(drupal_render($element), $element['#foo'] . $element['#bar'], 'Passing arguments to theme functions works'); - } - - /** * Tests theme preprocess functions being able to attach assets. */ function testDrupalRenderThemePreprocessAttached() { diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTest.php b/core/tests/Drupal/Tests/Core/Render/RendererTest.php index 7f3ba29..0698e20 100644 --- a/core/tests/Drupal/Tests/Core/Render/RendererTest.php +++ b/core/tests/Drupal/Tests/Core/Render/RendererTest.php @@ -48,6 +48,13 @@ class RendererTest extends UnitTestCase { */ protected $elementInfo; + protected $defaultThemeVars = [ + '#cache' => ['tags' => []], + '#attached' => [], + '#post_render_cache' => [], + '#children' => '', + ]; + /** * {@inheritdoc} */ @@ -77,19 +84,19 @@ public function providerTestRenderBasic() { $data = []; // Pass a NULL. -// $data[] = [NULL, '']; + $data[] = [NULL, '']; // Pass an empty string. -// $data[] = ['', '']; + $data[] = ['', '']; // Previously printed, see ::renderTwice for a more integration like test. -// $data[] = [[ -// '#markup' => 'foo', -// '#printed' => TRUE, -// ], '']; + $data[] = [[ + '#markup' => 'foo', + '#printed' => TRUE, + ], '']; // Printed in pre_render. -// $data[] = [[ -// '#markup' => 'foo', -// '#pre_render' => [[new TestCallables(), 'preRenderPrinted']] -// ], '']; + $data[] = [[ + '#markup' => 'foo', + '#pre_render' => [[new TestCallables(), 'preRenderPrinted']] + ], '']; // Test that #theme and #theme_wrappers can co-exist on an element. // #theme and #theme_wrappers basic @@ -185,43 +192,163 @@ public function providerTestRenderBasic() { $data[] = [$build, '
' . "\n", $setup_code]; // Test handling of #markup as a fallback for #theme hooks. + // Theme suggestion is not implemented, #markup should be rendered. + $build = [ + '#theme' => ['suggestionnotimplemented'], + '#markup' => 'foo', + ]; + $setup_code = function() { + $this->themeManager->expects($this->once()) + ->method('render') + ->with(['suggestionnotimplemented'], $this->anything()) + ->willReturn(FALSE); + }; + $data[] = [$build, 'foo', $setup_code]; + + // Theme suggestion is not implemented, child #markup should be rendered. + $build = [ + '#theme' => ['suggestionnotimplemented'], + 'child' => [ + '#markup' => 'foo', + ], + ]; + + $setup_code = function() { + $this->themeManager->expects($this->once()) + ->method('render') + ->with(['suggestionnotimplemented'], $this->anything()) + ->willReturn(FALSE); + }; + + $data[] = [$build, 'foo', $setup_code]; + + // Theme suggestion is implemented but returns empty string, #markup + // should not be rendered. + $build = [ + '#theme' => ['common_test_empty'], + '#markup' => 'foo', + ]; + + $setup_code = function() { + $this->themeManager->expects($this->once()) + ->method('render') + ->with(['common_test_empty'], $this->anything()) + ->willReturn(''); + }; + + $data[] = [$build, '', $setup_code]; + + // Theme suggestion is implemented but returns empty string, children + // should not be rendered. + + $build = [ + '#theme' => ['common_test_empty'], + 'child' => [ + '#markup' => 'foo', + ], + ]; + + $setup_code = function() { + $this->themeManager->expects($this->once()) + ->method('render') + ->with(['common_test_empty'], $this->anything()) + ->willReturn(''); + }; + + $data[] = [$build, '', $setup_code]; + + // Test handling of #children and child renderable elements. + // #theme is implemented so the values of both #children and 'child' will + // be ignored - it is the responsibility of the theme hook to render these + // if appropriate. + + $build = [ + '#theme' => 'common_test_foo', + '#children' => 'baz', + 'child' => ['#markup' => 'boo'], + ]; + + $setup_code = function() { + $this->themeManager->expects($this->once()) + ->method('render') + ->with('common_test_foo', $this->anything()) + ->willReturn('foobar'); + }; + + $data[] = [$build, 'foobar', $setup_code]; + + // #theme is implemented but #render_children is TRUE. As in the case + // where #theme is not set, empty #children means child elements are + // rendered recursively. + $build = [ + '#theme' => 'common_test_foo', + '#children' => '', + '#render_children' => TRUE, + 'child' => [ + '#markup' => 'boo', + ], + ]; + + $setup_code = function() { + $this->themeManager->expects($this->never()) + ->method('render'); + }; + + $data[] = [$build, 'boo', $setup_code]; + + // #theme is implemented but #render_children is TRUE. As in the case + // where #theme is not set, #children will take precedence over 'child'. + + $build = [ + '#theme' => 'common_test_foo', + '#children' => 'baz', + '#render_children' => TRUE, + 'child' => [ + '#markup' => 'boo', + ], + ]; + + $setup_code = function() { + $this->themeManager->expects($this->never()) + ->method('render'); + }; + + $data[] = [$build, 'baz', $setup_code]; + + // Test handling of #markup as a fallback for #theme hooks. // Simple #markup with no theme. // Basic #markup based renderable array. -// $data[] = [ -// ['#markup' => 'foo'] -// , 'foo']; + $data[] = [ + ['#markup' => 'foo'] + , 'foo']; // Test handling of #children and child renderable elements. // #theme is not set, #children is not set and the array has children. -// $data[] = [ -// [ -// 'child' => ['#markup' => 'bar'], -// ], 'bar']; + $data[] = [ + [ + 'child' => ['#markup' => 'bar'], + ], 'bar']; // #theme is not set, #children is set but empty and the array has // children. -// $data[] = [ -// [ -// '#children' => '', -// 'child' => ['#markup' => 'bar'], -// ], 'bar' -// ]; + $data[] = [ + [ + '#children' => '', + 'child' => ['#markup' => 'bar'], + ], 'bar' + ]; // #theme is not set, #children is not empty and will be assumed to be the // rendered child elements even though the #markup for 'child' differs. -// $data[] = [ -// [ -// '#children' => 'foo', -// 'child' => ['#markup' => 'bar'], -// ], 'foo' -// ]; + $data[] = [ + [ + '#children' => 'foo', + 'child' => ['#markup' => 'bar'], + ], 'foo' + ]; return $data; } - protected function setupThemeCommonTestFoo() { - - } - /** * @covers ::render */ @@ -255,6 +382,9 @@ public function testRenderSorting() { $this->assertTrue(array_shift($children) == 'second', 'Child found in the correct order.'); } + /** + * @covers ::render + */ public function testRenderSortingWithSetHashSorted() { $first = $this->randomMachineName(); $second = $this->randomMachineName(); @@ -290,6 +420,7 @@ public function testRenderWithPresetAccess($access) { /** * @dataProvider providerBoolean + * @covers ::render */ public function testRenderWithAccessCallbackCallable($access) { $build = [ @@ -306,6 +437,8 @@ public function testRenderWithAccessCallbackCallable($access) { * @dataProvider providerBoolean * * Ensure that the #access property wins over the callable. + * + * @covers ::render */ public function testRenderWithAccessPropertyAndCallback($access) { $build = [ @@ -321,6 +454,8 @@ public function testRenderWithAccessPropertyAndCallback($access) { /** * @dataProvider providerBoolean + * + * @covers ::render */ public function testRenderWithAccessControllerResolved($access) { $build = [ @@ -338,6 +473,9 @@ public function testRenderWithAccessControllerResolved($access) { $this->assertAccess($build, $access); } + /** + * @covers ::render + */ public function testRenderTwice() { $build = [ '#markup' => 'test', @@ -384,6 +522,44 @@ protected function setupThemeContainerMultiSuggestion($matcher = NULL) { }); } + /** + * @covers ::render + */ + public function testRenderWithoutThemeArguments() { + $element = array( + '#theme' => 'common_test_foo', + ); + + $this->themeManager->expects($this->once()) + ->method('render') + ->with('common_test_foo', $this->defaultThemeVars + $element) + ->willReturn('foobar'); + + // Test that defaults work. + $this->assertEquals($this->renderer->render($element), 'foobar', 'Defaults work'); + } + + /** + * @covers ::render + */ + public function testRenderWithThemeArguments() { + $element = array( + '#theme' => 'common_test_foo', + '#foo' => $this->randomMachineName(), + '#bar' => $this->randomMachineName(), + ); + + $this->themeManager->expects($this->once()) + ->method('render') + ->with('common_test_foo', $this->defaultThemeVars + $element) + ->willReturnCallback(function ($hook, $vars) { + return $vars['#foo'] . $vars['#bar']; + }); + + // Tests that passing arguments to the theme function works. + $this->assertEquals($this->renderer->render($element), $element['#foo'] . $element['#bar'], 'Passing arguments to theme functions works'); + } + } class TestAccessClass {