*/ public static function placeholders(): array { return [ 'color alias' => ['{{color:primary}}', '$variable({"type":"color","value":{"name":"gcid-primary-color","settings":{}}})$'], 'color label' => ['{{ color : Nachtblau }}', '$variable({"type":"color","value":{"name":"gcid-a1b2","settings":{}}})$'], 'color id' => ['{{color:gcid-a1b2}}', '$variable({"type":"color","value":{"name":"gcid-a1b2","settings":{}}})$'], 'variable' => ['{{var:Telefon}}', '$variable({"type":"content","value":{"name":"gvid-s1","settings":{}}})$'], 'variable id' => ['{{var:gvid-s1}}', '$variable({"type":"content","value":{"name":"gvid-s1","settings":{}}})$'], 'font' => ['{{font:heading}}', '$variable({"type":"content","value":{"name":"--et_global_heading_font","settings":{}}})$'], 'post title' => [ '{{post:title}}', '$variable({"type":"content","value":{"name":"post_title","settings":{"before":"","after":""}}})$', ], 'featured image' => ['{{post:featured_image}}', '$variable({"type":"content","value":{"name":"post_featured_image","settings":{}}})$'], 'custom field' => [ '{{field:telefon_mobil}}', '$variable({"type":"content","value":{"name":"custom_meta_telefon_mobil","settings":{"before":"","after":""}}})$', ], 'plain text' => ['Hallo Welt', 'Hallo Welt'], ]; } /** @dataProvider placeholders */ public function testResolvesToDiviVariables(string $input, string $expected): void { $placeholders = ComposeFixture::placeholders(); $resolved = $placeholders->resolve($input); self::assertSame($expected, $resolved); if ($expected !== $input) { // What placeholders produce passes the strict checker unchanged (ruling S1/S25). self::assertSame($resolved, ComposeFixture::references()->canonical($resolved, ComposeFixture::sanitizer())); } } /** @return array */ public static function invalid(): array { return [ 'unknown color' => ['{{color:Lila}}', 'Vorhanden: primary, body, Primärfarbe, Fließtextfarbe, Nachtblau.'], 'unknown color id' => ['{{color:gcid-nope}}', 'Unbekannte globale Farbe'], 'unknown variable' => ['{{var:Fax}}', 'Vorhanden: Radius, Telefon'], 'unknown font' => ['{{font:mono}}', 'heading, body'], 'unknown post value' => ['{{post:views}}', 'title, excerpt'], 'bad field key' => ['{{field:a b}}', 'Ungültiger Feldschlüssel'], 'protected field key' => ['{{field:_edit_lock}}', 'Ungültiger Feldschlüssel'], 'embedded' => ['Seite: {{post:title}}', 'allein im Wert'], ]; } /** @dataProvider invalid */ public function testRejectsUnknownNamesWithTheExistingOnes(string $input, string $message): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage($message); ComposeFixture::placeholders()->resolve($input); } /** @return array */ public static function ambiguous(): array { return [ 'color label' => ['{{color:blau}}', 'gcid-b1, gcid-b2'], 'variable label' => ['{{var:Info}}', 'gvid-i1, gvid-i2'], ]; } /** * Ruling S13a: a label two entries share never silently picks the first one; IDs work directly. * * @dataProvider ambiguous */ public function testAmbiguousLabelsFailWithTheIds(string $input, string $ids): void { $placeholders = new Placeholders(new DesignSystem( [ ['id' => 'gcid-b1', 'label' => 'Blau', 'value' => '#00f'], ['id' => 'gcid-b2', 'label' => 'blau', 'value' => '#00a'], ], [ ['id' => 'gvid-i1', 'type' => 'strings', 'label' => 'Info', 'value' => 'a'], ['id' => 'gvid-i2', 'type' => 'strings', 'label' => 'Info', 'value' => 'b'], ], [], ['heading' => '', 'body' => ''], [] )); try { $placeholders->resolve($input); self::fail('Ambiguous label accepted.'); } catch (InvalidArgumentException $e) { self::assertStringContainsString('mehrdeutig', $e->getMessage()); self::assertStringContainsString($ids, $e->getMessage()); } self::assertStringContainsString('"gcid-b2"', $placeholders->resolve('{{color:gcid-b2}}')); self::assertStringContainsString('"gvid-i2"', $placeholders->resolve('{{var:gvid-i2}}')); } public function testColorTypeVariablesBecomeColorReferences(): void { $placeholders = new Placeholders(new DesignSystem( [], [['id' => 'gvid-c1', 'type' => 'colors', 'label' => 'Akzent', 'value' => '#f00']], [], ['heading' => '', 'body' => ''], [] )); self::assertSame( '$variable({"type":"color","value":{"name":"gvid-c1","settings":{}}})$', $placeholders->resolve('{{var:Akzent}}') ); } public function testResolvesDeepValues(): void { self::assertSame( ['color' => '$variable({"type":"color","value":{"name":"gcid-primary-color","settings":{}}})$', 'size' => '20px'], ComposeFixture::placeholders()->resolveDeep(['color' => '{{color:primary}}', 'size' => '20px']) ); } }