diff --git a/src/Symfony/Bridge/PhpUnit/CHANGELOG.md b/src/Symfony/Bridge/PhpUnit/CHANGELOG.md index 17c3f201bf..43f562ed39 100644 --- a/src/Symfony/Bridge/PhpUnit/CHANGELOG.md +++ b/src/Symfony/Bridge/PhpUnit/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +5.1.0 +----- + + * ignore verbosity settings when the build fails because of deprecations + * added per-group verbosity + 5.0.0 ----- diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index 0b14604d5a..ea426c377a 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\TestResult; use PHPUnit\Util\ErrorHandler; use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Configuration; use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Deprecation; +use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\DeprecationGroup; use Symfony\Component\ErrorHandler\DebugClassLoader; /** @@ -30,24 +31,20 @@ class DeprecationErrorHandler private $mode; private $configuration; - private $deprecations = [ - 'unsilencedCount' => 0, - 'remaining selfCount' => 0, - 'legacyCount' => 0, - 'otherCount' => 0, - 'remaining directCount' => 0, - 'remaining indirectCount' => 0, - 'unsilenced' => [], - 'remaining self' => [], - 'legacy' => [], - 'other' => [], - 'remaining direct' => [], - 'remaining indirect' => [], - ]; + + /** + * @var DeprecationGroup[] + */ + private $deprecationGroups = []; private static $isRegistered = false; private static $isAtLeastPhpUnit83; + public function __construct() + { + $this->resetDeprecationGroups(); + } + /** * Registers and configures the deprecation handler. * @@ -135,9 +132,9 @@ class DeprecationErrorHandler $group = 'legacy'; } else { $group = [ - Deprecation::TYPE_SELF => 'remaining self', - Deprecation::TYPE_DIRECT => 'remaining direct', - Deprecation::TYPE_INDIRECT => 'remaining indirect', + Deprecation::TYPE_SELF => 'self', + Deprecation::TYPE_DIRECT => 'direct', + Deprecation::TYPE_INDIRECT => 'indirect', Deprecation::TYPE_UNDETERMINED => 'other', ][$deprecation->getType()]; } @@ -148,18 +145,14 @@ class DeprecationErrorHandler exit(1); } if ('legacy' !== $group) { - $ref = &$this->deprecations[$group][$msg]['count']; - ++$ref; - $ref = &$this->deprecations[$group][$msg][$class.'::'.$method]; - ++$ref; + $this->deprecationGroups[$group]->addNoticeFromObject($msg, $class, $method); + } else { + $this->deprecationGroups[$group]->addNotice(); } } else { - $ref = &$this->deprecations[$group][$msg]['count']; - ++$ref; + $this->deprecationGroups[$group]->addNoticeFromProceduralCode($msg); } - ++$this->deprecations[$group.'Count']; - return null; } @@ -184,34 +177,44 @@ class DeprecationErrorHandler echo "\n", self::colorize('THE ERROR HANDLER HAS CHANGED!', true), "\n"; } - $groups = ['unsilenced', 'remaining self', 'remaining direct', 'remaining indirect', 'legacy', 'other']; - - $this->displayDeprecations($groups, $configuration); + $groups = array_keys($this->deprecationGroups); // store failing status - $isFailing = !$configuration->tolerates($this->deprecations); + $isFailing = !$configuration->tolerates($this->deprecationGroups); - // reset deprecations array - foreach ($this->deprecations as $group => $arrayOrInt) { - $this->deprecations[$group] = \is_int($arrayOrInt) ? 0 : []; - } + $this->displayDeprecations($groups, $configuration, $isFailing); + + $this->resetDeprecationGroups(); register_shutdown_function(function () use ($isFailing, $groups, $configuration) { - foreach ($this->deprecations as $group => $arrayOrInt) { - if (0 < (\is_int($arrayOrInt) ? $arrayOrInt : \count($arrayOrInt))) { + foreach ($this->deprecationGroups as $group) { + if ($group->count() > 0) { echo "Shutdown-time deprecations:\n"; break; } } - $this->displayDeprecations($groups, $configuration); + $isFailingAtShutdown = !$configuration->tolerates($this->deprecationGroups); + $this->displayDeprecations($groups, $configuration, $isFailingAtShutdown); - if ($isFailing || !$configuration->tolerates($this->deprecations)) { + if ($isFailing || $isFailingAtShutdown) { exit(1); } }); } + private function resetDeprecationGroups() + { + $this->deprecationGroups = [ + 'unsilenced' => new DeprecationGroup(), + 'self' => new DeprecationGroup(), + 'direct' => new DeprecationGroup(), + 'indirect' => new DeprecationGroup(), + 'legacy' => new DeprecationGroup(), + 'other' => new DeprecationGroup(), + ]; + } + private function getConfiguration() { if (null !== $this->configuration) { @@ -270,31 +273,38 @@ class DeprecationErrorHandler /** * @param string[] $groups * @param Configuration $configuration + * @param bool $isFailing */ - private function displayDeprecations($groups, $configuration) + private function displayDeprecations($groups, $configuration, $isFailing) { $cmp = function ($a, $b) { - return $b['count'] - $a['count']; + return $b->count() - $a->count(); }; foreach ($groups as $group) { - if ($this->deprecations[$group.'Count']) { + if ($this->deprecationGroups[$group]->count()) { echo "\n", self::colorize( - sprintf('%s deprecation notices (%d)', ucfirst($group), $this->deprecations[$group.'Count']), - 'legacy' !== $group && 'remaining indirect' !== $group + sprintf( + '%s deprecation notices (%d)', + \in_array($group, ['direct', 'indirect', 'self'], true) ? "Remaining $group" : ucfirst($group), + $this->deprecationGroups[$group]->count() + ), + 'legacy' !== $group && 'indirect' !== $group ), "\n"; - if (!$configuration->verboseOutput()) { + if ('legacy' !== $group && !$configuration->verboseOutput($group) && !$isFailing) { continue; } - uasort($this->deprecations[$group], $cmp); + $notices = $this->deprecationGroups[$group]->notices(); + uasort($notices, $cmp); - foreach ($this->deprecations[$group] as $msg => $notices) { - echo "\n ", $notices['count'], 'x: ', $msg, "\n"; + foreach ($notices as $msg => $notice) { + echo "\n ", $notice->count(), 'x: ', $msg, "\n"; - arsort($notices); + $countsByCaller = $notice->getCountsByCaller(); + arsort($countsByCaller); - foreach ($notices as $method => $count) { + foreach ($countsByCaller as $method => $count) { if ('count' !== $method) { echo ' ', $count, 'x in ', preg_replace('/(.*)\\\\(.*?::.*?)$/', '$2 from $1', $method), "\n"; } diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php index 6b42814bbc..75c7bf888c 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php @@ -32,17 +32,17 @@ class Configuration private $enabled = true; /** - * @var bool + * @var bool[] */ - private $verboseOutput = true; + private $verboseOutput; /** * @param int[] $thresholds A hash associating groups to thresholds * @param string $regex Will be matched against messages, to decide * whether to display a stack trace - * @param bool $verboseOutput + * @param bool[] $verboseOutput Keyed by groups */ - private function __construct(array $thresholds = [], $regex = '', $verboseOutput = true) + private function __construct(array $thresholds = [], $regex = '', $verboseOutput = []) { $groups = ['total', 'indirect', 'direct', 'self']; @@ -72,7 +72,21 @@ class Configuration } } $this->regex = $regex; - $this->verboseOutput = $verboseOutput; + + $this->verboseOutput = [ + 'unsilenced' => true, + 'direct' => true, + 'indirect' => true, + 'self' => true, + 'other' => true, + ]; + + foreach ($verboseOutput as $group => $status) { + if (!isset($this->verboseOutput[$group])) { + throw new \InvalidArgumentException(sprintf('Unsupported verbosity group "%s", expected one of "%s"', $group, implode('", "', array_keys($this->verboseOutput)))); + } + $this->verboseOutput[$group] = (bool) $status; + } } /** @@ -84,24 +98,26 @@ class Configuration } /** - * @param mixed[] $deprecations + * @param DeprecationGroup[] $deprecationGroups * * @return bool */ - public function tolerates(array $deprecations) + public function tolerates(array $deprecationGroups) { - $deprecationCounts = []; - foreach ($deprecations as $key => $deprecation) { - if (false !== strpos($key, 'Count') && false === strpos($key, 'legacy')) { - $deprecationCounts[$key] = $deprecation; + $grandTotal = 0; + + foreach ($deprecationGroups as $name => $group) { + if ('legacy' !== $name) { + $grandTotal += $group->count(); } } - if (array_sum($deprecationCounts) > $this->thresholds['total']) { + if ($grandTotal > $this->thresholds['total']) { return false; } + foreach (['self', 'direct', 'indirect'] as $deprecationType) { - if ($deprecationCounts['remaining '.$deprecationType.'Count'] > $this->thresholds[$deprecationType]) { + if ($deprecationGroups[$deprecationType]->count() > $this->thresholds[$deprecationType]) { return false; } } @@ -130,9 +146,9 @@ class Configuration /** * @return bool */ - public function verboseOutput() + public function verboseOutput($group) { - return $this->verboseOutput; + return $this->verboseOutput[$group]; } /** @@ -145,7 +161,7 @@ class Configuration { parse_str($serializedConfiguration, $normalizedConfiguration); foreach (array_keys($normalizedConfiguration) as $key) { - if (!\in_array($key, ['max', 'disabled', 'verbose'], true)) { + if (!\in_array($key, ['max', 'disabled', 'verbose', 'quiet'], true)) { throw new \InvalidArgumentException(sprintf('Unknown configuration option "%s"', $key)); } } @@ -154,9 +170,19 @@ class Configuration return self::inDisabledMode(); } - $verboseOutput = true; - if (isset($normalizedConfiguration['verbose'])) { - $verboseOutput = (bool) $normalizedConfiguration['verbose']; + $verboseOutput = []; + if (!isset($normalizedConfiguration['verbose'])) { + $normalizedConfiguration['verbose'] = true; + } + + foreach (['unsilenced', 'direct', 'indirect', 'self', 'other'] as $group) { + $verboseOutput[$group] = (bool) $normalizedConfiguration['verbose']; + } + + if (isset($normalizedConfiguration['quiet']) && \is_array($normalizedConfiguration['quiet'])) { + foreach ($normalizedConfiguration['quiet'] as $shushedGroup) { + $verboseOutput[$shushedGroup] = false; + } } return new self( @@ -190,7 +216,12 @@ class Configuration */ public static function inWeakMode() { - return new self([], '', false); + $verboseOutput = []; + foreach (['unsilenced', 'direct', 'indirect', 'self', 'other'] as $group) { + $verboseOutput[$group] = false; + } + + return new self([], '', $verboseOutput); } /** diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/DeprecationGroup.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/DeprecationGroup.php new file mode 100644 index 0000000000..ea62be4164 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/DeprecationGroup.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\DeprecationErrorHandler; + +/** + * @internal + */ +final class DeprecationGroup +{ + private $count = 0; + + /** + * @var DeprecationNotice[] keys are messages + */ + private $deprecationNotices = []; + + /** + * @param string $message + * @param string $class + * @param string $method + */ + public function addNoticeFromObject($message, $class, $method) + { + $this->deprecationNotice($message)->addObjectOccurence($class, $method); + $this->addNotice(); + } + + /** + * @param string $message + */ + public function addNoticeFromProceduralCode($message) + { + $this->deprecationNotice($message)->addProceduralOccurence(); + $this->addNotice(); + } + + public function addNotice() + { + ++$this->count; + } + + /** + * @param string $message + * + * @return DeprecationNotice + */ + private function deprecationNotice($message) + { + if (!isset($this->deprecationNotices[$message])) { + $this->deprecationNotices[$message] = new DeprecationNotice(); + } + + return $this->deprecationNotices[$message]; + } + + public function count() + { + return $this->count; + } + + public function notices() + { + return $this->deprecationNotices; + } +} diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/DeprecationNotice.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/DeprecationNotice.php new file mode 100644 index 0000000000..d76073c8c4 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/DeprecationNotice.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\DeprecationErrorHandler; + +/** + * @internal + */ +final class DeprecationNotice +{ + private $count = 0; + + /** + * @var int[] + */ + private $countsByCaller = []; + + public function addObjectOccurence($class, $method) + { + if (!isset($this->countsByCaller["$class::$method"])) { + $this->countsByCaller["$class::$method"] = 0; + } + ++$this->countsByCaller["$class::$method"]; + ++$this->count; + } + + public function addProceduralOccurence() + { + ++$this->count; + } + + public function getCountsByCaller() + { + return $this->countsByCaller; + } + + public function count() + { + return $this->count; + } +} diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php index 39e792cd3a..bb5b3a72d4 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php @@ -13,6 +13,7 @@ namespace Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler; use PHPUnit\Framework\TestCase; use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Configuration; +use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\DeprecationGroup; class ConfigurationTest extends TestCase { @@ -47,122 +48,122 @@ class ConfigurationTest extends TestCase public function testItNoticesExceededTotalThreshold() { $configuration = Configuration::fromUrlEncodedString('max[total]=3'); - $this->assertTrue($configuration->tolerates([ - 'unsilencedCount' => 1, - 'remaining selfCount' => 0, - 'legacyCount' => 1, - 'otherCount' => 0, - 'remaining directCount' => 1, - 'remaining indirectCount' => 1, - ])); - $this->assertFalse($configuration->tolerates([ - 'unsilencedCount' => 1, - 'remaining selfCount' => 1, - 'legacyCount' => 1, - 'otherCount' => 0, - 'remaining directCount' => 1, - 'remaining indirectCount' => 1, - ])); + $this->assertTrue($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1, + 'self' => 0, + 'legacy' => 1, + 'other' => 0, + 'direct' => 1, + 'indirect' => 1, + ]))); + $this->assertFalse($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1, + 'self' => 1, + 'legacy' => 1, + 'other' => 0, + 'direct' => 1, + 'indirect' => 1, + ]))); } public function testItNoticesExceededSelfThreshold() { $configuration = Configuration::fromUrlEncodedString('max[self]=1'); - $this->assertTrue($configuration->tolerates([ - 'unsilencedCount' => 1234, - 'remaining selfCount' => 1, - 'legacyCount' => 23, - 'otherCount' => 13, - 'remaining directCount' => 124, - 'remaining indirectCount' => 3244, - ])); - $this->assertFalse($configuration->tolerates([ - 'unsilencedCount' => 1234, - 'remaining selfCount' => 2, - 'legacyCount' => 23, - 'otherCount' => 13, - 'remaining directCount' => 124, - 'remaining indirectCount' => 3244, - ])); + $this->assertTrue($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1234, + 'self' => 1, + 'legacy' => 23, + 'other' => 13, + 'direct' => 124, + 'indirect' => 3244, + ]))); + $this->assertFalse($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1234, + 'self' => 2, + 'legacy' => 23, + 'other' => 13, + 'direct' => 124, + 'indirect' => 3244, + ]))); } public function testItNoticesExceededDirectThreshold() { $configuration = Configuration::fromUrlEncodedString('max[direct]=1&max[self]=999999'); - $this->assertTrue($configuration->tolerates([ - 'unsilencedCount' => 1234, - 'remaining selfCount' => 123, - 'legacyCount' => 23, - 'otherCount' => 13, - 'remaining directCount' => 1, - 'remaining indirectCount' => 3244, - ])); - $this->assertFalse($configuration->tolerates([ - 'unsilencedCount' => 1234, - 'remaining selfCount' => 124, - 'legacyCount' => 23, - 'otherCount' => 13, - 'remaining directCount' => 2, - 'remaining indirectCount' => 3244, - ])); + $this->assertTrue($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1234, + 'self' => 123, + 'legacy' => 23, + 'other' => 13, + 'direct' => 1, + 'indirect' => 3244, + ]))); + $this->assertFalse($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1234, + 'self' => 124, + 'legacy' => 23, + 'other' => 13, + 'direct' => 2, + 'indirect' => 3244, + ]))); } public function testItNoticesExceededIndirectThreshold() { $configuration = Configuration::fromUrlEncodedString('max[indirect]=1&max[direct]=999999&max[self]=999999'); - $this->assertTrue($configuration->tolerates([ - 'unsilencedCount' => 1234, - 'remaining selfCount' => 123, - 'legacyCount' => 23, - 'otherCount' => 13, - 'remaining directCount' => 1234, - 'remaining indirectCount' => 1, - ])); - $this->assertFalse($configuration->tolerates([ - 'unsilencedCount' => 1234, - 'remaining selfCount' => 124, - 'legacyCount' => 23, - 'otherCount' => 13, - 'remaining directCount' => 2324, - 'remaining indirectCount' => 2, - ])); + $this->assertTrue($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1234, + 'self' => 123, + 'legacy' => 23, + 'other' => 13, + 'direct' => 1234, + 'indirect' => 1, + ]))); + $this->assertFalse($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1234, + 'self' => 124, + 'legacy' => 23, + 'other' => 13, + 'direct' => 2324, + 'indirect' => 2, + ]))); } public function testIndirectThresholdIsUsedAsADefaultForDirectAndSelfThreshold() { $configuration = Configuration::fromUrlEncodedString('max[indirect]=1'); - $this->assertTrue($configuration->tolerates([ - 'unsilencedCount' => 0, - 'remaining selfCount' => 1, - 'legacyCount' => 0, - 'otherCount' => 0, - 'remaining directCount' => 0, - 'remaining indirectCount' => 0, - ])); - $this->assertFalse($configuration->tolerates([ - 'unsilencedCount' => 0, - 'remaining selfCount' => 2, - 'legacyCount' => 0, - 'otherCount' => 0, - 'remaining directCount' => 0, - 'remaining indirectCount' => 0, - ])); - $this->assertTrue($configuration->tolerates([ - 'unsilencedCount' => 0, - 'remaining selfCount' => 0, - 'legacyCount' => 0, - 'otherCount' => 0, - 'remaining directCount' => 1, - 'remaining indirectCount' => 0, - ])); - $this->assertFalse($configuration->tolerates([ - 'unsilencedCount' => 0, - 'remaining selfCount' => 0, - 'legacyCount' => 0, - 'otherCount' => 0, - 'remaining directCount' => 2, - 'remaining indirectCount' => 0, - ])); + $this->assertTrue($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 0, + 'self' => 1, + 'legacy' => 0, + 'other' => 0, + 'direct' => 0, + 'indirect' => 0, + ]))); + $this->assertFalse($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 0, + 'self' => 2, + 'legacy' => 0, + 'other' => 0, + 'direct' => 0, + 'indirect' => 0, + ]))); + $this->assertTrue($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 0, + 'self' => 0, + 'legacy' => 0, + 'other' => 0, + 'direct' => 1, + 'indirect' => 0, + ]))); + $this->assertFalse($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 0, + 'self' => 0, + 'legacy' => 0, + 'other' => 0, + 'direct' => 2, + 'indirect' => 0, + ]))); } public function testItCanTellWhetherToDisplayAStackTrace() @@ -184,12 +185,51 @@ class ConfigurationTest extends TestCase public function testItCanBeShushed() { $configuration = Configuration::fromUrlEncodedString('verbose'); - $this->assertFalse($configuration->verboseOutput()); + $this->assertFalse($configuration->verboseOutput('unsilenced')); + $this->assertFalse($configuration->verboseOutput('direct')); + $this->assertFalse($configuration->verboseOutput('indirect')); + $this->assertFalse($configuration->verboseOutput('self')); + $this->assertFalse($configuration->verboseOutput('other')); + } + + public function testItCanBePartiallyShushed() + { + $configuration = Configuration::fromUrlEncodedString('quiet[]=unsilenced&quiet[]=indirect&quiet[]=other'); + $this->assertFalse($configuration->verboseOutput('unsilenced')); + $this->assertTrue($configuration->verboseOutput('direct')); + $this->assertFalse($configuration->verboseOutput('indirect')); + $this->assertTrue($configuration->verboseOutput('self')); + $this->assertFalse($configuration->verboseOutput('other')); + } + + public function testItThrowsOnUnknownVerbosityGroup() + { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('made-up'); + Configuration::fromUrlEncodedString('quiet[]=made-up'); } public function testOutputIsNotVerboseInWeakMode() { $configuration = Configuration::inWeakMode(); - $this->assertFalse($configuration->verboseOutput()); + $this->assertFalse($configuration->verboseOutput('unsilenced')); + $this->assertFalse($configuration->verboseOutput('direct')); + $this->assertFalse($configuration->verboseOutput('indirect')); + $this->assertFalse($configuration->verboseOutput('self')); + $this->assertFalse($configuration->verboseOutput('other')); + } + + private function buildGroups($counts) + { + $groups = []; + foreach ($counts as $name => $count) { + $groups[$name] = new DeprecationGroup(); + $i = 0; + while ($i++ < $count) { + $groups[$name]->addNotice(); + } + } + + return $groups; } } diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationGroupTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationGroupTest.php new file mode 100644 index 0000000000..df746e5e38 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationGroupTest.php @@ -0,0 +1,30 @@ +addNoticeFromObject( + 'Calling sfContext::getInstance() is deprecated', + 'MonsterController', + 'get5klocMethod' + ); + $group->addNoticeFromProceduralCode('Calling sfContext::getInstance() is deprecated'); + $this->assertCount(1, $group->notices()); + $this->assertSame(2, $group->count()); + } + + public function testItAllowsAddingANoticeWithoutClutteringTheMemory() + { + // this is useful for notices in the legacy group + $group = new DeprecationGroup(); + $group->addNotice(); + $this->assertSame(1, $group->count()); + } +} diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationNoticeTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationNoticeTest.php new file mode 100644 index 0000000000..7fa500aa07 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationNoticeTest.php @@ -0,0 +1,35 @@ +addObjectOccurence('MyAction', '__invoke'); + $notice->addObjectOccurence('MyAction', '__invoke'); + $notice->addObjectOccurence('MyOtherAction', '__invoke'); + + $countsByCaller = $notice->getCountsByCaller(); + + $this->assertCount(2, $countsByCaller); + $this->assertArrayHasKey('MyAction::__invoke', $countsByCaller); + $this->assertArrayHasKey('MyOtherAction::__invoke', $countsByCaller); + $this->assertSame(2, $countsByCaller['MyAction::__invoke']); + $this->assertSame(1, $countsByCaller['MyOtherAction::__invoke']); + } + + public function testItCountsBothTypesOfOccurences() + { + $notice = new DeprecationNotice(); + $notice->addObjectOccurence('MyAction', '__invoke'); + $this->assertSame(1, $notice->count()); + + $notice->addProceduralOccurence(); + $this->assertSame(2, $notice->count()); + } +} diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/partially_quiet.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/partially_quiet.phpt new file mode 100644 index 0000000000..d45c6f9af2 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/partially_quiet.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test DeprecationErrorHandler quiet on everything but indirect deprecations +--FILE-- + +--EXPECTF-- +Unsilenced deprecation notices (3) + +Remaining direct deprecation notices (1) + +Remaining indirect deprecation notices (1) + + 1x: deprecatedApi is deprecated! You should stop relying on it! + 1x in SomeService::deprecatedApi from acme\lib + +Legacy deprecation notices (2) + +Other deprecation notices (1) + diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/quiet_but_failing.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/quiet_but_failing.phpt new file mode 100644 index 0000000000..9c73d3c443 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/quiet_but_failing.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test DeprecationErrorHandler when failing and not verbose +--FILE-- + +--EXPECTF-- +Remaining indirect deprecation notices (1) + + 1x: deprecatedApi is deprecated! You should stop relying on it! + 1x in SomeService::deprecatedApi from acme\lib