feat: ThemeOptionBook – unveränderlicher Bestand der Theme-Optionen mit rev() (W6)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
a9edd850c1
commit
d9c4bc3751
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Design;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use LIT\MCP\Integrations\Divi\Design\ThemeOptionBook;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class ThemeOptionBookTest extends TestCase
|
||||
{
|
||||
/** @return array<string, mixed> The shape of get_option('et_divi') with the options of other areas around. */
|
||||
public static function stored(): array
|
||||
{
|
||||
return [
|
||||
'accent_color' => '#2ea3f2',
|
||||
'body_font_size' => 16,
|
||||
'heading_font' => false,
|
||||
'logo' => 'https://example.test/logo.png',
|
||||
'body_font_height' => 1.7,
|
||||
'body_header_style' => 'uppercase',
|
||||
'body_font' => 'Lato',
|
||||
];
|
||||
}
|
||||
|
||||
public function testOnlyWhitelistKeysStayInTheFixedOrderWithTheirRawTypes(): void
|
||||
{
|
||||
$book = ThemeOptionBook::fromDivi(self::stored());
|
||||
|
||||
self::assertSame([
|
||||
'heading_font' => false,
|
||||
'body_font' => 'Lato',
|
||||
'body_font_size' => 16,
|
||||
'body_font_height' => 1.7,
|
||||
'body_header_style' => 'uppercase',
|
||||
], $book->data());
|
||||
self::assertSame(['heading_font', 'body_font', 'body_font_size', 'body_font_height', 'body_header_style'],
|
||||
array_keys($book->data()));
|
||||
}
|
||||
|
||||
public function testNullAndValuesOfOtherTypesAreDropped(): void
|
||||
{
|
||||
$book = ThemeOptionBook::fromDivi([
|
||||
'heading_font' => null, 'body_font' => ['Lato'], 'content_width' => true, 'row_padding' => 0,
|
||||
'gutter_width' => '3', 'section_padding' => 0.0, 'body_header_spacing' => new \stdClass(),
|
||||
]);
|
||||
|
||||
self::assertSame(['gutter_width' => '3', 'section_padding' => 0.0, 'row_padding' => 0], $book->data());
|
||||
self::assertSame([], ThemeOptionBook::fromDivi([])->data());
|
||||
}
|
||||
|
||||
public function testHasAndGetDistinguishAFalseValueFromAMissingKey(): void
|
||||
{
|
||||
$book = ThemeOptionBook::fromDivi(self::stored());
|
||||
|
||||
self::assertTrue($book->has('heading_font'));
|
||||
self::assertFalse($book->get('heading_font'));
|
||||
self::assertFalse($book->has('primary_nav_font'));
|
||||
self::assertNull($book->get('primary_nav_font'));
|
||||
self::assertFalse($book->has('logo'));
|
||||
self::assertNull($book->get('logo'));
|
||||
self::assertSame(16, $book->get('body_font_size'));
|
||||
}
|
||||
|
||||
public function testRevIgnoresTheOrderAndOtherKeysButNotValuesOrTheirTypes(): void
|
||||
{
|
||||
$book = ThemeOptionBook::fromDivi(self::stored());
|
||||
$shuffled = ThemeOptionBook::fromDivi(array_reverse(self::stored(), true) + ['phone_body_font_size' => null]);
|
||||
|
||||
self::assertMatchesRegularExpression('/^[0-9a-f]{12}$/', $book->rev());
|
||||
self::assertSame($book->rev(), $shuffled->rev());
|
||||
self::assertSame($book->rev(), ThemeOptionBook::fromDivi($book->data())->rev());
|
||||
self::assertNotSame($book->rev(), $book->with('body_font_size', 17)->rev());
|
||||
self::assertNotSame($book->rev(), $book->with('body_font_size', '16')->rev(), '16 versus "16"');
|
||||
self::assertNotSame($book->rev(), $book->with('heading_font', 'Lato')->rev(), 'false versus a font');
|
||||
self::assertNotSame($book->rev(), $book->without('body_font_size')->rev());
|
||||
self::assertNotSame(
|
||||
ThemeOptionBook::fromDivi(['body_header_height' => 1])->rev(),
|
||||
ThemeOptionBook::fromDivi(['body_header_height' => 1.0])->rev(),
|
||||
'1 versus 1.0'
|
||||
);
|
||||
self::assertNotSame($book->rev(), ThemeOptionBook::fromDivi([])->rev());
|
||||
}
|
||||
|
||||
public function testWithAddsOrReplacesInPlaceOfTheFixedOrderAndLeavesTheOriginalAlone(): void
|
||||
{
|
||||
$book = ThemeOptionBook::fromDivi(self::stored());
|
||||
$changed = $book->with('primary_nav_font', 'Roboto')->with('body_font_size', 18);
|
||||
|
||||
self::assertSame(['heading_font', 'body_font', 'primary_nav_font', 'body_font_size', 'body_font_height',
|
||||
'body_header_style'], array_keys($changed->data()));
|
||||
self::assertSame(18, $changed->get('body_font_size'));
|
||||
self::assertSame(16, $book->get('body_font_size'));
|
||||
self::assertFalse($book->has('primary_nav_font'));
|
||||
self::assertFalse($book->with('body_font', false)->get('body_font'));
|
||||
}
|
||||
|
||||
public function testWithRejectsAKeyOutsideTheWhitelist(): void
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
ThemeOptionBook::fromDivi([])->with('accent_color', '#fff');
|
||||
}
|
||||
|
||||
public function testWithoutRemovesAKeyAndIgnoresAMissingOne(): void
|
||||
{
|
||||
$book = ThemeOptionBook::fromDivi(self::stored());
|
||||
$without = $book->without('heading_font');
|
||||
|
||||
self::assertFalse($without->has('heading_font'));
|
||||
self::assertTrue($book->has('heading_font'));
|
||||
self::assertSame($book->rev(), $book->without('row_padding')->rev());
|
||||
self::assertSame($book->data(), $book->without('logo')->data());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user