summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2017-11-09 12:51:06 +0000
committerNathaniel Catchpole2017-11-09 12:51:06 +0000
commit75dcf9af4425942240f221cbff8a9220a6e6df0a (patch)
tree4b7683c57c48c74f7fc00408d066715342f99da9
parentb83782a74b0fa73c9e172537fbd52b7155e49909 (diff)
Issue #2870194 by alexpott, Mile23, jibran, larowlan, tim.plunkett: Ensure that process-isolated tests can use Symfony's PHPunit bridge to catch usages of deprecated code
-rw-r--r--composer.lock19
-rw-r--r--core/composer.json2
-rw-r--r--core/includes/errors.inc69
-rw-r--r--core/lib/Drupal/Core/Test/HttpClientMiddleware/TestHttpClientMiddleware.php10
-rw-r--r--core/modules/basic_auth/src/Tests/BasicAuthTestTrait.php2
-rw-r--r--core/modules/migrate/src/Plugin/migrate/process/Iterator.php3
-rw-r--r--core/modules/migrate/src/Plugin/migrate/process/Migration.php3
-rw-r--r--core/modules/migrate/tests/src/Kernel/Plugin/MigrationDirectoryTest.php3
-rw-r--r--core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php14
-rw-r--r--core/modules/simpletest/src/WebTestBase.php19
-rw-r--r--core/modules/system/tests/modules/deprecation_test/deprecation_test.module20
-rw-r--r--core/modules/system/tests/modules/deprecation_test/deprecation_test.routing.yml6
-rw-r--r--core/modules/system/tests/modules/deprecation_test/src/DeprecatedController.php22
-rw-r--r--core/phpunit.xml.dist6
-rwxr-xr-xcore/scripts/run-tests.sh13
-rw-r--r--core/tests/Drupal/FunctionalTests/Core/Test/PhpUnitBridgeTest.php32
-rw-r--r--core/tests/Drupal/KernelTests/Core/Test/PhpUnitBridgeTest.php33
-rw-r--r--core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeIsolatedTest.php27
-rw-r--r--core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeTest.php29
-rw-r--r--core/tests/Drupal/Tests/Listeners/DeprecationListener.php116
20 files changed, 405 insertions, 43 deletions
diff --git a/composer.lock b/composer.lock
index ddaa66e..8694dc4 100644
--- a/composer.lock
+++ b/composer.lock
@@ -2801,7 +2801,7 @@
"version": "8.2.12",
"source": {
"type": "git",
- "url": "https://github.com/klausi/coder.git",
+ "url": "https://git.drupal.org/project/coder.git",
"reference": "984c54a7b1e8f27ff1c32348df69712afd86b17f"
},
"dist": {
@@ -4194,23 +4194,23 @@
},
{
"name": "symfony/phpunit-bridge",
- "version": "v3.2.8",
+ "version": "v3.4.0-BETA2",
"source": {
"type": "git",
"url": "https://github.com/symfony/phpunit-bridge.git",
- "reference": "00916603c524b8048906de460b7ea0dfa1651281"
+ "reference": "9128796e0cc46f17973e7e9345eb34696aafe00b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/00916603c524b8048906de460b7ea0dfa1651281",
- "reference": "00916603c524b8048906de460b7ea0dfa1651281",
+ "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/9128796e0cc46f17973e7e9345eb34696aafe00b",
+ "reference": "9128796e0cc46f17973e7e9345eb34696aafe00b",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"conflict": {
- "phpunit/phpunit": ">=6.0"
+ "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0"
},
"suggest": {
"ext-zip": "Zip support is required when using bin/simple-phpunit",
@@ -4222,7 +4222,7 @@
"type": "symfony-bridge",
"extra": {
"branch-alias": {
- "dev-master": "3.2-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -4252,13 +4252,14 @@
],
"description": "Symfony PHPUnit Bridge",
"homepage": "https://symfony.com",
- "time": "2017-04-12T14:13:17+00:00"
+ "time": "2017-10-28T16:49:05+00:00"
}
],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": {
- "behat/mink": 20
+ "behat/mink": 20,
+ "symfony/phpunit-bridge": 10
},
"prefer-stable": true,
"prefer-lowest": false,
diff --git a/core/composer.json b/core/composer.json
index 974626f..48e6619 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -47,7 +47,7 @@
"phpunit/phpunit": ">=4.8.35 <5",
"phpspec/prophecy": "^1.4",
"symfony/css-selector": "~3.2.8",
- "symfony/phpunit-bridge": "~3.2.8"
+ "symfony/phpunit-bridge": "^3.4.0@beta"
},
"replace": {
"drupal/action": "self.version",
diff --git a/core/includes/errors.inc b/core/includes/errors.inc
index 284d183..e3fd225 100644
--- a/core/includes/errors.inc
+++ b/core/includes/errors.inc
@@ -83,6 +83,19 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line, $c
'@backtrace_string' => (new \Exception())->getTraceAsString(),
], $recoverable || $to_string);
}
+ // If the site is a test site then fail for user deprecations so they can be
+ // caught by the deprecation error handler.
+ elseif (DRUPAL_TEST_IN_CHILD_SITE && $error_level === E_USER_DEPRECATED) {
+ $backtrace = debug_backtrace();
+ $caller = Error::getLastCaller($backtrace);
+ _drupal_error_header(
+ Markup::create(Xss::filterAdmin($message)),
+ 'User deprecated function',
+ $caller['function'],
+ $caller['file'],
+ $caller['line']
+ );
+ }
}
/**
@@ -136,25 +149,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
// When running inside the testing framework, we relay the errors
// to the tested site by the way of HTTP headers.
if (DRUPAL_TEST_IN_CHILD_SITE && !headers_sent() && (!defined('SIMPLETEST_COLLECT_ERRORS') || SIMPLETEST_COLLECT_ERRORS)) {
- // $number does not use drupal_static as it should not be reset
- // as it uniquely identifies each PHP error.
- static $number = 0;
- $assertion = [
- $error['@message'],
- $error['%type'],
- [
- 'function' => $error['%function'],
- 'file' => $error['%file'],
- 'line' => $error['%line'],
- ],
- ];
- // For non-fatal errors (e.g. PHP notices) _drupal_log_error can be called
- // multiple times per request. In that case the response is typically
- // generated outside of the error handler, e.g., in a controller. As a
- // result it is not possible to use a Response object here but instead the
- // headers need to be emitted directly.
- header('X-Drupal-Assertion-' . $number . ': ' . rawurlencode(serialize($assertion)));
- $number++;
+ _drupal_error_header($error['@message'], $error['%type'], $error['%function'], $error['%file'], $error['%line']);
}
$response = new Response();
@@ -325,3 +320,39 @@ function _drupal_get_error_level() {
// request on a public site, so use the non-verbose default value.
return $error_level ?: ERROR_REPORTING_DISPLAY_ALL;
}
+
+/**
+ * Adds error information to headers so that tests can access it.
+ *
+ * @param $message
+ * The error message.
+ * @param $type
+ * The type of error.
+ * @param $function
+ * The function that emitted the error.
+ * @param $file
+ * The file that emitted the error.
+ * @param $line
+ * The line number in file that emitted the error.
+ */
+function _drupal_error_header($message, $type, $function, $file, $line) {
+ // $number does not use drupal_static as it should not be reset
+ // as it uniquely identifies each PHP error.
+ static $number = 0;
+ $assertion = [
+ $message,
+ $type,
+ [
+ 'function' => $function,
+ 'file' => $file,
+ 'line' => $line,
+ ],
+ ];
+ // For non-fatal errors (e.g. PHP notices) _drupal_log_error can be called
+ // multiple times per request. In that case the response is typically
+ // generated outside of the error handler, e.g., in a controller. As a
+ // result it is not possible to use a Response object here but instead the
+ // headers need to be emitted directly.
+ header('X-Drupal-Assertion-' . $number . ': ' . rawurlencode(serialize($assertion)));
+ $number++;
+}
diff --git a/core/lib/Drupal/Core/Test/HttpClientMiddleware/TestHttpClientMiddleware.php b/core/lib/Drupal/Core/Test/HttpClientMiddleware/TestHttpClientMiddleware.php
index 3c4d1427..ecb6293 100644
--- a/core/lib/Drupal/Core/Test/HttpClientMiddleware/TestHttpClientMiddleware.php
+++ b/core/lib/Drupal/Core/Test/HttpClientMiddleware/TestHttpClientMiddleware.php
@@ -41,7 +41,15 @@ class TestHttpClientMiddleware {
// the header.
$parameters = unserialize(urldecode($header_value));
if (count($parameters) === 3) {
- throw new \Exception($parameters[1] . ': ' . $parameters[0] . "\n" . Error::formatBacktrace([$parameters[2]]));
+ if ($parameters[1] === 'User deprecated function') {
+ // Fire the same deprecation message to allow it to be
+ // collected by
+ // \Symfony\Bridge\PhpUnit\DeprecationErrorHandler::collectDeprecations().
+ @trigger_error((string) $parameters[0], E_USER_DEPRECATED);
+ }
+ else {
+ throw new \Exception($parameters[1] . ': ' . $parameters[0] . "\n" . Error::formatBacktrace([$parameters[2]]));
+ }
}
else {
throw new \Exception('Error thrown with the wrong amount of parameters.');
diff --git a/core/modules/basic_auth/src/Tests/BasicAuthTestTrait.php b/core/modules/basic_auth/src/Tests/BasicAuthTestTrait.php
index 0e0aceb..2d063eb 100644
--- a/core/modules/basic_auth/src/Tests/BasicAuthTestTrait.php
+++ b/core/modules/basic_auth/src/Tests/BasicAuthTestTrait.php
@@ -2,7 +2,7 @@
namespace Drupal\basic_auth\Tests;
-@trigger_error(__FILE__ . ' is deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. Use \Drupal\Tests\basic_auth\Traits\BasicAuthTestTrait instead. See https://www.drupal.org/node/2862800.', E_USER_DEPRECATED);
+@trigger_error(__NAMESPACE__ . '\BasicAuthTestTrait is deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. Use \Drupal\Tests\basic_auth\Traits\BasicAuthTestTrait instead. See https://www.drupal.org/node/2862800.', E_USER_DEPRECATED);
/**
* Provides common functionality for Basic Authentication test classes.
diff --git a/core/modules/migrate/src/Plugin/migrate/process/Iterator.php b/core/modules/migrate/src/Plugin/migrate/process/Iterator.php
index 5400e18..4878ad4 100644
--- a/core/modules/migrate/src/Plugin/migrate/process/Iterator.php
+++ b/core/modules/migrate/src/Plugin/migrate/process/Iterator.php
@@ -2,8 +2,7 @@
namespace Drupal\migrate\Plugin\migrate\process;
-@trigger_error('The ' . __NAMESPACE__ . '\Iterator is deprecated in
-Drupal 8.4.x and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\SubProcess', E_USER_DEPRECATED);
+@trigger_error('The ' . __NAMESPACE__ . '\Iterator is deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\SubProcess', E_USER_DEPRECATED);
/**
* Iterates and processes an associative array.
diff --git a/core/modules/migrate/src/Plugin/migrate/process/Migration.php b/core/modules/migrate/src/Plugin/migrate/process/Migration.php
index ef8ad72..8cae1dd 100644
--- a/core/modules/migrate/src/Plugin/migrate/process/Migration.php
+++ b/core/modules/migrate/src/Plugin/migrate/process/Migration.php
@@ -2,8 +2,7 @@
namespace Drupal\migrate\Plugin\migrate\process;
-@trigger_error('The ' . __NAMESPACE__ . '\Migration is deprecated in
-Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\MigrationLookup', E_USER_DEPRECATED);
+@trigger_error('The ' . __NAMESPACE__ . '\Migration is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\MigrationLookup', E_USER_DEPRECATED);
/**
* Calculates the value of a property based on a previous migration.
diff --git a/core/modules/migrate/tests/src/Kernel/Plugin/MigrationDirectoryTest.php b/core/modules/migrate/tests/src/Kernel/Plugin/MigrationDirectoryTest.php
index 427ca91..b85aea4 100644
--- a/core/modules/migrate/tests/src/Kernel/Plugin/MigrationDirectoryTest.php
+++ b/core/modules/migrate/tests/src/Kernel/Plugin/MigrationDirectoryTest.php
@@ -8,6 +8,7 @@ use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
* Tests that migrations exist in the migration_templates directory.
*
* @group migrate
+ * @group legacy
*/
class MigrationDirectoryTest extends MigrateDrupalTestBase {
@@ -18,6 +19,8 @@ class MigrationDirectoryTest extends MigrateDrupalTestBase {
/**
* Tests that migrations in the migration_templates directory are created.
+ *
+ * @expectedDeprecationMessage Use of the /migration_templates directory to store migration configuration files is deprecated in Drupal 8.1.0 and will be removed before Drupal 9.0.0.
*/
public function testMigrationDirectory() {
/** @var \Drupal\migrate\Plugin\MigrationPluginManager $plugin_manager */
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
index 418ddfb..9a4527f 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
@@ -483,10 +483,16 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
// GET requests - depending on web server configuration. This would usually
// be 'Transfer-Encoding: chunked'.
$ignored_headers = ['Date', 'Content-Length', 'X-Drupal-Cache', 'X-Drupal-Dynamic-Cache', 'Transfer-Encoding'];
- foreach ($ignored_headers as $ignored_header) {
- unset($head_headers[$ignored_header]);
- unset($get_headers[$ignored_header]);
- }
+ $header_cleaner = function ($headers) use ($ignored_headers) {
+ foreach ($headers as $header => $value) {
+ if (strpos($header, 'X-Drupal-Assertion-') === 0 || in_array($header, $ignored_headers)) {
+ unset($headers[$header]);
+ }
+ }
+ return $headers;
+ };
+ $get_headers = $header_cleaner($get_headers);
+ $head_headers = $header_cleaner($head_headers);
$this->assertSame($get_headers, $head_headers);
// BC: serialization_update_8302().
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index b5874b5..22cd768 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -18,6 +18,7 @@ use Drupal\Core\Url;
use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
use Drupal\Tests\EntityViewTrait;
use Drupal\Tests\block\Traits\BlockCreationTrait as BaseBlockCreationTrait;
+use Drupal\Tests\Listeners\DeprecationListener;
use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
use Drupal\Tests\node\Traits\NodeCreationTrait;
use Drupal\Tests\Traits\Core\CronRunTrait;
@@ -690,9 +691,21 @@ abstract class WebTestBase extends TestBase {
// generated by _drupal_log_error() in the exact form required
// by \Drupal\simpletest\WebTestBase::error().
if (preg_match('/^X-Drupal-Assertion-[0-9]+: (.*)$/', $header, $matches)) {
- // Call \Drupal\simpletest\WebTestBase::error() with the parameters from
- // the header.
- call_user_func_array([&$this, 'error'], unserialize(urldecode($matches[1])));
+ $parameters = unserialize(urldecode($matches[1]));
+ // Handle deprecation notices triggered by system under test.
+ if ($parameters[1] === 'User deprecated function') {
+ if (getenv('SYMFONY_DEPRECATIONS_HELPER') !== 'disabled') {
+ $message = (string) $parameters[0];
+ if (!in_array($message, DeprecationListener::getSkippedDeprecations())) {
+ call_user_func_array([&$this, 'error'], $parameters);
+ }
+ }
+ }
+ else {
+ // Call \Drupal\simpletest\WebTestBase::error() with the parameters from
+ // the header.
+ call_user_func_array([&$this, 'error'], $parameters);
+ }
}
// Save cookies.
diff --git a/core/modules/system/tests/modules/deprecation_test/deprecation_test.module b/core/modules/system/tests/modules/deprecation_test/deprecation_test.module
new file mode 100644
index 0000000..e255021
--- /dev/null
+++ b/core/modules/system/tests/modules/deprecation_test/deprecation_test.module
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * Contains functions for testing calling deprecated functions in tests.
+ */
+
+/**
+ * A deprecated function.
+ *
+ * @return string
+ * A known return value of 'known_return_value'.
+ *
+ * @deprecated in Drupal 8.4.x. Might be removed before Drupal 9.0.0. This is
+ * the deprecation message for deprecated_test_function().
+ */
+function deprecation_test_function() {
+ @trigger_error('This is the deprecation message for deprecation_test_function().', E_USER_DEPRECATED);
+ return 'known_return_value';
+}
diff --git a/core/modules/system/tests/modules/deprecation_test/deprecation_test.routing.yml b/core/modules/system/tests/modules/deprecation_test/deprecation_test.routing.yml
new file mode 100644
index 0000000..3ef71b8
--- /dev/null
+++ b/core/modules/system/tests/modules/deprecation_test/deprecation_test.routing.yml
@@ -0,0 +1,6 @@
+deprecation_test.route:
+ path: '/this-calls-a-deprecated-method'
+ defaults:
+ _controller: \Drupal\deprecation_test\DeprecatedController::deprecatedMethod
+ requirements:
+ _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/deprecation_test/src/DeprecatedController.php b/core/modules/system/tests/modules/deprecation_test/src/DeprecatedController.php
new file mode 100644
index 0000000..44cf330
--- /dev/null
+++ b/core/modules/system/tests/modules/deprecation_test/src/DeprecatedController.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Drupal\deprecation_test;
+
+/**
+ * Defines a controller that calls a deprecated method.
+ */
+class DeprecatedController {
+
+ /**
+ * Controller callback.
+ *
+ * @return array
+ * Render array.
+ */
+ public function deprecatedMethod() {
+ return [
+ '#markup' => deprecation_test_function(),
+ ];
+ }
+
+}
diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist
index e5bab48..9b3a8b2 100644
--- a/core/phpunit.xml.dist
+++ b/core/phpunit.xml.dist
@@ -29,6 +29,8 @@
<env name="SIMPLETEST_DB" value=""/>
<!-- Example BROWSERTEST_OUTPUT_DIRECTORY value: /path/to/webroot/sites/simpletest/browser_output -->
<env name="BROWSERTEST_OUTPUT_DIRECTORY" value=""/>
+ <!-- To disable deprecation testing uncomment the next line. -->
+ <!-- <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled"/> -->
</php>
<testsuites>
<testsuite name="unit">
@@ -45,6 +47,10 @@
</testsuite>
</testsuites>
<listeners>
+ <listener class="\Drupal\Tests\Listeners\DeprecationListener">
+ </listener>
+ <!-- The Symfony deprecation listener has to come after the Drupal
+ deprecation listener -->
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener">
</listener>
<listener class="\Drupal\Tests\Listeners\DrupalStandardsListener">
diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh
index 09a7aad..5ebf9f0 100755
--- a/core/scripts/run-tests.sh
+++ b/core/scripts/run-tests.sh
@@ -305,6 +305,10 @@ All arguments are long options.
--non-html Removes escaping from output. Useful for reading results on the
CLI.
+ --suppress-deprecations
+
+ Stops tests from failing if deprecation errors are triggered.
+
<test1>[,<test2>[,<test3> ...]]
One or more tests to be run. By default, these are interpreted
@@ -369,6 +373,7 @@ function simpletest_script_parse_args() {
'test_names' => array(),
'repeat' => 1,
'die-on-fail' => FALSE,
+ 'suppress-deprecations' => FALSE,
'browser' => FALSE,
// Used internally.
'test-id' => 0,
@@ -784,6 +789,12 @@ function simpletest_script_run_one_test($test_id, $test_class) {
$methods = array();
}
$test = new $class_name($test_id);
+ if ($args['suppress-deprecations']) {
+ putenv('SYMFONY_DEPRECATIONS_HELPER=disabled');
+ }
+ else {
+ putenv('SYMFONY_DEPRECATIONS_HELPER=strict');
+ }
if (is_subclass_of($test_class, TestCase::class)) {
$status = simpletest_script_run_phpunit($test_id, $test_class);
}
@@ -834,7 +845,7 @@ function simpletest_script_command($test_id, $test_class) {
}
$command .= ' --php ' . escapeshellarg($php);
$command .= " --test-id $test_id";
- foreach (array('verbose', 'keep-results', 'color', 'die-on-fail') as $arg) {
+ foreach (array('verbose', 'keep-results', 'color', 'die-on-fail', 'suppress-deprecations') as $arg) {
if ($args[$arg]) {
$command .= ' --' . $arg;
}
diff --git a/core/tests/Drupal/FunctionalTests/Core/Test/PhpUnitBridgeTest.php b/core/tests/Drupal/FunctionalTests/Core/Test/PhpUnitBridgeTest.php
new file mode 100644
index 0000000..bc843c3
--- /dev/null
+++ b/core/tests/Drupal/FunctionalTests/Core/Test/PhpUnitBridgeTest.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Drupal\FunctionalTests\Core\Test;
+
+use Drupal\Core\Url;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests Drupal's integration with Symfony PHPUnit Bridge.
+ *
+ * @group Test
+ * @group legacy
+ */
+class PhpUnitBridgeTest extends BrowserTestBase {
+
+ protected static $modules = ['deprecation_test'];
+
+ /**
+ * @expectedDeprecation This is the deprecation message for deprecation_test_function().
+ */
+ public function testSilencedError() {
+ $this->assertEquals('known_return_value', deprecation_test_function());
+ }
+
+ /**
+ * @expectedDeprecation This is the deprecation message for deprecation_test_function().
+ */
+ public function testErrorOnSiteUnderTest() {
+ $this->drupalGet(Url::fromRoute('deprecation_test.route'));
+ }
+
+}
diff --git a/core/tests/Drupal/KernelTests/Core/Test/PhpUnitBridgeTest.php b/core/tests/Drupal/KernelTests/Core/Test/PhpUnitBridgeTest.php
new file mode 100644
index 0000000..d82a37b
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Test/PhpUnitBridgeTest.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Test;
+
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass;
+
+/**
+ * Test how kernel tests interact with deprecation errors.
+ *
+ * @group Test
+ * @group legacy
+ */
+class PhpUnitBridgeTest extends KernelTestBase {
+
+ public static $modules = ['deprecation_test'];
+
+ /**
+ * @expectedDeprecation Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass is deprecated.
+ */
+ public function testDeprecatedClass() {
+ $deprecated = new FixtureDeprecatedClass();
+ $this->assertEquals('test', $deprecated->testFunction());
+ }
+
+ /**
+ * @expectedDeprecation This is the deprecation message for deprecation_test_function().
+ */
+ public function testDeprecatedFunction() {
+ $this->assertEquals('known_return_value', \deprecation_test_function());
+ }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeIsolatedTest.php b/core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeIsolatedTest.php
new file mode 100644
index 0000000..28e331a
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeIsolatedTest.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\Tests\Core\Test;
+
+use Drupal\Tests\UnitTestCase;
+use Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass;
+
+/**
+ * Test how unit tests interact with deprecation errors in process isolation.
+ *
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
+ *
+ * @group Test
+ * @group legacy
+ */
+class PhpUnitBridgeIsolatedTest extends UnitTestCase {
+
+ /**
+ * @expectedDeprecation Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass is deprecated.
+ */
+ public function testDeprecatedClass() {
+ $deprecated = new FixtureDeprecatedClass();
+ $this->assertEquals('test', $deprecated->testFunction());
+ }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeTest.php b/core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeTest.php
new file mode 100644
index 0000000..73ba0de
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeTest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Tests\Core\Test;
+
+use Drupal\Tests\UnitTestCase;
+use Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass;
+
+/**
+ * Test how unit tests interact with deprecation errors.
+ *
+ * @group Test
+ * @group legacy
+ */
+class PhpUnitBridgeTest extends UnitTestCase {
+
+ /**
+ * @expectedDeprecation Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass is deprecated.
+ */
+ public function testDeprecatedClass() {
+ $deprecated = new FixtureDeprecatedClass();
+ $this->assertEquals('test', $deprecated->testFunction());
+ }
+
+ public function testDeprecatedFunction() {
+ $this->markTestIncomplete('Modules are not loaded for unit tests, so deprecated_test_function() will not be available.');
+ $this->assertEquals('known_return_value', \deprecation_test_function());
+ }
+
+}
diff --git a/core/tests/Drupal/Tests/Listeners/DeprecationListener.php b/core/tests/Drupal/Tests/Listeners/DeprecationListener.php
new file mode 100644
index 0000000..a037c02
--- /dev/null
+++ b/core/tests/Drupal/Tests/Listeners/DeprecationListener.php
@@ -0,0 +1,116 @@
+<?php
+
+namespace Drupal\Tests\Listeners;
+
+/**
+ * Removes deprecations that we are yet to fix.
+ *
+ * @internal
+ * This class will be removed once all the deprecation notices have been
+ * fixed.
+ */
+class DeprecationListener extends \PHPUnit_Framework_BaseTestListener {
+
+ /**
+ * {@inheritdoc}
+ */
+ public function endTest(\PHPUnit_Framework_Test $test, $time) {
+ // Need to edit the file of deprecations.
+ if ($file = getenv('SYMFONY_DEPRECATIONS_SERIALIZE')) {
+ $deprecations = file_get_contents($file);
+ $deprecations = $deprecations ? unserialize($deprecations) : [];
+ $resave = FALSE;
+ foreach ($deprecations as $key => $deprecation) {
+ if (in_array($deprecation[1], static::getSkippedDeprecations())) {
+ unset($deprecations[$key]);
+ $resave = TRUE;
+ }
+ }
+ if ($resave) {
+ file_put_contents($file, serialize($deprecations));
+ }
+ }
+ }
+
+ /**
+ * A list of deprecations to ignore whilst fixes are put in place.
+ *
+ * @return string[]
+ * A list of deprecations to ignore.
+ *
+ * @internal
+ */
+ public static function getSkippedDeprecations() {
+ return [
+ 'As of 3.1 an Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface is used to resolve arguments. In 4.0 the $argumentResolver becomes the Symfony\Component\HttpKernel\Controller\ArgumentResolver if no other is provided instead of using the $resolver argument.',
+ 'Symfony\Component\HttpKernel\Controller\ControllerResolver::getArguments is deprecated as of 3.1 and will be removed in 4.0. Implement the Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface and inject it in the HttpKernel instead.',
+ 'The Twig_Node::getLine method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateLine() instead.',
+ 'The Twig_Environment::getCacheFilename method is deprecated since version 1.22 and will be removed in Twig 2.0.',
+ 'Install profile will be a mandatory parameter in Drupal 9.0.',
+ 'Setting the strict option of the Choice constraint to false is deprecated since version 3.2 and will be removed in 4.0.',
+ 'The revision_user revision metadata key is not set.',
+ 'The revision_created revision metadata key is not set.',
+ 'The revision_log_message revision metadata key is not set.',
+ 'The "entity.query" service relies on the deprecated "Drupal\Core\Entity\Query\QueryFactory" class. It should either be deprecated or its implementation upgraded.',
+ 'MigrateCckField is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateField instead.',
+ 'MigrateCckFieldPluginManager is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateFieldPluginManager instead.',
+ 'MigrateCckFieldPluginManagerInterface is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateFieldPluginManagerInterface instead.',
+ 'The "plugin.manager.migrate.cckfield" service is deprecated. You should use the \'plugin.manager.migrate.field\' service instead. See https://www.drupal.org/node/2751897',
+ 'The Drupal\migrate\Plugin\migrate\process\Iterator is deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0. Instead, use Drupal\migrate\Plugin\migrate\process\SubProcess',
+ 'Drupal\system\Tests\Update\DbUpdatesTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use \Drupal\FunctionalTests\Update\DbUpdatesTrait instead. See https://www.drupal.org/node/2896640.',
+ 'Using "null" for the value of node "count" of "Drupal\Core\Template\TwigNodeTrans" is deprecated since version 1.25 and will be removed in 2.0.',
+ 'Using "null" for the value of node "options" of "Drupal\Core\Template\TwigNodeTrans" is deprecated since version 1.25 and will be removed in 2.0.',
+ 'Using "null" for the value of node "plural" of "Drupal\Core\Template\TwigNodeTrans" is deprecated since version 1.25 and will be removed in 2.0.',
+ 'The Behat\Mink\Selector\SelectorsHandler::xpathLiteral method is deprecated as of 1.7 and will be removed in 2.0. Use \Behat\Mink\Selector\Xpath\Escaper::escapeLiteral instead when building Xpath or pass the unescaped value when using the named selector.',
+ 'Passing an escaped locator to the named selector is deprecated as of 1.7 and will be removed in 2.0. Pass the raw value instead.',
+ 'Providing settings under \'handler_settings\' is deprecated and will be removed before 9.0.0. Move the settings in the root of the configuration array. See https://www.drupal.org/node/2870971.',
+ 'AssertLegacyTrait::getRawContent() is scheduled for removal in Drupal 9.0.0. Use $this->getSession()->getPage()->getContent() instead.',
+ 'AssertLegacyTrait::getAllOptions() is scheduled for removal in Drupal 9.0.0. Use $element->findAll(\'xpath\', \'option\') instead.',
+ 'assertNoCacheTag() is deprecated and scheduled for removal in Drupal 9.0.0. Use $this->assertSession()->responseHeaderNotContains() instead. See https://www.drupal.org/node/2864029.',
+ 'assertNoPattern() is deprecated and scheduled for removal in Drupal 9.0.0. Use $this->assertSession()->responseNotMatches($pattern) instead. See https://www.drupal.org/node/2864262.',
+ 'The $published parameter is deprecated since version 8.3.x and will be removed in 9.0.0.',
+ 'The Drupal\config\Tests\AssertConfigEntityImportTrait is deprecated in Drupal 8.4.1 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\config\Traits\AssertConfigEntityImportTrait. See https://www.drupal.org/node/2916197.',
+ 'Drupal\system\Tests\Menu\AssertBreadcrumbTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\system\Functional\Menu\AssertBreadcrumbTrait',
+ '\Drupal\Tests\node\Functional\AssertButtonsTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\node\Functional\AssertButtonsTrait',
+ 'Drupal\system\Tests\Menu\AssertMenuActiveTrailTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\system\Functional\Menu\AssertMenuActiveTrailTrait',
+ 'Drupal\taxonomy\Tests\TaxonomyTranslationTestTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\taxonomy\Functional\TaxonomyTranslationTestTrait',
+ 'Drupal\basic_auth\Tests\BasicAuthTestTrait is deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. Use \Drupal\Tests\basic_auth\Traits\BasicAuthTestTrait instead. See https://www.drupal.org/node/2862800.',
+ 'Drupal\taxonomy\Tests\TaxonomyTestTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait',
+ 'Using UTF-8 route patterns without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for pattern "/system-test/Ȅchȏ/meφΩ/{text}".',
+ 'Using UTF-8 route patterns without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for pattern "/somewhere/{item}/over/the/קainbow".',
+ 'Using UTF-8 route patterns without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for pattern "/place/meφω".',
+ 'Using UTF-8 route patterns without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for pattern "/PLACE/meφω".',
+ 'Passing a Session object to the ExpectationException constructor is deprecated as of Mink 1.7. Pass the driver instead.',
+ 'The Drupal\editor\Plugin\EditorBase::settingsFormValidate method is deprecated since version 8.3.x and will be removed in 9.0.0.',
+ 'CckFile is deprecated in Drupal 8.3.x and will be be removed before Drupal 9.0.x. Use \Drupal\file\Plugin\migrate\process\d6\FieldFile instead.',
+ 'The Drupal\migrate\Plugin\migrate\process\Migration is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use Drupal\migrate\Plugin\migrate\process\MigrationLookup',
+ 'LinkField is deprecated in Drupal 8.3.x and will be be removed before Drupal 9.0.x. Use \Drupal\link\Plugin\migrate\field\d7\LinkField instead.',
+ 'LinkField is deprecated in Drupal 8.3.x and will be be removed before Drupal 9.0.x. Use \Drupal\link\Plugin\migrate\field\d6\LinkField instead.',
+ 'CckFieldPluginBase is deprecated in Drupal 8.3.x and will be be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase instead.',
+ 'MigrateCckFieldInterface is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateField instead.',
+ 'Drupal\system\Plugin\views\field\BulkForm is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\views\Plugin\views\field\BulkForm instead. See https://www.drupal.org/node/2916716.',
+ 'The numeric plugin for watchdog.wid field is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Must use standard plugin instead. See https://www.drupal.org/node/2876378.',
+ 'The numeric plugin for watchdog.uid field is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Must use standard plugin instead. See https://www.drupal.org/node/2876378.',
+ 'The in_operator plugin for watchdog.type filter is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Must use dblog_types plugin instead. See https://www.drupal.org/node/2876378.',
+ 'Using an instance of "Twig_Filter_Function" for filter "testfilter" is deprecated since version 1.21. Use Twig_SimpleFilter instead.',
+ 'The Twig_Function class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFunction instead.',
+ 'Using an instance of "Twig_Function_Function" for function "testfunc" is deprecated since version 1.21. Use Twig_SimpleFunction instead.',
+ 'The Twig_Function class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFunction instead.',
+ 'The Twig_Filter_Function class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFilter instead.',
+ 'The Twig_Filter class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFilter instead.',
+ 'The Twig_Function_Function class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFunction instead.',
+ 'Referencing the "twig_extension_test.test_extension" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.',
+ 'Passing in arguments the legacy way is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Provide the right parameter names in the method, similar to controllers. See https://www.drupal.org/node/2894819',
+ 'DateField is deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.x. Use \Drupal\datetime\Plugin\migrate\field\DateField instead.',
+ 'The Drupal\taxonomy\Entity\Term::getVocabularyId method is deprecated since version 8.4.0 and will be removed before 9.0.0. Use Drupal\taxonomy\Entity\Term::bundle() instead to get the vocabulary ID.',
+ 'The Drupal\editor\Plugin\EditorBase::settingsFormSubmit method is deprecated since version 8.3.x and will be removed in 9.0.0.',
+ 'CommentVariable is deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.x. Use \Drupal\node\Plugin\migrate\source\d6\NodeType instead.',
+ 'CommentType is deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.x. Use \Drupal\node\Plugin\migrate\source\d7\NodeType instead.',
+ 'CommentVariablePerCommentType is deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.x. Use \Drupal\node\Plugin\migrate\source\d6\NodeType instead.',
+ 'The Drupal\config_translation\Plugin\migrate\source\d6\I18nProfileField is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use Drupal\config_translation\Plugin\migrate\source\d6\ProfileFieldTranslation',
+ 'The Drupal\migrate_drupal\Plugin\migrate\source\d6\i18nVariable is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use Drupal\migrate_drupal\Plugin\migrate\source\d6\VariableTranslation',
+ 'Implicit cacheability metadata bubbling (onto the global render context) in normalizers is deprecated since Drupal 8.5.0 and will be removed in Drupal 9.0.0. Use the "cacheability" serialization context instead, for explicit cacheability metadata bubbling. See https://www.drupal.org/node/2918937',
+ ];
+ }
+
+}