function RendererPlaceholdersTest::providerPlaceholders

Same name in other branches
  1. 9 core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php \Drupal\Tests\Core\Render\RendererPlaceholdersTest::providerPlaceholders()
  2. 10 core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php \Drupal\Tests\Core\Render\RendererPlaceholdersTest::providerPlaceholders()
  3. 11.x core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php \Drupal\Tests\Core\Render\RendererPlaceholdersTest::providerPlaceholders()

Provides the two classes of placeholders: cacheable and uncacheable.

I.e. with or without #cache[keys].

Also, different types:

  • A) automatically generated placeholder

    • 1) manually triggered (#create_placeholder = TRUE)
    • 2) automatically triggered (based on max-age = 0 at the top level)
    • 3) automatically triggered (based on high cardinality cache contexts at the top level)
    • 4) automatically triggered (based on high-invalidation frequency cache tags at the top level)
    • 5) automatically triggered (based on max-age = 0 in its subtree, i.e. via bubbling)
    • 6) automatically triggered (based on high cardinality cache contexts in its subtree, i.e. via bubbling)
    • 7) automatically triggered (based on high-invalidation frequency cache tags in its subtree, i.e. via bubbling)
  • B) manually generated placeholder

So, in total 2*8 = 16 permutations. (On one axis: uncacheable vs. uncacheable = 2; on the other axis: A1–7 and B = 8.)

@todo Case A5 is not yet supported by core. So that makes for only 14 permutations currently, instead of 16. That will be done in https://www.drupal.org/node/2559847

Return value

array

File

core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php, line 66

Class

RendererPlaceholdersTest
@coversDefaultClass \Drupal\Core\Render\Renderer @covers \Drupal\Core\Render\RenderCache @covers \Drupal\Core\Render\PlaceholderingRenderCache @group Render

Namespace

Drupal\Tests\Core\Render

Code

public function providerPlaceholders() {
    $args = [
        $this->randomContextValue(),
    ];
    $generate_placeholder_markup = function ($cache_keys = NULL) use ($args) {
        $token_render_array = [
            '#lazy_builder' => [
                'Drupal\\Tests\\Core\\Render\\PlaceholdersTest::callback',
                $args,
            ],
        ];
        if (is_array($cache_keys)) {
            $token_render_array['#cache']['keys'] = $cache_keys;
        }
        $token = Crypt::hashBase64(serialize($token_render_array));
        // \Drupal\Core\Render\Markup::create() is necessary as the render
        // system would mangle this markup. As this is exactly what happens at
        // runtime this is a valid use-case.
        return Markup::create('<drupal-render-placeholder callback="Drupal\\Tests\\Core\\Render\\PlaceholdersTest::callback" arguments="' . '0=' . $args[0] . '" token="' . $token . '"></drupal-render-placeholder>');
    };
    $extract_placeholder_render_array = function ($placeholder_render_array) {
        return array_intersect_key($placeholder_render_array, [
            '#lazy_builder' => TRUE,
            '#cache' => TRUE,
        ]);
    };
    // Note the presence of '#create_placeholder'.
    $base_element_a1 = [
        '#attached' => [
            'drupalSettings' => [
                'foo' => 'bar',
            ],
        ],
        'placeholder' => [
            '#cache' => [
                'contexts' => [],
            ],
            '#create_placeholder' => TRUE,
            '#lazy_builder' => [
                'Drupal\\Tests\\Core\\Render\\PlaceholdersTest::callback',
                $args,
            ],
        ],
    ];
    // Note the absence of '#create_placeholder', presence of max-age=0 at the
    // top level.
    $base_element_a2 = [
        '#attached' => [
            'drupalSettings' => [
                'foo' => 'bar',
            ],
        ],
        'placeholder' => [
            '#cache' => [
                'contexts' => [],
                'max-age' => 0,
            ],
            '#lazy_builder' => [
                'Drupal\\Tests\\Core\\Render\\PlaceholdersTest::callback',
                $args,
            ],
        ],
    ];
    // Note the absence of '#create_placeholder', presence of high cardinality
    // cache context at the top level.
    $base_element_a3 = [
        '#attached' => [
            'drupalSettings' => [
                'foo' => 'bar',
            ],
        ],
        'placeholder' => [
            '#cache' => [
                'contexts' => [
                    'user',
                ],
            ],
            '#lazy_builder' => [
                'Drupal\\Tests\\Core\\Render\\PlaceholdersTest::callback',
                $args,
            ],
        ],
    ];
    // Note the absence of '#create_placeholder', presence of high-invalidation
    // frequency cache tag at the top level.
    $base_element_a4 = [
        '#attached' => [
            'drupalSettings' => [
                'foo' => 'bar',
            ],
        ],
        'placeholder' => [
            '#cache' => [
                'contexts' => [],
                'tags' => [
                    'current-temperature',
                ],
            ],
            '#lazy_builder' => [
                'Drupal\\Tests\\Core\\Render\\PlaceholdersTest::callback',
                $args,
            ],
        ],
    ];
    // Note the absence of '#create_placeholder', presence of max-age=0 created
    // by the #lazy_builder callback.
    // @todo in https://www.drupal.org/node/2559847
    $base_element_a5 = [];
    // Note the absence of '#create_placeholder', presence of high cardinality
    // cache context created by the #lazy_builder callback.
    // @see \Drupal\Tests\Core\Render\PlaceholdersTest::callbackPerUser()
    $base_element_a6 = [
        '#attached' => [
            'drupalSettings' => [
                'foo' => 'bar',
            ],
        ],
        'placeholder' => [
            '#cache' => [
                'contexts' => [],
            ],
            '#lazy_builder' => [
                'Drupal\\Tests\\Core\\Render\\PlaceholdersTest::callbackPerUser',
                $args,
            ],
        ],
    ];
    // Note the absence of '#create_placeholder', presence of high-invalidation
    // frequency cache tag created by the #lazy_builder callback.
    // @see \Drupal\Tests\Core\Render\PlaceholdersTest::callbackTagCurrentTemperature()
    $base_element_a7 = [
        '#attached' => [
            'drupalSettings' => [
                'foo' => 'bar',
            ],
        ],
        'placeholder' => [
            '#cache' => [
                'contexts' => [],
            ],
            '#lazy_builder' => [
                'Drupal\\Tests\\Core\\Render\\PlaceholdersTest::callbackTagCurrentTemperature',
                $args,
            ],
        ],
    ];
    // Note the absence of '#create_placeholder', but the presence of
    // '#attached[placeholders]'.
    $base_element_b = [
        '#markup' => $generate_placeholder_markup(),
        '#attached' => [
            'drupalSettings' => [
                'foo' => 'bar',
            ],
            'placeholders' => [
                (string) $generate_placeholder_markup() => [
                    '#lazy_builder' => [
                        'Drupal\\Tests\\Core\\Render\\PlaceholdersTest::callback',
                        $args,
                    ],
                ],
            ],
        ],
    ];
    $keys = [
        'placeholder',
        'output',
        'can',
        'be',
        'render',
        'cached',
        'too',
    ];
    $cases = [];
    // Case one: render array that has a placeholder that is:
    // - automatically created, but manually triggered (#create_placeholder = TRUE)
    // - uncacheable
    $element_without_cache_keys = $base_element_a1;
    $expected_placeholder_render_array = $extract_placeholder_render_array($base_element_a1['placeholder']);
    $cases[] = [
        $element_without_cache_keys,
        $args,
        $expected_placeholder_render_array,
        FALSE,
        [],
        [],
        [],
    ];
    // Case two: render array that has a placeholder that is:
    // - automatically created, but manually triggered (#create_placeholder = TRUE)
    // - cacheable
    $element_with_cache_keys = $base_element_a1;
    $element_with_cache_keys['placeholder']['#cache']['keys'] = $keys;
    $expected_placeholder_render_array['#cache']['keys'] = $keys;
    $cases[] = [
        $element_with_cache_keys,
        $args,
        $expected_placeholder_render_array,
        $keys,
        [],
        [],
        [
            '#markup' => '<p>This is a rendered placeholder!</p>',
            '#attached' => [
                'drupalSettings' => [
                    'dynamic_animal' => $args[0],
                ],
            ],
            '#cache' => [
                'contexts' => [],
                'tags' => [],
                'max-age' => Cache::PERMANENT,
            ],
        ],
    ];
    // Case three: render array that has a placeholder that is:
    // - automatically created, and automatically triggered due to max-age=0
    // - uncacheable
    $element_without_cache_keys = $base_element_a2;
    $expected_placeholder_render_array = $extract_placeholder_render_array($base_element_a2['placeholder']);
    $cases[] = [
        $element_without_cache_keys,
        $args,
        $expected_placeholder_render_array,
        FALSE,
        [],
        [],
        [],
    ];
    // Case four: render array that has a placeholder that is:
    // - automatically created, but automatically triggered due to max-age=0
    // - cacheable
    $element_with_cache_keys = $base_element_a2;
    $element_with_cache_keys['placeholder']['#cache']['keys'] = $keys;
    $expected_placeholder_render_array['#cache']['keys'] = $keys;
    $cases[] = [
        $element_with_cache_keys,
        $args,
        $expected_placeholder_render_array,
        FALSE,
        [],
        [],
        [],
    ];
    // Case five: render array that has a placeholder that is:
    // - automatically created, and automatically triggered due to high
    //   cardinality cache contexts
    // - uncacheable
    $element_without_cache_keys = $base_element_a3;
    $expected_placeholder_render_array = $extract_placeholder_render_array($base_element_a3['placeholder']);
    $cases[] = [
        $element_without_cache_keys,
        $args,
        $expected_placeholder_render_array,
        FALSE,
        [],
        [],
        [],
    ];
    // Case six: render array that has a placeholder that is:
    // - automatically created, and automatically triggered due to high
    //   cardinality cache contexts
    // - cacheable
    $element_with_cache_keys = $base_element_a3;
    $element_with_cache_keys['placeholder']['#cache']['keys'] = $keys;
    $expected_placeholder_render_array['#cache']['keys'] = $keys;
    // The CID parts here consist of the cache keys plus the 'user' cache
    // context, which in this unit test is simply the given cache context token,
    // see \Drupal\Tests\Core\Render\RendererTestBase::setUp().
    $cid_parts = array_merge($keys, [
        'user',
    ]);
    $cases[] = [
        $element_with_cache_keys,
        $args,
        $expected_placeholder_render_array,
        $cid_parts,
        [],
        [],
        [
            '#markup' => '<p>This is a rendered placeholder!</p>',
            '#attached' => [
                'drupalSettings' => [
                    'dynamic_animal' => $args[0],
                ],
            ],
            '#cache' => [
                'contexts' => [
                    'user',
                ],
                'tags' => [],
                'max-age' => Cache::PERMANENT,
            ],
        ],
    ];
    // Case seven: render array that has a placeholder that is:
    // - automatically created, and automatically triggered due to high
    //   invalidation frequency cache tags
    // - uncacheable
    $element_without_cache_keys = $base_element_a4;
    $expected_placeholder_render_array = $extract_placeholder_render_array($base_element_a4['placeholder']);
    $cases[] = [
        $element_without_cache_keys,
        $args,
        $expected_placeholder_render_array,
        FALSE,
        [],
        [],
        [],
    ];
    // Case eight: render array that has a placeholder that is:
    // - automatically created, and automatically triggered due to high
    //   invalidation frequency cache tags
    // - cacheable
    $element_with_cache_keys = $base_element_a4;
    $element_with_cache_keys['placeholder']['#cache']['keys'] = $keys;
    $expected_placeholder_render_array['#cache']['keys'] = $keys;
    $cases[] = [
        $element_with_cache_keys,
        $args,
        $expected_placeholder_render_array,
        $keys,
        [],
        [],
        [
            '#markup' => '<p>This is a rendered placeholder!</p>',
            '#attached' => [
                'drupalSettings' => [
                    'dynamic_animal' => $args[0],
                ],
            ],
            '#cache' => [
                'contexts' => [],
                'tags' => [
                    'current-temperature',
                ],
                'max-age' => Cache::PERMANENT,
            ],
        ],
    ];
    // Case nine: render array that DOES NOT have a placeholder that is:
    // - NOT created, despite max-age=0 that is bubbled
    // - uncacheable
    // (because the render element with #lazy_builder does not have #cache[keys]
    // and hence the max-age=0 bubbles up further)
    // @todo in https://www.drupal.org/node/2559847
    // Case ten: render array that has a placeholder that is:
    // - automatically created, and automatically triggered due to max-age=0
    //   that is bubbled
    // - cacheable
    // @todo in https://www.drupal.org/node/2559847
    // Case eleven: render array that DOES NOT have a placeholder that is:
    // - NOT created, despite high cardinality cache contexts that are bubbled
    // - uncacheable
    $element_without_cache_keys = $base_element_a6;
    $expected_placeholder_render_array = $extract_placeholder_render_array($base_element_a6['placeholder']);
    $cases[] = [
        $element_without_cache_keys,
        $args,
        $expected_placeholder_render_array,
        FALSE,
        [
            'user',
        ],
        [],
        [],
    ];
    // Case twelve: render array that has a placeholder that is:
    // - automatically created, and automatically triggered due to high
    //   cardinality cache contexts that are bubbled
    // - cacheable
    $element_with_cache_keys = $base_element_a6;
    $element_with_cache_keys['placeholder']['#cache']['keys'] = $keys;
    $expected_placeholder_render_array['#cache']['keys'] = $keys;
    $cases[] = [
        $element_with_cache_keys,
        $args,
        $expected_placeholder_render_array,
        $keys,
        [
            'user',
        ],
        [],
        [
            '#markup' => '<p>This is a rendered placeholder!</p>',
            '#attached' => [
                'drupalSettings' => [
                    'dynamic_animal' => $args[0],
                ],
            ],
            '#cache' => [
                'contexts' => [
                    'user',
                ],
                'tags' => [],
                'max-age' => Cache::PERMANENT,
            ],
        ],
    ];
    // Case thirteen: render array that has a placeholder that is:
    // - automatically created, and automatically triggered due to high
    //   invalidation frequency cache tags that are bubbled
    // - uncacheable
    $element_without_cache_keys = $base_element_a7;
    $expected_placeholder_render_array = $extract_placeholder_render_array($base_element_a7['placeholder']);
    $cases[] = [
        $element_without_cache_keys,
        $args,
        $expected_placeholder_render_array,
        FALSE,
        [],
        [
            'current-temperature',
        ],
        [],
    ];
    // Case fourteen: render array that has a placeholder that is:
    // - automatically created, and automatically triggered due to high
    //   invalidation frequency cache tags that are bubbled
    // - cacheable
    $element_with_cache_keys = $base_element_a7;
    $element_with_cache_keys['placeholder']['#cache']['keys'] = $keys;
    $expected_placeholder_render_array['#cache']['keys'] = $keys;
    $cases[] = [
        $element_with_cache_keys,
        $args,
        $expected_placeholder_render_array,
        $keys,
        [],
        [],
        [
            '#markup' => '<p>This is a rendered placeholder!</p>',
            '#attached' => [
                'drupalSettings' => [
                    'dynamic_animal' => $args[0],
                ],
            ],
            '#cache' => [
                'contexts' => [],
                'tags' => [
                    'current-temperature',
                ],
                'max-age' => Cache::PERMANENT,
            ],
        ],
    ];
    // Case fifteen: render array that has a placeholder that is:
    // - manually created
    // - uncacheable
    $x = $base_element_b;
    $expected_placeholder_render_array = $x['#attached']['placeholders'][(string) $generate_placeholder_markup()];
    unset($x['#attached']['placeholders'][(string) $generate_placeholder_markup()]['#cache']);
    $cases[] = [
        $x,
        $args,
        $expected_placeholder_render_array,
        FALSE,
        [],
        [],
        [],
    ];
    // Case sixteen: render array that has a placeholder that is:
    // - manually created
    // - cacheable
    $x = $base_element_b;
    $x['#markup'] = $placeholder_markup = $generate_placeholder_markup($keys);
    $placeholder_markup = (string) $placeholder_markup;
    $x['#attached']['placeholders'] = [
        $placeholder_markup => [
            '#lazy_builder' => [
                'Drupal\\Tests\\Core\\Render\\PlaceholdersTest::callback',
                $args,
            ],
            '#cache' => [
                'keys' => $keys,
            ],
        ],
    ];
    $expected_placeholder_render_array = $x['#attached']['placeholders'][$placeholder_markup];
    $cases[] = [
        $x,
        $args,
        $expected_placeholder_render_array,
        $keys,
        [],
        [],
        [
            '#markup' => '<p>This is a rendered placeholder!</p>',
            '#attached' => [
                'drupalSettings' => [
                    'dynamic_animal' => $args[0],
                ],
            ],
            '#cache' => [
                'contexts' => [],
                'tags' => [],
                'max-age' => Cache::PERMANENT,
            ],
        ],
    ];
    return $cases;
}

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