From 275496a1f429fa845880d090c18ad613ae6ae072 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 3 Sep 2020 23:57:37 +0200 Subject: [PATCH 01/15] [Debug] Parse "x not found" errors correctly on php 8. --- .../ClassNotFoundFatalErrorHandler.php | 54 +++++++------------ .../ClassNotFoundFatalErrorHandlerTest.php | 36 +++++++++++++ 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php b/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php index 9bae6f8656..b1216fe7ae 100644 --- a/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php +++ b/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php @@ -29,50 +29,34 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface */ public function handleError(array $error, FatalErrorException $exception) { - $messageLen = \strlen($error['message']); - $notFoundSuffix = '\' not found'; - $notFoundSuffixLen = \strlen($notFoundSuffix); - if ($notFoundSuffixLen > $messageLen) { + if (!preg_match('/^(Class|Interface|Trait) [\'"]([^\'"]+)[\'"] not found$/', $error['message'], $matches)) { return null; } + $typeName = strtolower($matches[1]); + $fullyQualifiedClassName = $matches[2]; - if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) { - return null; + if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) { + $className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1); + $namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex); + $message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix); + $tail = ' for another namespace?'; + } else { + $className = $fullyQualifiedClassName; + $message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className); + $tail = '?'; } - foreach (['class', 'interface', 'trait'] as $typeName) { - $prefix = ucfirst($typeName).' \''; - $prefixLen = \strlen($prefix); - if (0 !== strpos($error['message'], $prefix)) { - continue; - } - - $fullyQualifiedClassName = substr($error['message'], $prefixLen, -$notFoundSuffixLen); - if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) { - $className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1); - $namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex); - $message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix); - $tail = ' for another namespace?'; + if ($candidates = $this->getClassCandidates($className)) { + $tail = array_pop($candidates).'"?'; + if ($candidates) { + $tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail; } else { - $className = $fullyQualifiedClassName; - $message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className); - $tail = '?'; + $tail = ' for "'.$tail; } - - if ($candidates = $this->getClassCandidates($className)) { - $tail = array_pop($candidates).'"?'; - if ($candidates) { - $tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail; - } else { - $tail = ' for "'.$tail; - } - } - $message .= "\nDid you forget a \"use\" statement".$tail; - - return new ClassNotFoundException($message, $exception); } + $message .= "\nDid you forget a \"use\" statement".$tail; - return null; + return new ClassNotFoundException($message, $exception); } /** diff --git a/src/Symfony/Component/Debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php index d408cb43db..2b8a867882 100644 --- a/src/Symfony/Component/Debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php +++ b/src/Symfony/Component/Debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php @@ -80,6 +80,15 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase $debugClassLoader = new DebugClassLoader([$autoloader, 'loadClass']); return [ + [ + [ + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Class "WhizBangFactory" not found', + ], + "/^Attempted to load class \"WhizBangFactory\" from the global namespace.\nDid you forget a \"use\" statement\?$/", + ], [ [ 'type' => 1, @@ -98,6 +107,33 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase ], "/^Attempted to load class \"WhizBangFactory\" from namespace \"Foo\\\\Bar\".\nDid you forget a \"use\" statement for another namespace\?$/", ], + [ + [ + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Class "Foo\\Bar\\WhizBangFactory" not found', + ], + "/^Attempted to load class \"WhizBangFactory\" from namespace \"Foo\\\\Bar\".\nDid you forget a \"use\" statement for another namespace\?$/", + ], + [ + [ + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Interface "Foo\\Bar\\WhizBangInterface" not found', + ], + "/^Attempted to load interface \"WhizBangInterface\" from namespace \"Foo\\\\Bar\".\nDid you forget a \"use\" statement for another namespace\?$/", + ], + [ + [ + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Trait "Foo\\Bar\\WhizBangTrait" not found', + ], + "/^Attempted to load trait \"WhizBangTrait\" from namespace \"Foo\\\\Bar\".\nDid you forget a \"use\" statement for another namespace\?$/", + ], [ [ 'type' => 1, From dd44563004bf7f24a8b1da675ba6f3418186fde1 Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 5 Sep 2020 17:33:22 +0200 Subject: [PATCH 02/15] add bosnian (bs) translation --- .../Resources/translations/validators.bs.xlf | 391 ++++++++++++++++++ 1 file changed, 391 insertions(+) create mode 100644 src/Symfony/Component/Validator/Resources/translations/validators.bs.xlf diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.bs.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.bs.xlf new file mode 100644 index 0000000000..b17eae9ab8 --- /dev/null +++ b/src/Symfony/Component/Validator/Resources/translations/validators.bs.xlf @@ -0,0 +1,391 @@ + + + + + + This value should be false. + Ova vrijednost bi trebalo da bude "netačno" (false). + + + This value should be true. + Ova vrijednost bi trebalo da bude "tačno" (true). + + + This value should be of type {{ type }}. + Ova vrijednost bi trebalo da bude tipa {{ type }}. + + + This value should be blank. + Ova vrijednost bi trebalo da bude prazna. + + + The value you selected is not a valid choice. + Odabrana vrijednost nije validan izbor. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Morate odabrati barem {{ limit }} mogućnost.|Morate odabrati barem {{ limit }} mogućnosti.|Morate odabrati barem {{ limit }} mogućnosti. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Morate odabrati najviše {{ limit }} mogućnost.|Morate odabrati najviše {{ limit }} mogućnosti.|Morate odabrati najviše {{ limit }} mogućnosti. + + + One or more of the given values is invalid. + Jedna ili više datih vrijednosti nisu validne. + + + This field was not expected. + Ovo polje nije očekivano. + + + This field is missing. + Ovo polje nedostaje. + + + This value is not a valid date. + Ova vrijednost nije ispravan datum. + + + This value is not a valid datetime. + Ova vrijednost nije ispravnog datum-vrijeme (datetime) formata. + + + This value is not a valid email address. + Ova vrijednost nije ispravna e-mail adresa. + + + The file could not be found. + Ova datoteka ne može biti pronađena. + + + The file is not readable. + Ova datoteka nije čitljiva. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Ova datoteka je prevelika ({{ size }} {{ suffix }}). Najveća dozvoljena veličina je {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mime tip datoteke nije ispravan ({{ type }}). Dozvoljeni mime tipovi su {{ types }}. + + + This value should be {{ limit }} or less. + Ova vrijednost bi trebalo da bude {{ limit }} ili manje. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Ova vrijednost je predugačka. Trebalo bi da ima {{ limit }} karakter ili manje.|Ova vrijednost je predugačka. Trebalo bi da ima {{ limit }} karaktera ili manje.|Ova vrijednost je predugačka. Trebalo bi da ima {{ limit }} karaktera ili manje. + + + This value should be {{ limit }} or more. + Ova vrijednost bi trebalo da bude {{ limit }} ili više. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Ova vrijednost je prekratka. Trebalo bi da ima {{ limit }} karakter ili više.|Ova vrijednost je prekratka. Trebalo bi da ima {{ limit }} karaktera ili više.|Ova vrijednost je prekratka. Trebalo bi da ima {{ limit }} karaktera ili više. + + + This value should not be blank. + Ova vrijednost ne bi trebalo da bude prazna. + + + This value should not be null. + Ova vrijednost ne bi trebalo da bude null. + + + This value should be null. + Ova vrijednost bi trebalo da bude null. + + + This value is not valid. + Ova vrijednost nije ispravna. + + + This value is not a valid time. + Ova vrijednost nije ispravno vrijeme. + + + This value is not a valid URL. + Ova vrijednost nije ispravan URL. + + + The two values should be equal. + Obje vrijednosti bi trebalo da budu jednake. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Ova datoteka je prevelika. Najveća dozvoljena veličina je {{ limit }} {{ suffix }}. + + + The file is too large. + Ova datoteka je prevelika. + + + The file could not be uploaded. + Ova datoteka ne može biti prenijeta (uploaded). + + + This value should be a valid number. + Ova vrijednost bi trebalo da bude ispravan broj. + + + This file is not a valid image. + Ova datoteka nije validna slika. + + + This is not a valid IP address. + Ovo nije ispravna IP adresa. + + + This value is not a valid language. + Ova vrijednost nije validan jezik. + + + This value is not a valid locale. + Ova vrijednost nije validna regionalna oznaka. + + + This value is not a valid country. + Ova vrijednost nije validna država. + + + This value is already used. + Ova vrijednost je već upotrebljena. + + + The size of the image could not be detected. + Nije moguće otkriti veličinu ove slike. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Širina slike je prevelika ({{ width }}px). Najveća dozvoljena širina je {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Širina slike je premala ({{ width }}px). Najmanja dozvoljena širina je {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Dužina slike je prevelika ({{ height }}px). Najveća dozvoljena dužina je {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Dužina slike je premala ({{ height }}px). Najmanja dozvoljena dužina je {{ min_height }}px. + + + This value should be the user's current password. + Ova vrijednost bi trebalo da bude trenutna korisnička lozinka. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ova vrijednost bi trebalo da ima tačno {{ limit }} karakter.|Ova vrijednost bi trebalo da ima tačno {{ limit }} karaktera. + + + The file was only partially uploaded. + Datoteka je samo djelimično prenijeta (uploaded). + + + No file was uploaded. + Nijedna datoteka nije prenijeta (uploaded). + + + No temporary folder was configured in php.ini. + Privremeni direktorijum nije konfigurisan u datoteci php.ini. + + + Cannot write temporary file to disk. + Privremenu datoteku nije moguće upisati na disk. + + + A PHP extension caused the upload to fail. + Prenos datoteke nije uspio zbog PHP ekstenzije. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ova kolekcija bi trebalo da sadrži {{ limit }} ili više elemenata.|Ova kolekcija bi trebalo da sadrži {{ limit }} ili više elemenata.|Ova kolekcija bi trebalo da sadrži {{ limit }} ili više elemenata. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ova kolekcija bi trebalo da sadrži {{ limit }} ili manje elemenata.|Ova kolekcija bi trebalo da sadrži {{ limit }} ili manje elemenata.|Ova kolekcija bi trebalo da sadrži {{ limit }} ili manje elemenata. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ova kolekcija bi trebalo da sadrži tačno {{ limit }} element.|Ova kolekcija bi trebalo da sadrži tačno {{ limit }} elementa.|Ova kolekcija bi trebalo da sadrži tačno {{ limit }} elemenata. + + + Invalid card number. + Broj kartice je neispravan. + + + Unsupported card type or invalid card number. + Tip kartice nije podržan ili je broj kartice neispravan. + + + This is not a valid International Bank Account Number (IBAN). + Ova vrijednost nije ispravan međunarodni broj bankovnog računa (IBAN). + + + This value is not a valid ISBN-10. + Ova vrijednost nije ispravan ISBN-10. + + + This value is not a valid ISBN-13. + Ova vrijednost nije ispravan ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ova vrijednost nije ispravan ISBN-10 niti ISBN-13. + + + This value is not a valid ISSN. + Ova vrijednost nije ispravan ISSN. + + + This value is not a valid currency. + Ova vrijednost nije ispravna valuta. + + + This value should be equal to {{ compared_value }}. + Ova vrijednost bi trebalo da bude jednaka {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ova vrijednost bi trebalo da bude veća od {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ova vrijednost bi trebalo da bude jednaka ili veća od {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ova vrijednost bi trebalo da bude identična {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ova vrijednost bi trebalo da bude manja od {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ova vrijednost bi trebalo da bude jednaka ili manja od {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ova vrijednost bi trebalo da bude različita od {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ova vrijednost bi trebalo da bude identična sa {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Razmjera ove slike je prevelika ({{ ratio }}). Maksimalna dozvoljena razmjera je {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Razmjera ove slike je premala ({{ ratio }}). Minimalna očekivana razmjera je {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Ova slika je kvadratnog oblika ({{ width }}x{{ height }}px). Kvadratne slike nisu dozvoljene. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Ova slika je orijentisana horizontalno (landscape) ({{ width }}x{{ height }}px). Horizontalno orijentisane slike nisu dozvoljene. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Ova slika je orijentisana vertikalno (portrait) ({{ width }}x{{ height }}px). Vertikalno orijentisane slike nisu dozvoljene. + + + An empty file is not allowed. + Prazna datoteka nije dozvoljena. + + + The host could not be resolved. + Nije moguće odrediti poslužitelja (host). + + + This value does not match the expected {{ charset }} charset. + Ova vrijednost ne odgovara očekivanom {{ charset }} setu karaktera (charset). + + + This is not a valid Business Identifier Code (BIC). + Ovo nije validan poslovni identifikacioni kod (BIC). + + + Error + Greška + + + This is not a valid UUID. + Ovo nije validan UUID. + + + This value should be a multiple of {{ compared_value }}. + Ova vrijednost bi trebalo da bude djeljiva sa {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Ovaj poslovni identifikacioni kod (BIC) nije povezan sa IBAN-om {{ iban }}. + + + This value should be valid JSON. + Ova vrijednost bi trebalo da bude validan JSON. + + + This collection should contain only unique elements. + Ova kolekcija bi trebala da sadrži samo jedinstvene elemente. + + + This value should be positive. + Ova vrijednost bi trebalo da bude pozitivna. + + + This value should be either positive or zero. + Ova vrijednost bi trebalo da bude pozitivna ili jednaka nuli. + + + This value should be negative. + Ova vrijednost bi trebalo da bude negativna. + + + This value should be either negative or zero. + Ova vrijednost bi trebalo da bude negativna ili jednaka nuli. + + + This value is not a valid timezone. + Ova vrijednost nije validna vremenska zona. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Ova lozinka je procurila u nekom od slučajeva kompromitovanja podataka, nemojte je koristiti. Koristite drugu lozinku. + + + This value should be between {{ min }} and {{ max }}. + Ova vrijednosti bi trebala biti između {{ min }} i {{ max }}. + + + This value is not a valid hostname. + Ova vrijednost nije ispravno ime poslužitelja (hostname). + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Broj elemenata u ovoj kolekciji bi trebalo da bude djeljiv sa {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Ova vrijednost bi trebalo da zadovoljava namjanje jedno od narednih ograničenja: + + + Each element of this collection should satisfy its own set of constraints. + Svaki element ove kolekcije bi trebalo da zadovolji sopstveni skup ograničenja. + + + This value is not a valid International Securities Identification Number (ISIN). + Ova vrijednost nije ispravna međunarodna identifikaciona oznaka hartija od vrijednosti (ISIN). + + + + From 99c98bd716497ef70d198e264524bb62b2342a43 Mon Sep 17 00:00:00 2001 From: Alexey Kopytko Date: Fri, 4 Sep 2020 04:00:36 +0900 Subject: [PATCH 03/15] [PhpUnitBridge] CoverageListenerTrait update for PHPUnit 8.5/9.x --- .../PhpUnit/Legacy/CoverageListenerTrait.php | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php index ce5538f62d..2482b06585 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php @@ -13,6 +13,7 @@ namespace Symfony\Bridge\PhpUnit\Legacy; use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Warning; +use PHPUnit\Util\Annotation\Registry; /** * PHP 5.3 compatible trait-like shared implementation. @@ -70,9 +71,6 @@ class CoverageListenerTrait $testClass = \PHPUnit_Util_Test::class; } - $r = new \ReflectionProperty($testClass, 'annotationCache'); - $r->setAccessible(true); - $covers = $sutFqcn; if (!\is_array($sutFqcn)) { $covers = array($sutFqcn); @@ -82,6 +80,20 @@ class CoverageListenerTrait } } + if (class_exists(Registry::class)) { + $this->addCoversForDocBlockInsideRegistry($test, $covers); + + return; + } + + $this->addCoversForClassToAnnotationCache($testClass, $test, $covers); + } + + private function addCoversForClassToAnnotationCache($testClass, $test, $covers) + { + $r = new \ReflectionProperty($testClass, 'annotationCache'); + $r->setAccessible(true); + $cache = $r->getValue(); $cache = array_replace_recursive($cache, array( \get_class($test) => array( @@ -91,6 +103,18 @@ class CoverageListenerTrait $r->setValue($testClass, $cache); } + private function addCoversForDocBlockInsideRegistry($test, $covers) + { + $docBlock = Registry::getInstance()->forClassName(\get_class($test)); + + $symbolAnnotations = new \ReflectionProperty($docBlock, 'symbolAnnotations'); + $symbolAnnotations->setAccessible(true); + + $symbolAnnotations->setValue($docBlock, array_replace($docBlock->symbolAnnotations(), array( + 'covers' => $covers, + ))); + } + private function findSutFqcn($test) { if ($this->sutFqcnResolver) { From a3831dc0f25108fe888ec4f356127aeec4c01018 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 5 Sep 2020 18:04:17 +0200 Subject: [PATCH 04/15] [PhpUnitBridge] Adjust output parsing for PHPUnit 9.3. --- .../Bridge/PhpUnit/Tests/CoverageListenerTest.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/Tests/CoverageListenerTest.php b/src/Symfony/Bridge/PhpUnit/Tests/CoverageListenerTest.php index d69aee7037..3882b77ce7 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/CoverageListenerTest.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/CoverageListenerTest.php @@ -31,13 +31,19 @@ class CoverageListenerTest extends TestCase $dir = __DIR__.'/../Tests/Fixtures/coverage'; $phpunit = $_SERVER['argv'][0]; - exec("$php $phpunit -c $dir/phpunit-without-listener.xml.dist $dir/tests/ --coverage-text 2> /dev/null", $output); + exec("$php $phpunit -c $dir/phpunit-without-listener.xml.dist $dir/tests/ --coverage-text --colors=never 2> /dev/null", $output); $output = implode("\n", $output); - $this->assertStringContainsString('FooCov', $output); + $this->assertMatchesRegularExpression('/FooCov\n\s*Methods:\s+100.00%[^\n]+Lines:\s+100.00%/', $output); - exec("$php $phpunit -c $dir/phpunit-with-listener.xml.dist $dir/tests/ --coverage-text 2> /dev/null", $output); + exec("$php $phpunit -c $dir/phpunit-with-listener.xml.dist $dir/tests/ --coverage-text --colors=never 2> /dev/null", $output); $output = implode("\n", $output); - $this->assertStringNotContainsString('FooCov', $output); + + if (false === strpos($output, 'FooCov')) { + $this->addToAssertionCount(1); + } else { + $this->assertMatchesRegularExpression('/FooCov\n\s*Methods:\s+0.00%[^\n]+Lines:\s+0.00%/', $output); + } + $this->assertStringContainsString("SutNotFoundTest::test\nCould not find the tested class.", $output); $this->assertStringNotContainsString("CoversTest::test\nCould not find the tested class.", $output); $this->assertStringNotContainsString("CoversDefaultClassTest::test\nCould not find the tested class.", $output); From 7f1055b97c61c6be941371bbe38270fc048c988f Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 5 Sep 2020 18:44:57 +0200 Subject: [PATCH 05/15] [Intl] Skip test cases that produce a TypeError on php 8. --- .../AbstractNumberFormatterTest.php | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php b/src/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php index 0f2a7c4b53..dd6a300c55 100644 --- a/src/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php +++ b/src/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php @@ -377,14 +377,16 @@ abstract class AbstractNumberFormatterTest extends TestCase public function formatFractionDigitsProvider() { - return [ - [1.123, '1.123', null, 0], - [1.123, '1', 0, 0], - [1.123, '1.1', 1, 1], - [1.123, '1.12', 2, 2], - [1.123, '1.123', -1, 0], - [1.123, '1', 'abc', 0], - ]; + yield [1.123, '1.123', null, 0]; + yield [1.123, '1', 0, 0]; + yield [1.123, '1.1', 1, 1]; + yield [1.123, '1.12', 2, 2]; + yield [1.123, '1.123', -1, 0]; + + if (\PHP_VERSION_ID < 80000) { + // This dataset will produce a TypeError on php 8. + yield [1.123, '1', 'abc', 0]; + } } /** @@ -410,14 +412,16 @@ abstract class AbstractNumberFormatterTest extends TestCase public function formatGroupingUsedProvider() { - return [ - [1000, '1,000', null, 1], - [1000, '1000', 0, 0], - [1000, '1,000', 1, 1], - [1000, '1,000', 2, 1], - [1000, '1000', 'abc', 0], - [1000, '1,000', -1, 1], - ]; + yield [1000, '1,000', null, 1]; + yield [1000, '1000', 0, 0]; + yield [1000, '1,000', 1, 1]; + yield [1000, '1,000', 2, 1]; + yield [1000, '1,000', -1, 1]; + + if (\PHP_VERSION_ID < 80000) { + // This dataset will produce a TypeError on php 8. + yield [1000, '1000', 'abc', 0]; + } } /** From ab45e2aaae2e612d4fb8646edde028fd754b4f2b Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 5 Sep 2020 19:37:15 +0200 Subject: [PATCH 06/15] [VarDumper] Fix caster for invalid SplFileInfo objects on php 8. --- .../Component/VarDumper/Caster/SplCaster.php | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/VarDumper/Caster/SplCaster.php b/src/Symfony/Component/VarDumper/Caster/SplCaster.php index 53df3de239..7ecbb577d2 100644 --- a/src/Symfony/Component/VarDumper/Caster/SplCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/SplCaster.php @@ -92,10 +92,24 @@ class SplCaster unset($a["\0SplFileInfo\0fileName"]); unset($a["\0SplFileInfo\0pathName"]); - if (false === $c->getPathname()) { - $a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state'; + if (\PHP_VERSION_ID < 80000) { + if (false === $c->getPathname()) { + $a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state'; - return $a; + return $a; + } + } else { + try { + $c->isReadable(); + } catch (\RuntimeException $e) { + if ('Object not initialized' !== $e->getMessage()) { + throw $e; + } + + $a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state'; + + return $a; + } } foreach ($map as $key => $accessor) { From 4fcd4916ede15ca2df594e54f3193505a0558553 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 6 Sep 2020 21:31:28 +0200 Subject: [PATCH 07/15] [Console] Make sure $maxAttempts is an int or null. --- src/Symfony/Component/Console/Question/Question.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Console/Question/Question.php b/src/Symfony/Component/Console/Question/Question.php index 06464e135b..7d016ecea9 100644 --- a/src/Symfony/Component/Console/Question/Question.php +++ b/src/Symfony/Component/Console/Question/Question.php @@ -188,8 +188,11 @@ class Question */ public function setMaxAttempts($attempts) { - if (null !== $attempts && $attempts < 1) { - throw new InvalidArgumentException('Maximum number of attempts must be a positive value.'); + if (null !== $attempts) { + $attempts = (int) $attempts; + if ($attempts < 1) { + throw new InvalidArgumentException('Maximum number of attempts must be a positive value.'); + } } $this->attempts = $attempts; From a3275a7be9e91858aa1dd8429b52cdd34f726e10 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Sep 2020 14:07:49 +0200 Subject: [PATCH 08/15] [DI] fix ContainerBuilder on PHP8 --- src/Symfony/Component/DependencyInjection/ContainerBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index d9115bf8bf..97617cb04e 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -1173,7 +1173,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface } else { $r = new \ReflectionClass($class = $parameterBag->resolveValue($definition->getClass())); - $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments); + $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs(array_values($arguments)); // don't trigger deprecations for internal uses // @deprecated since version 3.3, to be removed in 4.0 along with the deprecated class $deprecationAllowlist = ['event_dispatcher' => ContainerAwareEventDispatcher::class]; From 3feff7218667ff0a98cf587e82ba286e318e40f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4dlich?= Date: Mon, 7 Sep 2020 17:24:28 +0200 Subject: [PATCH 09/15] remove unnecessary check for existing request --- .../Bundle/FrameworkBundle/Test/MailerAssertionsTrait.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/MailerAssertionsTrait.php b/src/Symfony/Bundle/FrameworkBundle/Test/MailerAssertionsTrait.php index 24d98b88eb..d0ca84e25a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/MailerAssertionsTrait.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/MailerAssertionsTrait.php @@ -118,10 +118,6 @@ trait MailerAssertionsTrait private static function getMessageMailerEvents(): MessageEvents { - if (!self::getClient()->getRequest()) { - static::fail('Unable to make email assertions. Did you forget to make an HTTP request?'); - } - if (!self::$container->has('mailer.logger_message_listener')) { static::fail('A client must have Mailer enabled to make email assertions. Did you forget to require symfony/mailer?'); } From c7dcd82f035cf3492e2687d56b276522f9a33904 Mon Sep 17 00:00:00 2001 From: Julien Falque Date: Mon, 7 Sep 2020 20:13:13 +0200 Subject: [PATCH 10/15] Prevent parsing invalid octal digits as octal numbers --- src/Symfony/Component/Yaml/Inline.php | 8 ++++---- src/Symfony/Component/Yaml/Tests/InlineTest.php | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index a5c520eb80..5f8fd55c79 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -759,16 +759,16 @@ class Inline switch (true) { case ctype_digit($scalar): - if ('0' === $scalar[0]) { - return octdec(preg_replace('/[^0-7]/', '', $scalar)); + if (preg_match('/^0[0-7]+$/', $scalar)) { + return octdec($scalar); } $cast = (int) $scalar; return ($scalar === (string) $cast) ? $cast : $scalar; case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)): - if ('0' === $scalar[1]) { - return -octdec(preg_replace('/[^0-7]/', '', substr($scalar, 1))); + if (preg_match('/^-0[0-7]+$/', $scalar)) { + return -octdec(substr($scalar, 1)); } $cast = (int) $scalar; diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index 32c6a681ce..d1eb2f7a5d 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -853,11 +853,11 @@ class InlineTest extends TestCase public function testParsePositiveOctalNumberContainingInvalidDigits() { - self::assertSame(342391, Inline::parse('0123456789')); + self::assertSame('0123456789', Inline::parse('0123456789')); } public function testParseNegativeOctalNumberContainingInvalidDigits() { - self::assertSame(-342391, Inline::parse('-0123456789')); + self::assertSame('-0123456789', Inline::parse('-0123456789')); } } From d9c9aea7eeb953d13fed63a982da1f0bce29face Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Mon, 7 Sep 2020 20:45:32 +0200 Subject: [PATCH 11/15] [ErrorHandler] Parse "x not found" errors correctly on php 8. --- .../ClassNotFoundErrorEnhancer.php | 54 +++++++------------ .../ClassNotFoundErrorEnhancerTest.php | 16 ++++++ 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/Symfony/Component/ErrorHandler/ErrorEnhancer/ClassNotFoundErrorEnhancer.php b/src/Symfony/Component/ErrorHandler/ErrorEnhancer/ClassNotFoundErrorEnhancer.php index 38111078bc..96a58be800 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorEnhancer/ClassNotFoundErrorEnhancer.php +++ b/src/Symfony/Component/ErrorHandler/ErrorEnhancer/ClassNotFoundErrorEnhancer.php @@ -29,50 +29,34 @@ class ClassNotFoundErrorEnhancer implements ErrorEnhancerInterface { // Some specific versions of PHP produce a fatal error when extending a not found class. $message = !$error instanceof FatalError ? $error->getMessage() : $error->getError()['message']; - $messageLen = \strlen($message); - $notFoundSuffix = '\' not found'; - $notFoundSuffixLen = \strlen($notFoundSuffix); - if ($notFoundSuffixLen > $messageLen) { + if (!preg_match('/^(Class|Interface|Trait) [\'"]([^\'"]+)[\'"] not found$/', $message, $matches)) { return null; } + $typeName = strtolower($matches[1]); + $fullyQualifiedClassName = $matches[2]; - if (0 !== substr_compare($message, $notFoundSuffix, -$notFoundSuffixLen)) { - return null; + if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) { + $className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1); + $namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex); + $message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix); + $tail = ' for another namespace?'; + } else { + $className = $fullyQualifiedClassName; + $message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className); + $tail = '?'; } - foreach (['class', 'interface', 'trait'] as $typeName) { - $prefix = ucfirst($typeName).' \''; - $prefixLen = \strlen($prefix); - if (0 !== strpos($message, $prefix)) { - continue; - } - - $fullyQualifiedClassName = substr($message, $prefixLen, -$notFoundSuffixLen); - if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) { - $className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1); - $namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex); - $message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix); - $tail = ' for another namespace?'; + if ($candidates = $this->getClassCandidates($className)) { + $tail = array_pop($candidates).'"?'; + if ($candidates) { + $tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail; } else { - $className = $fullyQualifiedClassName; - $message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className); - $tail = '?'; + $tail = ' for "'.$tail; } - - if ($candidates = $this->getClassCandidates($className)) { - $tail = array_pop($candidates).'"?'; - if ($candidates) { - $tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail; - } else { - $tail = ' for "'.$tail; - } - } - $message .= "\nDid you forget a \"use\" statement".$tail; - - return new ClassNotFoundError($message, $error); } + $message .= "\nDid you forget a \"use\" statement".$tail; - return null; + return new ClassNotFoundError($message, $error); } /** diff --git a/src/Symfony/Component/ErrorHandler/Tests/ErrorEnhancer/ClassNotFoundErrorEnhancerTest.php b/src/Symfony/Component/ErrorHandler/Tests/ErrorEnhancer/ClassNotFoundErrorEnhancerTest.php index eefba23fa6..1ca2f162b9 100644 --- a/src/Symfony/Component/ErrorHandler/Tests/ErrorEnhancer/ClassNotFoundErrorEnhancerTest.php +++ b/src/Symfony/Component/ErrorHandler/Tests/ErrorEnhancer/ClassNotFoundErrorEnhancerTest.php @@ -81,14 +81,30 @@ class ClassNotFoundErrorEnhancerTest extends TestCase $debugClassLoader = new DebugClassLoader([$autoloader, 'loadClass']); return [ + [ + 'Class "WhizBangFactory" not found', + "Attempted to load class \"WhizBangFactory\" from the global namespace.\nDid you forget a \"use\" statement?", + ], [ 'Class \'WhizBangFactory\' not found', "Attempted to load class \"WhizBangFactory\" from the global namespace.\nDid you forget a \"use\" statement?", ], + [ + 'Class "Foo\\Bar\\WhizBangFactory" not found', + "Attempted to load class \"WhizBangFactory\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?", + ], [ 'Class \'Foo\\Bar\\WhizBangFactory\' not found', "Attempted to load class \"WhizBangFactory\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?", ], + [ + 'Interface "Foo\\Bar\\WhizBangInterface" not found', + "Attempted to load interface \"WhizBangInterface\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?", + ], + [ + 'Trait "Foo\\Bar\\WhizBangTrait" not found', + "Attempted to load trait \"WhizBangTrait\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?", + ], [ 'Class \'UndefinedFunctionError\' not found', "Attempted to load class \"UndefinedFunctionError\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony\Component\ErrorHandler\Error\UndefinedFunctionError\"?", From 65112e11bc36264de842a12355136a2b5ed1a48e Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Mon, 7 Sep 2020 21:30:36 +0200 Subject: [PATCH 12/15] [VarExporter] unserialize() might throw an Exception on php 8. --- .../Exception/NotInstantiableTypeException.php | 4 ++-- .../Component/VarExporter/Internal/Registry.php | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/VarExporter/Exception/NotInstantiableTypeException.php b/src/Symfony/Component/VarExporter/Exception/NotInstantiableTypeException.php index 7ca4884596..771ee612db 100644 --- a/src/Symfony/Component/VarExporter/Exception/NotInstantiableTypeException.php +++ b/src/Symfony/Component/VarExporter/Exception/NotInstantiableTypeException.php @@ -13,8 +13,8 @@ namespace Symfony\Component\VarExporter\Exception; class NotInstantiableTypeException extends \Exception implements ExceptionInterface { - public function __construct(string $type) + public function __construct(string $type, \Throwable $previous = null) { - parent::__construct(sprintf('Type "%s" is not instantiable.', $type)); + parent::__construct(sprintf('Type "%s" is not instantiable.', $type), 0, $previous); } } diff --git a/src/Symfony/Component/VarExporter/Internal/Registry.php b/src/Symfony/Component/VarExporter/Internal/Registry.php index 19d91c9304..49f3c4833a 100644 --- a/src/Symfony/Component/VarExporter/Internal/Registry.php +++ b/src/Symfony/Component/VarExporter/Internal/Registry.php @@ -89,8 +89,18 @@ class Registry $proto = $reflector->implementsInterface('Serializable') && !method_exists($class, '__unserialize') ? 'C:' : 'O:'; if ('C:' === $proto && !$reflector->getMethod('unserialize')->isInternal()) { $proto = null; - } elseif (false === $proto = @unserialize($proto.\strlen($class).':"'.$class.'":0:{}')) { - throw new NotInstantiableTypeException($class); + } else { + try { + $proto = @unserialize($proto.\strlen($class).':"'.$class.'":0:{}'); + } catch (\Exception $e) { + if (__FILE__ !== $e->getFile()) { + throw $e; + } + throw new NotInstantiableTypeException($class, $e); + } + if (false === $proto) { + throw new NotInstantiableTypeException($class); + } } } if (null !== $proto && !$proto instanceof \Throwable && !$proto instanceof \Serializable && !method_exists($class, '__sleep') && (\PHP_VERSION_ID < 70400 || !method_exists($class, '__serialize'))) { From a0dedb9aa69addd276d33385b46b8f3f043199e1 Mon Sep 17 00:00:00 2001 From: Alexey Kopytko Date: Tue, 8 Sep 2020 00:10:35 +0900 Subject: [PATCH 13/15] [PhpUnitBridge] Skip internal classes in CoverageListenerTrait --- .../Bridge/PhpUnit/Legacy/CoverageListenerTrait.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php index ba369e43f8..bd8a452777 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php @@ -107,6 +107,13 @@ class CoverageListenerTrait $symbolAnnotations = new \ReflectionProperty($docBlock, 'symbolAnnotations'); $symbolAnnotations->setAccessible(true); + // Exclude internal classes; PHPUnit 9.1+ is picky about tests covering, say, a \RuntimeException + $covers = array_filter($covers, function ($class) { + $reflector = new ReflectionClass($class); + + return $reflector->isUserDefined(); + }); + $symbolAnnotations->setValue($docBlock, array_replace($docBlock->symbolAnnotations(), [ 'covers' => $covers, ])); From afc11684e06018cbece159bf67a44dc7d761b239 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 8 Sep 2020 10:26:11 +0200 Subject: [PATCH 14/15] consistently use same types for strict comparisons --- .../DependencyInjection/Tests/Loader/XmlFileLoaderTest.php | 6 ++---- .../DependencyInjection/Tests/Loader/YamlFileLoaderTest.php | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index 75f95973e5..1df8d536ee 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -675,7 +675,7 @@ class XmlFileLoaderTest extends TestCase sort($ids); $this->assertSame([Prototype\Foo::class, Prototype\Sub\Bar::class, 'service_container'], $ids); - $resources = $container->getResources(); + $resources = array_map('strval', $container->getResources()); $fixturesDir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR; $this->assertContains((string) new FileResource($fixturesDir.'xml'.\DIRECTORY_SEPARATOR.'services_prototype.xml'), $resources); @@ -693,7 +693,6 @@ class XmlFileLoaderTest extends TestCase ] ); $this->assertContains((string) $globResource, $resources); - $resources = array_map('strval', $resources); $this->assertContains('reflection.Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo', $resources); $this->assertContains('reflection.Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar', $resources); } @@ -708,7 +707,7 @@ class XmlFileLoaderTest extends TestCase sort($ids); $this->assertSame([Prototype\Foo::class, Prototype\Sub\Bar::class, 'service_container'], $ids); - $resources = $container->getResources(); + $resources = array_map('strval', $container->getResources()); $fixturesDir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR; $this->assertContains((string) new FileResource($fixturesDir.'xml'.\DIRECTORY_SEPARATOR.'services_prototype_array.xml'), $resources); @@ -726,7 +725,6 @@ class XmlFileLoaderTest extends TestCase ] ); $this->assertContains((string) $globResource, $resources); - $resources = array_map('strval', $resources); $this->assertContains('reflection.Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo', $resources); $this->assertContains('reflection.Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar', $resources); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index 5be22f05be..507a7f0220 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -451,7 +451,7 @@ class YamlFileLoaderTest extends TestCase sort($ids); $this->assertSame([Prototype\Foo::class, Prototype\Sub\Bar::class, 'service_container'], $ids); - $resources = $container->getResources(); + $resources = array_map('strval', $container->getResources()); $fixturesDir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR; $this->assertContains((string) new FileResource($fixturesDir.'yaml'.\DIRECTORY_SEPARATOR.'services_prototype.yml'), $resources); @@ -468,7 +468,6 @@ class YamlFileLoaderTest extends TestCase ] ); $this->assertContains((string) $globResource, $resources); - $resources = array_map('strval', $resources); $this->assertContains('reflection.Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo', $resources); $this->assertContains('reflection.Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar', $resources); } From 16a76739c02c332df1590ef38e28343970d30ed3 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 8 Sep 2020 15:04:06 +0200 Subject: [PATCH 15/15] [Debug] fix test --- .../FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php index 38fb181f0c..03ada95c84 100644 --- a/src/Symfony/Component/Debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php +++ b/src/Symfony/Component/Debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php @@ -68,7 +68,7 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase } $this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $exception); - $this->assertEquals($translatedMessage, $exception->getMessage()); + $this->assertMatchesRegularExpression($translatedMessage, $exception->getMessage()); $this->assertSame($error['type'], $exception->getSeverity()); $this->assertSame($error['file'], $exception->getFile()); $this->assertSame($error['line'], $exception->getLine());