diff --git a/composer.json b/composer.json index 61c5d3735acf2153e6b5f7b70a17a4a3fc54b1f2..d816666f6e9328ed488fcc96c16c999c1c2714eb 100644 --- a/composer.json +++ b/composer.json @@ -33,13 +33,12 @@ "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.10.62", "phpstan/phpstan-phpunit": "^1.3.16", - "phpunit/phpunit": "^9.6.13", + "phpunit/phpunit": "^10.5.19", "symfony/browser-kit": "^7.0", "symfony/css-selector": "^7.0", "symfony/dom-crawler": "^7.0", "symfony/error-handler": "^7.0", "symfony/lock": "^7.0", - "symfony/phpunit-bridge": "^7.0", "symfony/var-dumper": "^7.0" }, "replace": { diff --git a/composer.lock b/composer.lock index 59cc6b18cd44ec5512126cb9745a0dcbb590dc84..e1546f71124671c240234dfa4ff62bf510ac0d47 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7033803d9382729f982fd06b4b8603de", + "content-hash": "0fb1643cd4e3341596fa89fcbdf1b7e4", "packages": [ { "name": "asm89/stack-cors", @@ -1861,29 +1861,29 @@ }, { "name": "sebastian/diff", - "version": "4.0.6", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", - "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -1915,7 +1915,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" }, "funding": [ { @@ -1923,7 +1924,7 @@ "type": "github" } ], - "time": "2024-03-02T06:30:58+00:00" + "time": "2024-03-02T07:15:17+00:00" }, { "name": "symfony/console", @@ -7160,16 +7161,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.31", + "version": "10.1.14", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965" + "reference": "e3f51450ebffe8e0efdf7346ae966a656f7d5e5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/e3f51450ebffe8e0efdf7346ae966a656f7d5e5b", + "reference": "e3f51450ebffe8e0efdf7346ae966a656f7d5e5b", "shasum": "" }, "require": { @@ -7177,18 +7178,18 @@ "ext-libxml": "*", "ext-xmlwriter": "*", "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-text-template": "^3.0", + "sebastian/code-unit-reverse-lookup": "^3.0", + "sebastian/complexity": "^3.0", + "sebastian/environment": "^6.0", + "sebastian/lines-of-code": "^2.0", + "sebastian/version": "^4.0", "theseer/tokenizer": "^1.2.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.1" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -7197,7 +7198,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.2-dev" + "dev-main": "10.1-dev" } }, "autoload": { @@ -7226,7 +7227,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.31" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.14" }, "funding": [ { @@ -7234,32 +7235,32 @@ "type": "github" } ], - "time": "2024-03-02T06:37:42+00:00" + "time": "2024-03-12T15:33:41+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.6", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -7286,7 +7287,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" }, "funding": [ { @@ -7294,28 +7296,28 @@ "type": "github" } ], - "time": "2021-12-02T12:48:52+00:00" + "time": "2023-08-31T06:24:48+00:00" }, { "name": "phpunit/php-invoker", - "version": "3.1.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-pcntl": "*" @@ -7323,7 +7325,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -7349,7 +7351,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" }, "funding": [ { @@ -7357,32 +7359,32 @@ "type": "github" } ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2023-02-03T06:56:09+00:00" }, { "name": "phpunit/php-text-template", - "version": "2.0.4", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -7408,7 +7410,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" }, "funding": [ { @@ -7416,32 +7419,32 @@ "type": "github" } ], - "time": "2020-10-26T05:33:50+00:00" + "time": "2023-08-31T14:07:24+00:00" }, { "name": "phpunit/php-timer", - "version": "5.0.3", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -7467,7 +7470,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" }, "funding": [ { @@ -7475,24 +7478,23 @@ "type": "github" } ], - "time": "2020-10-26T13:16:10+00:00" + "time": "2023-02-03T06:57:52+00:00" }, { "name": "phpunit/phpunit", - "version": "9.6.19", + "version": "10.5.19", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8" + "reference": "c726f0de022368f6ed103e452a765d3304a996a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1a54a473501ef4cdeaae4e06891674114d79db8", - "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c726f0de022368f6ed103e452a765d3304a996a4", + "reference": "c726f0de022368f6ed103e452a765d3304a996a4", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -7502,27 +7504,26 @@ "myclabs/deep-copy": "^1.10.1", "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.28", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.8", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.5", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.2", - "sebastian/version": "^3.0.2" + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.5", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-invoker": "^4.0", + "phpunit/php-text-template": "^3.0", + "phpunit/php-timer": "^6.0", + "sebastian/cli-parser": "^2.0", + "sebastian/code-unit": "^2.0", + "sebastian/comparator": "^5.0", + "sebastian/diff": "^5.0", + "sebastian/environment": "^6.0", + "sebastian/exporter": "^5.1", + "sebastian/global-state": "^6.0.1", + "sebastian/object-enumerator": "^5.0", + "sebastian/recursion-context": "^5.0", + "sebastian/type": "^4.0", + "sebastian/version": "^4.0" }, "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + "ext-soap": "To be able to generate mocks based on WSDL files" }, "bin": [ "phpunit" @@ -7530,7 +7531,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.6-dev" + "dev-main": "10.5-dev" } }, "autoload": { @@ -7562,7 +7563,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.19" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.19" }, "funding": [ { @@ -7578,7 +7579,7 @@ "type": "tidelift" } ], - "time": "2024-04-05T04:35:58+00:00" + "time": "2024-04-17T14:06:18+00:00" }, { "name": "react/promise", @@ -7655,28 +7656,28 @@ }, { "name": "sebastian/cli-parser", - "version": "1.0.2", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", - "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -7699,7 +7700,8 @@ "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" }, "funding": [ { @@ -7707,32 +7709,32 @@ "type": "github" } ], - "time": "2024-03-02T06:27:43+00:00" + "time": "2024-03-02T07:12:49+00:00" }, { "name": "sebastian/code-unit", - "version": "1.0.8", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -7755,7 +7757,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" }, "funding": [ { @@ -7763,32 +7765,32 @@ "type": "github" } ], - "time": "2020-10-26T13:08:54+00:00" + "time": "2023-02-03T06:58:43+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -7810,7 +7812,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" }, "funding": [ { @@ -7818,34 +7820,36 @@ "type": "github" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2023-02-03T06:59:15+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.8", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + "reference": "2db5010a484d53ebf536087a70b4a5423c102372" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -7884,7 +7888,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" }, "funding": [ { @@ -7892,33 +7897,33 @@ "type": "github" } ], - "time": "2022-09-14T12:41:17+00:00" + "time": "2023-08-14T13:18:12+00:00" }, { "name": "sebastian/complexity", - "version": "2.0.3", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" + "reference": "68ff824baeae169ec9f2137158ee529584553799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", "shasum": "" }, "require": { "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.2-dev" } }, "autoload": { @@ -7941,7 +7946,8 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" }, "funding": [ { @@ -7949,27 +7955,27 @@ "type": "github" } ], - "time": "2023-12-22T06:19:30+00:00" + "time": "2023-12-21T08:37:17+00:00" }, { "name": "sebastian/environment", - "version": "5.1.5", + "version": "6.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-posix": "*" @@ -7977,7 +7983,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -7996,7 +8002,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -8004,7 +8010,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" }, "funding": [ { @@ -8012,34 +8019,34 @@ "type": "github" } ], - "time": "2023-02-03T06:03:51+00:00" + "time": "2024-03-23T08:47:14+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.6", + "version": "5.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" + "reference": "955288482d97c19a372d3f31006ab3f37da47adf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", + "reference": "955288482d97c19a372d3f31006ab3f37da47adf", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -8081,7 +8088,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" }, "funding": [ { @@ -8089,38 +8097,35 @@ "type": "github" } ], - "time": "2024-03-02T06:33:00+00:00" + "time": "2024-03-02T07:17:12+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.7", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -8139,13 +8144,14 @@ } ], "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" }, "funding": [ { @@ -8153,33 +8159,33 @@ "type": "github" } ], - "time": "2024-03-02T06:35:11+00:00" + "time": "2024-03-02T07:19:19+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.4", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", "shasum": "" }, "require": { "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -8202,7 +8208,8 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" }, "funding": [ { @@ -8210,34 +8217,34 @@ "type": "github" } ], - "time": "2023-12-22T06:20:34+00:00" + "time": "2023-12-21T08:38:20+00:00" }, { "name": "sebastian/object-enumerator", - "version": "4.0.4", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -8259,7 +8266,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" }, "funding": [ { @@ -8267,32 +8274,32 @@ "type": "github" } ], - "time": "2020-10-26T13:12:34+00:00" + "time": "2023-02-03T07:08:32+00:00" }, { "name": "sebastian/object-reflector", - "version": "2.0.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -8314,7 +8321,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" }, "funding": [ { @@ -8322,32 +8329,32 @@ "type": "github" } ], - "time": "2020-10-26T13:14:26+00:00" + "time": "2023-02-03T07:06:18+00:00" }, { "name": "sebastian/recursion-context", - "version": "4.0.5", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -8377,7 +8384,7 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" }, "funding": [ { @@ -8385,86 +8392,32 @@ "type": "github" } ], - "time": "2023-02-03T06:07:39+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", - "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-14T16:00:52+00:00" + "time": "2023-02-03T07:05:40+00:00" }, { "name": "sebastian/type", - "version": "3.2.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -8487,7 +8440,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" }, "funding": [ { @@ -8495,29 +8448,29 @@ "type": "github" } ], - "time": "2023-02-03T06:13:03+00:00" + "time": "2023-02-03T07:10:45+00:00" }, { "name": "sebastian/version", - "version": "3.0.2", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -8540,7 +8493,7 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" }, "funding": [ { @@ -8548,7 +8501,7 @@ "type": "github" } ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2023-02-07T11:34:05+00:00" }, { "name": "seld/jsonlint", @@ -9204,87 +9157,6 @@ ], "time": "2024-03-19T09:26:35+00:00" }, - { - "name": "symfony/phpunit-bridge", - "version": "v7.0.6", - "source": { - "type": "git", - "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "a014167aa1f66cb9990675840da65609d3e61612" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/a014167aa1f66cb9990675840da65609d3e61612", - "reference": "a014167aa1f66cb9990675840da65609d3e61612", - "shasum": "" - }, - "require": { - "php": ">=7.2.5" - }, - "conflict": { - "phpunit/phpunit": "<7.5|9.1.2" - }, - "require-dev": { - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/error-handler": "^5.4|^6.4|^7.0", - "symfony/polyfill-php81": "^1.27" - }, - "bin": [ - "bin/simple-phpunit" - ], - "type": "symfony-bridge", - "extra": { - "thanks": { - "name": "phpunit/phpunit", - "url": "https://github.com/sebastianbergmann/phpunit" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Bridge\\PhpUnit\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides utilities for PHPUnit, especially user deprecation notices management", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v7.0.6" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-03-19T11:57:22+00:00" - }, { "name": "theseer/tokenizer", "version": "1.2.3", diff --git a/composer/Metapackage/CoreRecommended/composer.json b/composer/Metapackage/CoreRecommended/composer.json index 1ff8f88aac7523fb193302c1f41c32676884a450..6b6058654dcee02da8ed8ea83d8b1d7ea3f62093 100644 --- a/composer/Metapackage/CoreRecommended/composer.json +++ b/composer/Metapackage/CoreRecommended/composer.json @@ -30,7 +30,7 @@ "psr/http-factory": "~1.0.2", "psr/log": "~3.0.0", "ralouphie/getallheaders": "~3.0.3", - "sebastian/diff": "~4.0.6", + "sebastian/diff": "~5.1.1", "symfony/console": "~v7.0.6", "symfony/dependency-injection": "~v7.0.6", "symfony/deprecation-contracts": "~v3.4.0", diff --git a/composer/Metapackage/DevDependencies/composer.json b/composer/Metapackage/DevDependencies/composer.json index 396fbfad68e5049081118102b165213ea800335b..259f200cec6b035f6e5a522e45f29912437aaa66 100644 --- a/composer/Metapackage/DevDependencies/composer.json +++ b/composer/Metapackage/DevDependencies/composer.json @@ -25,13 +25,12 @@ "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.10.62", "phpstan/phpstan-phpunit": "^1.3.16", - "phpunit/phpunit": "^9.6.13", + "phpunit/phpunit": "^10.5.19", "symfony/browser-kit": "^7.0", "symfony/css-selector": "^7.0", "symfony/dom-crawler": "^7.0", "symfony/error-handler": "^7.0", "symfony/lock": "^7.0", - "symfony/phpunit-bridge": "^7.0", "symfony/var-dumper": "^7.0" } } diff --git a/composer/Metapackage/PinnedDevDependencies/composer.json b/composer/Metapackage/PinnedDevDependencies/composer.json index e1d0859f401e742a7fb0c6c1478c74b6244fb1b5..1fea6769a13f5c907438398f5d4a9a7b173ee292 100644 --- a/composer/Metapackage/PinnedDevDependencies/composer.json +++ b/composer/Metapackage/PinnedDevDependencies/composer.json @@ -52,28 +52,27 @@ "phpstan/phpstan": "1.10.66", "phpstan/phpstan-deprecation-rules": "1.1.4", "phpstan/phpstan-phpunit": "1.3.16", - "phpunit/php-code-coverage": "9.2.31", - "phpunit/php-file-iterator": "3.0.6", - "phpunit/php-invoker": "3.1.1", - "phpunit/php-text-template": "2.0.4", - "phpunit/php-timer": "5.0.3", - "phpunit/phpunit": "9.6.19", + "phpunit/php-code-coverage": "10.1.14", + "phpunit/php-file-iterator": "4.1.0", + "phpunit/php-invoker": "4.0.0", + "phpunit/php-text-template": "3.0.1", + "phpunit/php-timer": "6.0.0", + "phpunit/phpunit": "10.5.19", "react/promise": "v3.1.0", - "sebastian/cli-parser": "1.0.2", - "sebastian/code-unit": "1.0.8", - "sebastian/code-unit-reverse-lookup": "2.0.3", - "sebastian/comparator": "4.0.8", - "sebastian/complexity": "2.0.3", - "sebastian/environment": "5.1.5", - "sebastian/exporter": "4.0.6", - "sebastian/global-state": "5.0.7", - "sebastian/lines-of-code": "1.0.4", - "sebastian/object-enumerator": "4.0.4", - "sebastian/object-reflector": "2.0.4", - "sebastian/recursion-context": "4.0.5", - "sebastian/resource-operations": "3.0.4", - "sebastian/type": "3.2.1", - "sebastian/version": "3.0.2", + "sebastian/cli-parser": "2.0.1", + "sebastian/code-unit": "2.0.0", + "sebastian/code-unit-reverse-lookup": "3.0.0", + "sebastian/comparator": "5.0.1", + "sebastian/complexity": "3.2.0", + "sebastian/environment": "6.1.0", + "sebastian/exporter": "5.1.2", + "sebastian/global-state": "6.0.2", + "sebastian/lines-of-code": "2.0.2", + "sebastian/object-enumerator": "5.0.0", + "sebastian/object-reflector": "3.0.0", + "sebastian/recursion-context": "5.0.0", + "sebastian/type": "4.0.0", + "sebastian/version": "4.0.1", "seld/jsonlint": "1.10.2", "seld/phar-utils": "1.2.1", "seld/signal-handler": "2.0.2", @@ -84,7 +83,6 @@ "symfony/css-selector": "v7.0.3", "symfony/dom-crawler": "v7.0.4", "symfony/lock": "v7.0.6", - "symfony/phpunit-bridge": "v7.0.6", "theseer/tokenizer": "1.2.3", "webflo/drupal-finder": "1.2.2", "webmozart/assert": "1.11.0" diff --git a/composer/Plugin/VendorHardening/Config.php b/composer/Plugin/VendorHardening/Config.php index 3db5c3372a3b0338c7ab19d26172726adc64dfd9..411425b14f539ee6c8960a16c73adefceb6793af 100644 --- a/composer/Plugin/VendorHardening/Config.php +++ b/composer/Plugin/VendorHardening/Config.php @@ -70,7 +70,6 @@ class Config { 'symfony/event-dispatcher' => ['Tests'], 'symfony/http-foundation' => ['Tests'], 'symfony/http-kernel' => ['Tests'], - 'symfony/phpunit-bridge' => ['Tests'], 'symfony/process' => ['Tests'], 'symfony/psr-http-message-bridge' => ['Tests'], 'symfony/routing' => ['Tests'], diff --git a/core/.deprecation-ignore.txt b/core/.deprecation-ignore.txt index 92d3da6177c9b789129312147ff952e7ae2c7916..1e589a23266c5a89177f4a92616b7ae62d2e48ee 100644 --- a/core/.deprecation-ignore.txt +++ b/core/.deprecation-ignore.txt @@ -3,7 +3,6 @@ # See https://www.drupal.org/node/3285162 for more details. %The "Symfony\\Component\\Validator\\Context\\ExecutionContextInterface::.*\(\)" method is considered internal Used by the validator engine\. (Should not be called by user\W+code\. )?It may change without further notice\. You should not extend it from "[^"]+"\.% -%The "PHPUnit\\Framework\\TestCase::addWarning\(\)" method is considered internal% # Skip some dependencies' DebugClassLoader forward compatibility warnings. %Method "Behat\\[^"]+" might add "[^"]+" as a native return type declaration in the future. Do the same in (child class|implementation) "[^"]+" now to avoid errors or add an explicit @return annotation to suppress this message% @@ -16,17 +15,10 @@ %Method "Twig\\NodeVisitor\\NodeVisitorInterface::[^"]+" might add "[^"]+" as a native return type declaration in the future. Do the same in (child class|implementation) "[^"]+" now to avoid errors or add an explicit @return annotation to suppress this message% %Method "Twig\\TokenParser\\TokenParserInterface::[^"]+" might add "[^"]+" as a native return type declaration in the future. Do the same in (child class|implementation) "[^"]+" now to avoid errors or add an explicit @return annotation to suppress this message% %Method "WebDriver\\Service\\CurlServiceInterface::[^"]+" might add "[^"]+" as a native return type declaration in the future. Do the same in implementation "[^"]+" now to avoid errors or add an explicit @return annotation to suppress this message% +# Indirect deprecations. These are not in Drupal's remit to fix, but it is +# worth keeping track of dependencies' issues. +%Method "[^"]+" might add "[^"]+" as a native return type declaration in the future. Do the same in implementation "org\\bovigo\\vfs\\[^"]+" now to avoid errors or add an explicit @return annotation to suppress this message% # The following deprecation is listed for Twig 2 compatibility when unit # testing using \Symfony\Component\ErrorHandler\DebugClassLoader. %The "Twig\\Environment::getTemplateClass\(\)" method is considered internal\. It may change without further notice\. You should not extend it from "Drupal\\Core\\Template\\TwigEnvironment"\.% - -# PHPUnit 9. -%"PHPUnit\\Framework\\TestListener".*is deprecated% -%"PHPUnit\\Framework\\TestListenerDefaultImplementation".*is deprecated% -%"PHPUnit\\Framework\\TestSuite".*is considered internal% -%"PHPUnit\\TextUI\\DefaultResultPrinter".*is considered internal% - -# PHPUnit 9.6. -%Expecting E_WARNING and E_USER_WARNING is deprecated and will no longer be possible in PHPUnit 10% -%Expecting E_ERROR and E_USER_ERROR is deprecated and will no longer be possible in PHPUnit 10% diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php index 4ab06a7bfe471c76d28f7db24b41159163ad6419..1d2dee7a1e4a743c75df2d49ba966980bcd6ff64 100644 --- a/core/.phpstan-baseline.php +++ b/core/.phpstan-baseline.php @@ -841,6 +841,16 @@ 'count' => 1, 'path' => __DIR__ . '/modules/filter/src/Plugin/Filter/FilterHtml.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 2, + 'path' => __DIR__ . '/modules/filter/tests/src/Unit/FilterUninstallValidatorTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/modules/help/tests/src/Unit/HelpTopicTwigTest.php', +]; $ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\history\\\\Plugin\\\\views\\\\field\\\\HistoryUserTimestamp\\:\\:render\\(\\) should return Drupal\\\\Component\\\\Render\\\\MarkupInterface\\|string but return statement is missing\\.$#', 'count' => 1, @@ -1106,6 +1116,11 @@ 'count' => 1, 'path' => __DIR__ . '/modules/migrate/tests/src/Kernel/MigrateTestBase.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/modules/migrate/tests/src/Unit/MigrateExecutableTest.php', +]; $ignoreErrors[] = [ 'message' => '#^Variable \\$sub_process_plugins might not be defined\\.$#', 'count' => 2, @@ -1356,6 +1371,11 @@ 'count' => 1, 'path' => __DIR__ . '/modules/serialization/src/Normalizer/EntityNormalizer.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/modules/serialization/tests/src/Unit/Normalizer/NormalizerBaseTest.php', +]; $ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\shortcut\\\\Form\\\\SetCustomize\\:\\:save\\(\\) should return int but return statement is missing\\.$#', 'count' => 1, @@ -1498,6 +1518,11 @@ 'count' => 2, 'path' => __DIR__ . '/modules/system/tests/src/Functional/Theme/ThemeUiTest.php', ]; +$ignoreErrors[] = [ + 'message' => '#^@dataProvider themeDataProvider related method must be static in PHPUnit 10 and newer\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/modules/system/tests/src/FunctionalJavascript/OffCanvasTest.php', +]; $ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\taxonomy\\\\Plugin\\\\migrate\\\\source\\\\d7\\\\TermTranslation\\:\\:prepareRow\\(\\) should return bool but return statement is missing\\.$#', 'count' => 1, @@ -1533,6 +1558,21 @@ 'count' => 1, 'path' => __DIR__ . '/modules/update/src/ProjectRelease.php', ]; +$ignoreErrors[] = [ + 'message' => '#^@dataProvider securityUpdateAvailabilityProvider related method must be static in PHPUnit 10 and newer\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/modules/update/tests/src/Functional/UpdateSemverContribSecurityAvailabilityTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^@dataProvider securityUpdateAvailabilityProvider related method must be static in PHPUnit 10 and newer\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/modules/update/tests/src/Functional/UpdateSemverCoreSecurityAvailabilityTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^@dataProvider providerProjectStatus related method must be static in PHPUnit 10 and newer\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/modules/update/tests/src/Kernel/UpdateCalculateProjectDataTest.php', +]; $ignoreErrors[] = [ 'message' => '#^Variable \\$users might not be defined\\.$#', 'count' => 1, @@ -1838,6 +1878,41 @@ 'count' => 2, 'path' => __DIR__ . '/modules/views/tests/src/Kernel/Plugin/StyleTest.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 5, + 'path' => __DIR__ . '/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 2, + 'path' => __DIR__ . '/modules/views/tests/src/Unit/Plugin/argument_validator/EntityTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/modules/views/tests/src/Unit/Plugin/display/PathPluginBaseTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/modules/views/tests/src/Unit/Plugin/pager/PagerPluginBaseTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/modules/views/tests/src/Unit/Plugin/pager/SqlBaseTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/modules/views/tests/src/Unit/Plugin/views/field/EntityOperationsUnitTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^@dataProvider provideAcceptExposedInput related method must be static in PHPUnit 10 and newer\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/modules/views/tests/src/Unit/Plugin/views/filter/NumericFilterTest.php', +]; $ignoreErrors[] = [ 'message' => '#^Variable \\$relationship_handler in empty\\(\\) always exists and is not falsy\\.$#', 'count' => 1, @@ -1963,6 +2038,11 @@ 'count' => 1, 'path' => __DIR__ . '/tests/Drupal/BuildTests/Composer/Template/ComposerProjectTemplatesTest.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 2, + 'path' => __DIR__ . '/tests/Drupal/BuildTests/Framework/Tests/BuildTestTest.php', +]; $ignoreErrors[] = [ 'message' => '#^Variable \\$found might not be defined\\.$#', 'count' => 1, @@ -1993,6 +2073,26 @@ 'count' => 1, 'path' => __DIR__ . '/tests/Drupal/KernelTests/Core/Entity/FieldableEntityDefinitionUpdateTest.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 2, + 'path' => __DIR__ . '/tests/Drupal/KernelTests/Core/Installer/InstallerRedirectTraitTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/KernelTests/Core/Installer/InstallerRedirectTraitTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Class PHPUnit\\\\Framework\\\\Error\\\\Warning not found\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/KernelTests/Core/Test/Comparator/MarkupInterfaceComparatorTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to an undefined method Drupal\\\\KernelTests\\\\KernelTestBase\\:\\:getTestResultObject\\(\\)\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/KernelTests/KernelTestBase.php', +]; $ignoreErrors[] = [ 'message' => '#^Variable \\$value in isset\\(\\) always exists and is not nullable\\.$#', 'count' => 1, @@ -2020,14 +2120,12 @@ 'path' => __DIR__ . '/tests/Drupal/Tests/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumperTest.php', ]; $ignoreErrors[] = [ - 'message' => '#^Call to deprecated method expectWarning\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\: -https\\://github\\.com/sebastianbergmann/phpunit/issues/5062$#', + 'message' => '#^Call to an undefined method Drupal\\\\Tests\\\\Component\\\\PhpStorage\\\\FileStorageTest\\:\\:expectWarning\\(\\)\\.$#', 'count' => 1, 'path' => __DIR__ . '/tests/Drupal/Tests/Component/PhpStorage/FileStorageTest.php', ]; $ignoreErrors[] = [ - 'message' => '#^Call to deprecated method expectWarningMessage\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\: -https\\://github\\.com/sebastianbergmann/phpunit/issues/5062$#', + 'message' => '#^Call to an undefined method Drupal\\\\Tests\\\\Component\\\\PhpStorage\\\\FileStorageTest\\:\\:expectWarningMessage\\(\\)\\.$#', 'count' => 1, 'path' => __DIR__ . '/tests/Drupal/Tests/Component/PhpStorage/FileStorageTest.php', ]; @@ -2086,6 +2184,16 @@ 'count' => 1, 'path' => __DIR__ . '/tests/Drupal/Tests/Component/Plugin/Factory/ReflectionFactoryTest.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 4, + 'path' => __DIR__ . '/tests/Drupal/Tests/Component/Plugin/PluginBaseTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 2, + 'path' => __DIR__ . '/tests/Drupal/Tests/Component/Plugin/PluginManagerBaseTest.php', +]; $ignoreErrors[] = [ 'message' => '#^Missing cache backend declaration for performance\\.$#', 'count' => 1, @@ -2096,6 +2204,61 @@ 'count' => 1, 'path' => __DIR__ . '/tests/Drupal/Tests/Composer/ComposerTest.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 3, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 5, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Config/Entity/EntityDisplayBaseTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Controller/ControllerBaseTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Entity/EntityFormTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Entity/EntityLinkTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 2, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Entity/EntityStorageBaseTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 2, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Entity/EntityTypeManagerTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Entity/EntityUrlTest.php', +]; $ignoreErrors[] = [ 'message' => '#^Trying to mock an undefined method getRevisionId\\(\\) on class Drupal\\\\Tests\\\\Core\\\\Entity\\\\UrlTestEntity\\.$#', 'count' => 1, @@ -2106,12 +2269,37 @@ 'count' => 1, 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Entity/EntityUrlTest.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Entity/KeyValueStore/KeyValueEntityStorageTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^@dataProvider providerTestRequiresEntityDataMigration related method must be static in PHPUnit 10 and newer\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^@dataProvider providerTestRequiresEntityStorageSchemaChanges related method must be static in PHPUnit 10 and newer\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 3, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php', +]; $ignoreErrors[] = [ 'message' => '#^Call to deprecated method getConfig\\(\\) of class GuzzleHttp\\\\Client\\: Client\\:\\:getConfig will be removed in guzzlehttp/guzzle\\:8\\.0\\.$#', 'count' => 1, 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Http/ClientFactoryTest.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Lock/LockBackendAbstractTest.php', +]; $ignoreErrors[] = [ 'message' => '#^Call to method getDefinitions\\(\\) on an unknown class Drupal\\\\Core\\\\Plugin\\\\CategorizingPluginManagerTrait\\.$#', 'count' => 1, @@ -2148,61 +2336,55 @@ 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Plugin/TestPluginManager.php', ]; $ignoreErrors[] = [ - 'message' => '#^Variable \\$value in isset\\(\\) always exists and is not nullable\\.$#', + 'message' => '#^@dataProvider dataProviderIsRenderArray related method must be static in PHPUnit 10 and newer\\.$#', 'count' => 1, - 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Test/AssertContentTraitTest.php', + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Render/ElementTest.php', ]; $ignoreErrors[] = [ - 'message' => '#^Call to deprecated method getConfig\\(\\) of class GuzzleHttp\\\\ClientInterface\\: -ClientInterface\\:\\:getConfig will be removed in guzzlehttp/guzzle\\:8\\.0\\.$#', + 'message' => '#^@dataProvider providerTestRenderBasic related method must be static in PHPUnit 10 and newer\\.$#', 'count' => 1, - 'path' => __DIR__ . '/tests/Drupal/Tests/DrupalTestBrowser.php', + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Render/RendererTest.php', ]; $ignoreErrors[] = [ - 'message' => '#^Class Drupal\\\\Tests\\\\Listeners\\\\DrupalListener implements deprecated interface PHPUnit\\\\Framework\\\\TestListener\\.$#', + 'message' => '#^@dataProvider alterPermissionsProvider related method must be static in PHPUnit 10 and newer\\.$#', 'count' => 1, - 'path' => __DIR__ . '/tests/Drupal/Tests/Listeners/DrupalListener.php', + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Session/SuperUserAccessPolicyTest.php', ]; $ignoreErrors[] = [ - 'message' => '#^Usage of deprecated trait PHPUnit\\\\Framework\\\\TestListenerDefaultImplementation in class Drupal\\\\Tests\\\\Listeners\\\\DrupalListener\\: -The `TestListener` interface is deprecated$#', + 'message' => '#^@dataProvider calculatePermissionsProvider related method must be static in PHPUnit 10 and newer\\.$#', 'count' => 1, - 'path' => __DIR__ . '/tests/Drupal/Tests/Listeners/DrupalListener.php', + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Session/SuperUserAccessPolicyTest.php', ]; $ignoreErrors[] = [ - 'message' => '#^Class Drupal\\\\Tests\\\\TestSuites\\\\BuildTestSuite extends deprecated class Drupal\\\\Tests\\\\TestSuites\\\\TestSuiteBase\\: -in drupal\\:10\\.3\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no - replacement and test discovery will be handled differently in PHPUnit 10\\.$#', + 'message' => '#^@dataProvider calculatePermissionsProvider related method must be static in PHPUnit 10 and newer\\.$#', 'count' => 1, - 'path' => __DIR__ . '/tests/TestSuites/BuildTestSuite.php', + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Session/UserRolesAccessPolicyTest.php', ]; $ignoreErrors[] = [ - 'message' => '#^Class Drupal\\\\Tests\\\\TestSuites\\\\FunctionalJavascriptTestSuite extends deprecated class Drupal\\\\Tests\\\\TestSuites\\\\TestSuiteBase\\: -in drupal\\:10\\.3\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no - replacement and test discovery will be handled differently in PHPUnit 10\\.$#', + 'message' => '#^Variable \\$value in isset\\(\\) always exists and is not nullable\\.$#', 'count' => 1, - 'path' => __DIR__ . '/tests/TestSuites/FunctionalJavascriptTestSuite.php', + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Test/AssertContentTraitTest.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', + 'count' => 3, + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Test/BrowserTestBaseTest.php', ]; $ignoreErrors[] = [ - 'message' => '#^Class Drupal\\\\Tests\\\\TestSuites\\\\FunctionalTestSuite extends deprecated class Drupal\\\\Tests\\\\TestSuites\\\\TestSuiteBase\\: -in drupal\\:10\\.3\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no - replacement and test discovery will be handled differently in PHPUnit 10\\.$#', + 'message' => '#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder\\.$#', 'count' => 1, - 'path' => __DIR__ . '/tests/TestSuites/FunctionalTestSuite.php', + 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Test/WebDriverTestBaseTest.php', ]; $ignoreErrors[] = [ - 'message' => '#^Class Drupal\\\\Tests\\\\TestSuites\\\\KernelTestSuite extends deprecated class Drupal\\\\Tests\\\\TestSuites\\\\TestSuiteBase\\: -in drupal\\:10\\.3\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no - replacement and test discovery will be handled differently in PHPUnit 10\\.$#', + 'message' => '#^Call to deprecated method getConfig\\(\\) of class GuzzleHttp\\\\ClientInterface\\: +ClientInterface\\:\\:getConfig will be removed in guzzlehttp/guzzle\\:8\\.0\\.$#', 'count' => 1, - 'path' => __DIR__ . '/tests/TestSuites/KernelTestSuite.php', + 'path' => __DIR__ . '/tests/Drupal/Tests/DrupalTestBrowser.php', ]; $ignoreErrors[] = [ - 'message' => '#^Class Drupal\\\\Tests\\\\TestSuites\\\\UnitTestSuite extends deprecated class Drupal\\\\Tests\\\\TestSuites\\\\TestSuiteBase\\: -in drupal\\:10\\.3\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no - replacement and test discovery will be handled differently in PHPUnit 10\\.$#', + 'message' => '#^@dataProvider hexCodes related method must be static in PHPUnit 10 and newer\\.$#', 'count' => 1, - 'path' => __DIR__ . '/tests/TestSuites/UnitTestSuite.php', + 'path' => __DIR__ . '/themes/olivero/tests/src/Unit/OliveroHexToHslTest.php', ]; return ['parameters' => ['ignoreErrors' => $ignoreErrors]]; diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 350bac908e328ab528eb70ec21fac6af80a6331c..e4a9f3f496df63596d1320a4de13d0d34392c9f6 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -235,6 +235,9 @@ function drupal_valid_test_ua($new_prefix = NULL) { /** * Generates a user agent string with a HMAC and timestamp for tests. + * + * @return string|null + * The user agent, or NULL on failure. */ function drupal_generate_test_ua($prefix) { static $key, $last_prefix; @@ -259,7 +262,9 @@ function drupal_generate_test_ua($prefix) { // Generate and save a new hash salt for a test run. // Consumed by drupal_valid_test_ua() before settings.php is loaded. $private_key = Crypt::randomBytesBase64(55); - file_put_contents($key_file, $private_key); + if (!@file_put_contents($key_file, $private_key)) { + return NULL; + } } // The file properties add more entropy not easily accessible to others. $key = $private_key . filectime(__FILE__) . fileinode(__FILE__); diff --git a/core/lib/Drupal/Core/Database/Database.php b/core/lib/Drupal/Core/Database/Database.php index 4e87201fba8824d780c4eb1ad5f87c986cd04834..aceb5fd128273f0b95e028cabbb11499f4084bfd 100644 --- a/core/lib/Drupal/Core/Database/Database.php +++ b/core/lib/Drupal/Core/Database/Database.php @@ -457,6 +457,13 @@ public static function closeConnection($target = NULL, $key = NULL) { } unset(self::$connections[$key]); } + + // When last connection for $key is closed, we also stop any active + // logging. + if (empty(self::$connections[$key])) { + unset(self::$logs[$key]); + } + // Force garbage collection to run. This ensures that client connection // objects and results in the connection being closed are destroyed. gc_collect_cycles(); diff --git a/core/lib/Drupal/Core/Test/HttpClientMiddleware/TestHttpClientMiddleware.php b/core/lib/Drupal/Core/Test/HttpClientMiddleware/TestHttpClientMiddleware.php index 4fbfff01cdd0f552a7184e550cc56e0d7df8e468..0a713702671c25ed74d88780e306201fa2651217 100644 --- a/core/lib/Drupal/Core/Test/HttpClientMiddleware/TestHttpClientMiddleware.php +++ b/core/lib/Drupal/Core/Test/HttpClientMiddleware/TestHttpClientMiddleware.php @@ -23,8 +23,8 @@ public function __invoke() { // database prefix were stored statically in a file or database variable. return function ($handler) { return function (RequestInterface $request, array $options) use ($handler) { - if ($test_prefix = drupal_valid_test_ua()) { - $request = $request->withHeader('User-Agent', drupal_generate_test_ua($test_prefix)); + if ($user_agent = drupal_generate_test_ua(drupal_valid_test_ua())) { + $request = $request->withHeader('User-Agent', $user_agent); } return $handler($request, $options) ->then(function (ResponseInterface $response) { diff --git a/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php b/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php index f238cf4d34560b73c888b91c9220d1c39de31877..522f76d5b45957fe96076e8676e4ef8b2f29f1d3 100644 --- a/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php +++ b/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php @@ -4,6 +4,7 @@ use Drupal\Core\Database\Database; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Drupal\TestTools\Extension\DeprecationBridge\DeprecationHandler; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Process\PhpExecutableFinder; use Symfony\Component\Process\Process; @@ -98,7 +99,7 @@ public function phpUnitCommand(): string { * @param string[] $unescaped_test_classnames * An array of test class names, including full namespaces, to be passed as * a regular expression to PHPUnit's --filter option. - * @param string $phpunit_file + * @param string $log_junit_file_path * A filepath to use for PHPUnit's --log-junit option. * @param int $status * (optional) The exit status code of the PHPUnit process will be assigned @@ -109,7 +110,7 @@ public function phpUnitCommand(): string { * * @internal */ - public function runCommand(array $unescaped_test_classnames, string $phpunit_file, int &$status = NULL, array &$output = NULL): void { + public function runCommand(array $unescaped_test_classnames, string $log_junit_file_path, int &$status = NULL, array &$output = NULL): void { global $base_url; // Setup an environment variable containing the database connection so that // functional tests can connect to the database. @@ -129,10 +130,21 @@ public function runCommand(array $unescaped_test_classnames, string $phpunit_fil $command = [ $phpunit_bin, + '--process-isolation', + '--display-errors', + '--display-warnings', + '--fail-on-warning', '--log-junit', - $phpunit_file, + $log_junit_file_path, ]; + if (DeprecationHandler::getConfiguration() !== FALSE) { + $command = array_merge($command, [ + '--display-deprecations', + '--fail-on-deprecation', + ]); + } + // Optimized for running a single test. if (count($unescaped_test_classnames) == 1) { $class = new \ReflectionClass($unescaped_test_classnames[0]); diff --git a/core/lib/Drupal/Core/Test/TestDiscovery.php b/core/lib/Drupal/Core/Test/TestDiscovery.php index 9112d6e7abb165c4223cc7b7ecf7f4c962d42851..f63510a0d1a1013118f74281c4cc8d3efb32865c 100644 --- a/core/lib/Drupal/Core/Test/TestDiscovery.php +++ b/core/lib/Drupal/Core/Test/TestDiscovery.php @@ -7,7 +7,6 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Extension\ExtensionDiscovery; use Drupal\Core\Test\Exception\MissingGroupException; -use Drupal\TestTools\PhpUnitCompatibility\ClassWriter; /** * Discovers available tests. @@ -108,10 +107,6 @@ public function registerTestNamespaces() { $this->classLoader->addPsr4($prefix, $paths); } - $loader = require __DIR__ . '/../../../../../autoload.php'; - // Ensure we have a valid TestCase class. - ClassWriter::mutateTestBase($loader); - return $this->testNamespaces; } diff --git a/core/lib/Drupal/Core/Test/TestRunnerKernel.php b/core/lib/Drupal/Core/Test/TestRunnerKernel.php index e1729f8250100c7c0f14cde4d5244471d697a4e5..e5ece5c07a2b211cd42e2b95293ebf7eed4dcf53 100644 --- a/core/lib/Drupal/Core/Test/TestRunnerKernel.php +++ b/core/lib/Drupal/Core/Test/TestRunnerKernel.php @@ -5,6 +5,7 @@ use Drupal\Core\DrupalKernel; use Drupal\Core\Extension\Extension; use Drupal\Core\Site\Settings; +use Drupal\Core\Utility\Error; use Symfony\Component\HttpFoundation\Request; /** @@ -60,7 +61,10 @@ public function boot() { // Remove Drupal's error/exception handlers; they are designed for HTML // and there is no storage nor a (watchdog) logger here. - restore_error_handler(); + $currentErrorHandler = Error::currentErrorHandler(); + if (is_string($currentErrorHandler) && $currentErrorHandler === '_drupal_error_handler') { + restore_error_handler(); + } restore_exception_handler(); // In addition, ensure that PHP errors are not hidden away in logs. diff --git a/core/lib/Drupal/Core/Test/TestSetupTrait.php b/core/lib/Drupal/Core/Test/TestSetupTrait.php index 287c4ad24bd430ff063b4c6a33f7bbdf4c585567..68ad7aaaebab2402b55d85df19258838cc5518be 100644 --- a/core/lib/Drupal/Core/Test/TestSetupTrait.php +++ b/core/lib/Drupal/Core/Test/TestSetupTrait.php @@ -186,6 +186,7 @@ protected function changeDatabasePrefix() { // prefixes of the test runner leak into the test. $connection_info[$target]['prefix'] = $value['prefix'] . $this->databasePrefix; } + Database::removeConnection('default'); Database::addConnectionInfo('default', 'default', $connection_info['default']); } } diff --git a/core/lib/Drupal/Core/Utility/Error.php b/core/lib/Drupal/Core/Utility/Error.php index f8a54e20a2819f9703cd29208cf75008cc2a4592..459af44d8c517733e57c75b43b365f9534d09bb4 100644 --- a/core/lib/Drupal/Core/Utility/Error.php +++ b/core/lib/Drupal/Core/Utility/Error.php @@ -206,4 +206,16 @@ public static function formatBacktrace(array $backtrace) { return $return; } + /** + * Returns the current PHP error handler as a callable. + * + * @return callable|null + * The current error handler as a callable, or NULL if none is set. + */ + public static function currentErrorHandler(): ?callable { + $currentHandler = set_error_handler('var_dump'); + restore_error_handler(); + return $currentHandler; + } + } diff --git a/core/modules/ckeditor5/tests/src/Kernel/CKEditor5PluginManagerTest.php b/core/modules/ckeditor5/tests/src/Kernel/CKEditor5PluginManagerTest.php index 6dfb3c0cac12b9129459ccb647c4a631096fa067..4525831eecb94b909b025bbcaf8fd0dc5ea55428 100644 --- a/core/modules/ckeditor5/tests/src/Kernel/CKEditor5PluginManagerTest.php +++ b/core/modules/ckeditor5/tests/src/Kernel/CKEditor5PluginManagerTest.php @@ -188,6 +188,7 @@ private function mockModuleInVfs(string $module_name, string $yaml, array $addit /** * @covers \Drupal\ckeditor5\Plugin\CKEditor5PluginManager::processDefinition * @dataProvider providerTestInvalidPluginDefinitions + * @runInSeparateProcess */ public function testInvalidPluginDefinitions(string $yaml, ?string $expected_message, array $additional_files = []): void { if ($expected_message) { @@ -1579,6 +1580,7 @@ public function testExternalLinkAutomaticLinkDecoratorDisallowed(): void { /** * @covers \Drupal\ckeditor5\Plugin\CKEditor5PluginManager::getDiscovery * @dataProvider providerTestDerivedPluginDefinitions + * @runInSeparateProcess */ public function testDerivedPluginDefinitions(string $yaml, ?string $expected_message, array $additional_files = [], ?array $expected_derived_plugin_definitions = NULL): void { if ($expected_message) { diff --git a/core/modules/datetime/tests/src/Kernel/Views/ArgumentDateTimeTest.php b/core/modules/datetime/tests/src/Kernel/Views/ArgumentDateTimeTest.php index 59345983d8d5ed4f94c119c2dd030d4d47d605f6..21ee26f61d3fade094d3f5d493650951beb7cff0 100644 --- a/core/modules/datetime/tests/src/Kernel/Views/ArgumentDateTimeTest.php +++ b/core/modules/datetime/tests/src/Kernel/Views/ArgumentDateTimeTest.php @@ -11,6 +11,7 @@ * Tests the Drupal\datetime\Plugin\views\filter\Date handler. * * @group datetime + * @runTestsInSeparateProcesses */ class ArgumentDateTimeTest extends DateTimeHandlerTestBase { diff --git a/core/modules/help/tests/src/Functional/HelpTopicSearchTest.php b/core/modules/help/tests/src/Functional/HelpTopicSearchTest.php index 8b6936442069488fdad0a56e227dd25e43b69b21..5195c7e291eac972ecd8aa5dfef3545e5740e761 100644 --- a/core/modules/help/tests/src/Functional/HelpTopicSearchTest.php +++ b/core/modules/help/tests/src/Functional/HelpTopicSearchTest.php @@ -15,6 +15,7 @@ * * @group help * @group #slow + * @runTestsInSeparateProcesses */ class HelpTopicSearchTest extends HelpTopicTranslatedTestBase { diff --git a/core/modules/language/tests/src/Functional/LanguageSwitchingTest.php b/core/modules/language/tests/src/Functional/LanguageSwitchingTest.php index b0fb5d0ef4bda9567a20a43342dcfdb90ac230f0..cbeb48cd94effcf1a1414aaa93dc2b312e6e6665 100644 --- a/core/modules/language/tests/src/Functional/LanguageSwitchingTest.php +++ b/core/modules/language/tests/src/Functional/LanguageSwitchingTest.php @@ -17,6 +17,7 @@ * Functional tests for the language switching feature. * * @group language + * @runTestsInSeparateProcesses */ class LanguageSwitchingTest extends BrowserTestBase { diff --git a/core/modules/language/tests/src/Unit/process/LanguageDomainsTest.php b/core/modules/language/tests/src/Unit/process/LanguageDomainsTest.php index 8f6c3105ec59c849923881beedb2a9ae608a5efe..87f69db62352705ba720790501f5b941274321d7 100644 --- a/core/modules/language/tests/src/Unit/process/LanguageDomainsTest.php +++ b/core/modules/language/tests/src/Unit/process/LanguageDomainsTest.php @@ -13,11 +13,6 @@ */ class LanguageDomainsTest extends MigrateProcessTestCase { - /** - * {@inheritdoc} - */ - protected $backupGlobalsBlacklist = ['base_url']; - /** * {@inheritdoc} */ diff --git a/core/modules/locale/tests/src/Functional/LocaleConfigTranslationImportTest.php b/core/modules/locale/tests/src/Functional/LocaleConfigTranslationImportTest.php index 02991c6076ae72314491cd077f610c7ddbfa9bf1..5d8c11194e34ae9ddecf933e9cb2289795842641 100644 --- a/core/modules/locale/tests/src/Functional/LocaleConfigTranslationImportTest.php +++ b/core/modules/locale/tests/src/Functional/LocaleConfigTranslationImportTest.php @@ -12,6 +12,7 @@ * Tests translation update's effects on configuration translations. * * @group locale + * @runTestsInSeparateProcesses */ class LocaleConfigTranslationImportTest extends BrowserTestBase { diff --git a/core/modules/media/tests/src/Kernel/MediaEmbedFilterTest.php b/core/modules/media/tests/src/Kernel/MediaEmbedFilterTest.php index eb2d1d3bdcaa764666480b9567a2de63eb11071e..03d095262b2fccb175f4357ead4a2dcbfe9c7e12 100644 --- a/core/modules/media/tests/src/Kernel/MediaEmbedFilterTest.php +++ b/core/modules/media/tests/src/Kernel/MediaEmbedFilterTest.php @@ -374,6 +374,8 @@ public function testOnlyDrupalMediaTagProcessed() { /** * Tests recursive rendering protection. + * + * @runInSeparateProcess */ public function testRecursionProtection() { $text = $this->createEmbedCode([ @@ -397,6 +399,7 @@ public function testRecursionProtection() { * @covers \Drupal\filter\Plugin\Filter\FilterAlign * @covers \Drupal\filter\Plugin\Filter\FilterCaption * @dataProvider providerFilterIntegration + * @runInSeparateProcess */ public function testFilterIntegration(array $filter_ids, array $additional_attributes, $verification_selector, $expected_verification_success, array $expected_asset_libraries = [], $prefix = '', $suffix = '') { $content = $this->createEmbedCode([ diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/CredentialFormTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/CredentialFormTest.php index 598e3d71ed44e7e049371c59102ecacc84447067..d576d24dde7596900cadf4511b11df4a30f933e1 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/CredentialFormTest.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/CredentialFormTest.php @@ -16,6 +16,7 @@ * credentials, and incorrect file paths. * * @group migrate_drupal_ui + * @runTestsInSeparateProcesses */ class CredentialFormTest extends MigrateUpgradeTestBase { diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateMessageControllerTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateMessageControllerTest.php index ca45d72878e06b457f32f0135c0f701fa864ac2e..fa2c755790854dbe4e747a9b915ca3b65c341449 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateMessageControllerTest.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateMessageControllerTest.php @@ -11,6 +11,7 @@ * Tests for the MigrateController class. * * @group migrate_drupal_ui + * @runTestsInSeparateProcesses */ class MigrateMessageControllerTest extends MigrateUpgradeTestBase { diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/SourceProviderTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/SourceProviderTest.php index 8027de8972065a1d9cbd15a5f59c1c0a0bfcf3ae..f8f0d91feabd964996f1062fb21304201e4fad49 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/SourceProviderTest.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/SourceProviderTest.php @@ -9,6 +9,7 @@ * * @group migrate_drupal_ui * @group #slow + * @runTestsInSeparateProcesses */ class SourceProviderTest extends MigrateUpgradeTestBase { diff --git a/core/modules/node/tests/src/Functional/NodeTypeTranslationTest.php b/core/modules/node/tests/src/Functional/NodeTypeTranslationTest.php index 0066864056c06492786ebfdf847fa8fd02827468..8953dd6a537d36c88f38c2e35511fddfb6b34e01 100644 --- a/core/modules/node/tests/src/Functional/NodeTypeTranslationTest.php +++ b/core/modules/node/tests/src/Functional/NodeTypeTranslationTest.php @@ -15,6 +15,7 @@ * ensures the asserts pass regardless of the Drupal version. * * @group node + * @runTestsInSeparateProcesses */ class NodeTypeTranslationTest extends BrowserTestBase { diff --git a/core/modules/system/tests/src/Functional/Module/ClassLoaderTest.php b/core/modules/system/tests/src/Functional/Module/ClassLoaderTest.php index f8bc064505716b80a90fb76b490c09a8a66971bf..31d4eaf7bd91fafb3df85a590f9d9ae440fb53b8 100644 --- a/core/modules/system/tests/src/Functional/Module/ClassLoaderTest.php +++ b/core/modules/system/tests/src/Functional/Module/ClassLoaderTest.php @@ -11,6 +11,7 @@ * Tests class loading for modules. * * @group Module + * @runTestsInSeparateProcesses */ class ClassLoaderTest extends BrowserTestBase { diff --git a/core/modules/system/tests/src/Kernel/Theme/ThemeTest.php b/core/modules/system/tests/src/Kernel/Theme/ThemeTest.php index 4b4f32b174bf4f3ed81d8e1832c6af2996ed509e..38d12889574df9b738d0b58ea062a412f7bb450e 100644 --- a/core/modules/system/tests/src/Kernel/Theme/ThemeTest.php +++ b/core/modules/system/tests/src/Kernel/Theme/ThemeTest.php @@ -185,6 +185,8 @@ public function testThemeUpdateManagement() { /** * Tests the update registry is correct during theme install and uninstall. + * + * @runInSeparateProcess */ public function testThemeUpdateManagementRemovedPostUpdates() { // Install modules the theme is dependent on and enable the removed post diff --git a/core/modules/update/tests/src/Functional/FileTransferAuthorizeFormTest.php b/core/modules/update/tests/src/Functional/FileTransferAuthorizeFormTest.php index e871d8d13550c1db4601a71029ef38c30c48bcf2..cba81eff23e5193f323ea48dd9a9bb1980c8d320 100644 --- a/core/modules/update/tests/src/Functional/FileTransferAuthorizeFormTest.php +++ b/core/modules/update/tests/src/Functional/FileTransferAuthorizeFormTest.php @@ -8,6 +8,7 @@ * Tests the Update Manager module upload via authorize.php functionality. * * @group update + * @runTestsInSeparateProcesses */ class FileTransferAuthorizeFormTest extends UpdateUploaderTestBase { diff --git a/core/modules/workspaces/tests/src/Functional/WorkspaceTest.php b/core/modules/workspaces/tests/src/Functional/WorkspaceTest.php index a4c492c6f722f9857348269afef4123171f94dcd..abf7194250986afbed2fcbca03ba0907732bc79c 100644 --- a/core/modules/workspaces/tests/src/Functional/WorkspaceTest.php +++ b/core/modules/workspaces/tests/src/Functional/WorkspaceTest.php @@ -322,6 +322,8 @@ public function testWorkspaceList() { /** * Verifies that a workspace can be published. + * + * @runInSeparateProcess */ public function testPublishWorkspace() { $this->createContentType(['type' => 'test', 'label' => 'Test']); diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist index c616c8c179f608d03bb9c546ddf8bf456595b3cf..6c8809a1e924575e226f71234d37c9d0f2065430 100644 --- a/core/phpunit.xml.dist +++ b/core/phpunit.xml.dist @@ -1,5 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> - <!-- For how to customize PHPUnit configuration, see core/tests/README.md. --> <!-- TODO set checkForUnintentionallyCoveredCode="true" once https://www.drupal.org/node/2626832 is resolved. --> <!-- PHPUnit expects functional tests to be run with either a privileged user @@ -7,14 +6,15 @@ https://www.drupal.org/node/2116263 for details. --> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - bootstrap="tests/bootstrap.php" colors="true" + bootstrap="tests/bootstrap.php" + colors="true" beStrictAboutTestsThatDoNotTestAnything="true" beStrictAboutOutputDuringTests="true" beStrictAboutChangesToGlobalState="true" failOnWarning="true" - printerClass="\Drupal\Tests\Listeners\HtmlOutputPrinter" cacheResult="false" - xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"> + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" + cacheDirectory=".phpunit.cache"> <php> <!-- Set error reporting to E_ALL. --> <ini name="error_reporting" value="32767"/> @@ -33,7 +33,6 @@ reachable from your host machine here. This will allow you to follow them directly and view the output. --> <env name="BROWSERTEST_OUTPUT_BASE_URL" value=""/> - <!-- Deprecation testing is managed through Symfony's PHPUnit Bridge. The environment variable SYMFONY_DEPRECATIONS_HELPER is used to configure the behavior of the deprecation tests. @@ -52,37 +51,42 @@ correctly. --> <!-- <env name="SYMFONY_DEPRECATIONS_HELPER" value="ignoreFile=.deprecation-ignore.txt"/> --> - <!-- Example for changing the driver class for mink tests MINK_DRIVER_CLASS value: 'Drupal\FunctionalJavascriptTests\DrupalSelenium2Driver' --> - <env name="MINK_DRIVER_CLASS" value=''/> + <env name="MINK_DRIVER_CLASS" value=""/> <!-- Example for changing the driver args to mink tests MINK_DRIVER_ARGS value: '["http://127.0.0.1:8510"]' --> - <env name="MINK_DRIVER_ARGS" value=''/> + <env name="MINK_DRIVER_ARGS" value=""/> <!-- Example for changing the driver args to webdriver tests MINK_DRIVER_ARGS_WEBDRIVER value: '["chrome", { "goog:chromeOptions": { "w3c": false } }, "http://localhost:4444/wd/hub"]' For using the Firefox browser, replace "chrome" with "firefox" --> - <env name="MINK_DRIVER_ARGS_WEBDRIVER" value=''/> + <env name="MINK_DRIVER_ARGS_WEBDRIVER" value=""/> </php> <testsuites> <testsuite name="unit"> - <file>./tests/TestSuites/UnitTestSuite.php</file> + <directory>tests/Drupal/Tests</directory> + <directory>modules/**/tests/src/Unit</directory> + <directory>../modules/**/tests/src/Unit</directory> </testsuite> <testsuite name="kernel"> - <file>./tests/TestSuites/KernelTestSuite.php</file> + <directory>tests/Drupal/KernelTests</directory> + <directory>modules/**/tests/src/Kernel</directory> + <directory>../modules/**/tests/src/Kernel</directory> </testsuite> <testsuite name="functional"> - <file>./tests/TestSuites/FunctionalTestSuite.php</file> + <directory>tests/Drupal/FunctionalTests</directory> + <directory>modules/**/tests/src/Functional</directory> + <directory>../modules/**/tests/src/Functional</directory> </testsuite> <testsuite name="functional-javascript"> - <file>./tests/TestSuites/FunctionalJavascriptTestSuite.php</file> + <directory>tests/Drupal/FunctionalJavascriptTests</directory> + <directory>modules/**/tests/src/FunctionalJavascript</directory> + <directory>../modules/**/tests/src/FunctionalJavascript</directory> </testsuite> <testsuite name="build"> - <file>./tests/TestSuites/BuildTestSuite.php</file> + <directory>tests/Drupal/BuildTests</directory> + <directory>modules/**/tests/src/Build</directory> + <directory>../modules/**/tests/src/Build</directory> </testsuite> </testsuites> - <listeners> - <listener class="\Drupal\Tests\Listeners\DrupalListener"> - </listener> - </listeners> <!-- Settings for coverage reports. --> - <coverage> + <source ignoreSuppressionOfDeprecations="true"> <include> <directory>./includes</directory> <directory>./lib</directory> @@ -101,5 +105,5 @@ <directory suffix=".api.php">./modules/**</directory> <directory suffix=".api.php">../modules/**</directory> </exclude> - </coverage> + </source> </phpunit> diff --git a/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php b/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php index 49117a946d49f19c394e5ca802550f26c4cd2b93..fa78e59c00996b6061a89adcf7a6f32fb3182dfe 100644 --- a/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php +++ b/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php @@ -11,6 +11,7 @@ * Tests demo_umami profile performance. * * @group #slow + * @runTestsInSeparateProcesses */ class AssetAggregationAcrossPagesTest extends PerformanceTestBase { diff --git a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php index 16d98937a86d11fcd406247e9012fd8a7e4b3f00..83313774826c27659cf063d735dbc5116b857497 100644 --- a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php +++ b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php @@ -12,6 +12,7 @@ * @group OpenTelemetry * @group #slow * @requires extension apcu + * @runTestsInSeparateProcesses */ class OpenTelemetryAuthenticatedPerformanceTest extends PerformanceTestBase { diff --git a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryFrontPagePerformanceTest.php b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryFrontPagePerformanceTest.php index 43b3b9f4b34758f739413fa73753926ebe78ffd8..0c58fc5e883674a189ad7d49d778cbf50ac173e6 100644 --- a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryFrontPagePerformanceTest.php +++ b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryFrontPagePerformanceTest.php @@ -12,6 +12,7 @@ * @group OpenTelemetry * @group #slow * @requires extension apcu + * @runTestsInSeparateProcesses */ class OpenTelemetryFrontPagePerformanceTest extends PerformanceTestBase { diff --git a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryNodePagePerformanceTest.php b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryNodePagePerformanceTest.php index 837a79c7016426cb19db3a6ab4caf7d37c82e3bd..51af239dbf607d9e20d9472f500f62c184b8cc8a 100644 --- a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryNodePagePerformanceTest.php +++ b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryNodePagePerformanceTest.php @@ -12,6 +12,7 @@ * @group OpenTelemetry * @group #slow * @requires extension apcu + * @runTestsInSeparateProcesses */ class OpenTelemetryNodePagePerformanceTest extends PerformanceTestBase { diff --git a/core/profiles/demo_umami/tests/src/FunctionalJavascript/PerformanceTest.php b/core/profiles/demo_umami/tests/src/FunctionalJavascript/PerformanceTest.php index aec2ec9115221afa5ed9620cfff9e14742d30a20..7def33e0acf1e0804083ae0edda422d3a8f084c6 100644 --- a/core/profiles/demo_umami/tests/src/FunctionalJavascript/PerformanceTest.php +++ b/core/profiles/demo_umami/tests/src/FunctionalJavascript/PerformanceTest.php @@ -10,6 +10,7 @@ * Tests demo_umami profile performance. * * @group Performance + * @runTestsInSeparateProcesses */ class PerformanceTest extends PerformanceTestBase { diff --git a/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php b/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php index 35977e4bcd423094cda6b1e60c7c62520fe4f53f..b4e325d30d59f11fade2f2fd5fe2b894262d0660 100644 --- a/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php +++ b/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php @@ -16,6 +16,7 @@ * * @group Common * @requires extension apcu + * @runTestsInSeparateProcesses */ class StandardPerformanceTest extends PerformanceTestBase { diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh index 56ad3e553f4db6cfd51ee519084a162c7245646b..b741bc6605b8917c20d5564940b0a86ca0c316cd 100755 --- a/core/scripts/run-tests.sh +++ b/core/scripts/run-tests.sh @@ -25,7 +25,6 @@ use Drupal\Core\Test\TestRunnerKernel; use Drupal\Core\Test\TestRunResultsStorageInterface; use Drupal\Core\Test\TestDiscovery; -use Drupal\TestTools\PhpUnitCompatibility\ClassWriter; use PHPUnit\Framework\TestCase; use PHPUnit\Runner\Version; use Symfony\Component\Console\Output\ConsoleOutput; @@ -511,7 +510,6 @@ function simpletest_script_init() { $autoloader = require_once __DIR__ . '/../../autoload.php'; // The PHPUnit compatibility layer needs to be available to autoload tests. $autoloader->add('Drupal\\TestTools', __DIR__ . '/../tests'); - ClassWriter::mutateTestBase($autoloader); // Get URL from arguments. if (!empty($args['url'])) { diff --git a/core/tests/Drupal/BuildTests/Framework/BuildTestBase.php b/core/tests/Drupal/BuildTests/Framework/BuildTestBase.php index f0cb552acf3629dfa10504e58835f5ba9d793e31..afdd7fcbcb552112e74cadb73723875c49c3787e 100644 --- a/core/tests/Drupal/BuildTests/Framework/BuildTestBase.php +++ b/core/tests/Drupal/BuildTests/Framework/BuildTestBase.php @@ -11,7 +11,6 @@ use Drupal\Component\FileSystem\FileSystem as DrupalFilesystem; use Drupal\Tests\DrupalTestBrowser; use Drupal\Tests\PhpUnitCompatibilityTrait; -use Drupal\Tests\Traits\PhpUnitWarnings; use Drupal\TestTools\Extension\RequiresComposerTrait; use PHPUnit\Framework\TestCase; use Symfony\Component\Filesystem\Filesystem as SymfonyFilesystem; @@ -55,7 +54,6 @@ abstract class BuildTestBase extends TestCase { use RequiresComposerTrait; - use PhpUnitWarnings; use PhpUnitCompatibilityTrait; /** diff --git a/core/tests/Drupal/BuildTests/Framework/Tests/BuildTestTest.php b/core/tests/Drupal/BuildTests/Framework/Tests/BuildTestTest.php index c55ae1580ebd0d4ded90cc48e31c4f03eaedc4ea..4803397db446fb3009b80378bcb52eb7e5a219b7 100644 --- a/core/tests/Drupal/BuildTests/Framework/Tests/BuildTestTest.php +++ b/core/tests/Drupal/BuildTests/Framework/Tests/BuildTestTest.php @@ -92,6 +92,7 @@ public function testCopyCodebaseExclude() { /** @var \PHPUnit\Framework\MockObject\MockBuilder|\Drupal\BuildTests\Framework\BuildTestBase $base */ $base = $this->getMockBuilder(BuildTestBase::class) ->onlyMethods(['getDrupalRoot', 'getComposerRoot']) + ->setConstructorArgs(['test']) ->getMockForAbstractClass(); $base->expects($this->exactly(1)) ->method('getDrupalRoot') @@ -170,6 +171,7 @@ public function testCopyCodebaseDocRoot() { /** @var \PHPUnit\Framework\MockObject\MockBuilder|\Drupal\BuildTests\Framework\BuildTestBase $base */ $base = $this->getMockBuilder(BuildTestBase::class) ->onlyMethods(['getDrupalRoot', 'getComposerRoot']) + ->setConstructorArgs(['test']) ->getMockForAbstractClass(); $base->expects($this->exactly(3)) ->method('getDrupalRoot') diff --git a/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php b/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php index 9ec27626137cb0446ef0747389102652c75b01a8..d8f0b3d2de65f2cb887a247b8d5ffb26700a24d7 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php @@ -7,7 +7,6 @@ use Behat\Mink\Exception\DriverException; use Drupal\Component\Utility\UrlHelper; use Drupal\Tests\BrowserTestBase; -use PHPUnit\Runner\BaseTestRunner; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -96,11 +95,6 @@ protected function initFrontPage() { */ protected function tearDown(): void { if ($this->mink) { - $status = $this->getStatus(); - if ($status === BaseTestRunner::STATUS_ERROR || $status === BaseTestRunner::STATUS_WARNING || $status === BaseTestRunner::STATUS_FAILURE) { - // Ensure we capture the output at point of failure. - @$this->htmlOutput(); - } // Wait for all requests to finish. It is possible that an AJAX request is // still on-going. $result = $this->getSession()->wait(5000, 'window.drupalActiveXhrCount === 0 || typeof window.drupalActiveXhrCount === "undefined"'); diff --git a/core/tests/Drupal/FunctionalTests/Installer/SuperUserAccessInstallTest.php b/core/tests/Drupal/FunctionalTests/Installer/SuperUserAccessInstallTest.php index 826b73504dfbd4f10765be32ec21dd0d4bbf992d..cdf2e1e8225be7c1c60b37300264b83bae343288 100644 --- a/core/tests/Drupal/FunctionalTests/Installer/SuperUserAccessInstallTest.php +++ b/core/tests/Drupal/FunctionalTests/Installer/SuperUserAccessInstallTest.php @@ -46,10 +46,10 @@ protected function prepareEnvironment() { mkdir($path, 0777, TRUE); file_put_contents("$path/superuser.info.yml", Yaml::encode($info)); - file_put_contents("$path/superuser.install", $this->getProvidedData()['install_code']); + file_put_contents("$path/superuser.install", $this->providedData()['install_code']); $services = Yaml::decode(file_get_contents(DRUPAL_ROOT . '/sites/default/default.services.yml')); - $services['parameters']['security.enable_super_user'] = $this->getProvidedData()['super_user_policy']; + $services['parameters']['security.enable_super_user'] = $this->providedData()['super_user_policy']; file_put_contents(DRUPAL_ROOT . '/' . $this->siteDirectory . '/services.yml', Yaml::encode($services)); } @@ -57,7 +57,7 @@ protected function prepareEnvironment() { * {@inheritdoc} */ protected function setUpSite() { - if ($this->getProvidedData()['super_user_policy'] === FALSE && empty($this->getProvidedData()['expected_roles'])) { + if ($this->providedData()['super_user_policy'] === FALSE && empty($this->providedData()['expected_roles'])) { $this->assertSession()->pageTextContains('Site account'); $this->assertSession()->pageTextNotContains('Site maintenance account'); } diff --git a/core/tests/Drupal/FunctionalTests/Test/FunctionalTestDebugHtmlOutputTest.php b/core/tests/Drupal/FunctionalTests/Test/FunctionalTestDebugHtmlOutputTest.php index ae88182aa68f5733f0932aad37c94e80d4e5f888..8042764364309ceafbffe57ae963fd036e2d4653 100644 --- a/core/tests/Drupal/FunctionalTests/Test/FunctionalTestDebugHtmlOutputTest.php +++ b/core/tests/Drupal/FunctionalTests/Test/FunctionalTestDebugHtmlOutputTest.php @@ -26,8 +26,15 @@ class FunctionalTestDebugHtmlOutputTest extends BrowserTestBase { * running a functional test are met. */ public function testFunctionalTestDebugHtmlOutput(): void { - // Test with the specified output directory. - $process = Process::fromShellCommandline('vendor/bin/phpunit --configuration core --verbose core/tests/Drupal/FunctionalTests/Test/FunctionalTestDebugHtmlOutputHelperTest.php'); + $command = [ + 'vendor/bin/phpunit', + '--configuration', + 'core', + 'core/tests/Drupal/FunctionalTests/Test/FunctionalTestDebugHtmlOutputHelperTest.php', + ]; + + // Test with the default output directory, specified by BROWSERTEST_OUTPUT_DIRECTORY. + $process = new Process($command); $process->setWorkingDirectory($this->root) ->setTimeout(300) ->setIdleTimeout(300); @@ -36,15 +43,31 @@ public function testFunctionalTestDebugHtmlOutput(): void { 'COMMAND: ' . $process->getCommandLine() . "\n" . 'OUTPUT: ' . $process->getOutput() . "\n" . 'ERROR: ' . $process->getErrorOutput() . "\n"); - $this->assertStringContainsString('HTML output was generated', $process->getOutput()); + $this->assertStringContainsString('HTML output was generated, 1 page(s).', $process->getOutput()); + + // Test with verbose output. + $process = new Process($command); + $process->setWorkingDirectory($this->root) + ->setTimeout(300) + ->setIdleTimeout(300); + $process->run(NULL, [ + 'BROWSERTEST_OUTPUT_VERBOSE' => '1', + ]); + $this->assertEquals(0, $process->getExitCode(), + 'COMMAND: ' . $process->getCommandLine() . "\n" . + 'OUTPUT: ' . $process->getOutput() . "\n" . + 'ERROR: ' . $process->getErrorOutput() . "\n"); + $this->assertStringContainsString('HTML output was generated.', $process->getOutput()); $this->assertStringContainsString('Drupal_FunctionalTests_Test_FunctionalTestDebugHtmlOutputHelperTest', $process->getOutput()); // Test with a wrong output directory. - $process = Process::fromShellCommandline('vendor/bin/phpunit --configuration core --verbose core/tests/Drupal/FunctionalTests/Test/FunctionalTestDebugHtmlOutputHelperTest.php'); + $process = new Process($command); $process->setWorkingDirectory($this->root) ->setTimeout(300) ->setIdleTimeout(300); - $process->run(NULL, ['BROWSERTEST_OUTPUT_DIRECTORY' => 'can_we_assume_that_a_subdirectory_with_this_name_does_not_exist']); + $process->run(NULL, [ + 'BROWSERTEST_OUTPUT_DIRECTORY' => 'can_we_assume_that_a_subdirectory_with_this_name_does_not_exist', + ]); $this->assertEquals(0, $process->getExitCode(), 'COMMAND: ' . $process->getCommandLine() . "\n" . 'OUTPUT: ' . $process->getOutput() . "\n" . diff --git a/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelSiteTest.php b/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelSiteTest.php index be7bf3c28fe93d73002af8078d7286edd755338a..c58461ea29eecacc9ca1efbc206d14fc09c7451b 100644 --- a/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelSiteTest.php +++ b/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelSiteTest.php @@ -38,6 +38,7 @@ class: Drupal\Component\Datetime\Time # Add a new service. site.service.yml: class: $class + arguments: ['test'] # Swap out a core service. cache.backend.database: class: Drupal\Core\Cache\MemoryBackendFactory diff --git a/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php b/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php index ec94d2fc52ef3ffe8ffa52623f5b49bc2cd4d8ef..d8b18f79049340d474bff9d04ca4c3f6edf38fe8 100644 --- a/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php +++ b/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php @@ -7,6 +7,7 @@ use Composer\Autoload\ClassLoader; use Drupal\Core\DrupalKernel; use Drupal\Core\DrupalKernelInterface; +use Drupal\Core\Utility\Error; use Drupal\KernelTests\KernelTestBase; use org\bovigo\vfs\vfsStream; use Prophecy\Argument; @@ -22,6 +23,17 @@ */ class DrupalKernelTest extends KernelTestBase { + /** + * {@inheritdoc} + */ + protected function tearDown(): void { + $currentErrorHandler = Error::currentErrorHandler(); + if (is_string($currentErrorHandler) && $currentErrorHandler === '_drupal_error_handler') { + restore_error_handler(); + } + parent::tearDown(); + } + /** * {@inheritdoc} */ @@ -164,6 +176,7 @@ public function testRepeatedBootWithDifferentEnvironment() { /** * Tests setting of site path after kernel boot. + * @runInSeparateProcess */ public function testPreventChangeOfSitePath() { // @todo: write a memory based storage backend for testing. @@ -251,6 +264,7 @@ public function testClassLoaderAutoDetect($value) { /** * @covers ::resetContainer + * @runInSeparateProcess */ public function testResetContainer() { $modules_enabled = [ diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php index 56b913432bdc4bed53bd905fc92ae0c436709e6d..4823e17ff7e7bd9236889bad5bea19259e135eea 100644 --- a/core/tests/Drupal/KernelTests/KernelTestBase.php +++ b/core/tests/Drupal/KernelTests/KernelTestBase.php @@ -23,8 +23,8 @@ use Drupal\Tests\RandomGeneratorTrait; use Drupal\Tests\PhpUnitCompatibilityTrait; use Drupal\Tests\TestRequirementsTrait; -use Drupal\Tests\Traits\PhpUnitWarnings; use Drupal\TestTools\Comparator\MarkupInterfaceComparator; +use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait; use Drupal\TestTools\Extension\SchemaInspector; use Drupal\TestTools\TestVarDumper; use PHPUnit\Framework\Exception; @@ -38,7 +38,6 @@ use Drupal\Core\Routing\RouteObjectInterface; use Symfony\Component\Routing\Route; use Symfony\Component\VarDumper\VarDumper; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; /** * Base class for functional integration tests. @@ -91,30 +90,10 @@ abstract class KernelTestBase extends TestCase implements ServiceProviderInterfa use ConfigTestTrait; use ExtensionListTestTrait; use TestRequirementsTrait; - use PhpUnitWarnings; use PhpUnitCompatibilityTrait; use ProphecyTrait; use ExpectDeprecationTrait; - /** - * {@inheritdoc} - * - * Back up and restore any global variables that may be changed by tests. - * - * @see self::runTestInSeparateProcess - */ - protected $backupGlobals = TRUE; - - /** - * {@inheritdoc} - * - * Kernel tests are run in separate processes because they allow autoloading - * of code from extensions. Running the test in a separate process isolates - * this behavior from other tests. Subclasses should not override this - * property. - */ - protected $runTestInSeparateProcess = TRUE; - /** * {@inheritdoc} * @@ -141,16 +120,6 @@ abstract class KernelTestBase extends TestCase implements ServiceProviderInterfa 'Drupal\Core\Site\Settings' => ['instance'], ]; - /** - * {@inheritdoc} - * - * Do not forward any global state from the parent process to the processes - * that run the actual tests. - * - * @see self::runTestInSeparateProcess - */ - protected $preserveGlobalState = FALSE; - /** * @var \Composer\Autoload\Classloader */ diff --git a/core/tests/Drupal/KernelTests/KernelTestBaseTest.php b/core/tests/Drupal/KernelTests/KernelTestBaseTest.php index fe71a5b2d1d5b300c06c43d42ea749e9c674c095..55c27fa4c0cac8c3a1b21427b3d5aa0ce964126c 100644 --- a/core/tests/Drupal/KernelTests/KernelTestBaseTest.php +++ b/core/tests/Drupal/KernelTests/KernelTestBaseTest.php @@ -75,9 +75,6 @@ public function testSetUp() { $this->assertEquals($this, $GLOBALS['conf']['container_service_providers']['test']); - $GLOBALS['destroy-me'] = TRUE; - $this->assertArrayHasKey('destroy-me', $GLOBALS); - $database = $this->container->get('database'); $database->schema()->createTable('foo', [ 'fields' => [ @@ -98,8 +95,6 @@ public function testSetUp() { * @depends testSetUp */ public function testSetUpDoesNotLeak() { - $this->assertArrayNotHasKey('destroy-me', $GLOBALS); - // Ensure that we have a different database prefix. $schema = $this->container->get('database')->schema(); $this->assertFalse($schema->tableExists('foo')); diff --git a/core/tests/Drupal/TestTools/Comparator/MarkupInterfaceComparator.php b/core/tests/Drupal/TestTools/Comparator/MarkupInterfaceComparator.php index 00499e599725bdcd7254f4f5af9b20990d265298..63804f88022dfb73a8b44df6dfcd5919b8c69268 100644 --- a/core/tests/Drupal/TestTools/Comparator/MarkupInterfaceComparator.php +++ b/core/tests/Drupal/TestTools/Comparator/MarkupInterfaceComparator.php @@ -39,7 +39,7 @@ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = F @trigger_error("Using assert[Not]Equals() to compare markup between MarkupInterface objects and plain strings is deprecated in drupal:10.1.0 and will throw an error from drupal:11.0.0. Expected: '{$expected_safe}' - Actual '{$actual_safe}'. Use assert[Not]Same() and cast objects to string instead. See https://www.drupal.org/node/3334057", E_USER_DEPRECATED); } } - $comparator = $this->factory->getComparatorFor($expected_safe_stripped, $actual_safe_stripped); + $comparator = $this->factory()->getComparatorFor($expected_safe_stripped, $actual_safe_stripped); $comparator->assertEquals($expected_safe_stripped, $actual_safe_stripped, $delta, $canonicalize, $ignoreCase); } diff --git a/core/tests/Drupal/TestTools/ErrorHandler/BootstrapErrorHandler.php b/core/tests/Drupal/TestTools/ErrorHandler/BootstrapErrorHandler.php new file mode 100644 index 0000000000000000000000000000000000000000..cd57743867adec27e76f9997131257e09fe87811 --- /dev/null +++ b/core/tests/Drupal/TestTools/ErrorHandler/BootstrapErrorHandler.php @@ -0,0 +1,60 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\TestTools\ErrorHandler; + +use Drupal\TestTools\Extension\DeprecationBridge\DeprecationHandler; +use PHPUnit\Event\Code\NoTestCaseObjectOnCallStackException; +use PHPUnit\Runner\ErrorHandler as PhpUnitErrorHandler; + +/** + * @todo + * + * @internal + */ +final class BootstrapErrorHandler { + + /** + * @todo + */ + public function __construct( + private PhpUnitErrorHandler $phpUnitErrorHandler, + ) { + } + + /** + * @todo + */ + public function __invoke(int $errorNumber, string $errorString, string $errorFile, int $errorLine): bool { + if (!DeprecationHandler::isEnabled()) { + throw new \RuntimeException(__METHOD__ . '() must not be called if the deprecation handler is not enabled.'); + } + + // We collect a deprecation no matter what. + if (E_USER_DEPRECATED === $errorNumber || E_DEPRECATED === $errorNumber) { + $prefix = (error_reporting() & $errorNumber) ? 'Unsilenced deprecation: ' : ''; + DeprecationHandler::collectActualDeprecation($prefix . $errorString); + } + + // If the deprecation handled is one of those in the ignore list, we keep + // running. + if ((E_USER_DEPRECATED === $errorNumber || E_DEPRECATED === $errorNumber) && DeprecationHandler::isIgnoredDeprecation($errorString)) { + return TRUE; + } + + // In all other cases (errors, warnings, deprecations to be reported), we + // fall back to PHPUnit's error handler, an instance of which was created + // when this error handler was created. + try { + call_user_func($this->phpUnitErrorHandler, $errorNumber, $errorString, $errorFile, $errorLine); + } + catch (NoTestCaseObjectOnCallStackException $e) { + // If we end up here, it's likely because a test's processing has + // finished already and we are processing an error that occurred while + // dealing with STDOUT rewinding or truncating. Do nothing. + } + return TRUE; + } + +} diff --git a/core/tests/Drupal/TestTools/ErrorHandler/TestErrorHandler.php b/core/tests/Drupal/TestTools/ErrorHandler/TestErrorHandler.php new file mode 100644 index 0000000000000000000000000000000000000000..97c5d0fbdb575624939c66f1809e59bd1bd4bcba --- /dev/null +++ b/core/tests/Drupal/TestTools/ErrorHandler/TestErrorHandler.php @@ -0,0 +1,49 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\TestTools\ErrorHandler; + +use Drupal\TestTools\Extension\DeprecationBridge\DeprecationHandler; + +/** + * @todo + * + * @internal + */ +final class TestErrorHandler { + + /** + * @todo + */ + public function __construct( + private $parentHandler, + private $testCase, + ) { + } + + /** + * @todo + */ + public function __invoke(int $errorNumber, string $errorString, string $errorFile, int $errorLine): bool { + if (!DeprecationHandler::isEnabled()) { + throw new \RuntimeException(__METHOD__ . '() must not be called if the deprecation handler is not enabled.'); + } + + // We are within a test execution. If we have a deprecation and the test is + // a deprecation test, than we just collect the deprecation and return to + // execution, since deprecations are expected. + if ((E_USER_DEPRECATED === $errorNumber || E_DEPRECATED === $errorNumber) && DeprecationHandler::isDeprecationTest($this->testCase)) { + $prefix = (error_reporting() & $errorNumber) ? 'Unsilenced deprecation: ' : ''; + DeprecationHandler::collectActualDeprecation($prefix . $errorString); + return TRUE; + } + + // In all other cases (errors, warnings, deprecations in normal tests), we + // fall back to the parent error handler, which is the one that was + // registered in the test runner bootstrap (BootstrapErrorHandler). + call_user_func($this->parentHandler, $errorNumber, $errorString, $errorFile, $errorLine); + return TRUE; + } + +} diff --git a/core/tests/Drupal/TestTools/Extension/DeprecationBridge/DeprecationHandler.php b/core/tests/Drupal/TestTools/Extension/DeprecationBridge/DeprecationHandler.php new file mode 100644 index 0000000000000000000000000000000000000000..6a972087b2d73f68f91d9ec0f56be2c5915f954e --- /dev/null +++ b/core/tests/Drupal/TestTools/Extension/DeprecationBridge/DeprecationHandler.php @@ -0,0 +1,161 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\TestTools\Extension\DeprecationBridge; + +use PHPUnit\Framework\TestCase; + +/** + * @todo + * + * @internal + */ +final class DeprecationHandler { + + private static bool $enabled = FALSE; + + /** + * @var list<string> + */ + private static array $deprecationIgnorePatterns = []; + + /** + * @var list<string> + */ + private static array $expectedDeprecations = []; + + /** + * @var list<string> + */ + private static array $collectedDeprecations = []; + + /** + * This class should not be instantiated. + */ + private function __construct() { + throw new \LogicException(__CLASS__ . ' should not be instantiated'); + } + + /** + * @todo + */ + public static function getConfiguration(): array|FALSE { + $environmentVariable = getenv('SYMFONY_DEPRECATIONS_HELPER'); + if ($environmentVariable === 'disabled') { + return FALSE; + } + if ($environmentVariable === FALSE) { + // Ensure ignored deprecation patterns listed in .deprecation-ignore.txt + // are considered in testing. + $relativeFilePath = __DIR__ . "/../../../../../.deprecation-ignore.txt"; + $deprecationIgnoreFilename = realpath($relativeFilePath); + if (empty($deprecationIgnoreFilename)) { + throw new \InvalidArgumentException(sprintf('The ignoreFile "%s" does not exist.', $relativeFilePath)); + } + $environmentVariable = "ignoreFile=$deprecationIgnoreFilename"; + } + parse_str($environmentVariable, $configuration); + return $configuration; + } + + /** + * @todo + */ + public static function isEnabled(): bool { + return self::$enabled; + } + + /** + * @todo + */ + public static function init(?string $ignoreFile = NULL): void { + if (self::isEnabled()) { + throw new \LogicException(__CLASS__ . ' is already initialized'); + } + + // Load the deprecation ignore patterns from the specified file. + if ($ignoreFile && !self::$deprecationIgnorePatterns) { + if (!is_file($ignoreFile)) { + throw new \InvalidArgumentException(sprintf('The ignoreFile "%s" does not exist.', $ignoreFile)); + } + set_error_handler(static function ($t, $m) use ($ignoreFile, &$line) { + throw new \RuntimeException(sprintf('Invalid pattern found in "%s" on line "%d"', $ignoreFile, 1 + $line) . substr($m, 12)); + }); + try { + foreach (file($ignoreFile) as $line => $pattern) { + if ((trim($pattern)[0] ?? '#') !== '#') { + preg_match($pattern, ''); + self::$deprecationIgnorePatterns[] = $pattern; + } + } + } + finally { + restore_error_handler(); + } + } + + // Mark the extension as enabled. + self::$enabled = TRUE; + } + + public static function reset(): void { + if (!self::isEnabled()) { + return; + } + self::$expectedDeprecations = []; + self::$collectedDeprecations = []; + } + + public static function expectDeprecation(string $message): void { + if (!self::isEnabled()) { + return; + } + self::$expectedDeprecations[] = $message; + } + + public static function getExpectedDeprecations(): array { + if (!self::isEnabled()) { + throw new \LogicException(__CLASS__ . ' is not initialized'); + } + return self::$expectedDeprecations; + } + + public static function collectActualDeprecation(string $message): void { + if (!self::isEnabled()) { + return; + } + self::$collectedDeprecations[] = $message; + } + + public static function getCollectedDeprecations(): array { + if (!self::isEnabled()) { + throw new \LogicException(__CLASS__ . ' is not initialized'); + } + return self::$collectedDeprecations; + } + + public static function isIgnoredDeprecation(string $deprecationMessage): bool { + if (!self::$deprecationIgnorePatterns) { + return FALSE; + } + $result = @preg_filter(self::$deprecationIgnorePatterns, '$0', $deprecationMessage); + if (preg_last_error() !== \PREG_NO_ERROR) { + throw new \RuntimeException(preg_last_error_msg()); + } + return (bool) $result; + } + + public static function isDeprecationTest(TestCase $testCase): bool { + return $testCase->valueObjectForEvents()->metadata()->isIgnoreDeprecations()->isNotEmpty() || self::isTestInLegacyGroup($testCase); + } + + private static function isTestInLegacyGroup(TestCase $testCase): bool { + $groups = []; + foreach ($testCase->valueObjectForEvents()->metadata()->isGroup() as $metadata) { + $groups[] = $metadata->groupName(); + } + return in_array('legacy', $groups, TRUE); + } + +} diff --git a/core/tests/Drupal/TestTools/Extension/DeprecationBridge/ExpectDeprecationTrait.php b/core/tests/Drupal/TestTools/Extension/DeprecationBridge/ExpectDeprecationTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..99a63ba0e023ee59221eea641c18739e4b1a93a5 --- /dev/null +++ b/core/tests/Drupal/TestTools/Extension/DeprecationBridge/ExpectDeprecationTrait.php @@ -0,0 +1,102 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\TestTools\Extension\DeprecationBridge; + +use Drupal\Core\Utility\Error; +use Drupal\TestTools\ErrorHandler\TestErrorHandler; +use PHPUnit\Framework\Attributes\After; +use PHPUnit\Framework\Attributes\Before; + +/** + * Manage expected deprecations. + * + * @internal + */ +trait ExpectDeprecationTrait { + + #[Before] + public function setUpErrorHandler(): void { + if (!DeprecationHandler::isEnabled()) { + return; + } + + DeprecationHandler::reset(); + set_error_handler(new TestErrorHandler(Error::currentErrorHandler(), $this)); + } + + #[After] + public function tearDownErrorHandler(): void { + if (!DeprecationHandler::isEnabled()) { + return; + } + + $handler = Error::currentErrorHandler(); + if (!$handler instanceof TestErrorHandler) { + throw new \RuntimeException(sprintf('%s registered its own error handler (%s) without restoring the previous one before or during tear down. This can cause unpredictable test results. Ensure the test cleans up after itself.', + $this->name(), + self::getCallableName($handler), + )); + } + restore_error_handler(); + + // Checks if collected deprecations match the expectations. + if (DeprecationHandler::getExpectedDeprecations()) { + $prefix = "@expectedDeprecation:\n"; + $expDep = $prefix . '%A ' . implode("\n%A ", DeprecationHandler::getExpectedDeprecations()) . "\n%A"; + $actDep = $prefix . ' ' . implode("\n ", DeprecationHandler::getCollectedDeprecations()) . "\n"; + $this->assertStringMatchesFormat($expDep, $actDep); + } + } + + public function expectDeprecation(string $message): void { + if (!DeprecationHandler::isDeprecationTest($this)) { + throw new \RuntimeException('expectDeprecation() can only be called from tests marked with #[IgnoreDeprecations] or \'@group legacy\''); + } + + if (!DeprecationHandler::isEnabled()) { + return; + } + + DeprecationHandler::expectDeprecation($message); + } + + /** + * Returns a callable as a string suitable for inclusion in a message. + * + * @param callable $callable + * The callable. + * + * @return string + * The string suitable for inclusion in a message. + * + * @see https://stackoverflow.com/questions/34324576/print-name-or-definition-of-callable-in-php + */ + private static function getCallableName(callable $callable): string { + switch (TRUE) { + case is_string($callable) && strpos($callable, '::'): + return '[static] ' . $callable; + + case is_string($callable): + return '[function] ' . $callable; + + case is_array($callable) && is_object($callable[0]): + return '[method] ' . get_class($callable[0]) . '->' . $callable[1]; + + case is_array($callable): + return '[static] ' . $callable[0] . '::' . $callable[1]; + + case $callable instanceof \Closure: + return '[closure]'; + + case is_object($callable): + return '[invokable] ' . get_class($callable); + + default: + return '[unknown]'; + + } + } + +} diff --git a/core/tests/Drupal/TestTools/Extension/HtmlLogging/HtmlOutputLogger.php b/core/tests/Drupal/TestTools/Extension/HtmlLogging/HtmlOutputLogger.php new file mode 100644 index 0000000000000000000000000000000000000000..98185be257a0dfc5b87de60517445ad028b63f9a --- /dev/null +++ b/core/tests/Drupal/TestTools/Extension/HtmlLogging/HtmlOutputLogger.php @@ -0,0 +1,102 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\TestTools\Extension\HtmlLogging; + +use PHPUnit\Event\Facade; +use PHPUnit\Event\TestRunner\Finished as TestRunnerFinished; +use PHPUnit\Event\TestRunner\Started as TestRunnerStarted; + +/** + * @internal + */ +final class HtmlOutputLogger { + + /** + * The singleton instance. + */ + private static ?self $instance = NULL; + + /** + * @todo + */ + private static array $links = []; + + /** + * @throws \PHPUnit\Event\EventFacadeIsSealedException + * @throws \PHPUnit\Util\Exception + * @throws \PHPUnit\Event\UnknownSubscriberTypeException + * @throws \RuntimeException + */ + private function __construct( + private readonly string $outputDirectory, + private readonly bool $outputVerbose, + private readonly Facade $facade, + ) { + $this->facade->registerSubscriber(new TestRunnerStartedSubscriber($this)); + $this->facade->registerSubscriber(new TestRunnerFinishedSubscriber($this)); + } + + /** + * @todo + * + * @throws \PHPUnit\Event\EventFacadeIsSealedException + * @throws \PHPUnit\Util\Exception + * @throws \PHPUnit\Event\UnknownSubscriberTypeException + * @throws \RuntimeException + */ + public static function init(string $outputDirectory, bool $outputVerbose): void { + if (self::$instance === NULL) { + if (!is_dir($outputDirectory) || !is_writable($outputDirectory)) { + print "HTML output directory {$outputDirectory} is not a writable directory.\n\n"; + } + self::$instance = new self($outputDirectory, $outputVerbose, Facade::instance()); + } + } + + /** + * @todo + */ + public static function isEnabled(): bool { + return self::$instance !== NULL; + } + + /** + * @todo + * + * @throws \RuntimeException + */ + public static function log(string $logEntry): void { + if (!self::isEnabled()) { + throw new \RuntimeException("HTML output is not enabled"); + } + self::$links[] = $logEntry; + } + + /** + * Empties the list of the HTML output created during the test run. + */ + public function testRunnerStarted(TestRunnerStarted $event): void { + self::$links = []; + } + + /** + * Prints the list of HTML output generated during the test. + */ + public function testRunnerFinished(TestRunnerFinished $event): void { + if (self::$links) { + print "\n\n"; + if ($this->outputVerbose) { + print "HTML output was generated.\n\n"; + foreach (self::$links as $link) { + print $link; + } + } + else { + print "HTML output was generated, " . count(self::$links) . " page(s).\n\n"; + } + } + } + +} diff --git a/core/tests/Drupal/TestTools/Extension/HtmlLogging/SubscriberBase.php b/core/tests/Drupal/TestTools/Extension/HtmlLogging/SubscriberBase.php new file mode 100644 index 0000000000000000000000000000000000000000..d5e7d2fd385a222eccbdb08f435ff0b2e963ce8a --- /dev/null +++ b/core/tests/Drupal/TestTools/Extension/HtmlLogging/SubscriberBase.php @@ -0,0 +1,21 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\TestTools\Extension\HtmlLogging; + +/** + * @internal + */ +abstract class SubscriberBase { + + public function __construct( + private readonly HtmlOutputLogger $logger, + ) { + } + + protected function logger(): HtmlOutputLogger { + return $this->logger; + } + +} diff --git a/core/tests/Drupal/TestTools/Extension/HtmlLogging/TestRunnerFinishedSubscriber.php b/core/tests/Drupal/TestTools/Extension/HtmlLogging/TestRunnerFinishedSubscriber.php new file mode 100644 index 0000000000000000000000000000000000000000..f0e3c14956cbcad7e3bb41fcc07bd593377dba2e --- /dev/null +++ b/core/tests/Drupal/TestTools/Extension/HtmlLogging/TestRunnerFinishedSubscriber.php @@ -0,0 +1,19 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\TestTools\Extension\HtmlLogging; + +use PHPUnit\Event\TestRunner\Finished; +use PHPUnit\Event\TestRunner\FinishedSubscriber; + +/** + * @internal + */ +final class TestRunnerFinishedSubscriber extends SubscriberBase implements FinishedSubscriber { + + public function notify(Finished $event): void { + $this->logger()->testRunnerFinished($event); + } + +} diff --git a/core/tests/Drupal/TestTools/Extension/HtmlLogging/TestRunnerStartedSubscriber.php b/core/tests/Drupal/TestTools/Extension/HtmlLogging/TestRunnerStartedSubscriber.php new file mode 100644 index 0000000000000000000000000000000000000000..f27a2e44bdd8c0d5cd2f5bd55493b9ed15d82dc7 --- /dev/null +++ b/core/tests/Drupal/TestTools/Extension/HtmlLogging/TestRunnerStartedSubscriber.php @@ -0,0 +1,19 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\TestTools\Extension\HtmlLogging; + +use PHPUnit\Event\TestRunner\Started; +use PHPUnit\Event\TestRunner\StartedSubscriber; + +/** + * @internal + */ +final class TestRunnerStartedSubscriber extends SubscriberBase implements StartedSubscriber { + + public function notify(Started $event): void { + $this->logger()->testRunnerStarted($event); + } + +} diff --git a/core/tests/Drupal/TestTools/PhpUnitCompatibility/ClassWriter.php b/core/tests/Drupal/TestTools/PhpUnitCompatibility/ClassWriter.php deleted file mode 100644 index 76d5deb891db7c9c3e4a49286623f3683e46aefd..0000000000000000000000000000000000000000 --- a/core/tests/Drupal/TestTools/PhpUnitCompatibility/ClassWriter.php +++ /dev/null @@ -1,118 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\TestTools\PhpUnitCompatibility; - -use Composer\Autoload\ClassLoader; - -/** - * Helper class to rewrite PHPUnit's TestCase class. - * - * This class contains static methods only and is not meant to be instantiated. - * - * @internal - * This should only be called by test running code. Drupal 9 will provide best - * effort to maintain this class for the Drupal 9 cycle. However if changes to - * PHP or PHPUnit make this impossible then support will be removed. - */ -final class ClassWriter { - - /** - * This class should not be instantiated. - */ - private function __construct() { - } - - /** - * Mutates PHPUnit classes to make it compatible with Drupal. - * - * @param \Composer\Autoload\ClassLoader $autoloader - * The autoloader. - * - * @throws \ReflectionException - */ - public static function mutateTestBase($autoloader) { - static::alterAssert($autoloader); - static::alterTestCase($autoloader); - } - - /** - * Alters the Assert class. - * - * @param \Composer\Autoload\ClassLoader $autoloader - * The autoloader. - * - * @throws \ReflectionException - */ - private static function alterAssert(ClassLoader $autoloader): void { - // If the class exists already there is nothing we can do. Hopefully this - // is happening because this has been called already. The call from - // \Drupal\Core\Test\TestDiscovery::registerTestNamespaces() necessitates - // this protection. - if (class_exists('PHPUnit\Framework\Assert', FALSE)) { - return; - } - // Mutate Assert code to make it forward compatible with different PhpUnit - // versions, by adding Symfony's PHPUnit-bridge PolyfillAssertTrait. - $alteredFile = $autoloader->findFile('PHPUnit\Framework\Assert'); - $phpunit_dir = dirname($alteredFile, 3); - $alteredCode = file_get_contents($alteredFile); - $alteredCode = preg_replace('/abstract class Assert[^\{]+\{/', '$0 ' . \PHP_EOL . " use \Symfony\Bridge\PhpUnit\Legacy\PolyfillAssertTrait;" . \PHP_EOL, $alteredCode, 1); - include static::flushAlteredCodeToFile('Assert.php', $alteredCode); - } - - /** - * Alters the TestCase class. - * - * @param \Composer\Autoload\ClassLoader $autoloader - * The autoloader. - * - * @throws \ReflectionException - */ - private static function alterTestCase(ClassLoader $autoloader): void { - // If the class exists already there is nothing we can do. Hopefully this - // is happening because this has been called already. The call from - // \Drupal\Core\Test\TestDiscovery::registerTestNamespaces() necessitates - // this protection. - if (class_exists('PHPUnit\Framework\TestCase', FALSE)) { - return; - } - // Mutate TestCase code to make it forward compatible with different PhpUnit - // versions, by adding Symfony's PHPUnit-bridge PolyfillTestCaseTrait. - $alteredFile = $autoloader->findFile('PHPUnit\Framework\TestCase'); - $phpunit_dir = dirname($alteredFile, 3); - $alteredCode = file_get_contents($alteredFile); - $alteredCode = preg_replace('/abstract class TestCase[^\{]+\{/', '$0 ' . \PHP_EOL . " use \Symfony\Bridge\PhpUnit\Legacy\PolyfillTestCaseTrait;" . \PHP_EOL, $alteredCode, 1); - $alteredCode = str_replace("__DIR__ . '/../Util/", "'$phpunit_dir/src/Util/", $alteredCode); - include static::flushAlteredCodeToFile('TestCase.php', $alteredCode); - } - - /** - * Flushes altered class code to file when necessary. - * - * @param string $file_name - * The file name. - * @param string $altered_code - * The altered code. - * - * @return string - * The full path of the file to be included. - */ - private static function flushAlteredCodeToFile(string $file_name, string $altered_code): string { - $directory = __DIR__ . '/../../../../../sites/simpletest'; - $full_path = $directory . '/' . $file_name; - - // Only write when necessary. - if (!file_exists($full_path) || md5_file($full_path) !== md5($altered_code)) { - // Create directory when necessary. - if (!is_dir($directory) && !@mkdir($directory, 0777, TRUE) && !is_dir($directory)) { - throw new \RuntimeException('Unable to create directory: ' . $directory); - } - file_put_contents($full_path, $altered_code); - } - - return $full_path; - } - -} diff --git a/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit9/TestCompatibilityTrait.php b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/TestCompatibilityTrait.php similarity index 52% rename from core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit9/TestCompatibilityTrait.php rename to core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/TestCompatibilityTrait.php index 06d874e2859bbfa44ad978a1af2a635b2ff5eeb0..a2dbea6ff52190bc293b06737cb1837258006b9c 100644 --- a/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit9/TestCompatibilityTrait.php +++ b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/TestCompatibilityTrait.php @@ -2,22 +2,15 @@ declare(strict_types=1); -namespace Drupal\TestTools\PhpUnitCompatibility\PhpUnit9; - -use PHPUnit\Util\Test; +namespace Drupal\TestTools\PhpUnitCompatibility\PhpUnit10; /** * Drupal's forward compatibility layer with multiple versions of PHPUnit. + * + * @internal */ trait TestCompatibilityTrait { - /** - * Get test name. - */ - public function name(): string { - return $this->getName(); - } - /** * Gets @covers defined on the test class. * @@ -25,8 +18,11 @@ public function name(): string { * An array of classes listed with the @covers annotation. */ public function getTestClassCovers(): array { - $annotations = Test::parseTestMethodAnnotations(static::class, $this->name()); - return $annotations['class']['covers'] ?? []; + $ret = []; + foreach ($this->valueObjectForEvents()->metadata()->isCovers()->isClassLevel() as $metadata) { + $ret[] = $metadata->target(); + } + return $ret; } } diff --git a/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php b/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php index 0ce61082fd1809114316a1e5906b832a6d6c0d59..1dea75ea8f601775d328d1f11526e2a5cb613095 100644 --- a/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php +++ b/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php @@ -6,6 +6,7 @@ use Drupal\Component\Utility\Html; use Drupal\Core\Utility\Error; +use Drupal\TestTools\Extension\HtmlLogging\HtmlOutputLogger; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; @@ -49,17 +50,6 @@ trait BrowserHtmlDebugTrait { */ protected $htmlOutputEnabled = FALSE; - /** - * The file name to write the list of URLs to. - * - * This file is read by the PHPUnit result printer. - * - * @var string - * - * @see \Drupal\Tests\Listeners\HtmlOutputPrinter - */ - protected $htmlOutputFile; - /** * HTML output test ID. * @@ -128,7 +118,7 @@ protected function htmlOutput($message = NULL) { // Do not use the file_url_generator service as the module_handler service // might not be available. $uri = $this->htmlOutputBaseUrl . '/sites/simpletest/browser_output/' . $html_output_filename; - file_put_contents($this->htmlOutputFile, $uri . "\n", FILE_APPEND); + HtmlOutputLogger::log($uri . "\n"); } /** @@ -138,11 +128,9 @@ protected function htmlOutput($message = NULL) { * URLs to has been created by \Drupal\Tests\Listeners\HtmlOutputPrinter. */ protected function initBrowserOutputFile() { - $browser_output_file = getenv('BROWSERTEST_OUTPUT_FILE'); - $this->htmlOutputEnabled = is_string($browser_output_file) && is_file($browser_output_file); + $this->htmlOutputEnabled = HtmlOutputLogger::isEnabled(); $this->htmlOutputBaseUrl = getenv('BROWSERTEST_OUTPUT_BASE_URL') ?: $GLOBALS['base_url']; if ($this->htmlOutputEnabled) { - $this->htmlOutputFile = $browser_output_file; $this->htmlOutputClassName = str_replace("\\", "_", static::class); $this->htmlOutputDirectory = DRUPAL_ROOT . '/sites/simpletest/browser_output'; // Do not use the file_system service so this method can be called before diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php index f27fa37a40bd439b5c0f4e48478b6f35a1f3bb0c..c653cf4fa5bb4eced490b5a3a209c0a6ea33f73e 100644 --- a/core/tests/Drupal/Tests/BrowserTestBase.php +++ b/core/tests/Drupal/Tests/BrowserTestBase.php @@ -6,6 +6,7 @@ use Behat\Mink\Driver\BrowserKitDriver; use Behat\Mink\Element\Element; +use Behat\Mink\Exception\Exception as MinkException; use Behat\Mink\Mink; use Behat\Mink\Selector\SelectorsHandler; use Behat\Mink\Session; @@ -19,13 +20,12 @@ use Drupal\Tests\block\Traits\BlockCreationTrait; use Drupal\Tests\node\Traits\ContentTypeCreationTrait; use Drupal\Tests\node\Traits\NodeCreationTrait; -use Drupal\Tests\Traits\PhpUnitWarnings; use Drupal\Tests\user\Traits\UserCreationTrait; use Drupal\TestTools\Comparator\MarkupInterfaceComparator; +use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait; use Drupal\TestTools\TestVarDumper; use GuzzleHttp\Cookie\CookieJar; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException; use Symfony\Component\VarDumper\VarDumper; @@ -72,7 +72,6 @@ abstract class BrowserTestBase extends TestCase { createUser as drupalCreateUser; } use XdebugRequestTrait; - use PhpUnitWarnings; use PhpUnitCompatibilityTrait; use ExpectDeprecationTrait; use ExtensionListTestTrait; @@ -173,19 +172,6 @@ abstract class BrowserTestBase extends TestCase { */ protected $mink; - /** - * {@inheritdoc} - * - * Browser tests are run in separate processes to prevent collisions between - * code that may be loaded by tests. - */ - protected $runTestInSeparateProcess = TRUE; - - /** - * {@inheritdoc} - */ - protected $preserveGlobalState = FALSE; - /** * The base URL. * @@ -369,7 +355,9 @@ protected function setUp(): void { $this->prepareEnvironment(); $this->installDrupal(); - // Setup Mink. + // Setup Mink. Register Mink exceptions to cause test failures instead of + // errors. + $this->registerFailureType(MinkException::class); $this->initMink(); // Set up the browser test output file. diff --git a/core/tests/Drupal/Tests/Component/Assertion/InspectorTest.php b/core/tests/Drupal/Tests/Component/Assertion/InspectorTest.php index 1bdca0702e7135f3e3f1502b02d072c96782625b..a5e1c570516390e5911471019ea60a598b81e4da 100644 --- a/core/tests/Drupal/Tests/Component/Assertion/InspectorTest.php +++ b/core/tests/Drupal/Tests/Component/Assertion/InspectorTest.php @@ -6,7 +6,7 @@ use PHPUnit\Framework\TestCase; use Drupal\Component\Assertion\Inspector; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; +use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait; /** * @coversDefaultClass \Drupal\Component\Assertion\Inspector diff --git a/core/tests/Drupal/Tests/Component/DependencyInjection/ContainerTest.php b/core/tests/Drupal/Tests/Component/DependencyInjection/ContainerTest.php index 7f1be690a8edc00497105582a9f9312a090aa500..0e42a0b4e8e5a8c9fb39e51aa9b1cf94ca038d6a 100644 --- a/core/tests/Drupal/Tests/Component/DependencyInjection/ContainerTest.php +++ b/core/tests/Drupal/Tests/Component/DependencyInjection/ContainerTest.php @@ -5,9 +5,9 @@ namespace Drupal\Tests\Component\DependencyInjection; use Drupal\Component\Utility\Crypt; +use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\LogicException; diff --git a/core/tests/Drupal/Tests/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumperTest.php b/core/tests/Drupal/Tests/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumperTest.php index df31c85d8a6335735b5918b52a5a5736cdf04e6e..9766833a0a53edbe429acf272422833922e2ee7c 100644 --- a/core/tests/Drupal/Tests/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumperTest.php +++ b/core/tests/Drupal/Tests/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumperTest.php @@ -5,10 +5,10 @@ namespace Drupal\Tests\Component\DependencyInjection\Dumper { use Drupal\Component\Utility\Crypt; + use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophet; - use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\Definition; diff --git a/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageReadOnlyTest.php b/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageReadOnlyTest.php index 60fa0b4404093e471e9e2aa52ace4e36e8280f89..438814702c62e232a9965f5f2c9748f44de6a9c1 100644 --- a/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageReadOnlyTest.php +++ b/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageReadOnlyTest.php @@ -7,7 +7,7 @@ use Drupal\Component\PhpStorage\FileStorage; use Drupal\Component\PhpStorage\FileReadOnlyStorage; use Drupal\Component\Utility\Random; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; +use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait; /** * @coversDefaultClass \Drupal\Component\PhpStorage\FileReadOnlyStorage diff --git a/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageTest.php b/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageTest.php index 8ce7ed9df3720b69f449e4d0b1fc6b048c4ab24d..e46ce7c4114f16b39472285449fb1560ac1ee381 100644 --- a/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageTest.php +++ b/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageTest.php @@ -6,9 +6,8 @@ use Drupal\Component\PhpStorage\FileStorage; use Drupal\Component\Utility\Random; -use Drupal\Tests\Traits\PhpUnitWarnings; +use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait; use org\bovigo\vfs\vfsStreamDirectory; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; /** * @coversDefaultClass \Drupal\Component\PhpStorage\FileStorage @@ -17,7 +16,7 @@ */ class FileStorageTest extends PhpStorageTestBase { - use PhpUnitWarnings, ExpectDeprecationTrait; + use ExpectDeprecationTrait; /** * Standard test settings to pass to storage instances. diff --git a/core/tests/Drupal/Tests/Component/Render/FormattableMarkupTest.php b/core/tests/Drupal/Tests/Component/Render/FormattableMarkupTest.php index 06a50ebd5bc7972c188f650b190a057299fa0769..898c0114ee1580e6901956342645ac847371518a 100644 --- a/core/tests/Drupal/Tests/Component/Render/FormattableMarkupTest.php +++ b/core/tests/Drupal/Tests/Component/Render/FormattableMarkupTest.php @@ -5,8 +5,8 @@ namespace Drupal\Tests\Component\Render; use Drupal\Component\Render\FormattableMarkup; +use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; /** * Tests the TranslatableMarkup class. diff --git a/core/tests/Drupal/Tests/Component/Utility/BytesTest.php b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php index e28b912fb5e203f20c422f85448ffba35effae92..04c77eb0a71b1de1afd1895cb895d79fa866694e 100644 --- a/core/tests/Drupal/Tests/Component/Utility/BytesTest.php +++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php @@ -5,10 +5,10 @@ namespace Drupal\Tests\Component\Utility; use Drupal\Component\Utility\Bytes; +use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Validator\Context\ExecutionContextInterface; /** diff --git a/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php b/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php index 6dfe031dd123e020f9c7e58b2feb5da485f856a4..291304532786fb49dd649ba3c644b5bddb7e7431 100644 --- a/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php +++ b/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php @@ -5,8 +5,8 @@ namespace Drupal\Tests\Component\Utility; use Drupal\Component\Utility\Unicode; +use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; /** * Test unicode handling features implemented in Unicode component. diff --git a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/AssertUtilsTrait.php b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/AssertUtilsTrait.php index a2257158b2c595a543a2a72788c0569c23075c03..9c5779f4604f86aa8f9a60a0e7918d4c6c89c6c0 100644 --- a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/AssertUtilsTrait.php +++ b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/AssertUtilsTrait.php @@ -4,13 +4,10 @@ namespace Drupal\Tests\Composer\Plugin\Scaffold; -use Drupal\Tests\Traits\PhpUnitWarnings; - /** * Convenience class for creating fixtures. */ trait AssertUtilsTrait { - use PhpUnitWarnings; /** * Asserts that a given file exists and is/is not a symlink. diff --git a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ManageGitIgnoreTest.php b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ManageGitIgnoreTest.php index 3bea63641f30c987db3f01f60cf49a7c16889ade..e61a716ff8bf70ff9ac2921fd5cfce63c8cd35a3 100644 --- a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ManageGitIgnoreTest.php +++ b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ManageGitIgnoreTest.php @@ -8,7 +8,6 @@ use Drupal\Tests\Composer\Plugin\Scaffold\Fixtures; use Drupal\Tests\Composer\Plugin\Scaffold\AssertUtilsTrait; use Drupal\Tests\Composer\Plugin\Scaffold\ExecTrait; -use Drupal\Tests\PhpUnitCompatibilityTrait; use PHPUnit\Framework\TestCase; /** @@ -23,7 +22,6 @@ class ManageGitIgnoreTest extends TestCase { use ExecTrait; use AssertUtilsTrait; - use PhpUnitCompatibilityTrait; /** * The root of this project. diff --git a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ScaffoldTest.php b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ScaffoldTest.php index e5127780cb7054dfefe03a8bcc3206c28504fc87..012cc4590c4420a45b5297a3aa3774a96404682a 100644 --- a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ScaffoldTest.php +++ b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ScaffoldTest.php @@ -8,7 +8,6 @@ use Drupal\Tests\Composer\Plugin\Scaffold\AssertUtilsTrait; use Drupal\Tests\Composer\Plugin\Scaffold\Fixtures; use Drupal\Tests\Composer\Plugin\Scaffold\ScaffoldTestResult; -use Drupal\Tests\PhpUnitCompatibilityTrait; use PHPUnit\Framework\TestCase; /** @@ -21,7 +20,6 @@ */ class ScaffoldTest extends TestCase { use AssertUtilsTrait; - use PhpUnitCompatibilityTrait; /** * The root of this project. diff --git a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ScaffoldUpgradeTest.php b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ScaffoldUpgradeTest.php index f28ec78ca510bcf7f8ead70ca4464270c83d95a7..c9f34d95516d1d592c724e2335bbebc76e63fed5 100644 --- a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ScaffoldUpgradeTest.php +++ b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ScaffoldUpgradeTest.php @@ -8,7 +8,6 @@ use Drupal\Tests\Composer\Plugin\Scaffold\AssertUtilsTrait; use Drupal\Tests\Composer\Plugin\Scaffold\ExecTrait; use Drupal\Tests\Composer\Plugin\Scaffold\Fixtures; -use Drupal\Tests\PhpUnitCompatibilityTrait; use PHPUnit\Framework\TestCase; /** @@ -28,7 +27,6 @@ class ScaffoldUpgradeTest extends TestCase { use AssertUtilsTrait; use ExecTrait; - use PhpUnitCompatibilityTrait; /** * The Fixtures object. diff --git a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Integration/AppendOpTest.php b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Integration/AppendOpTest.php index 45806562416b4ef284fa647b00a6b6b86d763532..3cce05475a44ae84505132320d14294cdb464d75 100644 --- a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Integration/AppendOpTest.php +++ b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Integration/AppendOpTest.php @@ -7,7 +7,6 @@ use Drupal\Composer\Plugin\Scaffold\Operations\AppendOp; use Drupal\Composer\Plugin\Scaffold\ScaffoldOptions; use Drupal\Tests\Composer\Plugin\Scaffold\Fixtures; -use Drupal\Tests\Traits\PhpUnitWarnings; use PHPUnit\Framework\TestCase; /** @@ -16,7 +15,6 @@ * @group Scaffold */ class AppendOpTest extends TestCase { - use PhpUnitWarnings; /** * @covers ::process diff --git a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Integration/ReplaceOpTest.php b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Integration/ReplaceOpTest.php index 00deb085684d63b5182a9064d229fa1eab99f89e..a781d5b9c66cc48ec48d6e3fcc055ddfcad57d5b 100644 --- a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Integration/ReplaceOpTest.php +++ b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Integration/ReplaceOpTest.php @@ -7,7 +7,6 @@ use Drupal\Composer\Plugin\Scaffold\Operations\ReplaceOp; use Drupal\Composer\Plugin\Scaffold\ScaffoldOptions; use Drupal\Tests\Composer\Plugin\Scaffold\Fixtures; -use Drupal\Tests\Traits\PhpUnitWarnings; use PHPUnit\Framework\TestCase; /** @@ -16,7 +15,6 @@ * @group Scaffold */ class ReplaceOpTest extends TestCase { - use PhpUnitWarnings; /** * @covers ::process diff --git a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Integration/SkipOpTest.php b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Integration/SkipOpTest.php index 8fd239540bdecfbe8d7f84412f980589373b15de..5a13e34918a44621070aab64be45259fea65255f 100644 --- a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Integration/SkipOpTest.php +++ b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Integration/SkipOpTest.php @@ -7,7 +7,6 @@ use Drupal\Composer\Plugin\Scaffold\Operations\SkipOp; use Drupal\Composer\Plugin\Scaffold\ScaffoldOptions; use Drupal\Tests\Composer\Plugin\Scaffold\Fixtures; -use Drupal\Tests\Traits\PhpUnitWarnings; use PHPUnit\Framework\TestCase; /** @@ -16,7 +15,6 @@ * @group Scaffold */ class SkipOpTest extends TestCase { - use PhpUnitWarnings; /** * @covers ::process diff --git a/core/tests/Drupal/Tests/Composer/Plugin/VendorHardening/ConfigTest.php b/core/tests/Drupal/Tests/Composer/Plugin/VendorHardening/ConfigTest.php index 442379723d3ddcb2d5635c454dfa7e34253b5d0c..66f28d2ed5e5ca86582fcda23e59c50107e4487a 100644 --- a/core/tests/Drupal/Tests/Composer/Plugin/VendorHardening/ConfigTest.php +++ b/core/tests/Drupal/Tests/Composer/Plugin/VendorHardening/ConfigTest.php @@ -6,7 +6,6 @@ use Composer\Package\RootPackageInterface; use Drupal\Composer\Plugin\VendorHardening\Config; -use Drupal\Tests\Traits\PhpUnitWarnings; use PHPUnit\Framework\TestCase; /** @@ -15,8 +14,6 @@ */ class ConfigTest extends TestCase { - use PhpUnitWarnings; - /** * @covers ::getPathsForPackage */ diff --git a/core/tests/Drupal/Tests/Composer/Plugin/VendorHardening/VendorHardeningPluginTest.php b/core/tests/Drupal/Tests/Composer/Plugin/VendorHardening/VendorHardeningPluginTest.php index 1382235f77726767a4bdeeeb660492795455a69d..29c935fe1444545637aad629837038ba99983782 100644 --- a/core/tests/Drupal/Tests/Composer/Plugin/VendorHardening/VendorHardeningPluginTest.php +++ b/core/tests/Drupal/Tests/Composer/Plugin/VendorHardening/VendorHardeningPluginTest.php @@ -10,7 +10,6 @@ use Composer\Package\RootPackageInterface; use Drupal\Composer\Plugin\VendorHardening\Config; use Drupal\Composer\Plugin\VendorHardening\VendorHardeningPlugin; -use Drupal\Tests\Traits\PhpUnitWarnings; use org\bovigo\vfs\vfsStream; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; @@ -21,7 +20,6 @@ */ class VendorHardeningPluginTest extends TestCase { - use PhpUnitWarnings; use ProphecyTrait; /** diff --git a/core/tests/Drupal/Tests/Core/Asset/CssOptimizerUnitTest.php b/core/tests/Drupal/Tests/Core/Asset/CssOptimizerUnitTest.php index 2b7033ac8e13a1abbe660ba0ba085421819f91f6..985cc785f5918e1db5ed88768fc62670e3b5002f 100644 --- a/core/tests/Drupal/Tests/Core/Asset/CssOptimizerUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Asset/CssOptimizerUnitTest.php @@ -15,11 +15,6 @@ */ class CssOptimizerUnitTest extends UnitTestCase { - /** - * {@inheritdoc} - */ - protected $backupGlobals = FALSE; - /** * A CSS asset optimizer. * diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php index 34e16dd5bae213750d2f6ebb567a123997869677..7e6590b797ded114a9c5714b644922b7dfdb3908 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php @@ -67,7 +67,7 @@ public function testGetFormIdWithString() { * @covers ::getFormId */ public function testGetFormIdWithNonFormClass() { - $form_arg = __CLASS__; + $form_arg = \stdClass::class; $form_state = new FormState(); $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage("The form argument $form_arg must be an instance of \Drupal\Core\Form\FormInterface."); diff --git a/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php b/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php index 8a532a4027f97013bcd68bf1cf0bac2626e54897..e83d5705c443b48a8517922c3b03d9dcaf0cc7a8 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php @@ -84,16 +84,6 @@ class FormCacheTest extends UnitTestCase { */ protected $requestPolicy; - /** - * {@inheritdoc} - */ - protected $runTestInSeparateProcess = TRUE; - - /** - * {@inheritdoc} - */ - protected $preserveGlobalState = FALSE; - /** * {@inheritdoc} */ diff --git a/core/tests/Drupal/Tests/Core/Form/FormStateDecoratorBaseTest.php b/core/tests/Drupal/Tests/Core/Form/FormStateDecoratorBaseTest.php index 2b00dfdfa1a6e38d86c7870d62dacf77448232a8..3924855fd97d17966aece95d1a21c35fdb70b554 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormStateDecoratorBaseTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormStateDecoratorBaseTest.php @@ -1451,7 +1451,7 @@ public static function providerPrepareCallback(): array { $closure = function () {}; $static_method_string = __METHOD__; $static_method_array = [__CLASS__, __FUNCTION__]; - $object_method_array = [new static(), __FUNCTION__]; + $object_method_array = [new static('test'), __FUNCTION__]; return [ // A shorthand form method is generally expanded to become a method on an diff --git a/core/tests/Drupal/Tests/Core/Security/RequestSanitizerTest.php b/core/tests/Drupal/Tests/Core/Security/RequestSanitizerTest.php index 6e508a1ea62bff6427e3be5565620720a62cd59e..070f1d12631d886d45d025b61b25f14243e3c12a 100644 --- a/core/tests/Drupal/Tests/Core/Security/RequestSanitizerTest.php +++ b/core/tests/Drupal/Tests/Core/Security/RequestSanitizerTest.php @@ -34,6 +34,14 @@ protected function setUp(): void { set_error_handler([$this, "errorHandler"]); } + /** + * {@inheritdoc} + */ + protected function tearDown(): void { + restore_error_handler(); + parent::tearDown(); + } + /** * Tests RequestSanitizer class. * diff --git a/core/tests/Drupal/Tests/Core/StringTranslation/TranslatableMarkupTest.php b/core/tests/Drupal/Tests/Core/StringTranslation/TranslatableMarkupTest.php index a9a1b363d27556369f32564f0244aa7c8f393f84..338c21a5c77abdd9a339e12995dee456983f716c 100644 --- a/core/tests/Drupal/Tests/Core/StringTranslation/TranslatableMarkupTest.php +++ b/core/tests/Drupal/Tests/Core/StringTranslation/TranslatableMarkupTest.php @@ -80,7 +80,7 @@ public function testToString() { restore_error_handler(); $this->assertEquals(E_USER_ERROR, $this->lastErrorNumber); - $this->assertMatchesRegularExpression('/Exception thrown while calling __toString on a .*Mock_TranslatableMarkup_.* object in .*TranslatableMarkupTest.php on line [0-9]+: Yes you may./', $this->lastErrorMessage); + $this->assertMatchesRegularExpression('/Exception thrown while calling __toString on a .*MockObject_TranslatableMarkup_.* object in .*TranslatableMarkupTest.php on line [0-9]+: Yes you may./', $this->lastErrorMessage); } /** diff --git a/core/tests/Drupal/Tests/Core/Test/PhpUnitCliTest.php b/core/tests/Drupal/Tests/Core/Test/PhpUnitCliTest.php index a240af9d4cbb7089ad26b31bfb1b2a46b8c42e4a..926a7cdedc5c006e3ce68fc0e3644ea3d3cd4265 100644 --- a/core/tests/Drupal/Tests/Core/Test/PhpUnitCliTest.php +++ b/core/tests/Drupal/Tests/Core/Test/PhpUnitCliTest.php @@ -5,7 +5,6 @@ namespace Drupal\Tests\Core\Test; use Drupal\Tests\UnitTestCase; -use Drupal\TestTools\PhpUnitCompatibility\RunnerVersion; use Symfony\Component\Process\Process; /** @@ -31,11 +30,6 @@ public function testPhpUnitListTests() { '--list-tests', ]; - // PHPUnit 10 dropped the --verbose command line option. - if (RunnerVersion::getMajor() < 10) { - $command[] = '--verbose'; - } - $process = new Process($command, $this->root); $process ->setTimeout(300) diff --git a/core/tests/Drupal/Tests/Core/Test/TestSuiteBaseTest.php b/core/tests/Drupal/Tests/Core/Test/TestSuiteBaseTest.php index 1f53f981775e562bed4f5a4073bd641a569403b8..13fdffbb790650ecd277a4ce8b614b19300464e3 100644 --- a/core/tests/Drupal/Tests/Core/Test/TestSuiteBaseTest.php +++ b/core/tests/Drupal/Tests/Core/Test/TestSuiteBaseTest.php @@ -4,113 +4,13 @@ namespace Drupal\Tests\Core\Test; -use Drupal\Tests\TestSuites\TestSuiteBase; -use org\bovigo\vfs\vfsStream; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; - -// The test suite class is not part of the autoloader, we need to include it -// manually. -require_once __DIR__ . '/../../../../TestSuites/TestSuiteBase.php'; /** - * @coversDefaultClass \Drupal\Tests\TestSuites\TestSuiteBase - * - * @group TestSuite + * @group Test */ class TestSuiteBaseTest extends TestCase { - use ExpectDeprecationTrait; - - /** - * Helper method to set up the file system. - * - * @return array[] - * A Drupal filesystem suitable for use with vfsStream. - */ - protected function getFilesystem() { - return [ - 'core' => [ - 'modules' => [], - 'profiles' => [], - 'tests' => [ - 'Drupal' => [ - 'NotUnitTests' => [ - 'CoreNotUnitTest.php' => '<?php', - ], - 'Tests' => [ - 'CoreUnitTest.php' => '<?php', - // Ensure that the following files are not found as tests. - 'Listeners' => [ - 'Listener.php' => '<?php', - 'Legacy' => [ - 'Listener.php' => '<?php', - ], - ], - ], - ], - ], - ], - ]; - } - - /** - * @return array[] - * Test data for testAddTestsBySuiteNamespaceCore(). An array of arrays: - * - A filesystem array for vfsStream. - * - The sub-namespace of the test suite. - * - The array of tests expected to be discovered. - */ - public function provideCoreTests() { - $filesystem = $this->getFilesystem(); - return [ - 'unit-tests' => [ - $filesystem, - 'Unit', - [ - 'Drupal\Tests\CoreUnitTest' => 'vfs://root/core/tests/Drupal/Tests/CoreUnitTest.php', - ], - ], - 'not-unit-tests' => [ - $filesystem, - 'NotUnit', - [ - 'Drupal\NotUnitTests\CoreNotUnitTest' => 'vfs://root/core/tests/Drupal/NotUnitTests/CoreNotUnitTest.php', - ], - ], - ]; - } - - /** - * Tests for special case behavior of unit test suite namespaces in core. - * - * @group legacy - * - * @covers ::addTestsBySuiteNamespace - * - * @dataProvider provideCoreTests - */ - public function testAddTestsBySuiteNamespaceCore($filesystem, $suite_namespace, $expected_tests) { - - $this->expectDeprecation('Drupal\\Tests\\Core\\Test\\StubTestSuiteBase is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. There is no replacement and test discovery will be handled differently in PHPUnit 10. See https://www.drupal.org/node/3405829'); - - // Set up the file system. - $vfs = vfsStream::setup('root'); - vfsStream::create($filesystem, $vfs); - - // Make a stub suite base to test. - $stub = new StubTestSuiteBase('test_me'); - - // Access addTestsBySuiteNamespace(). - $ref_add_tests = new \ReflectionMethod($stub, 'addTestsBySuiteNamespace'); - - // Invoke addTestsBySuiteNamespace(). - $ref_add_tests->invokeArgs($stub, [vfsStream::url('root'), $suite_namespace]); - - // Determine if we loaded the expected test files. - $this->assertEquals($expected_tests, $stub->testFiles); - } - /** * Tests the assumption that local time is in 'Australia/Sydney'. */ @@ -120,52 +20,3 @@ public function testLocalTimeZone() { } } - -/** - * Stub subclass of TestSuiteBase. - * - * We use this class to alter the behavior of TestSuiteBase so it can be - * testable. - * - * @phpstan-ignore-next-line - */ -class StubTestSuiteBase extends TestSuiteBase { - - /** - * Test files discovered by addTestsBySuiteNamespace(). - * - * @var string[] - */ - public $testFiles = []; - - public function __construct(string $name) { - @trigger_error(__CLASS__ . ' is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. There is no replacement and test discovery will be handled differently in PHPUnit 10. See https://www.drupal.org/node/3405829', E_USER_DEPRECATED); - // @phpstan-ignore-next-line - parent::__construct($name); - } - - /** - * {@inheritdoc} - */ - protected function findExtensionDirectories($root) { - // We have to stub findExtensionDirectories() because we can't inject a - // vfsStream filesystem into drupal_phpunit_find_extension_directories(), - // which uses \SplFileInfo->getRealPath(). getRealPath() resolves - // stream-based paths to an empty string. See - // https://github.com/mikey179/vfsStream/wiki/Known-Issues - return []; - } - - /** - * {@inheritdoc} - */ - public function addTestFiles($filenames): void { - // We stub addTestFiles() because the parent implementation can't deal with - // vfsStream-based filesystems due to an error in - // stream_resolve_include_path(). See - // https://github.com/mikey179/vfsStream/issues/5 Here we just store the - // test file being added in $this->testFiles. - $this->testFiles = array_merge($this->testFiles, $filenames); - } - -} diff --git a/core/tests/Drupal/Tests/Core/Test/WebDriverTestBaseTest.php b/core/tests/Drupal/Tests/Core/Test/WebDriverTestBaseTest.php index d457f21e81e7a7efb044a8ad2d627e5247e26089..7b3d4c488558fbdf0d9514fd4534b9e3ee48a3cc 100644 --- a/core/tests/Drupal/Tests/Core/Test/WebDriverTestBaseTest.php +++ b/core/tests/Drupal/Tests/Core/Test/WebDriverTestBaseTest.php @@ -31,7 +31,9 @@ public function testCapabilities($expected, ?string $mink_driver_args_webdriver, $this->putEnv("MINK_DRIVER_ARGS_WEBDRIVER", $mink_driver_args_webdriver); $this->putEnv("MINK_DRIVER_ARGS", $mink_driver_args); - $object = $this->getMockForAbstractClass(WebDriverTestBase::class); + $object = $this->getMockBuilder(WebDriverTestBase::class) + ->setConstructorArgs(['test']) + ->getMockForAbstractClass(); $method = new \ReflectionMethod($object, 'getMinkDriverArgs'); $this->assertSame($expected, $method->invoke($object)); } @@ -67,7 +69,9 @@ public function testChromeOptions(): void { $this->expectDeprecation('The "chromeOptions" array key is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use "goog:chromeOptions instead. See https://www.drupal.org/node/3422624'); putenv('MINK_DRIVER_ARGS_WEBDRIVER=["chrome",{"browserName":"chrome","chromeOptions":{"args":["--headless"]}},"http://localhost:4444"]'); - $object = $this->getMockForAbstractClass(WebDriverTestBase::class); + $object = $this->getMockBuilder(WebDriverTestBase::class) + ->setConstructorArgs(['test']) + ->getMockForAbstractClass(); $method = new \ReflectionMethod($object, 'getMinkDriverArgs'); $this->assertSame('["chrome",{"browserName":"chrome","goog:chromeOptions":{"args":["--headless"],"w3c":false}},"http:\\/\\/localhost:4444"]', $method->invoke($object)); } diff --git a/core/tests/Drupal/Tests/Core/Utility/CallableResolverTest.php b/core/tests/Drupal/Tests/Core/Utility/CallableResolverTest.php index 89f7957d6a06c602905fd865c73397ed2f80b645..01bb1b9727241b5f3d7a6c9db4587f79f417a1cf 100644 --- a/core/tests/Drupal/Tests/Core/Utility/CallableResolverTest.php +++ b/core/tests/Drupal/Tests/Core/Utility/CallableResolverTest.php @@ -78,8 +78,8 @@ function ($suffix) { __CLASS__ . '::method', ], 'Non-static function, instantiated by class resolver' => [ - static::class . '::method', - __CLASS__ . '::method', + MethodCallable::class . '::method', + MethodCallable::class . '::method', ], 'Non-static function, instantiated by class resolver, container injection' => [ '\Drupal\Tests\Core\Utility\MockContainerInjection::getResult', @@ -94,8 +94,8 @@ function ($suffix) { __CLASS__ . '::staticMethod', ], 'Class with invoke method' => [ - static::class, - __CLASS__ . '::__invoke', + MethodCallable::class, + MethodCallable::class . '::__invoke', ], ]; @@ -131,14 +131,14 @@ public static function callableResolverExceptionHandlingTestCases() { 'The callable definition provided "[not_a_callable,not_a_callable]" is not a valid callable.', ], 'Missing method on class, array notation' => [ - [static::class, 'method_not_exists'], + [\stdClass::class, 'method_not_exists'], \InvalidArgumentException::class, - 'The callable definition provided "[Drupal\Tests\Core\Utility\CallableResolverTest,method_not_exists]" is not a valid callable.', + 'The callable definition provided "[stdClass,method_not_exists]" is not a valid callable.', ], 'Missing method on class, static notation' => [ - static::class . '::method_not_exists', + \stdClass::class . '::method_not_exists', \InvalidArgumentException::class, - 'The callable definition provided was invalid. Either class "Drupal\Tests\Core\Utility\CallableResolverTest" does not have a method "method_not_exists", or it is not callable.', + 'The callable definition provided was invalid. Either class "stdClass" does not have a method "method_not_exists", or it is not callable.', ], 'Missing class, static notation' => [ '\NotARealClass::method', @@ -237,5 +237,38 @@ public static function staticMethod($suffix) { } +class MethodCallable { + + /** + * A test __invoke method. + * + * @param string $suffix + * A suffix to append. + * + * @return string + * A test string. + */ + public function __invoke($suffix) { + return __METHOD__ . '+' . $suffix; + } + + /** + * A test method that returns "foo". + * + * @param string $suffix + * A suffix to append. + * + * @return string + * A test string. + * + * @throws \Exception + * Throws an exception when called statically. + */ + public function method($suffix) { + return __METHOD__ . '+' . $suffix; + } + +} + class NoMethodCallable { } diff --git a/core/tests/Drupal/Tests/ExpectDeprecationTest.php b/core/tests/Drupal/Tests/ExpectDeprecationTest.php index 8fc2b4c872a5e170bac05e9670b5281e0b9b4479..349a34f015f1fc8e3a4f37244f04df269c6b83db 100644 --- a/core/tests/Drupal/Tests/ExpectDeprecationTest.php +++ b/core/tests/Drupal/Tests/ExpectDeprecationTest.php @@ -4,8 +4,8 @@ namespace Drupal\Tests; +use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; /** * Ensures Drupal has test coverage of Symfony's deprecation testing. diff --git a/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListenerTrait.php b/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListenerTrait.php deleted file mode 100644 index 90a5638e2dc0899ffbd178337f437b512484fa9c..0000000000000000000000000000000000000000 --- a/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListenerTrait.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests\Listeners; - -use Drupal\KernelTests\KernelTestBase; -use Drupal\Tests\BrowserTestBase; -use Drupal\Tests\UnitTestCase; -use PHPUnit\Framework\AssertionFailedError; - -/** - * Ensures that no component tests are extending a core test base class. - * - * @internal - */ -trait DrupalComponentTestListenerTrait { - - /** - * Reacts to the end of a test. - * - * @param \PHPUnit\Framework\Test $test - * The test object that has ended its test run. - * @param float $time - * The time the test took. - */ - protected function componentEndTest($test, $time) { - /** @var \PHPUnit\Framework\Test $test */ - if (str_starts_with($test->toString(), 'Drupal\Tests\Component')) { - if ($test instanceof BrowserTestBase || $test instanceof KernelTestBase || $test instanceof UnitTestCase) { - $error = new AssertionFailedError('Component tests should not extend a core test base class.'); - $test->getTestResultObject()->addFailure($test, $error, $time); - } - } - } - -} diff --git a/core/tests/Drupal/Tests/Listeners/DrupalListener.php b/core/tests/Drupal/Tests/Listeners/DrupalListener.php deleted file mode 100644 index 182e4fe4e7b23a27aef9b9ccbaf940f420a7bd13..0000000000000000000000000000000000000000 --- a/core/tests/Drupal/Tests/Listeners/DrupalListener.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests\Listeners; - -use PHPUnit\Framework\TestListener; -use PHPUnit\Framework\TestListenerDefaultImplementation; -use PHPUnit\Framework\Test; -use PHPUnit\Framework\TestSuite; -use Symfony\Bridge\PhpUnit\SymfonyTestsListener; - -/** - * Listens to PHPUnit test runs. - * - * @internal - */ -class DrupalListener implements TestListener { - - use TestListenerDefaultImplementation; - use DrupalComponentTestListenerTrait; - - /** - * The wrapped Symfony test listener. - * - * @var \Symfony\Bridge\PhpUnit\SymfonyTestsListener - */ - private $symfonyListener; - - /** - * Constructs the DrupalListener object. - */ - public function __construct() { - $this->symfonyListener = new SymfonyTestsListener(); - } - - /** - * {@inheritdoc} - */ - public function startTestSuite(TestSuite $suite): void { - $this->symfonyListener->startTestSuite($suite); - } - - /** - * {@inheritdoc} - */ - public function addSkippedTest(Test $test, \Throwable $t, float $time): void { - $this->symfonyListener->addSkippedTest($test, $t, $time); - } - - /** - * {@inheritdoc} - */ - public function startTest(Test $test): void { - $this->symfonyListener->startTest($test); - } - - /** - * {@inheritdoc} - */ - public function endTest(Test $test, float $time): void { - $this->symfonyListener->endTest($test, $time); - $this->componentEndTest($test, $time); - } - -} diff --git a/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinter.php b/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinter.php deleted file mode 100644 index dcfd8e80e2ff5d422d225f7e1fd3e666578bfd96..0000000000000000000000000000000000000000 --- a/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinter.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests\Listeners; - -use PHPUnit\Framework\TestResult; -use PHPUnit\TextUI\DefaultResultPrinter; - -/** - * Defines a class for providing html output results for functional tests. - * - * @internal - */ -class HtmlOutputPrinter extends DefaultResultPrinter { - - use HtmlOutputPrinterTrait; - - /** - * {@inheritdoc} - */ - public function printResult(TestResult $result): void { - parent::printResult($result); - - $this->printHtmlOutput(); - } - -} diff --git a/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinterTrait.php b/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinterTrait.php deleted file mode 100644 index 33507046884a6a6f93e279e9acaecb152bec95ed..0000000000000000000000000000000000000000 --- a/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinterTrait.php +++ /dev/null @@ -1,83 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests\Listeners; - -/** - * Defines a class for providing html output results for functional tests. - * - * @internal - */ -trait HtmlOutputPrinterTrait { - - /** - * File to write html links to. - * - * @var string - */ - protected $browserOutputFile; - - /** - * {@inheritdoc} - */ - public function __construct($out = NULL, $verbose = FALSE, $colors = self::COLOR_DEFAULT, $debug = FALSE, $numberOfColumns = 80, $reverse = FALSE) { - parent::__construct($out, $verbose, $colors, $debug, $numberOfColumns, $reverse); - - $this->setUpHtmlOutput(); - } - - /** - * Creates the file to list the HTML output created during the test. - * - * @see \Drupal\Tests\BrowserTestBase::initBrowserOutputFile() - */ - protected function setUpHtmlOutput() { - if ($html_output_directory = getenv('BROWSERTEST_OUTPUT_DIRECTORY')) { - // Initialize html output debugging. - $html_output_directory = rtrim($html_output_directory, '/'); - - // Check if directory exists. - if (!is_dir($html_output_directory) || !is_writable($html_output_directory)) { - $this->writeWithColor('bg-red, fg-black', "HTML output directory $html_output_directory is not a writable directory."); - } - else { - // Convert to a canonicalized absolute pathname just in case the current - // working directory is changed. - $html_output_directory = realpath($html_output_directory); - $this->browserOutputFile = tempnam($html_output_directory, 'browser_output_'); - if ($this->browserOutputFile) { - touch($this->browserOutputFile); - } - else { - $this->writeWithColor('bg-red, fg-black', "Unable to create a temporary file in $html_output_directory."); - } - } - } - - if ($this->browserOutputFile) { - putenv('BROWSERTEST_OUTPUT_FILE=' . $this->browserOutputFile); - } - else { - // Remove any environment variable. - putenv('BROWSERTEST_OUTPUT_FILE'); - } - } - - /** - * Prints the list of HTML output generated during the test. - */ - protected function printHtmlOutput() { - if ($this->browserOutputFile) { - $contents = file_get_contents($this->browserOutputFile); - if ($contents) { - $this->writeNewLine(); - $this->writeWithColor('bg-yellow, fg-black', 'HTML output was generated'); - $this->write($contents); - } - // No need to keep the file around any more. - unlink($this->browserOutputFile); - } - } - -} diff --git a/core/tests/Drupal/Tests/PhpUnitCompatibilityTrait.php b/core/tests/Drupal/Tests/PhpUnitCompatibilityTrait.php index 932bd03a3e83aa8b70e03d0d1954051bd549bb23..57885d9205724233f6ebcd1eb5e9c29b1a0d54ac 100644 --- a/core/tests/Drupal/Tests/PhpUnitCompatibilityTrait.php +++ b/core/tests/Drupal/Tests/PhpUnitCompatibilityTrait.php @@ -22,7 +22,7 @@ class_alias("Drupal\TestTools\PhpUnitCompatibility\PhpUnit" . RunnerVersion::get */ trait PhpUnitCompatibilityTrait { - use \Drupal\TestTools\PhpUnitCompatibility\PhpUnit9\TestCompatibilityTrait; + use \Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\TestCompatibilityTrait; } diff --git a/core/tests/Drupal/Tests/PhpUnitWarningsTest.php b/core/tests/Drupal/Tests/PhpUnitWarningsTest.php deleted file mode 100644 index 67d632928fb18ef204aad244088779c02ac71236..0000000000000000000000000000000000000000 --- a/core/tests/Drupal/Tests/PhpUnitWarningsTest.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests; - -/** - * @coversDefaultClass \Drupal\Tests\Traits\PhpUnitWarnings - * @group legacy - */ -class PhpUnitWarningsTest extends UnitTestCase { - - /** - * Tests that selected PHPUnit warning is converted to deprecation. - */ - public function testAddWarning() { - $this->expectDeprecation('Test warning for \Drupal\Tests\PhpUnitWarningsTest::testAddWarning()'); - $this->addWarning('Test warning for \Drupal\Tests\PhpUnitWarningsTest::testAddWarning()'); - } - -} diff --git a/core/tests/Drupal/Tests/Traits/PhpUnitWarnings.php b/core/tests/Drupal/Tests/Traits/PhpUnitWarnings.php deleted file mode 100644 index 180179a8a67a615bb13edc3df34ffdb6be71f0c5..0000000000000000000000000000000000000000 --- a/core/tests/Drupal/Tests/Traits/PhpUnitWarnings.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests\Traits; - -/** - * Converts deprecation warnings added by PHPUnit to silenced deprecations. - * - * This trait exists to allow Drupal to run tests with multiple versions of - * PHPUnit without failing due to PHPUnit's deprecation warnings. - * - * @internal - */ -trait PhpUnitWarnings { - - /** - * Deprecation warnings from PHPUnit to raise with @trigger_error(). - * - * Add any PHPUnit deprecations that should be handled as deprecation warnings - * (rather than unconditional failures) for core and contrib. - * - * @var string[] - */ - private static $deprecationWarnings = [ - // Warning for testing. - 'Test warning for \Drupal\Tests\PhpUnitWarningsTest::testAddWarning()', - // PHPUnit 9. - 'assertFileNotExists() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertFileDoesNotExist() instead.', - 'assertRegExp() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertMatchesRegularExpression() instead.', - 'assertNotRegExp() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertDoesNotMatchRegularExpression() instead.', - 'assertDirectoryNotExists() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertDirectoryDoesNotExist() instead.', - 'Support for using expectException() with PHPUnit\\Framework\\Error\\Warning is deprecated and will be removed in PHPUnit 10. Use expectWarning() instead.', - 'Support for using expectException() with PHPUnit\\Framework\\Error\\Error is deprecated and will be removed in PHPUnit 10. Use expectError() instead.', - 'assertDirectoryNotIsWritable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertDirectoryIsNotWritable() instead.', - 'assertFileNotIsWritable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertFileIsNotWritable() instead.', - // cspell:disable-next-line - 'The at() matcher has been deprecated. It will be removed in PHPUnit 10. Please refactor your test to not rely on the order in which methods are invoked.', - // PHPUnit 9.6. - 'Expecting E_WARNING and E_USER_WARNING is deprecated and will no longer be possible in PHPUnit 10.', - 'Expecting E_ERROR and E_USER_ERROR is deprecated and will no longer be possible in PHPUnit 10.', - 'assertObjectHasAttribute() is deprecated and will be removed in PHPUnit 10. Refactor your test to use assertObjectHasProperty() instead.', - 'assertObjectNotHasAttribute() is deprecated and will be removed in PHPUnit 10. Refactor your test to use assertObjectNotHasProperty() instead.', - ]; - - /** - * Converts PHPUnit deprecation warnings to E_USER_DEPRECATED. - * - * @param string $warning - * The warning message raised in tests. - * - * @see \PHPUnit\Framework\TestCase::addWarning() - * - * @internal - */ - public function addWarning(string $warning): void { - if (in_array($warning, self::$deprecationWarnings, TRUE)) { - // Convert listed PHPUnit deprecations into E_USER_DEPRECATED and prevent - // each from being raised as a test warning. - @trigger_error($warning, E_USER_DEPRECATED); - return; - } - - // Otherwise, let the parent raise any warning not specifically listed. - parent::addWarning($warning); - } - -} diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php index 2ca419d204bea7211bf2b6b142f33ea3477ca573..6bff44c0854449fbb43abe9e7aeac095ad073800 100644 --- a/core/tests/Drupal/Tests/UnitTestCase.php +++ b/core/tests/Drupal/Tests/UnitTestCase.php @@ -10,12 +10,11 @@ use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\StringTranslation\PluralTranslatableMarkup; -use Drupal\Tests\Traits\PhpUnitWarnings; +use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait; use Drupal\TestTools\TestVarDumper; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; use Symfony\Component\VarDumper\VarDumper; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; /** * Provides a base class and helpers for Drupal unit tests. @@ -27,7 +26,6 @@ */ abstract class UnitTestCase extends TestCase { - use PhpUnitWarnings; use PhpUnitCompatibilityTrait; use ProphecyTrait; use ExpectDeprecationTrait; diff --git a/core/tests/TestSuites/BuildTestSuite.php b/core/tests/TestSuites/BuildTestSuite.php deleted file mode 100644 index c26bf44e59f1b28d51804543bdb1cf0b0f2afbaa..0000000000000000000000000000000000000000 --- a/core/tests/TestSuites/BuildTestSuite.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests\TestSuites; - -require_once __DIR__ . '/TestSuiteBase.php'; - -/** - * Discovers tests for the build test suite. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. There is no - * replacement and test discovery will be handled differently in PHPUnit 10. - * - * @see https://www.drupal.org/node/3405829 - */ -class BuildTestSuite extends TestSuiteBase { - - /** - * Factory method which loads up a suite with all build tests. - * - * @return static - * The test suite. - */ - public static function suite() { - $root = dirname(__DIR__, 3); - - $suite = new static('build'); - $suite->addTestsBySuiteNamespace($root, 'Build'); - - return $suite; - } - -} diff --git a/core/tests/TestSuites/FunctionalJavascriptTestSuite.php b/core/tests/TestSuites/FunctionalJavascriptTestSuite.php deleted file mode 100644 index 5ae2325121b9e8d865b00ac58340bd6862697b3d..0000000000000000000000000000000000000000 --- a/core/tests/TestSuites/FunctionalJavascriptTestSuite.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests\TestSuites; - -require_once __DIR__ . '/TestSuiteBase.php'; - -/** - * Discovers tests for the functional-javascript test suite. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. There is no - * replacement and test discovery will be handled differently in PHPUnit 10. - * - * @see https://www.drupal.org/node/3405829 - */ -class FunctionalJavascriptTestSuite extends TestSuiteBase { - - /** - * Factory method which loads up a suite with all functional javascript tests. - * - * @return static - * The test suite. - */ - public static function suite() { - $root = dirname(__DIR__, 3); - - $suite = new static('functional-javascript'); - $suite->addTestsBySuiteNamespace($root, 'FunctionalJavascript'); - - return $suite; - } - -} diff --git a/core/tests/TestSuites/FunctionalTestSuite.php b/core/tests/TestSuites/FunctionalTestSuite.php deleted file mode 100644 index 20aed98deec65ed359b18248ef0f867bd635a272..0000000000000000000000000000000000000000 --- a/core/tests/TestSuites/FunctionalTestSuite.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests\TestSuites; - -require_once __DIR__ . '/TestSuiteBase.php'; - -/** - * Discovers tests for the functional test suite. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. There is no - * replacement and test discovery will be handled differently in PHPUnit 10. - * - * @see https://www.drupal.org/node/3405829 - */ -class FunctionalTestSuite extends TestSuiteBase { - - /** - * Factory method which loads up a suite with all functional tests. - * - * @return static - * The test suite. - */ - public static function suite() { - $root = dirname(__DIR__, 3); - - $suite = new static('functional'); - $suite->addTestsBySuiteNamespace($root, 'Functional'); - - return $suite; - } - -} diff --git a/core/tests/TestSuites/KernelTestSuite.php b/core/tests/TestSuites/KernelTestSuite.php deleted file mode 100644 index 0916c8528facb8d4b89dcadeca3835e4888a7c2b..0000000000000000000000000000000000000000 --- a/core/tests/TestSuites/KernelTestSuite.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests\TestSuites; - -require_once __DIR__ . '/TestSuiteBase.php'; - -/** - * Discovers tests for the kernel test suite. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. There is no - * replacement and test discovery will be handled differently in PHPUnit 10. - * - * @see https://www.drupal.org/node/3405829 - */ -class KernelTestSuite extends TestSuiteBase { - - /** - * Factory method which loads up a suite with all kernel tests. - * - * @return static - * The test suite. - */ - public static function suite() { - $root = dirname(__DIR__, 3); - - $suite = new static('kernel'); - $suite->addTestsBySuiteNamespace($root, 'Kernel'); - - return $suite; - } - -} diff --git a/core/tests/TestSuites/TestSuiteBase.php b/core/tests/TestSuites/TestSuiteBase.php deleted file mode 100644 index 435116d86584fc5f5616589d5a94bde4c2fcea21..0000000000000000000000000000000000000000 --- a/core/tests/TestSuites/TestSuiteBase.php +++ /dev/null @@ -1,75 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests\TestSuites; - -use Drupal\Core\Test\TestDiscovery; -use PHPUnit\Framework\TestSuite; - -/** - * Base class for Drupal test suites. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. There is no - * replacement and test discovery will be handled differently in PHPUnit 10. - * - * @see https://www.drupal.org/node/3405829 - */ -abstract class TestSuiteBase extends TestSuite { - - /** - * Finds extensions in a Drupal installation. - * - * An extension is defined as a directory with an *.info.yml file in it. - * - * @param string $root - * Path to the root of the Drupal installation. - * - * @return string[] - * Associative array of extension paths, with extension name as keys. - */ - protected function findExtensionDirectories($root) { - $extension_roots = \drupal_phpunit_contrib_extension_directory_roots($root); - - $extension_directories = array_map('drupal_phpunit_find_extension_directories', $extension_roots); - return array_reduce($extension_directories, 'array_merge', []); - } - - /** - * Find and add tests to the suite for core and any extensions. - * - * @param string $root - * Path to the root of the Drupal installation. - * @param string $suite_namespace - * SubNamespace used to separate test suite. Examples: Unit, Functional. - */ - protected function addTestsBySuiteNamespace($root, $suite_namespace) { - // Core's tests are in the namespace Drupal\{$suite_namespace}Tests\ and are - // always inside of core/tests/Drupal/{$suite_namespace}Tests. The exception - // to this is Unit tests for historical reasons. - if ($suite_namespace == 'Unit') { - $tests = TestDiscovery::scanDirectory("Drupal\\Tests\\", "$root/core/tests/Drupal/Tests"); - $tests = array_flip(array_filter(array_flip($tests), function ($test_class) { - // The Listeners directory does not contain tests. Use the class name - // to be compatible with all operating systems. - return !preg_match('/^Drupal\\\\Tests\\\\Listeners\\\\/', $test_class); - })); - $this->addTestFiles($tests); - } - else { - $this->addTestFiles(TestDiscovery::scanDirectory("Drupal\\{$suite_namespace}Tests\\", "$root/core/tests/Drupal/{$suite_namespace}Tests")); - } - - // Extensions' tests will always be in the namespace - // Drupal\Tests\$extension_name\$suite_namespace\ and be in the - // $extension_path/tests/src/$suite_namespace directory. Not all extensions - // will have all kinds of tests. - foreach ($this->findExtensionDirectories($root) as $extension_name => $dir) { - $test_path = "$dir/tests/src/$suite_namespace"; - if (is_dir($test_path)) { - $this->addTestFiles(TestDiscovery::scanDirectory("Drupal\\Tests\\$extension_name\\$suite_namespace\\", $test_path)); - } - } - } - -} diff --git a/core/tests/TestSuites/UnitTestSuite.php b/core/tests/TestSuites/UnitTestSuite.php deleted file mode 100644 index db779652db46c86ab6a67e016affc936e12b4961..0000000000000000000000000000000000000000 --- a/core/tests/TestSuites/UnitTestSuite.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests\TestSuites; - -require_once __DIR__ . '/TestSuiteBase.php'; - -/** - * Discovers tests for the unit test suite. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. There is no - * replacement and test discovery will be handled differently in PHPUnit 10. - * - * @see https://www.drupal.org/node/3405829 - */ -class UnitTestSuite extends TestSuiteBase { - - /** - * Factory method which loads up a suite with all unit tests. - * - * @return static - * The test suite. - */ - public static function suite() { - $root = dirname(__DIR__, 3); - - $suite = new static('unit'); - $suite->addTestsBySuiteNamespace($root, 'Unit'); - - return $suite; - } - -} diff --git a/core/tests/bootstrap.php b/core/tests/bootstrap.php index 05479c1d0e58469714fe7b63e70557555053ed70..56f7cd68a2477b7b8e359bf8a9d4b2b0b7131067 100644 --- a/core/tests/bootstrap.php +++ b/core/tests/bootstrap.php @@ -7,7 +7,11 @@ * @see phpunit.xml.dist */ -use Drupal\TestTools\PhpUnitCompatibility\ClassWriter; +use Drupal\TestTools\ErrorHandler\BootstrapErrorHandler; +use Drupal\TestTools\Extension\DeprecationBridge\DeprecationHandler; +use Drupal\TestTools\Extension\HtmlLogging\HtmlOutputLogger; +use PHPUnit\Runner\ErrorHandler as PhpUnitErrorHandler; +use Symfony\Component\ErrorHandler\DebugClassLoader; /** * Finds all valid extension directories recursively within a given directory. @@ -142,8 +146,6 @@ function drupal_phpunit_populate_class_loader() { $loader = drupal_phpunit_populate_class_loader(); class_alias('\Drupal\Tests\DocumentElement', '\Behat\Mink\Element\DocumentElement', TRUE); -ClassWriter::mutateTestBase($loader); - // Set sane locale settings, to ensure consistent string, dates, times and // numbers handling. // @see \Drupal\Core\DrupalKernel::bootEnvironment() @@ -160,11 +162,26 @@ class_alias('\Drupal\Tests\DocumentElement', '\Behat\Mink\Element\DocumentElemen // reduce the fragility of the testing system in general. date_default_timezone_set('Australia/Sydney'); -// Ensure ignored deprecation patterns listed in .deprecation-ignore.txt are -// considered in testing. -if (getenv('SYMFONY_DEPRECATIONS_HELPER') === FALSE) { - $deprecation_ignore_filename = realpath(__DIR__ . "/../.deprecation-ignore.txt"); - putenv("SYMFONY_DEPRECATIONS_HELPER=ignoreFile=$deprecation_ignore_filename"); +// Bootstrap the DeprecationHandler extension and the DebugClassloader to report +// deprecations in PHPUnit 10+. +if ($deprecationBridgeConfiguration = DeprecationHandler::getConfiguration()) { + DeprecationHandler::init($deprecationBridgeConfiguration['ignoreFile'] ?? NULL); + + // Need to have an early error handler to manage deprecations triggered by + // DebugClassLoader, that occur before tests' setUp() methods are called. + // We pass an instance of the PHPUnit error handler to redirect any error not + // managed by our layer back to PHPUnit. + set_error_handler(new BootstrapErrorHandler(new PhpUnitErrorHandler())); + + // Enable the DebugClassLoader to get deprecations for methods' signature + // changes. + DebugClassLoader::enable(); +} + +// Functional tests HTML output logging. +$browserTestOutputDirectory = getenv('BROWSERTEST_OUTPUT_DIRECTORY'); +if ($browserTestOutputDirectory !== FALSE) { + HtmlOutputLogger::init($browserTestOutputDirectory, (bool) getenv('BROWSERTEST_OUTPUT_VERBOSE') ?? FALSE); } // Drupal expects to be run from its root directory. This ensures all test types