diff --git a/core/lib/Drupal/Core/StreamWrapper/PublicStream.php b/core/lib/Drupal/Core/StreamWrapper/PublicStream.php index f2783530958..403263e3017 100644 --- a/core/lib/Drupal/Core/StreamWrapper/PublicStream.php +++ b/core/lib/Drupal/Core/StreamWrapper/PublicStream.php @@ -89,7 +89,7 @@ class PublicStream extends LocalStream { * $base_path = PublicStream::basePath(\Drupal::service('site.path')); * @endcode * - * @param \SplString $site_path + * @param string $site_path * (optional) The site.path service parameter, which is typically the path * to sites/ in a Drupal installation. This allows you to inject the site * path using services from the caller. If omitted, this method will use the @@ -99,7 +99,7 @@ class PublicStream extends LocalStream { * @return string * The base path for public:// typically sites/default/files. */ - public static function basePath(\SplString $site_path = NULL) { + public static function basePath($site_path = NULL) { if ($site_path === NULL) { // Find the site path. Kernel service is not always available at this // point, but is preferred, when available. diff --git a/core/modules/simpletest/simpletest.api.php b/core/modules/simpletest/simpletest.api.php index d8f82094601..5ab1f1ea3e1 100644 --- a/core/modules/simpletest/simpletest.api.php +++ b/core/modules/simpletest/simpletest.api.php @@ -36,6 +36,14 @@ function hook_simpletest_alter(&$groups) { * A test group has started. * * This hook is called just once at the beginning of a test group. + * + * This hook is only invoked by the Simpletest UI form runner. It will not be + * invoked by run-tests.sh or the phpunit tool. + * + * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Convert your + * test to a PHPUnit-based one and implement test listeners. + * + * @see https://www.drupal.org/node/2934242 */ function hook_test_group_started() { } @@ -44,6 +52,14 @@ function hook_test_group_started() { * A test group has finished. * * This hook is called just once at the end of a test group. + * + * This hook is only invoked by the Simpletest UI form runner. It will not be + * invoked by run-tests.sh or the phpunit tool. + * + * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Convert your + * test to a PHPUnit-based one and implement test listeners. + * + * @see https://www.drupal.org/node/2934242 */ function hook_test_group_finished() { } @@ -53,11 +69,18 @@ function hook_test_group_finished() { * * This hook is called when an individual test has finished. * + * This hook is only invoked by the Simpletest UI form runner. It will not be + * invoked by run-tests.sh or the phpunit tool. + * * @param * $results The results of the test as gathered by * \Drupal\simpletest\WebTestBase. * - * @see \Drupal\simpletest\WebTestBase::results() + * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Convert your + * test to a PHPUnit-based one and implement test listeners. + * + * @see https://www.drupal.org/node/2934242 + * @see _simpletest_batch_operation() */ function hook_test_finished($results) { } diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module index 3cc18b59436..8dc4ecea08c 100644 --- a/core/modules/simpletest/simpletest.module +++ b/core/modules/simpletest/simpletest.module @@ -167,7 +167,7 @@ function simpletest_run_tests($test_list) { ]; batch_set($batch); - \Drupal::moduleHandler()->invokeAll('test_group_started'); + \Drupal::moduleHandler()->invokeAllDeprecated('Convert your test to a PHPUnit-based one and implement test listeners. See https://www.drupal.org/node/2934242', 'test_group_started'); return $test_id; } @@ -351,7 +351,7 @@ function _simpletest_batch_operation($test_list_init, $test_id, &$context) { else { $test = new $test_class($test_id); $test->run(); - \Drupal::moduleHandler()->invokeAll('test_finished', [$test->results]); + \Drupal::moduleHandler()->invokeAllDeprecated('Convert your test to a PHPUnit-based one and implement test listeners. See https://www.drupal.org/node/2934242', 'test_finished', [$test->results]); $test_results[$test_class] = $test->results; } $size = count($test_list); @@ -413,7 +413,7 @@ function _simpletest_batch_finished($success, $results, $operations, $elapsed) { \Drupal::messenger()->addError(t('The test run did not successfully finish.')); \Drupal::messenger()->addWarning(t('Use the Clean environment button to clean-up temporary files and tables.')); } - \Drupal::moduleHandler()->invokeAll('test_group_finished'); + \Drupal::moduleHandler()->invokeAllDeprecated('Convert your test to a PHPUnit-based one and implement test listeners. See https://www.drupal.org/node/2934242', 'test_group_finished'); } /** diff --git a/core/modules/simpletest/tests/modules/simpletest_deprecation_test/simpletest_deprecation_test.module b/core/modules/simpletest/tests/modules/simpletest_deprecation_test/simpletest_deprecation_test.module index f61059783c0..d0f01eb7a62 100644 --- a/core/modules/simpletest/tests/modules/simpletest_deprecation_test/simpletest_deprecation_test.module +++ b/core/modules/simpletest/tests/modules/simpletest_deprecation_test/simpletest_deprecation_test.module @@ -13,3 +13,30 @@ function simpletest_deprecation_test_simpletest_alter(&$groups) { // No-op. } + +/** + * Implements hook_test_group_started(). + * + * This hook is deprecated and should trigger a deprecation error when invoked. + */ +function simpletest_deprecation_test_test_group_started() { + // No-op. +} + +/** + * Implements hook_test_group_finished(). + * + * This hook is deprecated and should trigger a deprecation error when invoked. + */ +function simpletest_deprecation_test_test_group_finished() { + // No-op. +} + +/** + * Implements hook_test_finished(). + * + * This hook is deprecated and should trigger a deprecation error when invoked. + */ +function simpletest_deprecation_test_test_finished($results) { + // No-op. +} diff --git a/core/modules/simpletest/tests/src/Kernel/TestDeprecatedTestHooks.php b/core/modules/simpletest/tests/src/Kernel/TestDeprecatedTestHooks.php new file mode 100644 index 00000000000..c578de6991f --- /dev/null +++ b/core/modules/simpletest/tests/src/Kernel/TestDeprecatedTestHooks.php @@ -0,0 +1,146 @@ +assertNull(_simpletest_batch_finished(TRUE, [], [], 10)); + } + + /** + * @expectedDeprecation The deprecated hook hook_test_group_started() is implemented in these functions: simpletest_deprecation_test_test_group_started(). Convert your test to a PHPUnit-based one and implement test listeners. See https://www.drupal.org/node/2934242 + */ + public function testHookTestGroupStarted() { + // Mock a database connection enough for simpletest_run_tests(). + $insert = $this->getMockBuilder(Insert::class) + ->disableOriginalConstructor() + ->setMethods(['execute', 'useDefaults']) + ->getMock(); + $insert->expects($this->any()) + ->method('useDefaults') + ->willReturn($insert); + $insert->expects($this->any()) + ->method('execute') + // Return an arbitrary test ID. + ->willReturn(__METHOD__); + + $connection = $this->getMockBuilder(Connection::class) + ->disableOriginalConstructor() + ->setMethods(['insert']) + ->getMockForAbstractClass(); + $connection->expects($this->once()) + ->method('insert') + ->willReturn($insert); + + // Mock public stream wrapper enough for simpletest_run_tests(). + $public = $this->getMockBuilder(PublicStream::class) + ->disableOriginalConstructor() + // Mock all methods to do nothing and return NULL. + ->setMethods([]) + ->getMock(); + + // Set up the container. + $this->container->set('database', $connection); + $this->container->set('stream_wrapper.public', $public); + + // Make sure our mocked database is in use by expecting a test ID that is + // __METHOD__. + $this->assertEquals(__METHOD__, simpletest_run_tests([static::class])); + } + + /** + * @expectedDeprecation The deprecated hook hook_test_finished() is implemented in these functions: simpletest_deprecation_test_test_finished(). Convert your test to a PHPUnit-based one and implement test listeners. See https://www.drupal.org/node/2934242 + */ + public function testHookTestFinished() { + // Mock test_discovery. + $discovery = $this->getMockBuilder(TestDiscovery::class) + ->disableOriginalConstructor() + ->setMethods(['registerTestNamespaces']) + ->getMock(); + $discovery->expects($this->once()) + ->method('registerTestNamespaces') + ->willReturn([]); + + // Mock renderer. + $renderer = $this->getMockBuilder(Renderer::class) + ->disableOriginalConstructor() + ->setMethods(['render']) + ->getMock(); + // We don't care what the rendered batch elements look like. + $renderer->expects($this->any()) + ->method('render') + ->willReturn(''); + + // Set up the container. + $this->container->set('test_discovery', $discovery); + $this->container->set('renderer', $renderer); + + // A mock batch. + $context = []; + + // InnocuousTest is a WebTestBase test class which passes and never touches + // the database. + _simpletest_batch_operation([InnocuousTest::class], __METHOD__, $context); + } + +} + +/** + * A very simple WebTestBase test that never touches the database. + * + * @group WebTestBase + * @group legacy + */ +class InnocuousTest extends WebTestBase { + + /** + * Override to prevent any environmental side-effects. + */ + protected function prepareEnvironment() { + } + + /** + * Override run() since it uses TestBase. + */ + public function run(array $methods = []) { + } + + /** + * Override to prevent any assertions from being stored. + */ + protected function storeAssertion(array $assertion) { + } + + /** + * Override to prevent any assertions from being stored. + */ + public static function insertAssert($test_id, $test_class, $status, $message = '', $group = 'Other', array $caller = []) { + } + +}