From 7cd0b1c133a8075ee670d56a67d76ceb9304d3c7 Mon Sep 17 00:00:00 2001 From: Wim Leers Date: Tue, 24 Feb 2015 17:04:12 +0100 Subject: [PATCH 4/4] review-test-render_cache --- .../Drupal/Tests/Core/Render/RendererTest.php | 181 ++++++++++++--------- 1 file changed, 100 insertions(+), 81 deletions(-) diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTest.php b/core/tests/Drupal/Tests/Core/Render/RendererTest.php index 2a1efa1..c850acd 100644 --- a/core/tests/Drupal/Tests/Core/Render/RendererTest.php +++ b/core/tests/Drupal/Tests/Core/Render/RendererTest.php @@ -565,6 +565,7 @@ protected function setupThemeContainerMultiSuggestion($matcher = NULL) { /** * @covers ::render + * @covers ::doRender */ public function testRenderWithoutThemeArguments() { $element = array( @@ -582,6 +583,7 @@ public function testRenderWithoutThemeArguments() { /** * @covers ::render + * @covers ::doRender */ public function testRenderWithThemeArguments() { $element = array( @@ -601,10 +603,18 @@ public function testRenderWithThemeArguments() { $this->assertEquals($this->renderer->render($element), $element['#foo'] . $element['#bar'], 'Passing arguments to theme functions works'); } + /** + * @covers ::render + * @covers ::doRender + * @covers ::cacheGet + * @covers ::cacheSet + * @covers ::createCacheID + */ public function testRenderCache() { // The cache system is turned off for POST requests. $request = Request::create('/', 'GET'); $this->requestStack->push($request); + $this->setupMemoryCache(); // Create an empty element. $test_element = [ @@ -622,15 +632,6 @@ public function testRenderCache() { ], ]; - // Setup a cache which acts like a cache, a memory backend. Adding a mock - // for such a generic test, couples the test too much to the internal - // implementation. - $cache = new MemoryBackend('render'); - $this->cacheFactory->expects($this->any()) - ->method('get') - ->with('render') - ->willReturn($cache); - // Render the element and confirm that it goes through the rendering // process (which will set $element['#printed']). $element = $test_element; @@ -703,59 +704,15 @@ protected function randomContextValue() { return $tokens[mt_rand(0, 4)]; } - public function testDrupalRenderChildrenAttached() { - // The cache system is turned off for POST requests. - $request = Request::create('/', 'GET'); - $this->requestStack->push($request); - - $cache = new MemoryBackend('render'); - $this->cacheFactory->expects($this->any()) - ->method('get') - ->willReturn($cache); - - // Mock the cache contexts. - $this->cacheContexts->expects($this->any()) - ->method('convertTokensToKeys') - ->willReturnArgument(0); - - $this->elementInfo->expects($this->any()) - ->method('getInfo') - ->willReturn([]); - - - // Create an element with a child and subchild. Each element loads a - // different library using #attached. - $element = [ - '#type' => 'container', - '#cache' => [ - 'keys' => ['simpletest', 'drupal_render', 'children_attached'], - ], - '#attached' => ['library' => ['test/parent']], - '#title' => 'Parent', - ]; - $element['child'] = [ - '#type' => 'container', - '#attached' => ['library' => ['test/child']], - '#title' => 'Child', - ]; - $element['child']['subchild'] = [ - '#attached' => ['library' => ['test/subchild']], - '#markup' => 'Subchild', - ]; - - // Render the element and verify the presence of #attached JavaScript. - $this->renderer->render($element); - $expected_libraries = ['test/parent', 'test/child', 'test/subchild']; - $this->assertEquals($element['#attached']['library'], $expected_libraries, 'The element, child and subchild #attached libraries are included.'); - - // Load the element from cache and verify the presence of the #attached - // JavaScript. - $element = ['#cache' => ['keys' => ['simpletest', 'drupal_render', 'children_attached']]]; - $this->assertTrue(strlen($this->renderer->render($element)) > 0, 'The element was retrieved from cache.'); - $this->assertEquals($element['#attached']['library'], $expected_libraries, 'The element, child and subchild #attached libraries are included.'); - } - - protected function drupalRenderPostCacheCacheElement() { + /** + * Generates an element with a #post_render_cache callback. + * + * @return array + * An array containing: + * 1. a render array containing a #post_render_cache callback + * 2. the context used for that #post_render_cache callback. + */ + protected function generatePostRenderCacheElement() { $context = ['foo' => $this->randomContextValue()]; $test_element = []; $test_element['#markup'] = ''; @@ -767,10 +724,14 @@ protected function drupalRenderPostCacheCacheElement() { return [$test_element, $context]; } + /** + * @covers ::render + * @covers ::doRender + */ public function testPostRenderCacheWithCacheDisabled() { - list ($element, $context) = $this->drupalRenderPostCacheCacheElement(); + list ($element, $context) = $this->generatePostRenderCacheElement(); $this->setupPostRenderCallbacks(); - $this->setupNullCache(); + $this->setUpUnusedCache(); // #cache disabled. $element['#markup'] = '

#cache disabled

'; @@ -784,9 +745,15 @@ public function testPostRenderCacheWithCacheDisabled() { $this->assertSame($element['#attached']['drupalSettings'], $expected_js_settings, '#attached is modified; both the original JavaScript setting and the one added by the #post_render_cache callback exist.'); } - - public function testPostRenderCacheWithCacheMiss() { - list ($test_element, $context) = $this->drupalRenderPostCacheCacheElement(); + /** + * @covers ::render + * @covers ::doRender + * @covers ::cacheGet + * @covers ::cacheSet + * @covers ::createCacheID + */ + public function testPostRenderCacheWithColdCache() { + list ($test_element, $context) = $this->generatePostRenderCacheElement(); $element = $test_element; $this->setupPostRenderCallbacks(); $this->setupMemoryCache(); @@ -833,10 +800,15 @@ public function testPostRenderCacheWithCacheMiss() { $this->assertSame($element['#attached']['drupalSettings'], $expected_js_settings, '#attached is modified; both the original JavaScript setting and the one added by the #post_render_cache callback exist.'); } + /** + * @covers ::render + * @covers ::doRender + * @covers ::cacheGet + */ public function testPostRenderCacheWithPostRequest() { - list ($test_element, $context) = $this->drupalRenderPostCacheCacheElement(); + list ($test_element, $context) = $this->generatePostRenderCacheElement(); $this->setupPostRenderCallbacks(); - $this->setupMemoryCache(); + $this->setUpUnusedCache(); // Verify behavior when handling a non-GET request, e.g. a POST request: // also in that case, #post_render_cache callbacks must be called. @@ -856,10 +828,6 @@ public function testPostRenderCacheWithPostRequest() { 'common_test' => $context, ]; $this->assertSame($element['#attached']['drupalSettings'], $expected_js_settings, '#attached is modified; both the original JavaScript setting and the one added by the #post_render_cache callback exist.'); - - // POST request: Ensure no data was cached. - $cached_element = $this->memoryCache->get('post_render_cache_test_POST'); - $this->assertFalse($cached_element, 'No data is cached because this is a POST request.'); } protected function setupPostRenderCallbacks() { @@ -868,16 +836,21 @@ protected function setupPostRenderCallbacks() { return [[$post_render_callback_recursive, 'callback'], [$post_render_callback, 'callback']]; } - protected function setupNullCache() { - $this->cacheFactory->expects($this->any()) - ->method('get') - ->willReturn(new NullBackend('render')); + /** + * Sets up a render cache back-end that is asserted to be never used. + */ + protected function setUpUnusedCache() { + $this->cacheFactory->expects($this->never()) + ->method('get'); } + /** + * Sets up a memory-based render cache back-end. + */ protected function setupMemoryCache() { $this->memoryCache = $this->memoryCache ?: new MemoryBackend('render'); - $this->cacheFactory->expects($this->any()) + $this->cacheFactory->expects($this->atLeastOnce()) ->method('get') ->willReturn($this->memoryCache); } @@ -1023,12 +996,58 @@ protected function setupGetRequest() { } /** + * Tests bubbling of assets when NOT using #pre_render callbacks. + */ + public function testRenderBubblingWithoutPreRender() { + // The cache system is turned off for POST requests. + $request = Request::create('/', 'GET'); + $this->requestStack->push($request); + $this->setupMemoryCache(); + + $this->elementInfo->expects($this->any()) + ->method('getInfo') + ->willReturn([]); + + + // Create an element with a child and subchild. Each element loads a + // different library using #attached. + $element = [ + '#type' => 'container', + '#cache' => [ + 'keys' => ['simpletest', 'drupal_render', 'children_attached'], + ], + '#attached' => ['library' => ['test/parent']], + '#title' => 'Parent', + ]; + $element['child'] = [ + '#type' => 'container', + '#attached' => ['library' => ['test/child']], + '#title' => 'Child', + ]; + $element['child']['subchild'] = [ + '#attached' => ['library' => ['test/subchild']], + '#markup' => 'Subchild', + ]; + + // Render the element and verify the presence of #attached JavaScript. + $this->renderer->render($element); + $expected_libraries = ['test/parent', 'test/child', 'test/subchild']; + $this->assertEquals($element['#attached']['library'], $expected_libraries, 'The element, child and subchild #attached libraries are included.'); + + // Load the element from cache and verify the presence of the #attached + // JavaScript. + $element = ['#cache' => ['keys' => ['simpletest', 'drupal_render', 'children_attached']]]; + $this->assertTrue(strlen($this->renderer->render($element)) > 0, 'The element was retrieved from cache.'); + $this->assertEquals($element['#attached']['library'], $expected_libraries, 'The element, child and subchild #attached libraries are included.'); + } + + /** * Tests bubbling of assets, cache tags and post-render cache callbacks when * they are added by #pre_render callbacks. * - * @dataProvider providerTestRenderBubbling + * @dataProvider providerTestRenderBubblingWithPrerender */ - public function testRenderBubbling($test_element) { + public function testRenderBubblingWithPrerender($test_element) { $this->setupGetRequest(); $this->setupMemoryCache(); @@ -1065,7 +1084,7 @@ public function testRenderBubbling($test_element) { $this->assertFalse(\Drupal::state()->get('bubbling_nested_pre_render_cached', FALSE)); } - public function providerTestRenderBubbling() { + public function providerTestRenderBubblingWithPrerender() { $data = []; // Test element without theme. -- 2.2.1