Vous êtes connecté en tant que anonymous Se Deconnecter
Browse code

Application modulaire fonctionnelle !

Emmanuel ROY authored on 12/08/2019 15:10:25
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,560 +0,0 @@
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\Component\Debug\Tests;
13
-
14
-use PHPUnit\Framework\TestCase;
15
-use Psr\Log\LogLevel;
16
-use Psr\Log\NullLogger;
17
-use Symfony\Component\Debug\BufferingLogger;
18
-use Symfony\Component\Debug\ErrorHandler;
19
-use Symfony\Component\Debug\Exception\SilencedErrorContext;
20
-use Symfony\Component\Debug\Tests\Fixtures\ErrorHandlerThatUsesThePreviousOne;
21
-use Symfony\Component\Debug\Tests\Fixtures\LoggerThatSetAnErrorHandler;
22
-
23
-/**
24
- * ErrorHandlerTest.
25
- *
26
- * @author Robert Schönthal <seroscho@googlemail.com>
27
- * @author Nicolas Grekas <p@tchwork.com>
28
- */
29
-class ErrorHandlerTest extends TestCase
30
-{
31
-    public function testRegister()
32
-    {
33
-        $handler = ErrorHandler::register();
34
-
35
-        try {
36
-            $this->assertInstanceOf('Symfony\Component\Debug\ErrorHandler', $handler);
37
-            $this->assertSame($handler, ErrorHandler::register());
38
-
39
-            $newHandler = new ErrorHandler();
40
-
41
-            $this->assertSame($handler, ErrorHandler::register($newHandler, false));
42
-            $h = set_error_handler('var_dump');
43
-            restore_error_handler();
44
-            $this->assertSame([$handler, 'handleError'], $h);
45
-
46
-            try {
47
-                $this->assertSame($newHandler, ErrorHandler::register($newHandler, true));
48
-                $h = set_error_handler('var_dump');
49
-                restore_error_handler();
50
-                $this->assertSame([$newHandler, 'handleError'], $h);
51
-            } catch (\Exception $e) {
52
-            }
53
-
54
-            restore_error_handler();
55
-            restore_exception_handler();
56
-
57
-            if (isset($e)) {
58
-                throw $e;
59
-            }
60
-        } catch (\Exception $e) {
61
-        }
62
-
63
-        restore_error_handler();
64
-        restore_exception_handler();
65
-
66
-        if (isset($e)) {
67
-            throw $e;
68
-        }
69
-    }
70
-
71
-    public function testErrorGetLast()
72
-    {
73
-        $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
74
-        $handler = ErrorHandler::register();
75
-        $handler->setDefaultLogger($logger);
76
-        $handler->screamAt(E_ALL);
77
-
78
-        try {
79
-            @trigger_error('Hello', E_USER_WARNING);
80
-            $expected = [
81
-                'type' => E_USER_WARNING,
82
-                'message' => 'Hello',
83
-                'file' => __FILE__,
84
-                'line' => __LINE__ - 5,
85
-            ];
86
-            $this->assertSame($expected, error_get_last());
87
-        } catch (\Exception $e) {
88
-            restore_error_handler();
89
-            restore_exception_handler();
90
-
91
-            throw $e;
92
-        }
93
-    }
94
-
95
-    public function testNotice()
96
-    {
97
-        ErrorHandler::register();
98
-
99
-        try {
100
-            self::triggerNotice($this);
101
-            $this->fail('ErrorException expected');
102
-        } catch (\ErrorException $exception) {
103
-            // if an exception is thrown, the test passed
104
-            $this->assertEquals(E_NOTICE, $exception->getSeverity());
105
-            $this->assertEquals(__FILE__, $exception->getFile());
106
-            $this->assertRegExp('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage());
107
-
108
-            $trace = $exception->getTrace();
109
-
110
-            $this->assertEquals(__FILE__, $trace[0]['file']);
111
-            $this->assertEquals(__CLASS__, $trace[0]['class']);
112
-            $this->assertEquals('triggerNotice', $trace[0]['function']);
113
-            $this->assertEquals('::', $trace[0]['type']);
114
-
115
-            $this->assertEquals(__FILE__, $trace[0]['file']);
116
-            $this->assertEquals(__CLASS__, $trace[1]['class']);
117
-            $this->assertEquals(__FUNCTION__, $trace[1]['function']);
118
-            $this->assertEquals('->', $trace[1]['type']);
119
-        } finally {
120
-            restore_error_handler();
121
-            restore_exception_handler();
122
-        }
123
-    }
124
-
125
-    // dummy function to test trace in error handler.
126
-    private static function triggerNotice($that)
127
-    {
128
-        $that->assertSame('', $foo.$foo.$bar);
129
-    }
130
-
131
-    public function testConstruct()
132
-    {
133
-        try {
134
-            $handler = ErrorHandler::register();
135
-            $handler->throwAt(3, true);
136
-            $this->assertEquals(3 | E_RECOVERABLE_ERROR | E_USER_ERROR, $handler->throwAt(0));
137
-        } finally {
138
-            restore_error_handler();
139
-            restore_exception_handler();
140
-        }
141
-    }
142
-
143
-    public function testDefaultLogger()
144
-    {
145
-        try {
146
-            $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
147
-            $handler = ErrorHandler::register();
148
-
149
-            $handler->setDefaultLogger($logger, E_NOTICE);
150
-            $handler->setDefaultLogger($logger, [E_USER_NOTICE => LogLevel::CRITICAL]);
151
-
152
-            $loggers = [
153
-                E_DEPRECATED => [null, LogLevel::INFO],
154
-                E_USER_DEPRECATED => [null, LogLevel::INFO],
155
-                E_NOTICE => [$logger, LogLevel::WARNING],
156
-                E_USER_NOTICE => [$logger, LogLevel::CRITICAL],
157
-                E_STRICT => [null, LogLevel::WARNING],
158
-                E_WARNING => [null, LogLevel::WARNING],
159
-                E_USER_WARNING => [null, LogLevel::WARNING],
160
-                E_COMPILE_WARNING => [null, LogLevel::WARNING],
161
-                E_CORE_WARNING => [null, LogLevel::WARNING],
162
-                E_USER_ERROR => [null, LogLevel::CRITICAL],
163
-                E_RECOVERABLE_ERROR => [null, LogLevel::CRITICAL],
164
-                E_COMPILE_ERROR => [null, LogLevel::CRITICAL],
165
-                E_PARSE => [null, LogLevel::CRITICAL],
166
-                E_ERROR => [null, LogLevel::CRITICAL],
167
-                E_CORE_ERROR => [null, LogLevel::CRITICAL],
168
-            ];
169
-            $this->assertSame($loggers, $handler->setLoggers([]));
170
-        } finally {
171
-            restore_error_handler();
172
-            restore_exception_handler();
173
-        }
174
-    }
175
-
176
-    public function testHandleError()
177
-    {
178
-        try {
179
-            $handler = ErrorHandler::register();
180
-            $handler->throwAt(0, true);
181
-            $this->assertFalse($handler->handleError(0, 'foo', 'foo.php', 12, []));
182
-
183
-            restore_error_handler();
184
-            restore_exception_handler();
185
-
186
-            $handler = ErrorHandler::register();
187
-            $handler->throwAt(3, true);
188
-            $this->assertFalse($handler->handleError(4, 'foo', 'foo.php', 12, []));
189
-
190
-            restore_error_handler();
191
-            restore_exception_handler();
192
-
193
-            $handler = ErrorHandler::register();
194
-            $handler->throwAt(3, true);
195
-            try {
196
-                $handler->handleError(4, 'foo', 'foo.php', 12, []);
197
-            } catch (\ErrorException $e) {
198
-                $this->assertSame('Parse Error: foo', $e->getMessage());
199
-                $this->assertSame(4, $e->getSeverity());
200
-                $this->assertSame('foo.php', $e->getFile());
201
-                $this->assertSame(12, $e->getLine());
202
-            }
203
-
204
-            restore_error_handler();
205
-            restore_exception_handler();
206
-
207
-            $handler = ErrorHandler::register();
208
-            $handler->throwAt(E_USER_DEPRECATED, true);
209
-            $this->assertFalse($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, []));
210
-
211
-            restore_error_handler();
212
-            restore_exception_handler();
213
-
214
-            $handler = ErrorHandler::register();
215
-            $handler->throwAt(E_DEPRECATED, true);
216
-            $this->assertFalse($handler->handleError(E_DEPRECATED, 'foo', 'foo.php', 12, []));
217
-
218
-            restore_error_handler();
219
-            restore_exception_handler();
220
-
221
-            $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
222
-
223
-            $warnArgCheck = function ($logLevel, $message, $context) {
224
-                $this->assertEquals('info', $logLevel);
225
-                $this->assertEquals('User Deprecated: foo', $message);
226
-                $this->assertArrayHasKey('exception', $context);
227
-                $exception = $context['exception'];
228
-                $this->assertInstanceOf(\ErrorException::class, $exception);
229
-                $this->assertSame('User Deprecated: foo', $exception->getMessage());
230
-                $this->assertSame(E_USER_DEPRECATED, $exception->getSeverity());
231
-            };
232
-
233
-            $logger
234
-                ->expects($this->once())
235
-                ->method('log')
236
-                ->willReturnCallback($warnArgCheck)
237
-            ;
238
-
239
-            $handler = ErrorHandler::register();
240
-            $handler->setDefaultLogger($logger, E_USER_DEPRECATED);
241
-            $this->assertTrue($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, []));
242
-
243
-            restore_error_handler();
244
-            restore_exception_handler();
245
-
246
-            $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
247
-
248
-            $line = null;
249
-            $logArgCheck = function ($level, $message, $context) use (&$line) {
250
-                $this->assertEquals('Notice: Undefined variable: undefVar', $message);
251
-                $this->assertArrayHasKey('exception', $context);
252
-                $exception = $context['exception'];
253
-                $this->assertInstanceOf(SilencedErrorContext::class, $exception);
254
-                $this->assertSame(E_NOTICE, $exception->getSeverity());
255
-                $this->assertSame(__FILE__, $exception->getFile());
256
-                $this->assertSame($line, $exception->getLine());
257
-                $this->assertNotEmpty($exception->getTrace());
258
-                $this->assertSame(1, $exception->count);
259
-            };
260
-
261
-            $logger
262
-                ->expects($this->once())
263
-                ->method('log')
264
-                ->willReturnCallback($logArgCheck)
265
-            ;
266
-
267
-            $handler = ErrorHandler::register();
268
-            $handler->setDefaultLogger($logger, E_NOTICE);
269
-            $handler->screamAt(E_NOTICE);
270
-            unset($undefVar);
271
-            $line = __LINE__ + 1;
272
-            @$undefVar++;
273
-
274
-            restore_error_handler();
275
-            restore_exception_handler();
276
-        } catch (\Exception $e) {
277
-            restore_error_handler();
278
-            restore_exception_handler();
279
-
280
-            throw $e;
281
-        }
282
-    }
283
-
284
-    public function testHandleUserError()
285
-    {
286
-        try {
287
-            $handler = ErrorHandler::register();
288
-            $handler->throwAt(0, true);
289
-
290
-            $e = null;
291
-            $x = new \Exception('Foo');
292
-
293
-            try {
294
-                $f = new Fixtures\ToStringThrower($x);
295
-                $f .= ''; // Trigger $f->__toString()
296
-            } catch (\Exception $e) {
297
-            }
298
-
299
-            $this->assertSame($x, $e);
300
-        } finally {
301
-            restore_error_handler();
302
-            restore_exception_handler();
303
-        }
304
-    }
305
-
306
-    public function testHandleDeprecation()
307
-    {
308
-        $logArgCheck = function ($level, $message, $context) {
309
-            $this->assertEquals(LogLevel::INFO, $level);
310
-            $this->assertArrayHasKey('exception', $context);
311
-            $exception = $context['exception'];
312
-            $this->assertInstanceOf(\ErrorException::class, $exception);
313
-            $this->assertSame('User Deprecated: Foo deprecation', $exception->getMessage());
314
-        };
315
-
316
-        $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
317
-        $logger
318
-            ->expects($this->once())
319
-            ->method('log')
320
-            ->willReturnCallback($logArgCheck)
321
-        ;
322
-
323
-        $handler = new ErrorHandler();
324
-        $handler->setDefaultLogger($logger);
325
-        @$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, []);
326
-
327
-        restore_error_handler();
328
-    }
329
-
330
-    public function testHandleException()
331
-    {
332
-        try {
333
-            $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
334
-            $handler = ErrorHandler::register();
335
-
336
-            $exception = new \Exception('foo');
337
-
338
-            $logArgCheck = function ($level, $message, $context) {
339
-                $this->assertSame('Uncaught Exception: foo', $message);
340
-                $this->assertArrayHasKey('exception', $context);
341
-                $this->assertInstanceOf(\Exception::class, $context['exception']);
342
-            };
343
-
344
-            $logger
345
-                ->expects($this->exactly(2))
346
-                ->method('log')
347
-                ->willReturnCallback($logArgCheck)
348
-            ;
349
-
350
-            $handler->setDefaultLogger($logger, E_ERROR);
351
-
352
-            try {
353
-                $handler->handleException($exception);
354
-                $this->fail('Exception expected');
355
-            } catch (\Exception $e) {
356
-                $this->assertSame($exception, $e);
357
-            }
358
-
359
-            $handler->setExceptionHandler(function ($e) use ($exception) {
360
-                $this->assertSame($exception, $e);
361
-            });
362
-
363
-            $handler->handleException($exception);
364
-        } finally {
365
-            restore_error_handler();
366
-            restore_exception_handler();
367
-        }
368
-    }
369
-
370
-    public function testBootstrappingLogger()
371
-    {
372
-        $bootLogger = new BufferingLogger();
373
-        $handler = new ErrorHandler($bootLogger);
374
-
375
-        $loggers = [
376
-            E_DEPRECATED => [$bootLogger, LogLevel::INFO],
377
-            E_USER_DEPRECATED => [$bootLogger, LogLevel::INFO],
378
-            E_NOTICE => [$bootLogger, LogLevel::WARNING],
379
-            E_USER_NOTICE => [$bootLogger, LogLevel::WARNING],
380
-            E_STRICT => [$bootLogger, LogLevel::WARNING],
381
-            E_WARNING => [$bootLogger, LogLevel::WARNING],
382
-            E_USER_WARNING => [$bootLogger, LogLevel::WARNING],
383
-            E_COMPILE_WARNING => [$bootLogger, LogLevel::WARNING],
384
-            E_CORE_WARNING => [$bootLogger, LogLevel::WARNING],
385
-            E_USER_ERROR => [$bootLogger, LogLevel::CRITICAL],
386
-            E_RECOVERABLE_ERROR => [$bootLogger, LogLevel::CRITICAL],
387
-            E_COMPILE_ERROR => [$bootLogger, LogLevel::CRITICAL],
388
-            E_PARSE => [$bootLogger, LogLevel::CRITICAL],
389
-            E_ERROR => [$bootLogger, LogLevel::CRITICAL],
390
-            E_CORE_ERROR => [$bootLogger, LogLevel::CRITICAL],
391
-        ];
392
-
393
-        $this->assertSame($loggers, $handler->setLoggers([]));
394
-
395
-        $handler->handleError(E_DEPRECATED, 'Foo message', __FILE__, 123, []);
396
-
397
-        $logs = $bootLogger->cleanLogs();
398
-
399
-        $this->assertCount(1, $logs);
400
-        $log = $logs[0];
401
-        $this->assertSame('info', $log[0]);
402
-        $this->assertSame('Deprecated: Foo message', $log[1]);
403
-        $this->assertArrayHasKey('exception', $log[2]);
404
-        $exception = $log[2]['exception'];
405
-        $this->assertInstanceOf(\ErrorException::class, $exception);
406
-        $this->assertSame('Deprecated: Foo message', $exception->getMessage());
407
-        $this->assertSame(__FILE__, $exception->getFile());
408
-        $this->assertSame(123, $exception->getLine());
409
-        $this->assertSame(E_DEPRECATED, $exception->getSeverity());
410
-
411
-        $bootLogger->log(LogLevel::WARNING, 'Foo message', ['exception' => $exception]);
412
-
413
-        $mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
414
-        $mockLogger->expects($this->once())
415
-            ->method('log')
416
-            ->with(LogLevel::WARNING, 'Foo message', ['exception' => $exception]);
417
-
418
-        $handler->setLoggers([E_DEPRECATED => [$mockLogger, LogLevel::WARNING]]);
419
-    }
420
-
421
-    public function testSettingLoggerWhenExceptionIsBuffered()
422
-    {
423
-        $bootLogger = new BufferingLogger();
424
-        $handler = new ErrorHandler($bootLogger);
425
-
426
-        $exception = new \Exception('Foo message');
427
-
428
-        $mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
429
-        $mockLogger->expects($this->once())
430
-            ->method('log')
431
-            ->with(LogLevel::CRITICAL, 'Uncaught Exception: Foo message', ['exception' => $exception]);
432
-
433
-        $handler->setExceptionHandler(function () use ($handler, $mockLogger) {
434
-            $handler->setDefaultLogger($mockLogger);
435
-        });
436
-
437
-        $handler->handleException($exception);
438
-    }
439
-
440
-    public function testHandleFatalError()
441
-    {
442
-        try {
443
-            $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
444
-            $handler = ErrorHandler::register();
445
-
446
-            $error = [
447
-                'type' => E_PARSE,
448
-                'message' => 'foo',
449
-                'file' => 'bar',
450
-                'line' => 123,
451
-            ];
452
-
453
-            $logArgCheck = function ($level, $message, $context) {
454
-                $this->assertEquals('Fatal Parse Error: foo', $message);
455
-                $this->assertArrayHasKey('exception', $context);
456
-                $this->assertInstanceOf(\Exception::class, $context['exception']);
457
-            };
458
-
459
-            $logger
460
-                ->expects($this->once())
461
-                ->method('log')
462
-                ->willReturnCallback($logArgCheck)
463
-            ;
464
-
465
-            $handler->setDefaultLogger($logger, E_PARSE);
466
-
467
-            $handler->handleFatalError($error);
468
-
469
-            restore_error_handler();
470
-            restore_exception_handler();
471
-        } catch (\Exception $e) {
472
-            restore_error_handler();
473
-            restore_exception_handler();
474
-
475
-            throw $e;
476
-        }
477
-    }
478
-
479
-    public function testHandleErrorException()
480
-    {
481
-        $exception = new \Error("Class 'IReallyReallyDoNotExistAnywhereInTheRepositoryISwear' not found");
482
-
483
-        $handler = new ErrorHandler();
484
-        $handler->setExceptionHandler(function () use (&$args) {
485
-            $args = \func_get_args();
486
-        });
487
-
488
-        $handler->handleException($exception);
489
-
490
-        $this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $args[0]);
491
-        $this->assertStringStartsWith("Attempted to load class \"IReallyReallyDoNotExistAnywhereInTheRepositoryISwear\" from the global namespace.\nDid you forget a \"use\" statement", $args[0]->getMessage());
492
-    }
493
-
494
-    /**
495
-     * @expectedException \Exception
496
-     */
497
-    public function testCustomExceptionHandler()
498
-    {
499
-        $handler = new ErrorHandler();
500
-        $handler->setExceptionHandler(function ($e) use ($handler) {
501
-            $handler->handleException($e);
502
-        });
503
-
504
-        $handler->handleException(new \Exception());
505
-    }
506
-
507
-    /**
508
-     * @dataProvider errorHandlerWhenLoggingProvider
509
-     */
510
-    public function testErrorHandlerWhenLogging($previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined)
511
-    {
512
-        try {
513
-            if ($previousHandlerWasDefined) {
514
-                set_error_handler('count');
515
-            }
516
-
517
-            $logger = $loggerSetsAnotherHandler ? new LoggerThatSetAnErrorHandler() : new NullLogger();
518
-
519
-            $handler = ErrorHandler::register();
520
-            $handler->setDefaultLogger($logger);
521
-
522
-            if ($nextHandlerIsDefined) {
523
-                $handler = ErrorHandlerThatUsesThePreviousOne::register();
524
-            }
525
-
526
-            @trigger_error('foo', E_USER_DEPRECATED);
527
-            @trigger_error('bar', E_USER_DEPRECATED);
528
-
529
-            $this->assertSame([$handler, 'handleError'], set_error_handler('var_dump'));
530
-
531
-            if ($logger instanceof LoggerThatSetAnErrorHandler) {
532
-                $this->assertCount(2, $logger->cleanLogs());
533
-            }
534
-
535
-            restore_error_handler();
536
-
537
-            if ($previousHandlerWasDefined) {
538
-                restore_error_handler();
539
-            }
540
-
541
-            if ($nextHandlerIsDefined) {
542
-                restore_error_handler();
543
-            }
544
-        } finally {
545
-            restore_error_handler();
546
-            restore_exception_handler();
547
-        }
548
-    }
549
-
550
-    public function errorHandlerWhenLoggingProvider()
551
-    {
552
-        foreach ([false, true] as $previousHandlerWasDefined) {
553
-            foreach ([false, true] as $loggerSetsAnotherHandler) {
554
-                foreach ([false, true] as $nextHandlerIsDefined) {
555
-                    yield [$previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined];
556
-                }
557
-            }
558
-        }
559
-    }
560
-}
Browse code

initial commit

Emmanuel ROY authored on 09/08/2019 08:39:02
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,560 @@
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\Component\Debug\Tests;
13
+
14
+use PHPUnit\Framework\TestCase;
15
+use Psr\Log\LogLevel;
16
+use Psr\Log\NullLogger;
17
+use Symfony\Component\Debug\BufferingLogger;
18
+use Symfony\Component\Debug\ErrorHandler;
19
+use Symfony\Component\Debug\Exception\SilencedErrorContext;
20
+use Symfony\Component\Debug\Tests\Fixtures\ErrorHandlerThatUsesThePreviousOne;
21
+use Symfony\Component\Debug\Tests\Fixtures\LoggerThatSetAnErrorHandler;
22
+
23
+/**
24
+ * ErrorHandlerTest.
25
+ *
26
+ * @author Robert Schönthal <seroscho@googlemail.com>
27
+ * @author Nicolas Grekas <p@tchwork.com>
28
+ */
29
+class ErrorHandlerTest extends TestCase
30
+{
31
+    public function testRegister()
32
+    {
33
+        $handler = ErrorHandler::register();
34
+
35
+        try {
36
+            $this->assertInstanceOf('Symfony\Component\Debug\ErrorHandler', $handler);
37
+            $this->assertSame($handler, ErrorHandler::register());
38
+
39
+            $newHandler = new ErrorHandler();
40
+
41
+            $this->assertSame($handler, ErrorHandler::register($newHandler, false));
42
+            $h = set_error_handler('var_dump');
43
+            restore_error_handler();
44
+            $this->assertSame([$handler, 'handleError'], $h);
45
+
46
+            try {
47
+                $this->assertSame($newHandler, ErrorHandler::register($newHandler, true));
48
+                $h = set_error_handler('var_dump');
49
+                restore_error_handler();
50
+                $this->assertSame([$newHandler, 'handleError'], $h);
51
+            } catch (\Exception $e) {
52
+            }
53
+
54
+            restore_error_handler();
55
+            restore_exception_handler();
56
+
57
+            if (isset($e)) {
58
+                throw $e;
59
+            }
60
+        } catch (\Exception $e) {
61
+        }
62
+
63
+        restore_error_handler();
64
+        restore_exception_handler();
65
+
66
+        if (isset($e)) {
67
+            throw $e;
68
+        }
69
+    }
70
+
71
+    public function testErrorGetLast()
72
+    {
73
+        $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
74
+        $handler = ErrorHandler::register();
75
+        $handler->setDefaultLogger($logger);
76
+        $handler->screamAt(E_ALL);
77
+
78
+        try {
79
+            @trigger_error('Hello', E_USER_WARNING);
80
+            $expected = [
81
+                'type' => E_USER_WARNING,
82
+                'message' => 'Hello',
83
+                'file' => __FILE__,
84
+                'line' => __LINE__ - 5,
85
+            ];
86
+            $this->assertSame($expected, error_get_last());
87
+        } catch (\Exception $e) {
88
+            restore_error_handler();
89
+            restore_exception_handler();
90
+
91
+            throw $e;
92
+        }
93
+    }
94
+
95
+    public function testNotice()
96
+    {
97
+        ErrorHandler::register();
98
+
99
+        try {
100
+            self::triggerNotice($this);
101
+            $this->fail('ErrorException expected');
102
+        } catch (\ErrorException $exception) {
103
+            // if an exception is thrown, the test passed
104
+            $this->assertEquals(E_NOTICE, $exception->getSeverity());
105
+            $this->assertEquals(__FILE__, $exception->getFile());
106
+            $this->assertRegExp('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage());
107
+
108
+            $trace = $exception->getTrace();
109
+
110
+            $this->assertEquals(__FILE__, $trace[0]['file']);
111
+            $this->assertEquals(__CLASS__, $trace[0]['class']);
112
+            $this->assertEquals('triggerNotice', $trace[0]['function']);
113
+            $this->assertEquals('::', $trace[0]['type']);
114
+
115
+            $this->assertEquals(__FILE__, $trace[0]['file']);
116
+            $this->assertEquals(__CLASS__, $trace[1]['class']);
117
+            $this->assertEquals(__FUNCTION__, $trace[1]['function']);
118
+            $this->assertEquals('->', $trace[1]['type']);
119
+        } finally {
120
+            restore_error_handler();
121
+            restore_exception_handler();
122
+        }
123
+    }
124
+
125
+    // dummy function to test trace in error handler.
126
+    private static function triggerNotice($that)
127
+    {
128
+        $that->assertSame('', $foo.$foo.$bar);
129
+    }
130
+
131
+    public function testConstruct()
132
+    {
133
+        try {
134
+            $handler = ErrorHandler::register();
135
+            $handler->throwAt(3, true);
136
+            $this->assertEquals(3 | E_RECOVERABLE_ERROR | E_USER_ERROR, $handler->throwAt(0));
137
+        } finally {
138
+            restore_error_handler();
139
+            restore_exception_handler();
140
+        }
141
+    }
142
+
143
+    public function testDefaultLogger()
144
+    {
145
+        try {
146
+            $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
147
+            $handler = ErrorHandler::register();
148
+
149
+            $handler->setDefaultLogger($logger, E_NOTICE);
150
+            $handler->setDefaultLogger($logger, [E_USER_NOTICE => LogLevel::CRITICAL]);
151
+
152
+            $loggers = [
153
+                E_DEPRECATED => [null, LogLevel::INFO],
154
+                E_USER_DEPRECATED => [null, LogLevel::INFO],
155
+                E_NOTICE => [$logger, LogLevel::WARNING],
156
+                E_USER_NOTICE => [$logger, LogLevel::CRITICAL],
157
+                E_STRICT => [null, LogLevel::WARNING],
158
+                E_WARNING => [null, LogLevel::WARNING],
159
+                E_USER_WARNING => [null, LogLevel::WARNING],
160
+                E_COMPILE_WARNING => [null, LogLevel::WARNING],
161
+                E_CORE_WARNING => [null, LogLevel::WARNING],
162
+                E_USER_ERROR => [null, LogLevel::CRITICAL],
163
+                E_RECOVERABLE_ERROR => [null, LogLevel::CRITICAL],
164
+                E_COMPILE_ERROR => [null, LogLevel::CRITICAL],
165
+                E_PARSE => [null, LogLevel::CRITICAL],
166
+                E_ERROR => [null, LogLevel::CRITICAL],
167
+                E_CORE_ERROR => [null, LogLevel::CRITICAL],
168
+            ];
169
+            $this->assertSame($loggers, $handler->setLoggers([]));
170
+        } finally {
171
+            restore_error_handler();
172
+            restore_exception_handler();
173
+        }
174
+    }
175
+
176
+    public function testHandleError()
177
+    {
178
+        try {
179
+            $handler = ErrorHandler::register();
180
+            $handler->throwAt(0, true);
181
+            $this->assertFalse($handler->handleError(0, 'foo', 'foo.php', 12, []));
182
+
183
+            restore_error_handler();
184
+            restore_exception_handler();
185
+
186
+            $handler = ErrorHandler::register();
187
+            $handler->throwAt(3, true);
188
+            $this->assertFalse($handler->handleError(4, 'foo', 'foo.php', 12, []));
189
+
190
+            restore_error_handler();
191
+            restore_exception_handler();
192
+
193
+            $handler = ErrorHandler::register();
194
+            $handler->throwAt(3, true);
195
+            try {
196
+                $handler->handleError(4, 'foo', 'foo.php', 12, []);
197
+            } catch (\ErrorException $e) {
198
+                $this->assertSame('Parse Error: foo', $e->getMessage());
199
+                $this->assertSame(4, $e->getSeverity());
200
+                $this->assertSame('foo.php', $e->getFile());
201
+                $this->assertSame(12, $e->getLine());
202
+            }
203
+
204
+            restore_error_handler();
205
+            restore_exception_handler();
206
+
207
+            $handler = ErrorHandler::register();
208
+            $handler->throwAt(E_USER_DEPRECATED, true);
209
+            $this->assertFalse($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, []));
210
+
211
+            restore_error_handler();
212
+            restore_exception_handler();
213
+
214
+            $handler = ErrorHandler::register();
215
+            $handler->throwAt(E_DEPRECATED, true);
216
+            $this->assertFalse($handler->handleError(E_DEPRECATED, 'foo', 'foo.php', 12, []));
217
+
218
+            restore_error_handler();
219
+            restore_exception_handler();
220
+
221
+            $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
222
+
223
+            $warnArgCheck = function ($logLevel, $message, $context) {
224
+                $this->assertEquals('info', $logLevel);
225
+                $this->assertEquals('User Deprecated: foo', $message);
226
+                $this->assertArrayHasKey('exception', $context);
227
+                $exception = $context['exception'];
228
+                $this->assertInstanceOf(\ErrorException::class, $exception);
229
+                $this->assertSame('User Deprecated: foo', $exception->getMessage());
230
+                $this->assertSame(E_USER_DEPRECATED, $exception->getSeverity());
231
+            };
232
+
233
+            $logger
234
+                ->expects($this->once())
235
+                ->method('log')
236
+                ->willReturnCallback($warnArgCheck)
237
+            ;
238
+
239
+            $handler = ErrorHandler::register();
240
+            $handler->setDefaultLogger($logger, E_USER_DEPRECATED);
241
+            $this->assertTrue($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, []));
242
+
243
+            restore_error_handler();
244
+            restore_exception_handler();
245
+
246
+            $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
247
+
248
+            $line = null;
249
+            $logArgCheck = function ($level, $message, $context) use (&$line) {
250
+                $this->assertEquals('Notice: Undefined variable: undefVar', $message);
251
+                $this->assertArrayHasKey('exception', $context);
252
+                $exception = $context['exception'];
253
+                $this->assertInstanceOf(SilencedErrorContext::class, $exception);
254
+                $this->assertSame(E_NOTICE, $exception->getSeverity());
255
+                $this->assertSame(__FILE__, $exception->getFile());
256
+                $this->assertSame($line, $exception->getLine());
257
+                $this->assertNotEmpty($exception->getTrace());
258
+                $this->assertSame(1, $exception->count);
259
+            };
260
+
261
+            $logger
262
+                ->expects($this->once())
263
+                ->method('log')
264
+                ->willReturnCallback($logArgCheck)
265
+            ;
266
+
267
+            $handler = ErrorHandler::register();
268
+            $handler->setDefaultLogger($logger, E_NOTICE);
269
+            $handler->screamAt(E_NOTICE);
270
+            unset($undefVar);
271
+            $line = __LINE__ + 1;
272
+            @$undefVar++;
273
+
274
+            restore_error_handler();
275
+            restore_exception_handler();
276
+        } catch (\Exception $e) {
277
+            restore_error_handler();
278
+            restore_exception_handler();
279
+
280
+            throw $e;
281
+        }
282
+    }
283
+
284
+    public function testHandleUserError()
285
+    {
286
+        try {
287
+            $handler = ErrorHandler::register();
288
+            $handler->throwAt(0, true);
289
+
290
+            $e = null;
291
+            $x = new \Exception('Foo');
292
+
293
+            try {
294
+                $f = new Fixtures\ToStringThrower($x);
295
+                $f .= ''; // Trigger $f->__toString()
296
+            } catch (\Exception $e) {
297
+            }
298
+
299
+            $this->assertSame($x, $e);
300
+        } finally {
301
+            restore_error_handler();
302
+            restore_exception_handler();
303
+        }
304
+    }
305
+
306
+    public function testHandleDeprecation()
307
+    {
308
+        $logArgCheck = function ($level, $message, $context) {
309
+            $this->assertEquals(LogLevel::INFO, $level);
310
+            $this->assertArrayHasKey('exception', $context);
311
+            $exception = $context['exception'];
312
+            $this->assertInstanceOf(\ErrorException::class, $exception);
313
+            $this->assertSame('User Deprecated: Foo deprecation', $exception->getMessage());
314
+        };
315
+
316
+        $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
317
+        $logger
318
+            ->expects($this->once())
319
+            ->method('log')
320
+            ->willReturnCallback($logArgCheck)
321
+        ;
322
+
323
+        $handler = new ErrorHandler();
324
+        $handler->setDefaultLogger($logger);
325
+        @$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, []);
326
+
327
+        restore_error_handler();
328
+    }
329
+
330
+    public function testHandleException()
331
+    {
332
+        try {
333
+            $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
334
+            $handler = ErrorHandler::register();
335
+
336
+            $exception = new \Exception('foo');
337
+
338
+            $logArgCheck = function ($level, $message, $context) {
339
+                $this->assertSame('Uncaught Exception: foo', $message);
340
+                $this->assertArrayHasKey('exception', $context);
341
+                $this->assertInstanceOf(\Exception::class, $context['exception']);
342
+            };
343
+
344
+            $logger
345
+                ->expects($this->exactly(2))
346
+                ->method('log')
347
+                ->willReturnCallback($logArgCheck)
348
+            ;
349
+
350
+            $handler->setDefaultLogger($logger, E_ERROR);
351
+
352
+            try {
353
+                $handler->handleException($exception);
354
+                $this->fail('Exception expected');
355
+            } catch (\Exception $e) {
356
+                $this->assertSame($exception, $e);
357
+            }
358
+
359
+            $handler->setExceptionHandler(function ($e) use ($exception) {
360
+                $this->assertSame($exception, $e);
361
+            });
362
+
363
+            $handler->handleException($exception);
364
+        } finally {
365
+            restore_error_handler();
366
+            restore_exception_handler();
367
+        }
368
+    }
369
+
370
+    public function testBootstrappingLogger()
371
+    {
372
+        $bootLogger = new BufferingLogger();
373
+        $handler = new ErrorHandler($bootLogger);
374
+
375
+        $loggers = [
376
+            E_DEPRECATED => [$bootLogger, LogLevel::INFO],
377
+            E_USER_DEPRECATED => [$bootLogger, LogLevel::INFO],
378
+            E_NOTICE => [$bootLogger, LogLevel::WARNING],
379
+            E_USER_NOTICE => [$bootLogger, LogLevel::WARNING],
380
+            E_STRICT => [$bootLogger, LogLevel::WARNING],
381
+            E_WARNING => [$bootLogger, LogLevel::WARNING],
382
+            E_USER_WARNING => [$bootLogger, LogLevel::WARNING],
383
+            E_COMPILE_WARNING => [$bootLogger, LogLevel::WARNING],
384
+            E_CORE_WARNING => [$bootLogger, LogLevel::WARNING],
385
+            E_USER_ERROR => [$bootLogger, LogLevel::CRITICAL],
386
+            E_RECOVERABLE_ERROR => [$bootLogger, LogLevel::CRITICAL],
387
+            E_COMPILE_ERROR => [$bootLogger, LogLevel::CRITICAL],
388
+            E_PARSE => [$bootLogger, LogLevel::CRITICAL],
389
+            E_ERROR => [$bootLogger, LogLevel::CRITICAL],
390
+            E_CORE_ERROR => [$bootLogger, LogLevel::CRITICAL],
391
+        ];
392
+
393
+        $this->assertSame($loggers, $handler->setLoggers([]));
394
+
395
+        $handler->handleError(E_DEPRECATED, 'Foo message', __FILE__, 123, []);
396
+
397
+        $logs = $bootLogger->cleanLogs();
398
+
399
+        $this->assertCount(1, $logs);
400
+        $log = $logs[0];
401
+        $this->assertSame('info', $log[0]);
402
+        $this->assertSame('Deprecated: Foo message', $log[1]);
403
+        $this->assertArrayHasKey('exception', $log[2]);
404
+        $exception = $log[2]['exception'];
405
+        $this->assertInstanceOf(\ErrorException::class, $exception);
406
+        $this->assertSame('Deprecated: Foo message', $exception->getMessage());
407
+        $this->assertSame(__FILE__, $exception->getFile());
408
+        $this->assertSame(123, $exception->getLine());
409
+        $this->assertSame(E_DEPRECATED, $exception->getSeverity());
410
+
411
+        $bootLogger->log(LogLevel::WARNING, 'Foo message', ['exception' => $exception]);
412
+
413
+        $mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
414
+        $mockLogger->expects($this->once())
415
+            ->method('log')
416
+            ->with(LogLevel::WARNING, 'Foo message', ['exception' => $exception]);
417
+
418
+        $handler->setLoggers([E_DEPRECATED => [$mockLogger, LogLevel::WARNING]]);
419
+    }
420
+
421
+    public function testSettingLoggerWhenExceptionIsBuffered()
422
+    {
423
+        $bootLogger = new BufferingLogger();
424
+        $handler = new ErrorHandler($bootLogger);
425
+
426
+        $exception = new \Exception('Foo message');
427
+
428
+        $mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
429
+        $mockLogger->expects($this->once())
430
+            ->method('log')
431
+            ->with(LogLevel::CRITICAL, 'Uncaught Exception: Foo message', ['exception' => $exception]);
432
+
433
+        $handler->setExceptionHandler(function () use ($handler, $mockLogger) {
434
+            $handler->setDefaultLogger($mockLogger);
435
+        });
436
+
437
+        $handler->handleException($exception);
438
+    }
439
+
440
+    public function testHandleFatalError()
441
+    {
442
+        try {
443
+            $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
444
+            $handler = ErrorHandler::register();
445
+
446
+            $error = [
447
+                'type' => E_PARSE,
448
+                'message' => 'foo',
449
+                'file' => 'bar',
450
+                'line' => 123,
451
+            ];
452
+
453
+            $logArgCheck = function ($level, $message, $context) {
454
+                $this->assertEquals('Fatal Parse Error: foo', $message);
455
+                $this->assertArrayHasKey('exception', $context);
456
+                $this->assertInstanceOf(\Exception::class, $context['exception']);
457
+            };
458
+
459
+            $logger
460
+                ->expects($this->once())
461
+                ->method('log')
462
+                ->willReturnCallback($logArgCheck)
463
+            ;
464
+
465
+            $handler->setDefaultLogger($logger, E_PARSE);
466
+
467
+            $handler->handleFatalError($error);
468
+
469
+            restore_error_handler();
470
+            restore_exception_handler();
471
+        } catch (\Exception $e) {
472
+            restore_error_handler();
473
+            restore_exception_handler();
474
+
475
+            throw $e;
476
+        }
477
+    }
478
+
479
+    public function testHandleErrorException()
480
+    {
481
+        $exception = new \Error("Class 'IReallyReallyDoNotExistAnywhereInTheRepositoryISwear' not found");
482
+
483
+        $handler = new ErrorHandler();
484
+        $handler->setExceptionHandler(function () use (&$args) {
485
+            $args = \func_get_args();
486
+        });
487
+
488
+        $handler->handleException($exception);
489
+
490
+        $this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $args[0]);
491
+        $this->assertStringStartsWith("Attempted to load class \"IReallyReallyDoNotExistAnywhereInTheRepositoryISwear\" from the global namespace.\nDid you forget a \"use\" statement", $args[0]->getMessage());
492
+    }
493
+
494
+    /**
495
+     * @expectedException \Exception
496
+     */
497
+    public function testCustomExceptionHandler()
498
+    {
499
+        $handler = new ErrorHandler();
500
+        $handler->setExceptionHandler(function ($e) use ($handler) {
501
+            $handler->handleException($e);
502
+        });
503
+
504
+        $handler->handleException(new \Exception());
505
+    }
506
+
507
+    /**
508
+     * @dataProvider errorHandlerWhenLoggingProvider
509
+     */
510
+    public function testErrorHandlerWhenLogging($previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined)
511
+    {
512
+        try {
513
+            if ($previousHandlerWasDefined) {
514
+                set_error_handler('count');
515
+            }
516
+
517
+            $logger = $loggerSetsAnotherHandler ? new LoggerThatSetAnErrorHandler() : new NullLogger();
518
+
519
+            $handler = ErrorHandler::register();
520
+            $handler->setDefaultLogger($logger);
521
+
522
+            if ($nextHandlerIsDefined) {
523
+                $handler = ErrorHandlerThatUsesThePreviousOne::register();
524
+            }
525
+
526
+            @trigger_error('foo', E_USER_DEPRECATED);
527
+            @trigger_error('bar', E_USER_DEPRECATED);
528
+
529
+            $this->assertSame([$handler, 'handleError'], set_error_handler('var_dump'));
530
+
531
+            if ($logger instanceof LoggerThatSetAnErrorHandler) {
532
+                $this->assertCount(2, $logger->cleanLogs());
533
+            }
534
+
535
+            restore_error_handler();
536
+
537
+            if ($previousHandlerWasDefined) {
538
+                restore_error_handler();
539
+            }
540
+
541
+            if ($nextHandlerIsDefined) {
542
+                restore_error_handler();
543
+            }
544
+        } finally {
545
+            restore_error_handler();
546
+            restore_exception_handler();
547
+        }
548
+    }
549
+
550
+    public function errorHandlerWhenLoggingProvider()
551
+    {
552
+        foreach ([false, true] as $previousHandlerWasDefined) {
553
+            foreach ([false, true] as $loggerSetsAnotherHandler) {
554
+                foreach ([false, true] as $nextHandlerIsDefined) {
555
+                    yield [$previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined];
556
+                }
557
+            }
558
+        }
559
+    }
560
+}