summaryrefslogtreecommitdiffstatshomepage
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/lib/Drupal/Core/Test/PhpUnitTestDiscovery.php73
-rw-r--r--core/lib/Drupal/Core/Test/PhpUnitTestDiscoveryTracer.php38
-rw-r--r--core/modules/locale/src/StringDatabaseStorage.php5
-rw-r--r--core/modules/locale/tests/src/Kernel/LocaleStringTest.php23
-rwxr-xr-xcore/scripts/run-tests.sh16
-rw-r--r--core/tests/Drupal/KernelTests/Core/Test/PhpUnitApiFindAllClassFilesTest.php2
-rw-r--r--core/tests/Drupal/KernelTests/Core/Test/PhpUnitApiGetTestClassesTest.php2
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.