'divi/button', 'preset' => 'aaaaaaaaaa']; /** PresetBookTest::stored() with settings in "CTA primär" (aaaaaaaaaa): background colour #111111. */ private static function stored(): array { $stored = PresetBookTest::stored(); $stored['module']['divi/button']['items']['aaaaaaaaaa']['attrs'] = [ 'button' => ['decoration' => ['background' => ['desktop' => ['value' => ['color' => '#111111']]]]], ]; return $stored; } private static function assignment(): PresetAssignment { return new PresetAssignment( static fn (): PresetBook => PresetBook::fromDivi(self::stored()), static fn (string $module): array => $module === 'divi/text' ? ['content.decoration.bodyFont' => 'divi/font-body'] : [], static fn (string $id): bool => preg_match('/^[a-z0-9]{10}$/D', $id) === 1 ); } /** @return NodeIndex Blocks below s0.r0.c0 are m0, m1, … in the order of $inner. */ private static function index(string $inner): NodeIndex { return NodeIndex::build((new Parser())->parse( '' . $inner . '' )); } private static function node(NodeIndex $index, string $id): Block { $block = $index->find('s0.r0.c0.' . $id); self::assertNotNull($block); return $block; } public function testAssignsTheStackToBlocksOfTheModuleOnly(): void { $index = self::index(''); $rewrite = new AssignRewrite('divi/button', self::assignment(), ['preset' => ['aaaaaaaaaa', 'bbbbbbbbbb']]); $button = $rewrite->rewrite(self::node($index, 'm0')); self::assertSame(['aaaaaaaaaa', 'bbbbbbbbbb'], $button['modulePreset'] ?? null); self::assertNull($rewrite->rewrite(self::node($index, 'm1')), 'another module'); } public function testOnlyWithoutPresetSkipsBlocksWithAnExplicitPreset(): void { $index = self::index( '' . '' . '' ); $rewrite = new AssignRewrite('divi/button', self::assignment(), self::BUTTON, onlyWithoutPreset: true); self::assertNull($rewrite->rewrite(self::node($index, 'm0'))); self::assertSame(['aaaaaaaaaa'], $rewrite->rewrite(self::node($index, 'm1'))['modulePreset'] ?? null); self::assertSame(['aaaaaaaaaa'], $rewrite->rewrite(self::node($index, 'm2'))['modulePreset'] ?? null); } public function testOnlyWithPresetIdReplacesThatPreset(): void { $index = self::index( '' . '' . '' ); $rewrite = new AssignRewrite('divi/button', self::assignment(), self::BUTTON, onlyWithPresetId: 'bbbbbbbbbb'); self::assertSame(['aaaaaaaaaa'], $rewrite->rewrite(self::node($index, 'm0'))['modulePreset'] ?? null); self::assertNull($rewrite->rewrite(self::node($index, 'm1')), 'another preset'); self::assertNull($rewrite->rewrite(self::node($index, 'm2')), 'no preset at all'); } public function testBothFiltersMustHold(): void { $index = self::index(''); $rewrite = new AssignRewrite( 'divi/button', self::assignment(), self::BUTTON, onlyWithoutPreset: true, onlyWithPresetId: 'bbbbbbbbbb' ); self::assertNull($rewrite->rewrite(self::node($index, 'm0'))); } public function testRunningAgainChangesNothing(): void { $index = self::index(''); $rewrite = new AssignRewrite('divi/button', self::assignment(), self::BUTTON); self::assertNull($rewrite->rewrite(self::node($index, 'm0'))); } public function testGroupPresetsAreAssignedThroughTheKeyOfTheGroup(): void { $index = self::index(''); $rewrite = new AssignRewrite( 'divi/text', self::assignment(), ['group_presets' => ['font-body' => 'Lesetext']] ); $attrs = $rewrite->rewrite(self::node($index, 'm0')); self::assertSame( ['presetId' => ['gggggggggg'], 'groupName' => 'divi/font-body'], $attrs['groupPreset']['content.decoration.bodyFont'] ?? null ); self::assertArrayNotHasKey('modulePreset', $attrs); } public function testNotesDescribeWhatTheAssignedPresetCovers(): void { $index = self::index( '' . '' ); $rewrite = new AssignRewrite('divi/button', self::assignment(), self::BUTTON); $different = self::node($index, 'm0'); $different->setAttrs($rewrite->rewrite($different) ?? []); $notes = $rewrite->notes($different, 's0.r0.c0.m0'); self::assertCount(1, $notes); self::assertStringContainsString('s0.r0.c0.m0: lokale Werte überdecken „CTA primär“', $notes[0]); self::assertStringContainsString('clear_overrides: true entfernt sie.', $notes[0]); $same = self::node($index, 'm1'); $same->setAttrs($rewrite->rewrite($same) ?? []); self::assertSame([], $rewrite->notes($same, 's0.r0.c0.m1'), 'the same value covers nothing'); } public function testClearOverridesRemovesTheCoveredValuesAndHasNoNotes(): void { $index = self::index( '' ); $rewrite = new AssignRewrite('divi/button', self::assignment(), self::BUTTON, clearOverrides: true); $block = self::node($index, 'm0'); $attrs = $rewrite->rewrite($block); self::assertSame(['aaaaaaaaaa'], $attrs['modulePreset'] ?? null); self::assertArrayNotHasKey('button', $attrs, 'the local value and its empty parents are gone'); $block->setAttrs($attrs); self::assertSame([], $rewrite->notes($block, 's0.r0.c0.m0')); } public function testClearOverridesAloneAlsoChangesABlockThatAlreadyHasThePreset(): void { $index = self::index( '' ); $rewrite = new AssignRewrite('divi/button', self::assignment(), self::BUTTON, clearOverrides: true); $attrs = $rewrite->rewrite(self::node($index, 'm0')); self::assertSame(['modulePreset' => ['aaaaaaaaaa']], $attrs); } public function testAnUnvalidatedSpecIsALogicError(): void { $index = self::index(''); $rewrite = new AssignRewrite('divi/button', self::assignment(), ['preset' => 'Gibt es nicht']); $this->expectException(LogicException::class); $rewrite->rewrite(self::node($index, 'm0')); } public function testGlobalInstancesOfTheModuleConcernTheRewrite(): void { $index = self::index( '' . '' ); $rewrite = new AssignRewrite('divi/button', self::assignment(), self::BUTTON); self::assertTrue($rewrite->concernsInstance(self::node($index, 'g0'))); self::assertFalse($rewrite->concernsInstance(self::node($index, 'g1'))); } }