From 2375eba02403bf51737cdc31c9a2e74745f59086 Mon Sep 17 00:00:00 2001 From: Thoriq Firdaus <2067467+tfirdaus@users.noreply.github.com> Date: Sun, 29 Sep 2024 21:23:36 +0700 Subject: [PATCH] Remove `SettingsProvider` (#13) * Remove `SettingsProvider` * Some improvements to the PluginTest --- app/Core/App.php | 22 +- app/Facades/App.php | 4 +- app/Facades/Config.php | 20 -- app/Foundation/Settings/Registry.php | 92 ------ app/Foundation/Settings/Setting.php | 144 --------- .../Settings/Support/SettingRegistrar.php | 73 ----- app/Plugin.php | 6 +- app/Providers/SettingsProvider.php | 104 ------ tests/app/Facades/AppTest.php | 39 +-- tests/app/Facades/ConfigTest.php | 42 --- .../app/Foundation/Settings/RegistryTest.php | 305 ------------------ tests/app/Foundation/Settings/SettingTest.php | 29 -- .../Settings/Support/SettingRegistrarTest.php | 24 -- tests/app/PluginTest.php | 225 ++++++------- 14 files changed, 118 insertions(+), 1011 deletions(-) delete mode 100644 app/Facades/Config.php delete mode 100644 app/Foundation/Settings/Registry.php delete mode 100644 app/Foundation/Settings/Setting.php delete mode 100644 app/Foundation/Settings/Support/SettingRegistrar.php delete mode 100644 app/Providers/SettingsProvider.php delete mode 100644 tests/app/Facades/ConfigTest.php delete mode 100644 tests/app/Foundation/Settings/RegistryTest.php delete mode 100644 tests/app/Foundation/Settings/SettingTest.php delete mode 100644 tests/app/Foundation/Settings/Support/SettingRegistrarTest.php diff --git a/app/Core/App.php b/app/Core/App.php index 8925dab..824e941 100644 --- a/app/Core/App.php +++ b/app/Core/App.php @@ -4,21 +4,16 @@ namespace Codex\Core; -use Codex\Foundation\Settings\Registry; -use Syntatis\Utils\Val; - final class App { private string $name; - /** @var array */ - private array $settingRegistries = []; + private Config $config; - /** @param array $settingRegistries */ - public function __construct(string $name, array $settingRegistries = []) + public function __construct(string $name, Config $config) { $this->name = $name; - $this->settingRegistries = $settingRegistries; + $this->config = $config; } public function name(): string @@ -26,15 +21,8 @@ public function name(): string return $this->name; } - /** @return array|Registry|null */ - public function settings(?string $group = null) + public function config(): Config { - if (! Val::isBlank($group)) { - $group = $this->name . '/' . $group; - - return $this->settingRegistries[$group] ?? null; - } - - return $this->settingRegistries; + return $this->config; } } diff --git a/app/Facades/App.php b/app/Facades/App.php index 8fe2056..63b25a9 100644 --- a/app/Facades/App.php +++ b/app/Facades/App.php @@ -5,11 +5,11 @@ namespace Codex\Facades; use Codex\Abstracts\Facade; -use Codex\Foundation\Settings\Registry; +use Codex\Core\Config; /** * @method static string name() Retrieve the application name. - * @method static array|Registry|null settings(?string $group = null) Retrieve the setting registry collection. + * @method static Config config() Retrieve the app config object. */ final class App extends Facade { diff --git a/app/Facades/Config.php b/app/Facades/Config.php deleted file mode 100644 index 52a0bed..0000000 --- a/app/Facades/Config.php +++ /dev/null @@ -1,20 +0,0 @@ - */ - private array $settings = []; - - /** @var array */ - private array $registered = []; - - public function __construct(string $settingGroup) - { - if (Val::isBlank($settingGroup)) { - throw new InvalidArgumentException('The setting group cannot be empty.'); - } - - $this->settingGroup = $settingGroup; - } - - public function setPrefix(string $prefix): void - { - $this->prefix = $prefix; - } - - public function addSettings(Setting ...$settings): void - { - foreach ($settings as $key => $setting) { - $this->settings[$setting->getName()] = $setting; - } - } - - public function register(): void - { - foreach ($this->settings as $setting) { - $registry = new SettingRegistrar($setting, $this->settingGroup); - $registry->setPrefix($this->prefix); - $registry->register(); - - $this->registered[$registry->getName()] = $registry; - } - } - - public function isRegistered(): bool - { - return count($this->registered) === count($this->settings); - } - - public function getSettingGroup(): string - { - return $this->settingGroup; - } - - /** @return array */ - public function getSettings(): array - { - return $this->settings; - } - - /** @return array */ - public function getRegisteredSettings(): array - { - return $this->registered; - } - - /** - * Remove options from the registry. - * - * @param bool $delete Whether to delete the options from the database. - */ - public function deregister(bool $delete = false): void - { - foreach ($this->registered as $key => $registry) { - $registry->deregister($delete); - unset($this->registered[$key]); - } - } -} diff --git a/app/Foundation/Settings/Setting.php b/app/Foundation/Settings/Setting.php deleted file mode 100644 index dbb2786..0000000 --- a/app/Foundation/Settings/Setting.php +++ /dev/null @@ -1,144 +0,0 @@ ->|null - * @phpstan-type ValueFormat 'date-time'|'uri'|'email'|'ip'|'uuid'|'hex-color' - * @phpstan-type ValueType 'string'|'boolean'|'integer'|'number'|'array'|'object' - * @phpstan-type APISchemaProperties array|bool|float|int|string}> - * @phpstan-type APISchema array{properties?: APISchemaProperties, items?: array{type?: ValueType, format?: ValueFormat}} - * @phpstan-type APIConfig array{name?: string, schema: APISchema} - * @phpstan-type SettingVars array{description?: string, show_in_rest?: APIConfig|bool} - * @phpstan-type SettingArgs array{type: ValueType, default: ValueDefault, description?: string, show_in_rest?: APIConfig|bool} - */ -class Setting -{ - protected string $name; - - /** @phpstan-var ValueType */ - protected string $type = 'string'; - - /** @phpstan-var ValueDefault */ - protected $default = null; - - /** - * The priority determines the order in which the `option_` related hooks - * are executed. - */ - protected int $priority = 73; - - /** - * @var array - * @phpstan-var SettingVars - */ - protected array $settingVars = ['show_in_rest' => true]; - - /** @phpstan-param ValueType $type */ - public function __construct(string $name, string $type = 'string') - { - if (Val::isBlank($name)) { - throw new InvalidArgumentException('Option name must not be blank.'); - } - - $this->name = $name; - $this->type = $type; - } - - public function getName(): string - { - return $this->name; - } - - /** - * @param array|bool|float|int|string $value - * @phpstan-param ValueDefault $value - * - * @return static - */ - public function withDefault($value) - { - $self = clone $this; - $self->default = $value; - - return $self; - } - - /** @return static */ - public function withLabel(string $label) - { - $self = clone $this; - $self->settingVars['label'] = $label; - - return $self; - } - - /** @return static */ - public function withDescription(string $value) - { - $self = clone $this; - $self->settingVars['description'] = $value; - - return $self; - } - - /** @return static */ - public function withPriority(int $priority) - { - $self = clone $this; - $self->priority = $priority; - - return $self; - } - - /** - * Whether to show the option on WordPress REST API endpoint, `/wp/v2/settings`. - * - * @phpstan-param APISchema $schema - * - * @return static - */ - public function apiSchema(array $schema) - { - $self = clone $this; - $self->settingVars['show_in_rest'] = [ - 'name' => $this->name, - 'schema' => $schema, - ]; - - return $self; - } - - /** @phpstan-return ValueDefault */ - public function getDefault() - { - return $this->default; - } - - public function getPriority(): int - { - return $this->priority; - } - - /** - * Retrieve the arguments to pass for the `register_setting` function. - * - * @see https://developer.wordpress.org/reference/functions/register_setting/#parameters - * - * @phpstan-return SettingArgs - */ - public function getSettingArgs(): array - { - return array_merge([ - 'type' => $this->type, - 'default' => $this->default, - ], $this->settingVars); - } -} diff --git a/app/Foundation/Settings/Support/SettingRegistrar.php b/app/Foundation/Settings/Support/SettingRegistrar.php deleted file mode 100644 index 3740500..0000000 --- a/app/Foundation/Settings/Support/SettingRegistrar.php +++ /dev/null @@ -1,73 +0,0 @@ -setting = $setting; - $this->group = $group; - $this->name = $setting->getName(); - } - - /** - * Set the option prefix. e.g. `codex_`. - */ - public function setPrefix(string $prefix = ''): void - { - $this->name = trim($prefix) . $this->name; - } - - /** - * Retrieve the option name to register, which may contain the prefix if set. - */ - public function getName(): string - { - return $this->name; - } - - public function getGroup(): string - { - return $this->group; - } - - public function getSetting(): Setting - { - return $this->setting; - } - - public function register(): void - { - register_setting( - $this->group, - $this->name, - $this->setting->getSettingArgs(), - ); - } - - public function deregister(bool $delete = false): void - { - unregister_setting($this->group, $this->name); - - if ($delete !== true) { - return; - } - - delete_option($this->name); - } -} diff --git a/app/Plugin.php b/app/Plugin.php index cbb2f08..7a1d9f2 100644 --- a/app/Plugin.php +++ b/app/Plugin.php @@ -15,7 +15,6 @@ use Codex\Core\Config; use Codex\Foundation\Blocks; use Codex\Foundation\Hooks\Hook; -use Codex\Foundation\Settings\Registry; use InvalidArgumentException; use Pimple\Container as PimpleContainer; use Pimple\Psr11\Container; @@ -239,10 +238,7 @@ private function registerCoreServices(): void throw new InvalidArgumentException('The app "name" is required and cannot be empty.'); } - /** @var array $settingRegistries */ - $settingRegistries = $container['app/setting_registries'] ?? []; - - return new App($name, $settingRegistries); + return new App($name, $config); }; } } diff --git a/app/Providers/SettingsProvider.php b/app/Providers/SettingsProvider.php deleted file mode 100644 index 7a0d87d..0000000 --- a/app/Providers/SettingsProvider.php +++ /dev/null @@ -1,104 +0,0 @@ -container['app/setting_registries'] = static function (Container $container): array { - /** @var Config $config */ - $config = $container['app/config']; - $filePath = $container['app/plugin_file_path'] ?? ''; - $filePath = is_string($filePath) ? $filePath : ''; - - if (Val::isBlank($filePath)) { - throw new InvalidArgumentException('The plugin file path is required to register the settings.'); - } - - $settingsDir = wp_normalize_path(dirname($filePath) . '/inc/settings'); - - if (! is_dir($settingsDir)) { - throw new InvalidArgumentException('The settings directory does not exist.'); - } - - $appName = $config->get('app.name'); - $settingFiles = new RecursiveDirectoryIterator( - $settingsDir, - RecursiveDirectoryIterator::SKIP_DOTS, - ); - - /** @var array $settingRegistries */ - $settingRegistries = []; - - foreach ($settingFiles as $settingFile) { - if ( - ! $settingFile instanceof SplFileInfo || - ! $settingFile->isFile() || - $settingFile->getExtension() !== 'php' - ) { - continue; - } - - /** @var array $register */ - $register = include $settingFile->getPathname(); - $settingGroup = $appName . '/' . $settingFile->getBasename('.php'); - - if (Val::isBlank($register)) { - continue; - } - - /** - * Defines the registry to register and manage the plugin settings. - * - * The registry allows us to register the plugin options in the WordPress - * Setting API with their type, default, and other attributes. - */ - $registry = new Registry($settingGroup); - $registry->addSettings(...$register); - - if (! $config->isBlank('app.option_prefix')) { - /** @var string $prefix */ - $prefix = $config->get('app.option_prefix'); - $registry->setPrefix($prefix); - } - - $settingRegistries[$settingGroup] = $registry; - } - - return $settingRegistries; - }; - } - - public function boot(): void - { - /** - * Register all the options added in the registry. - * - * @var array $settings - */ - $settings = $this->container['app/setting_registries']; - - foreach ($settings as $setting) { - $this->hook->addAction('admin_init', [$setting, 'register']); - $this->hook->addAction('rest_api_init', [$setting, 'register']); - } - } -} diff --git a/tests/app/Facades/AppTest.php b/tests/app/Facades/AppTest.php index f22d6dd..855c4aa 100644 --- a/tests/app/Facades/AppTest.php +++ b/tests/app/Facades/AppTest.php @@ -6,15 +6,10 @@ use Codex\Contracts\Extendable; use Codex\Facades\App; -use Codex\Foundation\Settings\Registry; -use Codex\Foundation\Settings\Support\SettingRegistrar; use Codex\Plugin; -use Codex\Providers\SettingsProvider; use Codex\Tests\WPTestCase; use Psr\Container\ContainerInterface; -use function array_key_exists; - class AppTest extends WPTestCase { // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps @@ -72,14 +67,13 @@ public function init(): void } }, ); - $app->addServices([SettingsProvider::class]); $app->setPluginFilePath(self::getFixturesPath('/plugin-name.php')); $app->boot(); $this->assertSame('wp-test', App::name()); } - public function testSettings(): void + public function testConfig(): void { $app = new Plugin( new class () implements Extendable { @@ -93,30 +87,17 @@ public function init(): void } }, ); - $app->addServices([SettingsProvider::class]); $app->setPluginFilePath(self::getFixturesPath('/plugin-name.php')); $app->boot(); - do_action('admin_init'); - - $settings = App::settings(); - - $this->assertArrayNotHasKey('wp-test/plugin-foo', $settings); // Unsupported file extension, `.json`. - $this->assertArrayNotHasKey('wp-test/plugin-name-1', $settings); // Settings empty. - - // wp-test/plugin-name-0 - $this->assertInstanceOf(Registry::class, $settings['wp-test/plugin-name-0']); - $this->assertTrue($settings['wp-test/plugin-name-0']->isRegistered()); - $this->assertTrue(array_key_exists('wp_test_foo', $settings['wp-test/plugin-name-0']->getRegisteredSettings())); - $this->assertInstanceOf(SettingRegistrar::class, $settings['wp-test/plugin-name-0']->getRegisteredSettings()['wp_test_foo']); - - // wp-test/plugin-name-2 - $this->assertInstanceOf(Registry::class, $settings['wp-test/plugin-name-2']); - $this->assertTrue($settings['wp-test/plugin-name-2']->isRegistered()); - - $setting = App::settings('plugin-name-2'); - - $this->assertInstanceOf(Registry::class, $setting); - $this->assertSame('wp-test/plugin-name-2', $setting->getSettingGroup()); + self::assertSame('wp-test', App::config()->get('app.text_domain')); + self::assertSame('/dist', App::config()->get('app.assets_path')); + self::assertSame('https://example.org/dist', App::config()->get('app.assets_url')); + self::assertSame('wp_test_', App::config()->get('app.option_prefix')); + self::assertSame('wp_test_', App::config()->get('app.option_prefix')); + self::assertTrue(App::config()->has('app.option_prefix')); + self::assertFalse(App::config()->has('non-existent-key')); + self::assertTrue(App::config()->isBlank('empty')); + self::assertTrue(App::config()->isBlank('blank')); } } diff --git a/tests/app/Facades/ConfigTest.php b/tests/app/Facades/ConfigTest.php deleted file mode 100644 index 63e8a71..0000000 --- a/tests/app/Facades/ConfigTest.php +++ /dev/null @@ -1,42 +0,0 @@ -setPluginFilePath(self::getFixturesPath('/plugin-name.php')); - $app->boot(); - - self::assertSame('wp-test', Config::get('app.text_domain')); - self::assertSame('/dist', Config::get('app.assets_path')); - self::assertSame('https://example.org/dist', Config::get('app.assets_url')); - self::assertSame('wp_test_', Config::get('app.option_prefix')); - self::assertSame('wp_test_', Config::get('app.option_prefix')); - self::assertTrue(Config::has('app.option_prefix')); - self::assertFalse(Config::has('non-existent-key')); - self::assertTrue(Config::isBlank('empty')); - self::assertTrue(Config::isBlank('blank')); - } -} diff --git a/tests/app/Foundation/Settings/RegistryTest.php b/tests/app/Foundation/Settings/RegistryTest.php deleted file mode 100644 index 6aa4f9b..0000000 --- a/tests/app/Foundation/Settings/RegistryTest.php +++ /dev/null @@ -1,305 +0,0 @@ -hook = new Hook(); - } - - /** @dataProvider dataInvalidGroup */ - public function testInvalidGroup(string $group): void - { - $this->expectException(InvalidArgumentException::class); - - new Registry($group); - } - - public static function dataInvalidGroup(): iterable - { - yield ['']; - yield [' ']; - } - - public function testIsRegistered(): void - { - $registry = new Registry('codex'); - $registry->addSettings(...[ - (new Setting('say')) - ->withDefault('Hello, World!'), - (new Setting('count', 'number')) - ->withDefault(1), - (new Setting('list', 'array')) - ->withDefault(['count', 'two', 'three']) - ->apiSchema(['items' => ['type' => 'string']]), - ]); - $registry->register(); - - $this->assertTrue($registry->isRegistered()); - - $registry->deregister(); - - $this->assertFalse($registry->isRegistered()); - } - - public function testRegisteredSettings(): void - { - $registry = new Registry('codex'); - $registry->addSettings(...[ - (new Setting('say', 'string')) - ->withDefault('Hello, World!') - ->withLabel('Say'), - (new Setting('count', 'integer')) - ->withDefault(1) - ->withDescription('How many time?'), - (new Setting('list', 'array')) - ->withDefault(['count', 'two', 'three']) - ->apiSchema(['items' => ['type' => 'string']]), - ]); - $registeredSettings = get_registered_settings(); - - $this->assertArrayNotHasKey('say', $registeredSettings); - $this->assertArrayNotHasKey('count', $registeredSettings); - $this->assertArrayNotHasKey('list', $registeredSettings); - - $registry->register(); - - $registeredSettings = get_registered_settings(); - - $this->assertArrayHasKey('say', $registeredSettings); - $this->assertSame('string', $registeredSettings['say']['type']); - $this->assertSame('', $registeredSettings['say']['description']); - $this->assertTrue($registeredSettings['say']['show_in_rest']); - - if (version_compare($GLOBALS['wp_version'], '6.6', '>=')) { - $this->assertSame('Say', $registeredSettings['say']['label']); - } - - $this->assertArrayHasKey('count', $registeredSettings); - $this->assertSame('integer', $registeredSettings['count']['type']); - $this->assertSame('How many time?', $registeredSettings['count']['description']); - $this->assertTrue($registeredSettings['count']['show_in_rest']); - - if (version_compare($GLOBALS['wp_version'], '6.6', '>=')) { - $this->assertSame('', $registeredSettings['count']['label']); - } - - $this->assertArrayHasKey('list', $registeredSettings); - $this->assertSame('array', $registeredSettings['list']['type']); - $this->assertSame('', $registeredSettings['list']['description']); - $this->assertEquals([ - 'name' => 'list', - 'schema' => ['items' => ['type' => 'string']], - ], $registeredSettings['list']['show_in_rest']); - - if (version_compare($GLOBALS['wp_version'], '6.6', '>=')) { - $this->assertSame('', $registeredSettings['list']['label']); - } - - $registry->deregister(); - - $registeredSettings = get_registered_settings(); - - $this->assertArrayNotHasKey('say', $registeredSettings); - $this->assertArrayNotHasKey('count', $registeredSettings); - $this->assertArrayNotHasKey('list', $registeredSettings); - } - - public function testDefault(): void - { - $registry = new Registry('codex'); - $registry->addSettings(...[ - (new Setting('say', 'string')) - ->withDefault('Hello, World!'), - (new Setting('count', 'number')) - ->withDefault(1), - (new Setting('list', 'array')) - ->withDefault(['count', 'two', 'three']) - ->apiSchema(['items' => ['type' => 'string']]), - ]); - - $this->assertFalse(get_option('say')); - $this->assertFalse(get_option('count')); - $this->assertFalse(get_option('list')); - - $registry->register(); - - $this->assertSame('Hello, World!', get_option('say')); - $this->assertSame(1, get_option('count')); - $this->assertSame(['count', 'two', 'three'], get_option('list')); - - $registry->deregister(); - - $this->assertFalse(get_option('say')); - $this->assertFalse(get_option('count')); - $this->assertFalse(get_option('list')); - } - - public function testPrefix(): void - { - $registry = new Registry('codex'); - $registry->addSettings(...[ - (new Setting('say', 'string')) - ->withDefault('Hello, World!'), - (new Setting('count', 'number')) - ->withDefault(1), - (new Setting('list', 'array')) - ->withDefault(['count', 'two', 'three']) - ->apiSchema(['items' => ['type' => 'string']]), - ]); - $registry->setPrefix('codex_'); - - $this->assertFalse(get_option('codex_say')); - $this->assertFalse(get_option('codex_count')); - $this->assertFalse(get_option('codex_list')); - - $registry->register(); - - $this->assertSame('Hello, World!', get_option('codex_say')); - $this->assertSame(1, get_option('codex_count')); - $this->assertSame(['count', 'two', 'three'], get_option('codex_list')); - - $registry->deregister(); - - $this->assertFalse(get_option('codex_say')); - $this->assertFalse(get_option('codex_count')); - $this->assertFalse(get_option('codex_list')); - } - - public function testAddOption(): void - { - $registry = new Registry('codex'); - $registry->addSettings(...[ - (new Setting('say', 'string')) - ->withDefault('Hello, World!'), - ]); - $registry->setPrefix('codex_'); - $registry->register(); - - $this->assertSame('Hello, World!', get_option('codex_say')); - $this->assertTrue(add_option('codex_say', 'Hi')); - $this->assertSame('Hi', get_option('codex_say')); - } - - public function testUpdateOption(): void - { - $registry = new Registry('codex'); - $registry->addSettings(...[ - (new Setting('say', 'string')) - ->withDefault('Hello, World!'), - ]); - $registry->setPrefix('codex_'); - $registry->register(); - - $this->assertTrue(add_option('codex_say', 'Hi')); - $this->assertSame('Hi', get_option('codex_say')); - $this->assertTrue(update_option('codex_say', 'Hai')); - $this->assertSame('Hai', get_option('codex_say')); - } - - public function testDeleteOption(): void - { - $registry = new Registry('codex'); - $registry->addSettings(...[ - (new Setting('say', 'string')) - ->withDefault('Hello, World!'), - ]); - $registry->setPrefix('codex_'); - $registry->register(); - - $this->assertSame('Hello, World!', get_option('codex_say')); - $this->assertTrue(update_option('codex_say', 'Hai')); - $this->assertSame('Hai', get_option('codex_say')); - $this->assertTrue(delete_option('codex_say')); - $this->assertSame('Hello, World!', get_option('codex_say')); - } - - public function testPassingDefault(): void - { - $registry = new Registry('codex'); - $registry->addSettings(...[ - (new Setting('say', 'string')) - ->withDefault('Hello, World!'), - ]); - $registry->setPrefix('codex_'); - $registry->register(); - - $this->assertSame('Hello, World!', get_option('codex_say')); - $this->assertSame('Hai', get_option('codex_say', 'Hai')); - } - - public function testDeregister(): void - { - $wpdb = $GLOBALS['wpdb']; - $registry = new Registry('codex'); - $registry->addSettings(...[ - (new Setting('say', 'string')) - ->withDefault('Hello, World!'), - ]); - $registry->setPrefix('codex_'); - $registry->register(); - - $this->assertSame('Hello, World!', get_option('codex_say')); - $this->assertTrue(update_option('codex_say', 'World')); - $this->assertSame('World', get_option('codex_say')); - - // phpcs:ignore Squiz.Strings.DoubleQuoteUsage.ContainsVar - $row = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'codex_say')); - - $this->assertEquals(['option_value' => 'World'], (array) $row); - - $registry->deregister(); - - // phpcs:ignore Squiz.Strings.DoubleQuoteUsage.ContainsVar - $row = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'codex_say')); - - $this->assertEquals(['option_value' => 'World'], (array) $row); - $this->assertSame('World', get_option('codex_say')); - } - - public function testDeregisterWithDelete(): void - { - $wpdb = $GLOBALS['wpdb']; - $registry = new Registry('codex'); - $registry->addSettings(...[ - (new Setting('say', 'string')) - ->withDefault('Hello, World!'), - ]); - $registry->setPrefix('codex_'); - $registry->register(); - - $this->assertSame('Hello, World!', get_option('codex_say')); - $this->assertTrue(update_option('codex_say', 'World')); - $this->assertSame('World', get_option('codex_say')); - - // phpcs:ignore Squiz.Strings.DoubleQuoteUsage.ContainsVar - $row = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'codex_say')); - - $this->assertEquals(['option_value' => 'World'], (array) $row); - - $registry->deregister(true); - - // phpcs:ignore Squiz.Strings.DoubleQuoteUsage.ContainsVar - $row = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'codex_say')); - - $this->assertNull($row); - $this->assertFalse(get_option('codex_say')); - } -} diff --git a/tests/app/Foundation/Settings/SettingTest.php b/tests/app/Foundation/Settings/SettingTest.php deleted file mode 100644 index c0b0135..0000000 --- a/tests/app/Foundation/Settings/SettingTest.php +++ /dev/null @@ -1,29 +0,0 @@ -expectException(InvalidArgumentException::class); - - new Setting(''); - } - - public function testName(): void - { - $this->assertSame('say', (new Setting('say'))->getName()); - } - - public function testPriority(): void - { - $this->assertSame(73, (new Setting('say'))->getPriority()); - } -} diff --git a/tests/app/Foundation/Settings/Support/SettingRegistrarTest.php b/tests/app/Foundation/Settings/Support/SettingRegistrarTest.php deleted file mode 100644 index 3b0e4b5..0000000 --- a/tests/app/Foundation/Settings/Support/SettingRegistrarTest.php +++ /dev/null @@ -1,24 +0,0 @@ -assertSame('say', $registrar->getName()); - - $registrar->setPrefix('codex_prefix_'); - - $this->assertSame('codex_prefix_say', $registrar->getName()); - } -} diff --git a/tests/app/PluginTest.php b/tests/app/PluginTest.php index 1901b7d..26be759 100644 --- a/tests/app/PluginTest.php +++ b/tests/app/PluginTest.php @@ -14,15 +14,11 @@ use Codex\Facades\App; use Codex\Foundation\Blocks; use Codex\Foundation\Hooks\Hook; -use Codex\Foundation\Settings\Registry as SettingsRegistry; -use Codex\Foundation\Settings\Support\SettingRegistrar; use Codex\Plugin; -use Codex\Providers\SettingsProvider; use Pimple\Container; use Psr\Container\ContainerInterface; use stdClass; -use function array_key_exists; use function array_key_last; use function array_values; use function get_class; @@ -54,6 +50,7 @@ public function set_up(): void public function tear_down(): void { unset($GLOBALS[Overture::class]); + unset($GLOBALS[Notes::class]); App::clearResolvedInstances(); @@ -100,124 +97,6 @@ public function getInstances(ContainerInterface $container): iterable $this->assertTrue($config->isBlank('blank')); } - public function testSettingsService(): void - { - // $this->markAsRisky('Does not test with "admin_init" hook, as it may lead to unexpected warning.'); - - $app = new Plugin( - new class () implements Extendable { - public function getInstances(ContainerInterface $container): iterable - { - return []; - } - }, - ); - $app->setPluginFilePath(self::getFixturesPath('/plugin-name.php')); - $app->addServices([SettingsProvider::class]); - $app->boot(); - - $settingRegistries = $app->getContainer()->get('app/setting_registries'); - - do_action('admin_init'); - - $this->assertArrayNotHasKey('wp-test/plugin-foo', $settingRegistries); // Unsupported file extension, `.json`. - $this->assertArrayNotHasKey('wp-test/plugin-name-1', $settingRegistries); // Settings empty. - - // wp-test/plugin-name-0 - $this->assertInstanceOf(SettingsRegistry::class, $settingRegistries['wp-test/plugin-name-0']); - $this->assertTrue($settingRegistries['wp-test/plugin-name-0']->isRegistered()); - $this->assertSame('Hello, World!', get_option('wp_test_foo')); - - $registered = $settingRegistries['wp-test/plugin-name-0']->getRegisteredSettings(); - - $this->assertTrue(array_key_exists('wp_test_foo', $registered)); - $this->assertInstanceOf(SettingRegistrar::class, $registered['wp_test_foo']); - - // wp-test/plugin-name-2 - $this->assertInstanceOf(SettingsRegistry::class, $settingRegistries['wp-test/plugin-name-2']); - $this->assertTrue($settingRegistries['wp-test/plugin-name-2']->isRegistered()); - $this->assertSame(100, get_option('wp_test_bar')); - - $registered = $settingRegistries['wp-test/plugin-name-2']->getRegisteredSettings(); - - $this->assertTrue(array_key_exists('wp_test_bar', $registered)); - $this->assertInstanceOf(SettingRegistrar::class, $registered['wp_test_bar']); - - $settingRegistries['wp-test/plugin-name-0']->deregister(); - - // wp-test/plugin-name-0 - $this->assertFalse($settingRegistries['wp-test/plugin-name-0']->isRegistered()); - $this->assertFalse(get_option('wp_test_foo')); - $this->assertEmpty($settingRegistries['wp-test/plugin-name-0']->getRegisteredSettings()); - - // wp-test/plugin-name-2 - $this->assertInstanceOf(SettingsRegistry::class, $settingRegistries['wp-test/plugin-name-2']); - $this->assertTrue($settingRegistries['wp-test/plugin-name-2']->isRegistered()); - $this->assertSame(100, get_option('wp_test_bar')); - - $registered = $settingRegistries['wp-test/plugin-name-2']->getRegisteredSettings(); - - $this->assertTrue(array_key_exists('wp_test_bar', $registered)); - $this->assertInstanceOf(SettingRegistrar::class, $registered['wp_test_bar']); - - $settingRegistries['wp-test/plugin-name-2']->deregister(); - - // wp-test/plugin-name-2 - $this->assertFalse($settingRegistries['wp-test/plugin-name-2']->isRegistered()); - $this->assertFalse(get_option('wp_test_bar')); - $this->assertEmpty($settingRegistries['wp-test/plugin-name-2']->getRegisteredSettings()); - } - - public function testSettingsServiceAddOptionDeregisteredInvalidValue(): void - { - $app = new Plugin( - new class () implements Extendable { - public function getInstances(ContainerInterface $container): iterable - { - return []; - } - }, - ); - $app->setPluginFilePath(self::getFixturesPath('/plugin-name.php')); - $app->addServices([SettingsProvider::class]); - $app->boot(); - - do_action('admin_init'); - - $this->assertSame('Hello, World!', get_option('wp_test_foo')); - - $settingRegistries = $app->getContainer()->get('app/setting_registries'); - $settingRegistries['wp-test/plugin-name-0']->deregister(); - - $this->assertTrue(add_option('wp_test_foo', '')); - } - - public function testSettingsServiceUpdateOptionDeregisteredInvalidValue(): void - { - $app = new Plugin( - new class () implements Extendable { - public function getInstances(ContainerInterface $container): iterable - { - return []; - } - }, - ); - $app->setPluginFilePath(self::getFixturesPath('/plugin-name.php')); - $app->addServices([SettingsProvider::class]); - $app->boot(); - - do_action('admin_init'); - - $this->assertSame('Hello, World!', get_option('wp_test_foo')); - $this->assertTrue(add_option('wp_test_foo', 'Hai!')); - $this->assertSame('Hai!', get_option('wp_test_foo')); - - $settingRegistries = $app->getContainer()->get('app/setting_registries'); - $settingRegistries['wp-test/plugin-name-0']->deregister(); - - $this->assertTrue(update_option('wp_test_foo', '')); - } - public function testActivatable(): void { $app = new Plugin( @@ -320,7 +199,7 @@ public function deactivate(ContainerInterface $container): void self::assertTrue($app->getContainer()->has('concerto')); } - public function testHookableAndBootableService(): void + public function testHookableAndBootableInstance(): void { $app = new Plugin( new class () implements Extendable { @@ -337,7 +216,24 @@ public function getInstances(ContainerInterface $container): iterable self::assertSame(1, $GLOBALS[Overture::class]); } - public function testBoot(): void + public function testBootableInstanceWithoutInterface(): void + { + $app = new Plugin( + new class () implements Extendable { + public function getInstances(ContainerInterface $container): iterable + { + yield new Unoverture(); + } + }, + ); + $app->setPluginFilePath(self::getFixturesPath('/plugin-name.php')); + $app->boot(); + + self::assertSame(123, has_action('wp_loaded', '__return_null')); + self::assertFalse(isset($GLOBALS[Unoverture::class])); + } + + public function testBootatbleExtension(): void { $plugin = new class () implements Extendable, Bootable { public function getInstances(ContainerInterface $container): iterable @@ -357,7 +253,7 @@ public function boot(): void self::assertSame(2, $GLOBALS[get_class($plugin)]); } - public function testBootWithoutInterface(): void + public function testBootableExtensionWithoutInterface(): void { $plugin = new class () implements Extendable { public function getInstances(ContainerInterface $container): iterable @@ -376,6 +272,46 @@ public function boot(): void self::assertFalse(isset($GLOBALS[get_class($plugin)])); } + + public function testBootableServiceProvider(): void + { + $app = new Plugin( + new class () implements Extendable { + public function getInstances(ContainerInterface $container): iterable + { + return []; + } + }, + ); + $app->addServices([Notes::class]); + $app->setPluginFilePath(self::getFixturesPath('/plugin-name.php')); + + self::assertFalse(isset($GLOBALS[Notes::class])); + + $app->boot(); + + self::assertSame(123, $GLOBALS[Notes::class]); + } + + public function testBootableServiceProviderWithoutInterface(): void + { + $app = new Plugin( + new class () implements Extendable { + public function getInstances(ContainerInterface $container): iterable + { + return []; + } + }, + ); + $app->addServices([Unotes::class]); + $app->setPluginFilePath(self::getFixturesPath('/plugin-name.php')); + + self::assertFalse(isset($GLOBALS[Unotes::class])); + + $app->boot(); + + self::assertFalse(isset($GLOBALS[Unotes::class])); + } } // phpcs:disable @@ -413,3 +349,42 @@ public function boot(): void $GLOBALS[self::class] = 1; } } + +class Unoverture implements Hookable +{ + public function hook(Hook $hook): void + { + $hook->addAction('wp_loaded', '__return_null', 123); + } + + public function boot(): void + { + $GLOBALS[self::class] = 234; + } +} + +class Notes extends ServiceProvider implements Bootable +{ + public function register(): void + { + $this->container['notes'] = new stdClass; + } + + public function boot(): void + { + $GLOBALS[self::class] = 123; + } +} + +class Unotes extends ServiceProvider +{ + public function register(): void + { + $this->container['unotes'] = new stdClass; + } + + public function boot(): void + { + $GLOBALS[self::class] = 124; + } +}