Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/phpunit-bridge/DeprecationErrorHandler.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 7a779792577d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 /* | |
4 * This file is part of the Symfony package. | |
5 * | |
6 * (c) Fabien Potencier <fabien@symfony.com> | |
7 * | |
8 * For the full copyright and license information, please view the LICENSE | |
9 * file that was distributed with this source code. | |
10 */ | |
11 | |
12 namespace Symfony\Bridge\PhpUnit; | |
13 | |
14 /** | |
15 * Catch deprecation notices and print a summary report at the end of the test suite. | |
16 * | |
17 * @author Nicolas Grekas <p@tchwork.com> | |
18 */ | |
19 class DeprecationErrorHandler | |
20 { | |
21 const MODE_WEAK = 'weak'; | |
22 const MODE_DISABLED = 'disabled'; | |
23 | |
24 private static $isRegistered = false; | |
25 | |
26 /** | |
27 * Registers and configures the deprecation handler. | |
28 * | |
29 * The following reporting modes are supported: | |
30 * - use "weak" to hide the deprecation report but keep a global count; | |
31 * - use "/some-regexp/" to stop the test suite whenever a deprecation | |
32 * message matches the given regular expression; | |
33 * - use a number to define the upper bound of allowed deprecations, | |
34 * making the test suite fail whenever more notices are trigerred. | |
35 * | |
36 * @param int|string|false $mode The reporting mode, defaults to not allowing any deprecations | |
37 */ | |
38 public static function register($mode = 0) | |
39 { | |
40 if (self::$isRegistered) { | |
41 return; | |
42 } | |
43 | |
44 $getMode = function () use ($mode) { | |
45 static $memoizedMode = false; | |
46 | |
47 if (false !== $memoizedMode) { | |
48 return $memoizedMode; | |
49 } | |
50 if (false === $mode) { | |
51 $mode = getenv('SYMFONY_DEPRECATIONS_HELPER'); | |
52 } | |
53 if (DeprecationErrorHandler::MODE_WEAK !== $mode && (!isset($mode[0]) || '/' !== $mode[0])) { | |
54 $mode = preg_match('/^[1-9][0-9]*$/', $mode) ? (int) $mode : 0; | |
55 } | |
56 | |
57 return $memoizedMode = $mode; | |
58 }; | |
59 | |
60 $deprecations = array( | |
61 'unsilencedCount' => 0, | |
62 'remainingCount' => 0, | |
63 'legacyCount' => 0, | |
64 'otherCount' => 0, | |
65 'unsilenced' => array(), | |
66 'remaining' => array(), | |
67 'legacy' => array(), | |
68 'other' => array(), | |
69 ); | |
70 $deprecationHandler = function ($type, $msg, $file, $line, $context) use (&$deprecations, $getMode) { | |
71 $mode = $getMode(); | |
72 if ((E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) || DeprecationErrorHandler::MODE_DISABLED === $mode) { | |
73 return \PHPUnit_Util_ErrorHandler::handleError($type, $msg, $file, $line, $context); | |
74 } | |
75 | |
76 $trace = debug_backtrace(true); | |
77 $group = 'other'; | |
78 | |
79 $i = count($trace); | |
80 while (1 < $i && (!isset($trace[--$i]['class']) || ('ReflectionMethod' === $trace[$i]['class'] || 0 === strpos($trace[$i]['class'], 'PHPUnit_')))) { | |
81 // No-op | |
82 } | |
83 | |
84 if (isset($trace[$i]['object']) || isset($trace[$i]['class'])) { | |
85 $class = isset($trace[$i]['object']) ? get_class($trace[$i]['object']) : $trace[$i]['class']; | |
86 $method = $trace[$i]['function']; | |
87 | |
88 if (0 !== error_reporting()) { | |
89 $group = 'unsilenced'; | |
90 } elseif (0 === strpos($method, 'testLegacy') | |
91 || 0 === strpos($method, 'provideLegacy') | |
92 || 0 === strpos($method, 'getLegacy') | |
93 || strpos($class, '\Legacy') | |
94 || in_array('legacy', \PHPUnit_Util_Test::getGroups($class, $method), true) | |
95 ) { | |
96 $group = 'legacy'; | |
97 } else { | |
98 $group = 'remaining'; | |
99 } | |
100 | |
101 if (isset($mode[0]) && '/' === $mode[0] && preg_match($mode, $msg)) { | |
102 $e = new \Exception($msg); | |
103 $r = new \ReflectionProperty($e, 'trace'); | |
104 $r->setAccessible(true); | |
105 $r->setValue($e, array_slice($trace, 1, $i)); | |
106 | |
107 echo "\n".ucfirst($group).' deprecation triggered by '.$class.'::'.$method.':'; | |
108 echo "\n".$msg; | |
109 echo "\nStack trace:"; | |
110 echo "\n".str_replace(' '.getcwd().DIRECTORY_SEPARATOR, ' ', $e->getTraceAsString()); | |
111 echo "\n"; | |
112 | |
113 exit(1); | |
114 } | |
115 if ('legacy' !== $group && DeprecationErrorHandler::MODE_WEAK !== $mode) { | |
116 $ref = &$deprecations[$group][$msg]['count']; | |
117 ++$ref; | |
118 $ref = &$deprecations[$group][$msg][$class.'::'.$method]; | |
119 ++$ref; | |
120 } | |
121 } elseif (DeprecationErrorHandler::MODE_WEAK !== $mode) { | |
122 $ref = &$deprecations[$group][$msg]['count']; | |
123 ++$ref; | |
124 } | |
125 ++$deprecations[$group.'Count']; | |
126 }; | |
127 $oldErrorHandler = set_error_handler($deprecationHandler); | |
128 | |
129 if (null !== $oldErrorHandler) { | |
130 restore_error_handler(); | |
131 if (array('PHPUnit_Util_ErrorHandler', 'handleError') === $oldErrorHandler) { | |
132 restore_error_handler(); | |
133 self::register($mode); | |
134 } | |
135 } else { | |
136 self::$isRegistered = true; | |
137 if (self::hasColorSupport()) { | |
138 $colorize = function ($str, $red) { | |
139 $color = $red ? '41;37' : '43;30'; | |
140 | |
141 return "\x1B[{$color}m{$str}\x1B[0m"; | |
142 }; | |
143 } else { | |
144 $colorize = function ($str) { return $str; }; | |
145 } | |
146 register_shutdown_function(function () use ($getMode, &$deprecations, $deprecationHandler, $colorize) { | |
147 $mode = $getMode(); | |
148 if (isset($mode[0]) && '/' === $mode[0]) { | |
149 return; | |
150 } | |
151 $currErrorHandler = set_error_handler('var_dump'); | |
152 restore_error_handler(); | |
153 | |
154 if (DeprecationErrorHandler::MODE_WEAK === $mode) { | |
155 $colorize = function ($str) { return $str; }; | |
156 } | |
157 if ($currErrorHandler !== $deprecationHandler) { | |
158 echo "\n", $colorize('THE ERROR HANDLER HAS CHANGED!', true), "\n"; | |
159 } | |
160 | |
161 $cmp = function ($a, $b) { | |
162 return $b['count'] - $a['count']; | |
163 }; | |
164 | |
165 foreach (array('unsilenced', 'remaining', 'legacy', 'other') as $group) { | |
166 if ($deprecations[$group.'Count']) { | |
167 echo "\n", $colorize(sprintf('%s deprecation notices (%d)', ucfirst($group), $deprecations[$group.'Count']), 'legacy' !== $group), "\n"; | |
168 | |
169 uasort($deprecations[$group], $cmp); | |
170 | |
171 foreach ($deprecations[$group] as $msg => $notices) { | |
172 echo "\n", rtrim($msg, '.'), ': ', $notices['count'], "x\n"; | |
173 | |
174 arsort($notices); | |
175 | |
176 foreach ($notices as $method => $count) { | |
177 if ('count' !== $method) { | |
178 echo ' ', $count, 'x in ', preg_replace('/(.*)\\\\(.*?::.*?)$/', '$2 from $1', $method), "\n"; | |
179 } | |
180 } | |
181 } | |
182 } | |
183 } | |
184 if (!empty($notices)) { | |
185 echo "\n"; | |
186 } | |
187 | |
188 if (DeprecationErrorHandler::MODE_WEAK !== $mode && $mode < $deprecations['unsilencedCount'] + $deprecations['remainingCount'] + $deprecations['otherCount']) { | |
189 exit(1); | |
190 } | |
191 }); | |
192 } | |
193 } | |
194 | |
195 private static function hasColorSupport() | |
196 { | |
197 if ('\\' === DIRECTORY_SEPARATOR) { | |
198 return | |
199 '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD | |
200 || false !== getenv('ANSICON') | |
201 || 'ON' === getenv('ConEmuANSI') | |
202 || 'xterm' === getenv('TERM'); | |
203 } | |
204 | |
205 return defined('STDOUT') && function_exists('posix_isatty') && @posix_isatty(STDOUT); | |
206 } | |
207 } |