class RendererTestBase

Same name in other branches
  1. 9 core/tests/Drupal/Tests/Core/Render/RendererTestBase.php \Drupal\Tests\Core\Render\RendererTestBase
  2. 8.9.x core/tests/Drupal/Tests/Core/Render/RendererTestBase.php \Drupal\Tests\Core\Render\RendererTestBase
  3. 11.x core/tests/Drupal/Tests/Core/Render/RendererTestBase.php \Drupal\Tests\Core\Render\RendererTestBase

Base class for the actual unit tests testing \Drupal\Core\Render\Renderer.

Hierarchy

Expanded class hierarchy of RendererTestBase

1 file declares its use of RendererTestBase
HtmlTagTest.php in core/tests/Drupal/Tests/Core/Render/Element/HtmlTagTest.php

File

core/tests/Drupal/Tests/Core/Render/RendererTestBase.php, line 27

Namespace

Drupal\Tests\Core\Render
View source
abstract class RendererTestBase extends UnitTestCase {
    
    /**
     * System time service.
     *
     * @var \Drupal\Component\Datetime\TimeInterface
     */
    protected TimeInterface $datetimeTime;
    
    /**
     * The tested renderer.
     *
     * @var \Drupal\Core\Render\Renderer
     */
    protected $renderer;
    
    /**
     * The tested render cache.
     *
     * @var \Drupal\Core\Render\PlaceholderingRenderCache
     */
    protected $renderCache;
    
    /**
     * The tested placeholder generator.
     *
     * @var \Drupal\Core\Render\PlaceholderGenerator
     */
    protected $placeholderGenerator;
    
    /**
     * @var \Symfony\Component\HttpFoundation\RequestStack
     */
    protected $requestStack;
    
    /**
     * @var \Drupal\Core\Cache\VariationCacheFactoryInterface|\PHPUnit\Framework\MockObject\MockObject
     */
    protected $cacheFactory;
    
    /**
     * @var \Drupal\Core\Cache\Context\CacheContextsManager|\PHPUnit\Framework\MockObject\MockObject
     */
    protected $cacheContextsManager;
    
    /**
     * The mocked controller resolver.
     *
     * @var \Drupal\Core\Utility\CallableResolver|\PHPUnit\Framework\MockObject\MockObject
     */
    protected $callableResolver;
    
    /**
     * The mocked theme manager.
     *
     * @var \Drupal\Core\Theme\ThemeManagerInterface|\PHPUnit\Framework\MockObject\MockObject
     */
    protected $themeManager;
    
    /**
     * The mocked element info.
     *
     * @var \Drupal\Core\Render\ElementInfoManagerInterface|\PHPUnit\Framework\MockObject\MockObject
     */
    protected $elementInfo;
    
    /**
     * @var \Drupal\Core\Cache\VariationCacheInterface
     */
    protected $memoryCache;
    
    /**
     * The simulated "current" user role, for use in tests with cache contexts.
     *
     * @var string
     */
    protected $currentUserRole;
    
    /**
     * The mocked renderer configuration.
     *
     * @var array
     */
    protected $rendererConfig = [
        'required_cache_contexts' => [
            'languages:language_interface',
            'theme',
        ],
        'auto_placeholder_conditions' => [
            'max-age' => 0,
            'contexts' => [
                'session',
                'user',
            ],
            'tags' => [
                'current-temperature',
            ],
        ],
        'debug' => FALSE,
    ];
    
    /**
     * {@inheritdoc}
     */
    protected function setUp() : void {
        parent::setUp();
        $this->callableResolver = $this->createMock(CallableResolver::class);
        $this->callableResolver
            ->expects($this->any())
            ->method('getCallableFromDefinition')
            ->willReturnArgument(0);
        $this->themeManager = $this->createMock('Drupal\\Core\\Theme\\ThemeManagerInterface');
        $this->elementInfo = $this->createMock('Drupal\\Core\\Render\\ElementInfoManagerInterface');
        $this->elementInfo
            ->expects($this->any())
            ->method('getInfo')
            ->willReturnCallback(function ($type) {
            switch ($type) {
                case 'details':
                    $info = [
                        '#theme_wrappers' => [
                            'details',
                        ],
                    ];
                    break;
                case 'link':
                    $info = [
                        '#theme' => 'link',
                    ];
                    break;
                default:
                    $info = [];
            }
            $info['#defaults_loaded'] = TRUE;
            return $info;
        });
        $this->requestStack = new RequestStack();
        $request = new Request();
        $request->server
            ->set('REQUEST_TIME', $_SERVER['REQUEST_TIME']);
        $this->requestStack
            ->push($request);
        $this->cacheFactory = $this->createMock('Drupal\\Core\\Cache\\VariationCacheFactoryInterface');
        $this->cacheContextsManager = $this->getMockBuilder('Drupal\\Core\\Cache\\Context\\CacheContextsManager')
            ->disableOriginalConstructor()
            ->getMock();
        $this->cacheContextsManager
            ->method('assertValidTokens')
            ->willReturn(TRUE);
        $this->cacheContextsManager
            ->expects($this->any())
            ->method('optimizeTokens')
            ->willReturnCallback(function ($context_tokens) {
            return $context_tokens;
        });
        $current_user_role =& $this->currentUserRole;
        $this->cacheContextsManager
            ->expects($this->any())
            ->method('convertTokensToKeys')
            ->willReturnCallback(function ($context_tokens) use (&$current_user_role) {
            $keys = [];
            foreach ($context_tokens as $context_id) {
                switch ($context_id) {
                    case 'user.roles':
                        $keys[] = 'r.' . $current_user_role;
                        break;
                    case 'languages:language_interface':
                        $keys[] = 'en';
                        break;
                    case 'theme':
                        $keys[] = 'stark';
                        break;
                    default:
                        $keys[] = $context_id;
                }
            }
            return new ContextCacheKeys($keys);
        });
        $this->placeholderGenerator = new PlaceholderGenerator($this->cacheContextsManager, $this->rendererConfig);
        $this->renderCache = new PlaceholderingRenderCache($this->requestStack, $this->cacheFactory, $this->cacheContextsManager, $this->placeholderGenerator);
        $this->renderer = new Renderer($this->callableResolver, $this->themeManager, $this->elementInfo, $this->placeholderGenerator, $this->renderCache, $this->requestStack, $this->rendererConfig);
        $this->datetimeTime = new Time($this->requestStack);
        $container = new ContainerBuilder();
        $container->set('cache_contexts_manager', $this->cacheContextsManager);
        $container->set('render_cache', $this->renderCache);
        $container->set('renderer', $this->renderer);
        $container->set('datetime.time', $this->datetimeTime);
        \Drupal::setContainer($container);
    }
    
    /**
     * Generates a random context value for the placeholder tests.
     *
     * The #context array used by the placeholder #lazy_builder callback will
     * generally be used to provide metadata like entity IDs, field machine names,
     * paths, etc. for JavaScript replacement of content or assets. In this test,
     * the #lazy_builder callback PlaceholdersTest::callback() renders the context
     * inside test HTML, so using any random string would sometimes cause random
     * test failures because the test output would not be parseable. Instead, we
     * provide random tokens for replacement.
     *
     * @see PlaceholdersTest::callback()
     * @see https://www.drupal.org/node/2151609
     */
    protected static function randomContextValue() : string {
        $tokens = [
            'llama',
            'alpaca',
            'camel',
            'moose',
            'elk',
        ];
        return $tokens[mt_rand(0, 4)];
    }
    
    /**
     * 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 VariationCache($this->requestStack, new MemoryBackend(new Time($this->requestStack)), $this->cacheContextsManager);
        $this->cacheFactory
            ->expects($this->atLeastOnce())
            ->method('get')
            ->with('render')
            ->willReturn($this->memoryCache);
    }
    
    /**
     * Sets up a request object on the request stack.
     *
     * @param string $method
     *   The HTTP method to use for the request. Defaults to 'GET'.
     */
    protected function setUpRequest($method = 'GET') {
        $request = Request::create('/', $method);
        // Ensure that the request time is set as expected.
        $request->server
            ->set('REQUEST_TIME', (int) $_SERVER['REQUEST_TIME']);
        $this->requestStack
            ->push($request);
    }
    
    /**
     * Asserts a render cache item.
     *
     * @param string[] $keys
     *   The expected cache keys.
     * @param mixed $data
     *   The expected data for that cache ID.
     * @param string $bin
     *   The expected cache bin.
     */
    protected function assertRenderCacheItem($keys, $data, $bin = 'render') {
        $cache_backend = $this->cacheFactory
            ->get($bin);
        $cached = $cache_backend->get($keys, CacheableMetadata::createFromRenderArray($data));
        $this->assertNotFalse($cached, sprintf('Expected cache item "%s" exists.', implode(':', $keys)));
        if ($cached !== FALSE) {
            $this->assertEqualsCanonicalizing(array_keys($data), array_keys($cached->data), 'The cache item contains the same parent array keys.');
            foreach ($data as $key => $value) {
                // We do not want to assert on the order of cacheability information.
                // @see https://www.drupal.org/project/drupal/issues/3225328
                if ($key === '#cache') {
                    $this->assertEqualsCanonicalizing($value, $cached->data[$key], sprintf('Cache item "%s" has the expected data.', implode(':', $keys)));
                }
                else {
                    $this->assertEquals($value, $cached->data[$key], sprintf('Cache item "%s" has the expected data.', implode(':', $keys)));
                }
            }
            $this->assertEqualsCanonicalizing(Cache::mergeTags($data['#cache']['tags'], [
                'rendered',
            ]), $cached->tags, "The cache item's cache tags also has the 'rendered' cache tag.");
        }
    }

}

Members

Title Sort descending Deprecated Modifiers Object type Summary Overriden Title Overrides
PhpUnitWarnings::$deprecationWarnings private static property Deprecation warnings from PHPUnit to raise with @trigger_error().
PhpUnitWarnings::addWarning public function Converts PHPUnit deprecation warnings to E_USER_DEPRECATED.
RandomGeneratorTrait::getRandomGenerator protected function Gets the random generator for the utility methods.
RandomGeneratorTrait::randomMachineName protected function Generates a unique random string containing letters and numbers.
RandomGeneratorTrait::randomObject public function Generates a random PHP object.
RandomGeneratorTrait::randomString public function Generates a pseudo-random string of ASCII characters of codes 32 to 126.
RandomGeneratorTrait::randomStringValidate Deprecated public function Callback for random string validation.
RendererTestBase::$cacheContextsManager protected property
RendererTestBase::$cacheFactory protected property
RendererTestBase::$callableResolver protected property The mocked controller resolver.
RendererTestBase::$currentUserRole protected property The simulated "current" user role, for use in tests with cache contexts.
RendererTestBase::$datetimeTime protected property System time service.
RendererTestBase::$elementInfo protected property The mocked element info.
RendererTestBase::$memoryCache protected property
RendererTestBase::$placeholderGenerator protected property The tested placeholder generator. 1
RendererTestBase::$renderCache protected property The tested render cache.
RendererTestBase::$renderer protected property The tested renderer.
RendererTestBase::$rendererConfig protected property The mocked renderer configuration.
RendererTestBase::$requestStack protected property
RendererTestBase::$themeManager protected property The mocked theme manager.
RendererTestBase::assertRenderCacheItem protected function Asserts a render cache item.
RendererTestBase::randomContextValue protected static function Generates a random context value for the placeholder tests.
RendererTestBase::setUp protected function Overrides UnitTestCase::setUp 4
RendererTestBase::setUpMemoryCache protected function Sets up a memory-based render cache back-end.
RendererTestBase::setUpRequest protected function Sets up a request object on the request stack.
RendererTestBase::setUpUnusedCache protected function Sets up a render cache back-end that is asserted to be never used.
UnitTestCase::$root protected property The app root. 1
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::setUpBeforeClass public static function
UnitTestCase::__get public function

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.