diff options
Diffstat (limited to 'core')
7 files changed, 145 insertions, 14 deletions
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/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/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. |