refactor: one VariableRef per composition, design lookups in DesignSystem (H3)
- DiviComposition::references() builds the one VariableRef with the entry's
live map (S22/S31) and passes it to AttrWriter; Placeholders only needs the
design system now, Placeholders::references() is gone (no reach-through).
- DesignSystem::colorIdFor()/variableFor() replace the dead colorId()/variable()
and carry Placeholders' lookup incl. the S13a ambiguity check (byLabel moved,
messages unchanged); isColorVariable() decides color vs content for {{var:}}.
- DesignSystem::colorReferenceIds() (VariableRef color names) and
contentVariableIds() (DynamicContentRules design names) replace the two
inline computations; same lists, same order.
Tests: fixtures/tests get the VariableRef from ComposeFixture::references() or
build it with the map; DesignSystemTest uses the new lookups (+2 tests).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
@@ -58,6 +58,7 @@ final class AttrWriter
|
||||
public function __construct(
|
||||
private ModuleCatalog $catalog,
|
||||
private Placeholders $placeholders,
|
||||
private VariableRef $references,
|
||||
private ValueSanitizer $sanitizer
|
||||
) {
|
||||
}
|
||||
@@ -263,7 +264,7 @@ final class AttrWriter
|
||||
$kind ??= $routed;
|
||||
if (VariableRef::contains($value)) {
|
||||
// The only way a reference is stored: whole, straight from canonical().
|
||||
return $this->placeholders->references()->canonical($value, $this->sanitizer, $kind === 'url');
|
||||
return $this->references->canonical($value, $this->sanitizer, $kind === 'url');
|
||||
}
|
||||
|
||||
$clean = match ($kind) {
|
||||
|
||||
@@ -116,13 +116,7 @@ final class DynamicContentRules
|
||||
));
|
||||
}
|
||||
|
||||
$design = array_values(DesignSystem::FONT_VARIABLES);
|
||||
foreach ($this->design->variables() as $variable) {
|
||||
if ($variable['type'] !== 'colors') {
|
||||
$design[] = $variable['id'];
|
||||
}
|
||||
}
|
||||
if (in_array($name, $design, true)) {
|
||||
if (in_array($name, $this->design->contentVariableIds(), true)) {
|
||||
return self::DESIGN_SETTINGS;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ use LIT\MCP\Integrations\Divi\Design\DesignSystem;
|
||||
* {{color:primary|<Name>|gcid-…}}, {{var:<Name>|gvid-…}}, {{font:heading|body}},
|
||||
* {{post:title|…}}, {{field:<meta_key>}}. A placeholder must be the whole value (D9); unknown
|
||||
* names fail with the list of existing ones, labels two entries share fail with their IDs
|
||||
* (ruling S13a). The result is still checked by VariableRef wherever it is written. Pure PHP.
|
||||
* (ruling S13a, DesignSystem::colorIdFor/variableFor). The result is still checked by VariableRef
|
||||
* wherever it is written. Pure PHP.
|
||||
*/
|
||||
final class Placeholders
|
||||
{
|
||||
@@ -36,21 +37,8 @@ final class Placeholders
|
||||
|
||||
private const PATTERN = '/^\{\{\s*(color|var|font|post|field)\s*:\s*([^{}]+?)\s*\}\}$/';
|
||||
|
||||
private VariableRef $references;
|
||||
|
||||
/**
|
||||
* @param array<string, array<string, string>>|null $dynamicContent Divi's dynamic content
|
||||
* options for VariableRef (ruling S22); null = DynamicContentRules::DEFAULT_DYNAMIC_CONTENT.
|
||||
*/
|
||||
public function __construct(private DesignSystem $design, ?array $dynamicContent = null)
|
||||
public function __construct(private DesignSystem $design)
|
||||
{
|
||||
$this->references = new VariableRef($design, $dynamicContent);
|
||||
}
|
||||
|
||||
/** The strict checker of $variable(…)$ values against this design system (ruling S1). */
|
||||
public function references(): VariableRef
|
||||
{
|
||||
return $this->references;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,18 +90,11 @@ final class Placeholders
|
||||
|
||||
private function color(string $name): string
|
||||
{
|
||||
$colors = $this->design->colors();
|
||||
$ids = array_column($colors, 'id');
|
||||
$alias = DesignSystem::COLOR_ALIASES[mb_strtolower($name)] ?? null;
|
||||
$id = match (true) {
|
||||
in_array($name, $ids, true) => $name,
|
||||
$alias !== null && in_array($alias, $ids, true) => $alias,
|
||||
default => self::byLabel($colors, $name, 'globale Farbe'),
|
||||
};
|
||||
|
||||
$id = $this->design->colorIdFor($name);
|
||||
if ($id === null) {
|
||||
$colors = $this->design->colors();
|
||||
$known = array_merge(
|
||||
array_keys(array_intersect(DesignSystem::COLOR_ALIASES, $ids)),
|
||||
array_keys(array_intersect(DesignSystem::COLOR_ALIASES, array_column($colors, 'id'))),
|
||||
array_column($colors, 'label')
|
||||
);
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
@@ -128,12 +109,9 @@ final class Placeholders
|
||||
|
||||
private function variable(string $name): string
|
||||
{
|
||||
$variables = $this->design->variables();
|
||||
$id = in_array($name, array_column($variables, 'id'), true)
|
||||
? $name
|
||||
: self::byLabel($variables, $name, 'globale Variable');
|
||||
$id = $this->design->variableFor($name);
|
||||
if ($id === null) {
|
||||
$labels = array_column($variables, 'label');
|
||||
$labels = array_column($this->design->variables(), 'label');
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Unbekannte globale Variable "%s". Vorhanden: %s.',
|
||||
$name,
|
||||
@@ -141,42 +119,7 @@ final class Placeholders
|
||||
));
|
||||
}
|
||||
|
||||
$type = 'content';
|
||||
foreach ($variables as $variable) {
|
||||
if ($variable['id'] === $id && $variable['type'] === 'colors') {
|
||||
$type = 'color';
|
||||
}
|
||||
}
|
||||
|
||||
return VariableRef::serialize($type, $id, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* ID of the one entry labelled $name (case-insensitive); null when none is.
|
||||
*
|
||||
* @param list<array{id: string, label: string}> $entries
|
||||
* @throws InvalidArgumentException When several entries share the label (ruling S13a).
|
||||
*/
|
||||
private static function byLabel(array $entries, string $name, string $what): ?string
|
||||
{
|
||||
$key = mb_strtolower($name);
|
||||
$ids = [];
|
||||
foreach ($entries as $entry) {
|
||||
if (mb_strtolower($entry['label']) === $key) {
|
||||
$ids[] = $entry['id'];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($ids) > 1) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Name der %s "%s" ist mehrdeutig; bitte die ID angeben: %s.',
|
||||
$what,
|
||||
$name,
|
||||
implode(', ', $ids)
|
||||
));
|
||||
}
|
||||
|
||||
return $ids[0] ?? null;
|
||||
return VariableRef::serialize($this->design->isColorVariable($id) ? 'color' : 'content', $id, []);
|
||||
}
|
||||
|
||||
private function font(string $name): string
|
||||
|
||||
@@ -204,13 +204,7 @@ final class VariableRef
|
||||
*/
|
||||
private function colorSettings(string $name, array $settings): array
|
||||
{
|
||||
$names = array_column($this->design->colors(), 'id');
|
||||
foreach ($this->design->variables() as $variable) {
|
||||
if ($variable['type'] === 'colors') {
|
||||
$names[] = $variable['id'];
|
||||
}
|
||||
}
|
||||
if (! in_array($name, $names, true)) {
|
||||
if (! in_array($name, $this->design->colorReferenceIds(), true)) {
|
||||
throw self::unknownName($name, 'color');
|
||||
}
|
||||
|
||||
|
||||
@@ -137,31 +137,60 @@ final class DesignSystem
|
||||
return $this->sizes;
|
||||
}
|
||||
|
||||
/** gcid of an alias (primary …), an ID or a label (case-insensitive); null when unknown. */
|
||||
public function colorId(string $name): ?string
|
||||
/**
|
||||
* gcid for a placeholder name: an ID, an alias (primary …) of an existing customizer color,
|
||||
* else the one color of that label (case-insensitive); null when unknown.
|
||||
*
|
||||
* @throws InvalidArgumentException When several colors share the label (ruling S13a).
|
||||
*/
|
||||
public function colorIdFor(string $name): ?string
|
||||
{
|
||||
$key = mb_strtolower(trim($name));
|
||||
$alias = self::COLOR_ALIASES[$key] ?? null;
|
||||
foreach ($this->colors as $color) {
|
||||
if ($color['id'] === $alias || $color['id'] === trim($name) || mb_strtolower($color['label']) === $key) {
|
||||
return $color['id'];
|
||||
}
|
||||
$ids = array_column($this->colors, 'id');
|
||||
$alias = self::COLOR_ALIASES[mb_strtolower($name)] ?? null;
|
||||
|
||||
return match (true) {
|
||||
in_array($name, $ids, true) => $name,
|
||||
$alias !== null && in_array($alias, $ids, true) => $alias,
|
||||
default => self::byLabel($this->colors, $name, 'globale Farbe'),
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
/**
|
||||
* gvid for a placeholder name: an ID, else the one variable of that label (case-insensitive);
|
||||
* null when unknown.
|
||||
*
|
||||
* @throws InvalidArgumentException When several variables share the label (ruling S13a).
|
||||
*/
|
||||
public function variableFor(string $name): ?string
|
||||
{
|
||||
return in_array($name, array_column($this->variables, 'id'), true)
|
||||
? $name
|
||||
: self::byLabel($this->variables, $name, 'globale Variable');
|
||||
}
|
||||
|
||||
/** @return array{id: string, type: string, label: string, value: string}|null By label or ID. */
|
||||
public function variable(string $name): ?array
|
||||
/** Whether $id is a global variable of type "colors" (a color reference, not content). */
|
||||
public function isColorVariable(string $id): bool
|
||||
{
|
||||
$key = mb_strtolower(trim($name));
|
||||
return in_array($id, $this->colorVariableIds(), true);
|
||||
}
|
||||
|
||||
/** @return list<string> Names a color reference may carry: global color IDs, then color variable IDs. */
|
||||
public function colorReferenceIds(): array
|
||||
{
|
||||
return array_merge(array_column($this->colors, 'id'), $this->colorVariableIds());
|
||||
}
|
||||
|
||||
/** @return list<string> Design names a content reference may carry: theme fonts, then non-color variable IDs. */
|
||||
public function contentVariableIds(): array
|
||||
{
|
||||
$ids = array_values(self::FONT_VARIABLES);
|
||||
foreach ($this->variables as $variable) {
|
||||
if ($variable['id'] === trim($name) || mb_strtolower($variable['label']) === $key) {
|
||||
return $variable;
|
||||
if ($variable['type'] !== 'colors') {
|
||||
$ids[] = $variable['id'];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,6 +261,47 @@ final class DesignSystem
|
||||
return '{{color:' . ($alias !== false ? $alias : $label) . '}}';
|
||||
}
|
||||
|
||||
/** @return list<string> */
|
||||
private function colorVariableIds(): array
|
||||
{
|
||||
$ids = [];
|
||||
foreach ($this->variables as $variable) {
|
||||
if ($variable['type'] === 'colors') {
|
||||
$ids[] = $variable['id'];
|
||||
}
|
||||
}
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* ID of the one entry labelled $name (case-insensitive); null when none is.
|
||||
*
|
||||
* @param list<array{id: string, label: string}> $entries
|
||||
* @throws InvalidArgumentException When several entries share the label (ruling S13a).
|
||||
*/
|
||||
private static function byLabel(array $entries, string $name, string $what): ?string
|
||||
{
|
||||
$key = mb_strtolower($name);
|
||||
$ids = [];
|
||||
foreach ($entries as $entry) {
|
||||
if (mb_strtolower($entry['label']) === $key) {
|
||||
$ids[] = $entry['id'];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($ids) > 1) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Name der %s "%s" ist mehrdeutig; bitte die ID angeben: %s.',
|
||||
$what,
|
||||
$name,
|
||||
implode(', ', $ids)
|
||||
));
|
||||
}
|
||||
|
||||
return $ids[0] ?? null;
|
||||
}
|
||||
|
||||
private static function plain(mixed $value): mixed
|
||||
{
|
||||
if (is_object($value)) {
|
||||
|
||||
@@ -12,6 +12,7 @@ use LIT\MCP\Integrations\Divi\Compose\ShortformWriter;
|
||||
use LIT\MCP\Integrations\Divi\Compose\StructureRules;
|
||||
use LIT\MCP\Integrations\Divi\Compose\TreeEditor;
|
||||
use LIT\MCP\Integrations\Divi\Compose\ValueSanitizer;
|
||||
use LIT\MCP\Integrations\Divi\Compose\VariableRef;
|
||||
use LIT\MCP\Integrations\Divi\Compose\Warnings;
|
||||
use LIT\MCP\Integrations\Divi\Design\DesignSystemReader;
|
||||
use LIT\MCP\Integrations\Divi\Schema\DiviModules;
|
||||
@@ -19,8 +20,9 @@ use LIT\MCP\Integrations\Divi\Schema\DiviModules;
|
||||
/**
|
||||
* Wires the pure Compose classes with the live catalog, design system, Divi's dynamic content
|
||||
* registry and the WordPress sanitizer/media lookup – once per request and entry. Ruling S31:
|
||||
* ONE Placeholders instance (carrying the live dynamic content map of the entry, S22) is shared
|
||||
* by AttrWriter and ShortformWriter, and the same AttrWriter serves ShortformWriter and Composer.
|
||||
* ONE VariableRef (carrying the live dynamic content map of the entry, S22) and ONE Placeholders
|
||||
* instance are shared by AttrWriter and ShortformWriter, and the same AttrWriter serves
|
||||
* ShortformWriter and Composer.
|
||||
*
|
||||
* forPost() binds the composition to the entry being written (DiviWriter::composition() does it
|
||||
* for the abilities); unbound, VariableRef's default map applies. Not final so abilities can be
|
||||
@@ -29,6 +31,7 @@ use LIT\MCP\Integrations\Divi\Schema\DiviModules;
|
||||
class DiviComposition
|
||||
{
|
||||
private ?int $postId = null;
|
||||
private ?VariableRef $references = null;
|
||||
private ?Placeholders $placeholders = null;
|
||||
private ?AttrWriter $attrWriter = null;
|
||||
private ?Composer $composer = null;
|
||||
@@ -42,11 +45,12 @@ class DiviComposition
|
||||
) {
|
||||
}
|
||||
|
||||
/** A fresh composition for entry $postId (own Placeholders with that entry's live map). */
|
||||
/** A fresh composition for entry $postId (own VariableRef with that entry's live map). */
|
||||
public function forPost(int $postId): static
|
||||
{
|
||||
$bound = clone $this;
|
||||
$bound->postId = $postId;
|
||||
$bound->references = null;
|
||||
$bound->placeholders = null;
|
||||
$bound->attrWriter = null;
|
||||
$bound->composer = null;
|
||||
@@ -54,18 +58,29 @@ class DiviComposition
|
||||
return $bound;
|
||||
}
|
||||
|
||||
/** The one Placeholders instance of this composition (ruling S31). */
|
||||
public function placeholders(): Placeholders
|
||||
/** The one checker of $variable(…)$ values of this composition, with the entry's live map (S22, S31). */
|
||||
public function references(): VariableRef
|
||||
{
|
||||
return $this->placeholders ??= new Placeholders(
|
||||
return $this->references ??= new VariableRef(
|
||||
$this->design->read(),
|
||||
$this->postId === null ? null : $this->dynamicContent->forPost($this->postId)
|
||||
);
|
||||
}
|
||||
|
||||
/** The one Placeholders instance of this composition (ruling S31). */
|
||||
public function placeholders(): Placeholders
|
||||
{
|
||||
return $this->placeholders ??= new Placeholders($this->design->read());
|
||||
}
|
||||
|
||||
public function attrWriter(): AttrWriter
|
||||
{
|
||||
return $this->attrWriter ??= new AttrWriter($this->modules->catalog(), $this->placeholders(), $this->sanitizer);
|
||||
return $this->attrWriter ??= new AttrWriter(
|
||||
$this->modules->catalog(),
|
||||
$this->placeholders(),
|
||||
$this->references(),
|
||||
$this->sanitizer
|
||||
);
|
||||
}
|
||||
|
||||
public function composer(): Composer
|
||||
|
||||
@@ -11,6 +11,7 @@ use LIT\MCP\Integrations\Divi\Compose\Placeholders;
|
||||
use LIT\MCP\Integrations\Divi\Compose\ShortformWriter;
|
||||
use LIT\MCP\Integrations\Divi\Compose\StructureRules;
|
||||
use LIT\MCP\Integrations\Divi\Compose\ValueSanitizer;
|
||||
use LIT\MCP\Integrations\Divi\Compose\VariableRef;
|
||||
use LIT\MCP\Integrations\Divi\Design\DesignSystem;
|
||||
|
||||
/**
|
||||
@@ -131,9 +132,15 @@ final class ComposeFixture
|
||||
return new Placeholders(DiviFixtures::designSystem());
|
||||
}
|
||||
|
||||
/** The strict $variable(…)$ checker for the sample design system and the default map. */
|
||||
public static function references(): VariableRef
|
||||
{
|
||||
return new VariableRef(DiviFixtures::designSystem());
|
||||
}
|
||||
|
||||
public static function attrWriter(bool $unfiltered = false): AttrWriter
|
||||
{
|
||||
return new AttrWriter(DiviFixtures::catalog(), self::placeholders(), self::sanitizer($unfiltered));
|
||||
return new AttrWriter(DiviFixtures::catalog(), self::placeholders(), self::references(), self::sanitizer($unfiltered));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,14 +158,14 @@ final class ComposeFixture
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder version 5.2.1. $design replaces the sample design system (one Placeholders instance
|
||||
* shared by AttrWriter and ShortformWriter, like the live wiring – ruling S31).
|
||||
* Builder version 5.2.1. $design replaces the sample design system (one Placeholders and one
|
||||
* VariableRef instance shared by AttrWriter and ShortformWriter, like the live wiring – ruling S31).
|
||||
*/
|
||||
public static function composer(bool $unfiltered = false, ?DesignSystem $design = null): Composer
|
||||
{
|
||||
$design ??= DiviFixtures::designSystem();
|
||||
$placeholders = new Placeholders($design);
|
||||
$attrWriter = new AttrWriter(DiviFixtures::catalog(), $placeholders, self::sanitizer($unfiltered));
|
||||
$attrWriter = new AttrWriter(DiviFixtures::catalog(), $placeholders, new VariableRef($design), self::sanitizer($unfiltered));
|
||||
|
||||
return new Composer(
|
||||
DiviFixtures::catalog(),
|
||||
|
||||
@@ -44,7 +44,7 @@ final class PlaceholdersTest extends TestCase
|
||||
self::assertSame($expected, $resolved);
|
||||
if ($expected !== $input) {
|
||||
// What placeholders produce passes the strict checker unchanged (ruling S1/S25).
|
||||
self::assertSame($resolved, $placeholders->references()->canonical($resolved, ComposeFixture::sanitizer()));
|
||||
self::assertSame($resolved, ComposeFixture::references()->canonical($resolved, ComposeFixture::sanitizer()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Design;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use LIT\MCP\Integrations\Divi\Design\DesignSystem;
|
||||
use LIT\MCP\Tests\Support\DiviFixtures;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
@@ -34,16 +35,53 @@ final class DesignSystemTest extends TestCase
|
||||
self::assertSame(['p-1' => 'Standard', 'p-2' => 'CTA primär', 'g-1' => 'Fließtext groß'], $design->presetNames());
|
||||
}
|
||||
|
||||
/** The name lists VariableRef/DynamicContentRules check references against (H3: one place). */
|
||||
public function testReferenceNameLists(): void
|
||||
{
|
||||
$design = new DesignSystem(
|
||||
[['id' => 'gcid-a', 'label' => 'A', 'value' => '#000']],
|
||||
[
|
||||
['id' => 'gvid-c', 'type' => 'colors', 'label' => 'C', 'value' => '#fff'],
|
||||
['id' => 'gvid-t', 'type' => 'strings', 'label' => 'T', 'value' => 'x'],
|
||||
],
|
||||
[],
|
||||
['heading' => '', 'body' => ''],
|
||||
[]
|
||||
);
|
||||
|
||||
self::assertSame(['gcid-a', 'gvid-c'], $design->colorReferenceIds());
|
||||
self::assertSame(['--et_global_heading_font', '--et_global_body_font', 'gvid-t'], $design->contentVariableIds());
|
||||
self::assertTrue($design->isColorVariable('gvid-c'));
|
||||
self::assertFalse($design->isColorVariable('gvid-t'));
|
||||
self::assertFalse($design->isColorVariable('gcid-a'));
|
||||
}
|
||||
|
||||
public function testLabelLookupsRefuseAmbiguousLabels(): void
|
||||
{
|
||||
$design = new DesignSystem(
|
||||
[['id' => 'gcid-a', 'label' => 'Blau', 'value' => '#00f'], ['id' => 'gcid-b', 'label' => 'blau', 'value' => '#00e']],
|
||||
[],
|
||||
[],
|
||||
['heading' => '', 'body' => ''],
|
||||
[]
|
||||
);
|
||||
|
||||
self::assertSame('gcid-b', $design->colorIdFor('gcid-b'));
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Name der globale Farbe "Blau" ist mehrdeutig; bitte die ID angeben: gcid-a, gcid-b.');
|
||||
$design->colorIdFor('Blau');
|
||||
}
|
||||
|
||||
public function testLooksUpByAliasLabelOrId(): void
|
||||
{
|
||||
$design = DiviFixtures::designSystem();
|
||||
|
||||
self::assertSame('gcid-primary-color', $design->colorId('primary'));
|
||||
self::assertSame('gcid-a1b2', $design->colorId('nachtblau'));
|
||||
self::assertSame('gcid-a1b2', $design->colorId('gcid-a1b2'));
|
||||
self::assertNull($design->colorId('secondary'));
|
||||
self::assertNull($design->colorId('Alt'));
|
||||
self::assertSame('gvid-s1', $design->variable('telefon')['id'] ?? null);
|
||||
self::assertSame('gcid-primary-color', $design->colorIdFor('primary'));
|
||||
self::assertSame('gcid-a1b2', $design->colorIdFor('nachtblau'));
|
||||
self::assertSame('gcid-a1b2', $design->colorIdFor('gcid-a1b2'));
|
||||
self::assertNull($design->colorIdFor('secondary'));
|
||||
self::assertNull($design->colorIdFor('Alt'));
|
||||
self::assertSame('gvid-s1', $design->variableFor('telefon'));
|
||||
self::assertSame('p-2', $design->modulePresetId('divi/button', 'cta PRIMÄR'));
|
||||
self::assertNull($design->modulePresetId('divi/text', 'Standard'));
|
||||
self::assertSame(['Standard', 'CTA primär'], $design->modulePresetNames('divi/button'));
|
||||
|
||||
@@ -71,6 +71,7 @@ final class DiviCompositionTest extends TestCase
|
||||
self::assertSame([7], $this->registryCalls, 'the registry is read once per post');
|
||||
self::assertSame($composition->attrWriter(), $composition->attrWriter());
|
||||
self::assertSame($composition->placeholders(), $composition->placeholders());
|
||||
self::assertSame($composition->references(), $composition->references());
|
||||
}
|
||||
|
||||
public function testWithoutAPostTheDefaultMapApplies(): void
|
||||
@@ -97,6 +98,8 @@ final class DiviCompositionTest extends TestCase
|
||||
self::assertNotSame($base, $seven);
|
||||
self::assertNotSame($seven->placeholders(), $eight->placeholders());
|
||||
self::assertNotSame($base->placeholders(), $seven->placeholders());
|
||||
self::assertNotSame($seven->references(), $eight->references());
|
||||
self::assertNotSame($base->references(), $seven->references());
|
||||
self::assertSame([7, 8], $this->registryCalls);
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ final class DiviWriterTest extends TestCase
|
||||
$writer = $this->writer(Mockery::mock(DiviSaver::class), FakeChangeLog::forbidden());
|
||||
$page = $writer->page(['post_id' => 7, 'tree_rev' => Rev::of($content)]);
|
||||
|
||||
$writer->composition($page)->placeholders();
|
||||
$writer->composition($page)->references();
|
||||
|
||||
self::assertSame([7], $this->registryCalls, 'the live dynamic content map of post 7 (ruling S22)');
|
||||
}
|
||||
|
||||
@@ -61,12 +61,13 @@ final class DynamicContentMapTest extends TestCase
|
||||
self::assertSame('select', $map['post_date']['date_format']);
|
||||
self::assertSame('text', $map['post_excerpt']['words']);
|
||||
|
||||
$placeholders = new Placeholders(DiviFixtures::designSystem(), $map);
|
||||
$placeholders = new Placeholders(DiviFixtures::designSystem());
|
||||
$references = new VariableRef(DiviFixtures::designSystem(), $map);
|
||||
foreach (array_keys(Placeholders::POST) as $key) {
|
||||
$reference = $placeholders->resolve('{{post:' . $key . '}}');
|
||||
self::assertSame(
|
||||
$reference,
|
||||
$placeholders->references()->canonical($reference, ComposeFixture::sanitizer()),
|
||||
$references->canonical($reference, ComposeFixture::sanitizer()),
|
||||
$key
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user