diff options
Diffstat (limited to 'core')
28 files changed, 588 insertions, 266 deletions
diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php index 3598385a373c..e52a99b406fc 100644 --- a/core/.phpstan-baseline.php +++ b/core/.phpstan-baseline.php @@ -1238,12 +1238,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/lib/Drupal/Core/Action/ActionManager.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\Core\\\\Action\\\\ConfigurableActionBase\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/lib/Drupal/Core/Action/ConfigurableActionBase.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\Core\\\\Action\\\\ConfigurableActionBase\\:\\:validateConfigurationForm\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -3968,12 +3962,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/lib/Drupal/Core/Display/VariantBase.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\Core\\\\Display\\\\VariantBase\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/lib/Drupal/Core/Display/VariantBase.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\Core\\\\Display\\\\VariantBase\\:\\:setWeight\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -5162,12 +5150,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginBase.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\Core\\\\Entity\\\\EntityReferenceSelection\\\\SelectionPluginBase\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginBase.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\Core\\\\Entity\\\\EntityReferenceSelection\\\\SelectionPluginBase\\:\\:submitConfigurationForm\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -8540,12 +8522,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/lib/Drupal/Core/Layout/LayoutDefault.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\Core\\\\Layout\\\\LayoutDefault\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/lib/Drupal/Core/Layout/LayoutDefault.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\Core\\\\Layout\\\\LayoutDefault\\:\\:setContext\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -18704,12 +18680,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/modules/image/src/Form/ImageStyleFormBase.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\image\\\\ImageEffectBase\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/image/src/ImageEffectBase.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\image\\\\ImageEffectBase\\:\\:transformDimensions\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -29055,12 +29025,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/modules/search/src/Plugin/Block/SearchBlock.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\search\\\\Plugin\\\\ConfigurableSearchPluginBase\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/search/src/Plugin/ConfigurableSearchPluginBase.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\search\\\\Plugin\\\\ConfigurableSearchPluginBase\\:\\:validateConfigurationForm\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -45579,12 +45543,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/modules/workflows/src/Form/WorkflowTransitionEditForm.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\workflows\\\\Plugin\\\\WorkflowTypeBase\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/workflows/src/Plugin/WorkflowTypeBase.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\workflows\\\\Plugin\\\\WorkflowTypeConfigureFormBase\\:\\:setPlugin\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, @@ -51588,12 +51546,6 @@ $ignoreErrors[] = [ 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Plugin/FilteredPluginManagerTraitTest.php', ]; $ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\Tests\\\\Core\\\\Plugin\\\\Fixtures\\\\TestConfigurablePlugin\\:\\:setConfiguration\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Plugin/Fixtures/TestConfigurablePlugin.php', -]; -$ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\Tests\\\\Core\\\\Plugin\\\\LazyPluginCollectionTestBase\\:\\:setupPluginCollection\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', 'count' => 1, diff --git a/core/lib/Drupal/Core/Action/ConfigurableActionBase.php b/core/lib/Drupal/Core/Action/ConfigurableActionBase.php index dd1e8ccdc541..a2a55f354e6a 100644 --- a/core/lib/Drupal/Core/Action/ConfigurableActionBase.php +++ b/core/lib/Drupal/Core/Action/ConfigurableActionBase.php @@ -5,6 +5,7 @@ namespace Drupal\Core\Action; use Drupal\Component\Plugin\ConfigurableInterface; use Drupal\Component\Plugin\DependentPluginInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\ConfigurableTrait; use Drupal\Core\Plugin\PluginFormInterface; /** @@ -12,6 +13,8 @@ use Drupal\Core\Plugin\PluginFormInterface; */ abstract class ConfigurableActionBase extends ActionBase implements ConfigurableInterface, DependentPluginInterface, PluginFormInterface { + use ConfigurableTrait; + /** * {@inheritdoc} */ @@ -24,27 +27,6 @@ abstract class ConfigurableActionBase extends ActionBase implements Configurable /** * {@inheritdoc} */ - public function defaultConfiguration() { - return []; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() { - return $this->configuration; - } - - /** - * {@inheritdoc} - */ - public function setConfiguration(array $configuration) { - $this->configuration = $configuration + $this->defaultConfiguration(); - } - - /** - * {@inheritdoc} - */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { } diff --git a/core/lib/Drupal/Core/Display/VariantBase.php b/core/lib/Drupal/Core/Display/VariantBase.php index dafb060d59f6..328bb89a2db0 100644 --- a/core/lib/Drupal/Core/Display/VariantBase.php +++ b/core/lib/Drupal/Core/Display/VariantBase.php @@ -4,7 +4,7 @@ namespace Drupal\Core\Display; use Drupal\Core\Cache\RefinableCacheableDependencyTrait; use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; use Drupal\Core\Plugin\PluginDependencyTrait; use Drupal\Core\Session\AccountInterface; @@ -16,7 +16,7 @@ use Drupal\Core\Session\AccountInterface; * @see \Drupal\Core\Display\VariantManager * @see plugin_api */ -abstract class VariantBase extends PluginBase implements VariantInterface { +abstract class VariantBase extends ConfigurablePluginBase implements VariantInterface { use PluginDependencyTrait; use RefinableCacheableDependencyTrait; @@ -24,15 +24,6 @@ abstract class VariantBase extends PluginBase implements VariantInterface { /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - - $this->setConfiguration($configuration); - } - - /** - * {@inheritdoc} - */ public function label() { return $this->configuration['label']; } @@ -77,14 +68,6 @@ abstract class VariantBase extends PluginBase implements VariantInterface { /** * {@inheritdoc} */ - public function setConfiguration(array $configuration) { - $this->configuration = $configuration + $this->defaultConfiguration(); - return $this; - } - - /** - * {@inheritdoc} - */ public function defaultConfiguration() { return [ 'label' => '', diff --git a/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginBase.php b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginBase.php index b40e32636719..019f8535ef6d 100644 --- a/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginBase.php +++ b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginBase.php @@ -2,32 +2,15 @@ namespace Drupal\Core\Entity\EntityReferenceSelection; -use Drupal\Component\Plugin\ConfigurableInterface; use Drupal\Component\Plugin\DependentPluginInterface; -use Drupal\Component\Utility\NestedArray; use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; /** * Provides a base class for configurable selection handlers. */ -abstract class SelectionPluginBase extends PluginBase implements SelectionInterface, ConfigurableInterface, DependentPluginInterface { - - /** - * Constructs a new selection object. - * - * @param array $configuration - * A configuration array containing information about the plugin instance. - * @param string $plugin_id - * The plugin ID for the plugin instance. - * @param mixed $plugin_definition - * The plugin implementation definition. - */ - public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->setConfiguration($configuration); - } +abstract class SelectionPluginBase extends ConfigurablePluginBase implements SelectionInterface, DependentPluginInterface { /** * {@inheritdoc} @@ -42,24 +25,6 @@ abstract class SelectionPluginBase extends PluginBase implements SelectionInterf /** * {@inheritdoc} */ - public function getConfiguration() { - return $this->configuration; - } - - /** - * {@inheritdoc} - */ - public function setConfiguration(array $configuration) { - // Merge in defaults. - $this->configuration = NestedArray::mergeDeep( - $this->defaultConfiguration(), - $configuration - ); - } - - /** - * {@inheritdoc} - */ public function calculateDependencies() { return []; } diff --git a/core/lib/Drupal/Core/Layout/LayoutDefault.php b/core/lib/Drupal/Core/Layout/LayoutDefault.php index 67980ba82e20..e9aac0eb4905 100644 --- a/core/lib/Drupal/Core/Layout/LayoutDefault.php +++ b/core/lib/Drupal/Core/Layout/LayoutDefault.php @@ -2,18 +2,17 @@ namespace Drupal\Core\Layout; -use Drupal\Component\Utility\NestedArray; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContextAwarePluginAssignmentTrait; use Drupal\Core\Plugin\ContextAwarePluginTrait; -use Drupal\Core\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; use Drupal\Core\Plugin\PluginFormInterface; use Drupal\Core\Plugin\PreviewAwarePluginInterface; /** * Provides a default class for Layout plugins. */ -class LayoutDefault extends PluginBase implements LayoutInterface, PluginFormInterface, PreviewAwarePluginInterface { +class LayoutDefault extends ConfigurablePluginBase implements LayoutInterface, PluginFormInterface, PreviewAwarePluginInterface { use ContextAwarePluginAssignmentTrait; use ContextAwarePluginTrait; @@ -35,14 +34,6 @@ class LayoutDefault extends PluginBase implements LayoutInterface, PluginFormInt /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->setConfiguration($configuration); - } - - /** - * {@inheritdoc} - */ public function build(array $regions) { // Ensure $build only contains defined regions and in the order defined. $build = []; @@ -64,20 +55,6 @@ class LayoutDefault extends PluginBase implements LayoutInterface, PluginFormInt /** * {@inheritdoc} */ - public function getConfiguration() { - return $this->configuration; - } - - /** - * {@inheritdoc} - */ - public function setConfiguration(array $configuration) { - $this->configuration = NestedArray::mergeDeep($this->defaultConfiguration(), $configuration); - } - - /** - * {@inheritdoc} - */ public function defaultConfiguration() { return [ 'label' => '', diff --git a/core/lib/Drupal/Core/Plugin/ConfigurablePluginBase.php b/core/lib/Drupal/Core/Plugin/ConfigurablePluginBase.php new file mode 100644 index 000000000000..0d51a8025562 --- /dev/null +++ b/core/lib/Drupal/Core/Plugin/ConfigurablePluginBase.php @@ -0,0 +1,31 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Core\Plugin; + +use Drupal\Component\Plugin\ConfigurableInterface; + +/** + * Base class for plugins that are configurable. + * + * Provides boilerplate methods for implementing + * Drupal\Component\Plugin\ConfigurableInterface. Configurable plugins may + * extend this base class instead of PluginBase. If your plugin must extend a + * different base class, you may use \Drupal\Component\Plugin\ConfigurableTrait + * directly and call setConfiguration() in your constructor. + * + * @see \Drupal\Core\Plugin\ConfigurableTrait + */ +abstract class ConfigurablePluginBase extends PluginBase implements ConfigurableInterface { + use ConfigurableTrait; + + /** + * {@inheritdoc} + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->setConfiguration($configuration); + } + +} diff --git a/core/lib/Drupal/Core/Plugin/ConfigurableTrait.php b/core/lib/Drupal/Core/Plugin/ConfigurableTrait.php new file mode 100644 index 000000000000..bfe4a6615127 --- /dev/null +++ b/core/lib/Drupal/Core/Plugin/ConfigurableTrait.php @@ -0,0 +1,81 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Core\Plugin; + +use Drupal\Component\Utility\NestedArray; + +/** + * Implementation class for \Drupal\Component\Plugin\ConfigurableInterface. + * + * In order for configurable plugins to maintain their configuration, the + * default configuration must be merged into any explicitly defined + * configuration. This trait provides the appropriate getters and setters to + * handle this logic, removing the need for excess boilerplate. + * + * To use this trait implement ConfigurableInterface and add a constructor. In + * the constructor call the parent constructor and then call setConfiguration(). + * That will merge the explicitly defined plugin configuration and the default + * plugin configuration. + * + * @ingroup Plugin + */ +trait ConfigurableTrait { + + /** + * Configuration information passed into the plugin. + * + * This property is declared in \Drupal\Component\Plugin\PluginBase as well, + * which most classes using this trait will ultimately be extending. It is + * re-declared here to make the trait self-contained and to permit use of the + * trait in classes that do not extend PluginBase. + * + * @var array + */ + protected $configuration; + + /** + * Gets this plugin's configuration. + * + * @return array + * An associative array containing the plugin's configuration. + * + * @see \Drupal\Component\Plugin\ConfigurableInterface::getConfiguration() + */ + public function getConfiguration() { + return $this->configuration; + } + + /** + * Sets the configuration for this plugin instance. + * + * The provided configuration is merged with the plugin's default + * configuration. If the same configuration key exists in both configurations, + * then the value in the provided configuration will override the default. + * + * @param array $configuration + * An associative array containing the plugin's configuration. + * + * @return $this + * + * @see \Drupal\Component\Plugin\ConfigurableInterface::setConfiguration() + */ + public function setConfiguration(array $configuration) { + $this->configuration = NestedArray::mergeDeepArray([$this->defaultConfiguration(), $configuration], TRUE); + return $this; + } + + /** + * Gets default configuration for this plugin. + * + * @return array + * An associative array containing the default configuration. + * + * @see \Drupal\Component\Plugin\ConfigurableInterface::defaultConfiguration() + */ + public function defaultConfiguration() { + return []; + } + +} diff --git a/core/lib/Drupal/Core/Test/PhpUnitTestDiscovery.php b/core/lib/Drupal/Core/Test/PhpUnitTestDiscovery.php index d9737028821c..a02894c1c74d 100644 --- a/core/lib/Drupal/Core/Test/PhpUnitTestDiscovery.php +++ b/core/lib/Drupal/Core/Test/PhpUnitTestDiscovery.php @@ -6,6 +6,8 @@ namespace Drupal\Core\Test; use Drupal\Core\Test\Exception\MissingGroupException; use Drupal\TestTools\PhpUnitCompatibility\RunnerVersion; +use PHPUnit\Event\EventFacadeIsSealedException; +use PHPUnit\Event\Facade as EventFacade; use PHPUnit\Framework\DataProviderTestSuite; use PHPUnit\Framework\Test; use PHPUnit\Framework\TestCase; @@ -21,6 +23,13 @@ use PHPUnit\TextUI\Configuration\TestSuiteBuilder; class PhpUnitTestDiscovery { /** + * The singleton. + * + * @var \Drupal\Core\Test\PhpUnitTestDiscovery|null + */ + private static ?self $instance = NULL; + + /** * The map of legacy test suite identifiers to phpunit.xml ones. * * @var array<string,string> @@ -42,16 +51,44 @@ class PhpUnitTestDiscovery { private array $reverseMap; /** + * Path to PHPUnit's configuration file. + */ + private string $configurationFilePath; + + /** * The warnings generated during the discovery. * * @var list<string> */ private array $warnings = []; - public function __construct( - private string $configurationFilePath, - ) { + private function __construct() { $this->reverseMap = array_flip($this->map); + try { + EventFacade::instance()->registerTracer(new PhpUnitTestDiscoveryTracer($this)); + EventFacade::instance()->seal(); + } + catch (EventFacadeIsSealedException) { + // Just continue. + } + } + + /** + * Returns the singleton instance. + */ + public static function instance(): self { + if (self::$instance === NULL) { + self::$instance = new self(); + } + return self::$instance; + } + + /** + * Sets the configuration file path. + */ + public function setConfigurationFilePath(string $configurationFilePath): self { + $this->configurationFilePath = $configurationFilePath; + return $this; } /** @@ -109,9 +146,11 @@ class PhpUnitTestDiscovery { } $phpUnitTestSuite = (new TestSuiteBuilder())->build($phpUnitConfiguration); if (isset($containerObjectId) && $containerObjectId !== spl_object_id(\Drupal::getContainer())) { - $this->warnings[] = '*** The service container was changed during the test discovery ***'; - $this->warnings[] = 'Probably a test data provider method called \\Drupal::setContainer.'; - $this->warnings[] = 'Ensure that all the data providers restore the original container before returning data.'; + $this->addWarning( + ">>> The service container was changed during the test discovery <<<\n" . + "Probably, a test data provider method called \\Drupal::setContainer().\n" . + "Ensure that all the data providers restore the original container before returning data." + ); assert(isset($container)); \Drupal::setContainer($container); } @@ -153,6 +192,16 @@ class PhpUnitTestDiscovery { } /** + * Adds warning message generated during the discovery. + * + * @param string $message + * The warning message. + */ + public function addWarning(string $message): void { + $this->warnings[] = $message; + } + + /** * Returns the warnings generated during the discovery. * * @return list<string> @@ -180,6 +229,10 @@ class PhpUnitTestDiscovery { $list = []; foreach ($phpUnitTestSuite->tests() as $testSuite) { foreach ($testSuite->tests() as $testClass) { + if ($testClass->isEmpty()) { + continue; + } + if ($extension !== NULL && !str_starts_with($testClass->name(), "Drupal\\Tests\\{$extension}\\")) { continue; } @@ -218,6 +271,10 @@ class PhpUnitTestDiscovery { // In this case, PHPUnit found a single test class to run tests for. if ($phpUnitTestSuite->isForTestClass()) { + if ($phpUnitTestSuite->isEmpty()) { + return []; + } + if ($extension !== NULL && !str_starts_with($phpUnitTestSuite->name(), "Drupal\\Tests\\{$extension}\\")) { return []; } @@ -239,6 +296,10 @@ class PhpUnitTestDiscovery { // Multiple test classes were found. $list = []; foreach ($phpUnitTestSuite->tests() as $testClass) { + if ($testClass->isEmpty()) { + continue; + } + if ($extension !== NULL && !str_starts_with($testClass->name(), "Drupal\\Tests\\{$extension}\\")) { continue; } diff --git a/core/lib/Drupal/Core/Test/PhpUnitTestDiscoveryTracer.php b/core/lib/Drupal/Core/Test/PhpUnitTestDiscoveryTracer.php new file mode 100644 index 000000000000..681704830967 --- /dev/null +++ b/core/lib/Drupal/Core/Test/PhpUnitTestDiscoveryTracer.php @@ -0,0 +1,38 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Core\Test; + +use PHPUnit\Event\Event; +use PHPUnit\Event\Test\PhpunitErrorTriggered; +use PHPUnit\Event\Test\PhpunitWarningTriggered; +use PHPUnit\Event\TestRunner\WarningTriggered; +use PHPUnit\Event\Tracer\Tracer; + +/** + * Traces events dispatched by PHPUnit during the test discovery. + * + * @internal + */ +class PhpUnitTestDiscoveryTracer implements Tracer { + + public function __construct( + private readonly PHPUnitTestDiscovery $testDiscovery, + ) { + } + + /** + * {@inheritdoc} + */ + public function trace(Event $event): void { + if (in_array(get_class($event), [ + PhpunitErrorTriggered::class, + PhpunitWarningTriggered::class, + WarningTriggered::class, + ])) { + $this->testDiscovery->addWarning(sprintf('%s: %s', get_class($event), $event->message())); + } + } + +} diff --git a/core/modules/comment/tests/src/Kernel/Plugin/migrate/source/CommentTypeRequirementsTest.php b/core/modules/comment/tests/src/Kernel/Plugin/migrate/source/CommentTypeRequirementsTest.php index 379e51803b05..c04c478f3a2f 100644 --- a/core/modules/comment/tests/src/Kernel/Plugin/migrate/source/CommentTypeRequirementsTest.php +++ b/core/modules/comment/tests/src/Kernel/Plugin/migrate/source/CommentTypeRequirementsTest.php @@ -11,6 +11,7 @@ use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase; * Tests check requirements for comment type source plugin. * * @group comment + * @group #slow */ class CommentTypeRequirementsTest extends MigrateDrupal7TestBase { diff --git a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceLabelDescriptionTest.php b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceLabelDescriptionTest.php index ca81ab17602b..20ea2c954b2c 100644 --- a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceLabelDescriptionTest.php +++ b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceLabelDescriptionTest.php @@ -13,6 +13,7 @@ use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase; * Tests migration of field label and description translations. * * @group migrate_drupal_6 + * @group #slow */ class MigrateFieldInstanceLabelDescriptionTest extends MigrateDrupal6TestBase implements MigrateDumpAlterInterface { diff --git a/core/modules/image/src/ImageEffectBase.php b/core/modules/image/src/ImageEffectBase.php index 58be370c1e6e..745976133be7 100644 --- a/core/modules/image/src/ImageEffectBase.php +++ b/core/modules/image/src/ImageEffectBase.php @@ -3,7 +3,7 @@ namespace Drupal\image; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; -use Drupal\Core\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -17,7 +17,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * @see \Drupal\image\ImageEffectManager * @see plugin_api */ -abstract class ImageEffectBase extends PluginBase implements ImageEffectInterface, ContainerFactoryPluginInterface { +abstract class ImageEffectBase extends ConfigurablePluginBase implements ImageEffectInterface, ContainerFactoryPluginInterface { /** * The image effect ID. @@ -46,7 +46,6 @@ abstract class ImageEffectBase extends PluginBase implements ImageEffectInterfac public function __construct(array $configuration, $plugin_id, $plugin_definition, LoggerInterface $logger) { parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->setConfiguration($configuration); $this->logger = $logger; } @@ -154,13 +153,6 @@ abstract class ImageEffectBase extends PluginBase implements ImageEffectInterfac /** * {@inheritdoc} */ - public function defaultConfiguration() { - return []; - } - - /** - * {@inheritdoc} - */ public function calculateDependencies() { return []; } diff --git a/core/modules/locale/src/StringDatabaseStorage.php b/core/modules/locale/src/StringDatabaseStorage.php index f023d1968ae7..75c73411978d 100644 --- a/core/modules/locale/src/StringDatabaseStorage.php +++ b/core/modules/locale/src/StringDatabaseStorage.php @@ -527,7 +527,10 @@ class StringDatabaseStorage implements StringStorageInterface { protected function dbDelete($table, $keys) { $query = $this->connection->delete($table, $this->options); foreach ($keys as $field => $value) { - $query->condition($field, $value); + if (!is_array($value)) { + $value = [$value]; + } + $query->condition($field, $value, 'IN'); } return $query; } diff --git a/core/modules/locale/tests/src/Kernel/LocaleStringTest.php b/core/modules/locale/tests/src/Kernel/LocaleStringTest.php index f5f27b01a627..b007c7ab55b0 100644 --- a/core/modules/locale/tests/src/Kernel/LocaleStringTest.php +++ b/core/modules/locale/tests/src/Kernel/LocaleStringTest.php @@ -258,4 +258,27 @@ class LocaleStringTest extends KernelTestBase { ])->save(); } + /** + * Tests that strings are correctly deleted. + */ + public function testDeleteStrings(): void { + $source = $this->storage->createString([ + 'source' => 'Revision ID', + ])->save(); + + $this->storage->createTranslation([ + 'lid' => $source->lid, + 'language' => 'fr', + 'translation' => 'Translated Revision ID', + ])->save(); + + // Confirm that the string has been created. + $this->assertNotEmpty($this->storage->findString(['lid' => $source->lid])); + + $this->storage->deleteStrings(['lid' => $source->lid]); + + // Confirm that the string has been deleted. + $this->assertEmpty($this->storage->findString(['lid' => $source->lid])); + } + } diff --git a/core/modules/migrate_drupal/tests/src/Kernel/d7/FollowUpMigrationsTest.php b/core/modules/migrate_drupal/tests/src/Kernel/d7/FollowUpMigrationsTest.php index 151b7fae2477..c7d40c4c2d9d 100644 --- a/core/modules/migrate_drupal/tests/src/Kernel/d7/FollowUpMigrationsTest.php +++ b/core/modules/migrate_drupal/tests/src/Kernel/d7/FollowUpMigrationsTest.php @@ -12,6 +12,7 @@ use Drupal\user\Entity\User; * Tests follow-up migrations. * * @group migrate_drupal + * @group #slow */ class FollowUpMigrationsTest extends MigrateDrupal7TestBase { diff --git a/core/modules/package_manager/tests/src/Build/PackageInstallDirectWriteTest.php b/core/modules/package_manager/tests/src/Build/PackageInstallDirectWriteTest.php new file mode 100644 index 000000000000..307d17cdcdb3 --- /dev/null +++ b/core/modules/package_manager/tests/src/Build/PackageInstallDirectWriteTest.php @@ -0,0 +1,52 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\package_manager\Build; + +use PHPUnit\Framework\Attributes\Group; + +/** + * Tests installing packages with direct write mode enabled. + * + * @internal + */ +#[Group('package_manager')] +#[Group('#slow')] +class PackageInstallDirectWriteTest extends TemplateProjectTestBase { + + /** + * Tests installing packages in a stage directory. + */ + public function testPackageInstall(): void { + $this->createTestProject('RecommendedProject'); + $allow_direct_write = var_export(TRUE, TRUE); + $this->writeSettings("\n\$settings['package_manager_allow_direct_write'] = $allow_direct_write;"); + + $this->setReleaseMetadata([ + 'alpha' => __DIR__ . '/../../fixtures/release-history/alpha.1.1.0.xml', + ]); + $this->addRepository('alpha', $this->copyFixtureToTempDirectory(__DIR__ . '/../../fixtures/build_test_projects/alpha/1.0.0')); + // Repository definitions affect the lock file hash, so update the hash to + // ensure that Composer won't complain that the lock file is out of sync. + $this->runComposer('composer update --lock', 'project'); + + // Use the API endpoint to create a stage and install alpha 1.0.0. + $this->makePackageManagerTestApiRequest( + '/package-manager-test-api', + [ + 'runtime' => [ + 'drupal/alpha:1.0.0', + ], + ] + ); + // Assert the module was installed. + $this->assertFileEquals( + __DIR__ . '/../../fixtures/build_test_projects/alpha/1.0.0/composer.json', + $this->getWebRoot() . '/modules/contrib/alpha/composer.json', + ); + $this->assertRequestedChangesWereLogged(['Install drupal/alpha 1.0.0']); + $this->assertAppliedChangesWereLogged(['Installed drupal/alpha 1.0.0']); + } + +} diff --git a/core/modules/package_manager/tests/src/Build/PackageInstallTest.php b/core/modules/package_manager/tests/src/Build/PackageInstallTest.php index bea2c0d40243..362343eaa91a 100644 --- a/core/modules/package_manager/tests/src/Build/PackageInstallTest.php +++ b/core/modules/package_manager/tests/src/Build/PackageInstallTest.php @@ -15,15 +15,9 @@ class PackageInstallTest extends TemplateProjectTestBase { /** * Tests installing packages in a stage directory. - * - * @testWith [true] - * [false] */ - public function testPackageInstall(bool $allow_direct_write): void { + public function testPackageInstall(): void { $this->createTestProject('RecommendedProject'); - $allow_direct_write = var_export($allow_direct_write, TRUE); - $this->writeSettings("\n\$settings['package_manager_allow_direct_write'] = $allow_direct_write;"); - $this->setReleaseMetadata([ 'alpha' => __DIR__ . '/../../fixtures/release-history/alpha.1.1.0.xml', ]); diff --git a/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php b/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php index 7ad95f16823b..acc2e49a5cb6 100644 --- a/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php +++ b/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php @@ -2,14 +2,16 @@ namespace Drupal\search\Plugin; -use Drupal\Component\Utility\NestedArray; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\ConfigurableTrait; /** * Provides a base implementation for a configurable Search plugin. */ abstract class ConfigurableSearchPluginBase extends SearchPluginBase implements ConfigurableSearchPluginInterface { + use ConfigurableTrait; + /** * The unique ID for the search page using this plugin. * @@ -29,27 +31,6 @@ abstract class ConfigurableSearchPluginBase extends SearchPluginBase implements /** * {@inheritdoc} */ - public function defaultConfiguration() { - return []; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() { - return $this->configuration; - } - - /** - * {@inheritdoc} - */ - public function setConfiguration(array $configuration) { - $this->configuration = NestedArray::mergeDeep($this->defaultConfiguration(), $configuration); - } - - /** - * {@inheritdoc} - */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { } diff --git a/core/modules/system/tests/src/Functional/Module/VersionTest.php b/core/modules/system/tests/src/Functional/Module/VersionTest.php index 7f3af598cfb8..1a98b7f246fa 100644 --- a/core/modules/system/tests/src/Functional/Module/VersionTest.php +++ b/core/modules/system/tests/src/Functional/Module/VersionTest.php @@ -8,6 +8,7 @@ namespace Drupal\Tests\system\Functional\Module; * Tests module version dependencies. * * @group Module + * @group #slow */ class VersionTest extends ModuleTestBase { diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyTermTranslationTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyTermTranslationTest.php index 1fb8b819fdc7..3499a404ac95 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyTermTranslationTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyTermTranslationTest.php @@ -12,6 +12,7 @@ use Drupal\taxonomy\TermInterface; * Test migration of translated taxonomy terms. * * @group migrate_drupal_7 + * @group #slow */ class MigrateTaxonomyTermTranslationTest extends MigrateDrupal7TestBase { diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php index 47488b38801b..e86b77a22857 100644 --- a/core/modules/workflows/src/Plugin/WorkflowTypeBase.php +++ b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php @@ -2,7 +2,7 @@ namespace Drupal\workflows\Plugin; -use Drupal\Component\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; use Drupal\Core\Plugin\PluginWithFormsTrait; use Drupal\workflows\State; use Drupal\workflows\StateInterface; @@ -16,7 +16,7 @@ use Drupal\workflows\WorkflowTypeInterface; * * @see \Drupal\workflows\Annotation\WorkflowType */ -abstract class WorkflowTypeBase extends PluginBase implements WorkflowTypeInterface { +abstract class WorkflowTypeBase extends ConfigurablePluginBase implements WorkflowTypeInterface { use PluginWithFormsTrait; @@ -28,14 +28,6 @@ abstract class WorkflowTypeBase extends PluginBase implements WorkflowTypeInterf /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->setConfiguration($configuration); - } - - /** - * {@inheritdoc} - */ public function label() { $definition = $this->getPluginDefinition(); // The label can be an object. @@ -60,15 +52,9 @@ abstract class WorkflowTypeBase extends PluginBase implements WorkflowTypeInterf /** * {@inheritdoc} */ - public function getConfiguration() { - return $this->configuration; - } - - /** - * {@inheritdoc} - */ public function setConfiguration(array $configuration) { $this->configuration = $configuration + $this->defaultConfiguration(); + return $this; } /** diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh index 96f16eed9c71..30e366f97b2e 100755 --- a/core/scripts/run-tests.sh +++ b/core/scripts/run-tests.sh @@ -89,7 +89,7 @@ if ($args['list']) { // Display all available tests organized by one @group annotation. echo "\nAvailable test groups & classes\n"; echo "-------------------------------\n\n"; - $test_discovery = new PhpUnitTestDiscovery(\Drupal::root() . \DIRECTORY_SEPARATOR . 'core'); + $test_discovery = PhpUnitTestDiscovery::instance()->setConfigurationFilePath(\Drupal::root() . \DIRECTORY_SEPARATOR . 'core'); try { $groups = $test_discovery->getTestClasses($args['module']); foreach ($test_discovery->getWarnings() as $warning) { @@ -122,7 +122,7 @@ if ($args['list']) { // @see https://www.drupal.org/node/2569585 if ($args['list-files'] || $args['list-files-json']) { // List all files which could be run as tests. - $test_discovery = new PhpUnitTestDiscovery(\Drupal::root() . \DIRECTORY_SEPARATOR . 'core'); + $test_discovery = PhpUnitTestDiscovery::instance()->setConfigurationFilePath(\Drupal::root() . \DIRECTORY_SEPARATOR . 'core'); // PhpUnitTestDiscovery::findAllClassFiles() gives us a classmap similar to a // Composer 'classmap' array. $test_classes = $test_discovery->findAllClassFiles(); @@ -934,14 +934,20 @@ function simpletest_script_command(TestRun $test_run, string $test_class): array function simpletest_script_get_test_list() { global $args; - $test_discovery = new PhpUnitTestDiscovery(\Drupal::root() . \DIRECTORY_SEPARATOR . 'core'); + $test_discovery = PhpUnitTestDiscovery::instance()->setConfigurationFilePath(\Drupal::root() . \DIRECTORY_SEPARATOR . 'core'); $test_list = []; $slow_tests = []; if ($args['all'] || $args['module'] || $args['directory']) { try { $groups = $test_discovery->getTestClasses($args['module'], $args['types'], $args['directory']); - foreach ($test_discovery->getWarnings() as $warning) { - simpletest_script_print($warning . "\n", SIMPLETEST_SCRIPT_COLOR_EXCEPTION); + $warnings = $test_discovery->getWarnings(); + if (!empty($warnings)) { + simpletest_script_print("Test discovery warnings\n", SIMPLETEST_SCRIPT_COLOR_BRIGHT_WHITE); + simpletest_script_print("-----------------------\n", SIMPLETEST_SCRIPT_COLOR_BRIGHT_WHITE); + foreach ($warnings as $warning) { + simpletest_script_print('* ' . $warning . "\n\n", SIMPLETEST_SCRIPT_COLOR_EXCEPTION); + } + echo "\n"; } } catch (Exception $e) { diff --git a/core/tests/Drupal/KernelTests/Core/Test/PhpUnitApiFindAllClassFilesTest.php b/core/tests/Drupal/KernelTests/Core/Test/PhpUnitApiFindAllClassFilesTest.php index 2afb26f1b9e0..a8697cc84968 100644 --- a/core/tests/Drupal/KernelTests/Core/Test/PhpUnitApiFindAllClassFilesTest.php +++ b/core/tests/Drupal/KernelTests/Core/Test/PhpUnitApiFindAllClassFilesTest.php @@ -38,7 +38,7 @@ class PhpUnitApiFindAllClassFilesTest extends KernelTestBase { if (RunnerVersion::getMajor() >= 11) { $configurationFilePath .= \DIRECTORY_SEPARATOR . '.phpunit-next.xml'; } - $phpUnitTestDiscovery = new PhpUnitTestDiscovery($configurationFilePath); + $phpUnitTestDiscovery = PhpUnitTestDiscovery::instance()->setConfigurationFilePath($configurationFilePath); $phpUnitList = $phpUnitTestDiscovery->findAllClassFiles($extension, $directory); // Legacy TestDiscovery. diff --git a/core/tests/Drupal/KernelTests/Core/Test/PhpUnitApiGetTestClassesTest.php b/core/tests/Drupal/KernelTests/Core/Test/PhpUnitApiGetTestClassesTest.php index 81cdfc9c6c5f..caedbc0d2b62 100644 --- a/core/tests/Drupal/KernelTests/Core/Test/PhpUnitApiGetTestClassesTest.php +++ b/core/tests/Drupal/KernelTests/Core/Test/PhpUnitApiGetTestClassesTest.php @@ -38,7 +38,7 @@ class PhpUnitApiGetTestClassesTest extends KernelTestBase { if (RunnerVersion::getMajor() >= 11) { $configurationFilePath .= \DIRECTORY_SEPARATOR . '.phpunit-next.xml'; } - $phpUnitTestDiscovery = new PhpUnitTestDiscovery($configurationFilePath); + $phpUnitTestDiscovery = PhpUnitTestDiscovery::instance()->setConfigurationFilePath($configurationFilePath); $phpUnitList = $phpUnitTestDiscovery->getTestClasses($extension, $suites, $directory); // Legacy TestDiscovery. diff --git a/core/tests/Drupal/Tests/Core/Plugin/ConfigurablePluginBaseTest.php b/core/tests/Drupal/Tests/Core/Plugin/ConfigurablePluginBaseTest.php new file mode 100644 index 000000000000..d05413eb444e --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Plugin/ConfigurablePluginBaseTest.php @@ -0,0 +1,47 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\Core\Plugin; + +use Drupal\Core\Plugin\ConfigurablePluginBase; +use PHPUnit\Framework\TestCase; + +/** + * Tests ConfigurablePluginBase. + * + * @group Plugin + * + * @coversDefaultClass \Drupal\Core\Plugin\ConfigurablePluginBase + */ +class ConfigurablePluginBaseTest extends TestCase { + + /** + * Tests the Constructor. + */ + public function testConstructor(): void { + $provided_configuration = [ + 'foo' => 'bar', + ]; + $merged_configuration = ['default' => 'default'] + $provided_configuration; + $plugin = new ConfigurablePluginBaseTestClass($provided_configuration, '', []); + $this->assertSame($merged_configuration, $plugin->getConfiguration()); + } + +} + +/** + * Test class for ConfigurablePluginBase. + */ +class ConfigurablePluginBaseTestClass extends ConfigurablePluginBase { + + /** + * {@inheritdoc} + */ + public function defaultConfiguration(): array { + return [ + 'default' => 'default', + ]; + } + +} diff --git a/core/tests/Drupal/Tests/Core/Plugin/ConfigurableTraitTest.php b/core/tests/Drupal/Tests/Core/Plugin/ConfigurableTraitTest.php new file mode 100644 index 000000000000..21543658769c --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Plugin/ConfigurableTraitTest.php @@ -0,0 +1,205 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\Core\Plugin; + +use Drupal\Component\Plugin\ConfigurableInterface; +use Drupal\Component\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurableTrait; +use PHPUnit\Framework\TestCase; + +/** + * Tests for ConfigurableTrait. + * + * @group Plugin + * + * @coversDefaultClass \Drupal\Core\Plugin\ConfigurableTrait + */ +class ConfigurableTraitTest extends TestCase { + + /** + * Tests ConfigurableTrait::defaultConfiguration. + * + * @covers ::defaultConfiguration + */ + public function testDefaultConfiguration(): void { + /** @var \Drupal\Component\Plugin\ConfigurableInterface $configurable_plugin */ + $configurable_plugin = new ConfigurableTestClass(); + $this->assertSame([], $configurable_plugin->defaultConfiguration()); + } + + /** + * Tests ConfigurableTrait::getConfiguration. + * + * @covers ::getConfiguration + */ + public function testGetConfiguration(): void { + $test_configuration = [ + 'config_key_1' => 'config_value_1', + 'config_key_2' => [ + 'nested_key_1' => 'nested_value_1', + 'nested_key_2' => 'nested_value_2', + ], + ]; + $configurable_plugin = new ConfigurableTestClass($test_configuration); + $this->assertSame($test_configuration, $configurable_plugin->getConfiguration()); + } + + /** + * Tests configurableTrait::setConfiguration. + * + * Specifically test the way default and provided configurations are merged. + * + * @param array $default_configuration + * The default configuration to use for the trait. + * @param array $test_configuration + * The configuration to test. + * @param array $final_configuration + * The expected final plugin configuration. + * + * @covers ::setConfiguration + * + * @dataProvider setConfigurationDataProvider + */ + public function testSetConfiguration(array $default_configuration, array $test_configuration, array $final_configuration): void { + $test_object = new ConfigurableTestClass(); + $test_object->setDefaultConfiguration($default_configuration); + $test_object->setConfiguration($test_configuration); + $this->assertSame($final_configuration, $test_object->getConfiguration()); + } + + /** + * Provides data for testSetConfiguration. + * + * @return array + * The data. + */ + public static function setConfigurationDataProvider(): array { + return [ + 'Direct Override' => [ + 'default_configuration' => [ + 'default_key_1' => 'default_value_1', + 'default_key_2' => [ + 'default_nested_key_1' => 'default_nested_value_1', + 'default_nested_key_2' => 'default_nested_value_2', + ], + ], + 'test_configuration' => [ + 'default_key_1' => 'override_value_1', + 'default_key_2' => [ + 'default_nested_key_1' => 'override_nested_value_1', + 'default_nested_key_2' => 'override_nested_value_2', + ], + ], + 'final_configuration' => [ + 'default_key_1' => 'override_value_1', + 'default_key_2' => [ + 'default_nested_key_1' => 'override_nested_value_1', + 'default_nested_key_2' => 'override_nested_value_2', + ], + ], + ], + 'Mixed Override' => [ + 'default_configuration' => [ + 'default_key_1' => 'default_value_1', + 'default_key_2' => [ + 'default_nested_key_1' => 'default_nested_value_1', + 'default_nested_key_2' => 'default_nested_value_2', + ], + ], + 'test_configuration' => [ + 'override_key_1' => 'config_value_1', + 'default_key_2' => [ + 'default_nested_key_1' => 'override_value_1', + 'override_nested_key' => 'override_value', + ], + ], + 'final_configuration' => [ + 'default_key_1' => 'default_value_1', + 'default_key_2' => [ + 'default_nested_key_1' => 'override_value_1', + 'default_nested_key_2' => 'default_nested_value_2', + 'override_nested_key' => 'override_value', + ], + 'override_key_1' => 'config_value_1', + ], + ], + 'indexed_override' => [ + 'default_configuration' => [ + 'config_value_1', + 'config_value_2', + 'config_value_3', + ], + 'test_configuration' => [ + 'override_value_1', + 'override_value_2', + ], + 'final_configuration' => [ + 'override_value_1', + 'override_value_2', + 'config_value_3', + ], + ], + 'indexed_override_complex' => [ + 'default_configuration' => [ + 'config_value_1', + 'config_value_2', + 'config_value_3', + ], + 'test_configuration' => [ + 0 => 'override_value_1', + 2 => 'override_value_3', + ], + 'final_configuration' => [ + 'override_value_1', + 'config_value_2', + 'override_value_3', + ], + ], + ]; + } + +} + +/** + * A test class using ConfigurablePluginTrait that can modify the de. + */ +class ConfigurableTestClass extends PluginBase implements ConfigurableInterface { + use ConfigurableTrait { + defaultConfiguration as traitDefaultConfiguration; + } + + /** + * A default configuration for the test class to return. + * + * @var array|null + */ + protected ?array $defaultConfiguration = NULL; + + /** + * {@inheritdoc} + */ + public function __construct(array $configuration = [], string $plugin_id = '', array $plugin_definition = []) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->setConfiguration($configuration); + } + + /** + * Sets the default configuration this test will return. + * + * @param array $default_configuration + * The default configuration to use. + */ + public function setDefaultConfiguration(array $default_configuration): void { + $this->defaultConfiguration = $default_configuration; + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration(): array { + return $this->defaultConfiguration ?? $this->traitDefaultConfiguration(); + } + +} diff --git a/core/tests/Drupal/Tests/Core/Plugin/DefaultSingleLazyPluginCollectionTest.php b/core/tests/Drupal/Tests/Core/Plugin/DefaultSingleLazyPluginCollectionTest.php index 99da7a2f9741..60e147f434a5 100644 --- a/core/tests/Drupal/Tests/Core/Plugin/DefaultSingleLazyPluginCollectionTest.php +++ b/core/tests/Drupal/Tests/Core/Plugin/DefaultSingleLazyPluginCollectionTest.php @@ -4,8 +4,7 @@ declare(strict_types=1); namespace Drupal\Tests\Core\Plugin; -use Drupal\Component\Plugin\ConfigurableInterface; -use Drupal\Component\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; use Drupal\Core\Plugin\DefaultSingleLazyPluginCollection; use PHPUnit\Framework\MockObject\Rule\InvocationOrder; @@ -98,24 +97,5 @@ class DefaultSingleLazyPluginCollectionTest extends LazyPluginCollectionTestBase /** * Stub configurable plugin class for testing. */ -class ConfigurablePlugin extends PluginBase implements ConfigurableInterface { - - public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - - $this->configuration = $configuration + $this->defaultConfiguration(); - } - - public function defaultConfiguration() { - return []; - } - - public function getConfiguration() { - return $this->configuration; - } - - public function setConfiguration(array $configuration): void { - $this->configuration = $configuration; - } - +class ConfigurablePlugin extends ConfigurablePluginBase { } diff --git a/core/tests/Drupal/Tests/Core/Plugin/Fixtures/TestConfigurablePlugin.php b/core/tests/Drupal/Tests/Core/Plugin/Fixtures/TestConfigurablePlugin.php index 55695ace6de7..7b72a3df4530 100644 --- a/core/tests/Drupal/Tests/Core/Plugin/Fixtures/TestConfigurablePlugin.php +++ b/core/tests/Drupal/Tests/Core/Plugin/Fixtures/TestConfigurablePlugin.php @@ -4,35 +4,13 @@ declare(strict_types=1); namespace Drupal\Tests\Core\Plugin\Fixtures; -use Drupal\Component\Plugin\ConfigurableInterface; use Drupal\Component\Plugin\DependentPluginInterface; -use Drupal\Component\Plugin\PluginBase; +use Drupal\Core\Plugin\ConfigurablePluginBase; /** * A configurable plugin implementation used for testing. */ -class TestConfigurablePlugin extends PluginBase implements ConfigurableInterface, DependentPluginInterface { - - /** - * {@inheritdoc} - */ - public function getConfiguration() { - return $this->configuration; - } - - /** - * {@inheritdoc} - */ - public function setConfiguration(array $configuration) { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function defaultConfiguration() { - return []; - } +class TestConfigurablePlugin extends ConfigurablePluginBase implements DependentPluginInterface { /** * {@inheritdoc} |