Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * PHPUnit
4
 *
5
 * Copyright (c) 2002-2010, Sebastian Bergmann <sb@sebastian-bergmann.de>.
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 *   * Redistributions of source code must retain the above copyright
13
 *     notice, this list of conditions and the following disclaimer.
14
 *
15
 *   * Redistributions in binary form must reproduce the above copyright
16
 *     notice, this list of conditions and the following disclaimer in
17
 *     the documentation and/or other materials provided with the
18
 *     distribution.
19
 *
20
 *   * Neither the name of Sebastian Bergmann nor the names of his
21
 *     contributors may be used to endorse or promote products derived
22
 *     from this software without specific prior written permission.
23
 *
24
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35
 * POSSIBILITY OF SUCH DAMAGE.
36
 *
37
 * @category   Testing
38
 * @package    PHPUnit
39
 * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
40
 * @copyright  2002-2010 Sebastian Bergmann <sb@sebastian-bergmann.de>
41
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
42
 * @link       http://www.phpunit.de/
43
 * @since      File available since Release 2.0.0
44
 */
45
 
46
require_once 'PHPUnit/Framework.php';
47
require_once 'PHPUnit/Util/Filter.php';
48
require_once 'PHPUnit/Util/Printer.php';
49
require_once 'PHPUnit/Util/Test.php';
50
require_once 'PHPUnit/Util/Timer.php';
51
 
52
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
53
 
54
/**
55
 * Prints the result of a TextUI TestRunner run.
56
 *
57
 * @category   Testing
58
 * @package    PHPUnit
59
 * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
60
 * @copyright  2002-2010 Sebastian Bergmann <sb@sebastian-bergmann.de>
61
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
62
 * @version    Release: 3.4.15
63
 * @link       http://www.phpunit.de/
64
 * @since      Class available since Release 2.0.0
65
 */
66
class PHPUnit_TextUI_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
67
{
68
    const EVENT_TEST_START      = 0;
69
    const EVENT_TEST_END        = 1;
70
    const EVENT_TESTSUITE_START = 2;
71
    const EVENT_TESTSUITE_END   = 3;
72
 
73
    /**
74
     * @var integer
75
     */
76
    protected $column = 0;
77
 
78
    /**
79
     * @var integer
80
     */
81
    protected $indent = 0;
82
 
83
    /**
84
     * @var integer
85
     */
86
    protected $lastEvent = -1;
87
 
88
    /**
89
     * @var boolean
90
     */
91
    protected $lastTestFailed = FALSE;
92
 
93
    /**
94
     * @var integer
95
     */
96
    protected $numAssertions = 0;
97
 
98
    /**
99
     * @var integer
100
     */
101
    protected $numTests = -1;
102
 
103
    /**
104
     * @var integer
105
     */
106
    protected $numTestsRun = 0;
107
 
108
    /**
109
     * @var integer
110
     */
111
    protected $numTestsWidth;
112
 
113
    /**
114
     * @var boolean
115
     */
116
    protected $colors = FALSE;
117
 
118
    /**
119
     * @var boolean
120
     */
121
    protected $debug = FALSE;
122
 
123
    /**
124
     * @var boolean
125
     */
126
    protected $verbose = FALSE;
127
 
128
    /**
129
     * Constructor.
130
     *
131
     * @param  mixed   $out
132
     * @param  boolean $verbose
133
     * @param  boolean $colors
134
     * @param  boolean $debug
135
     * @throws InvalidArgumentException
136
     * @since  Method available since Release 3.0.0
137
     */
138
    public function __construct($out = NULL, $verbose = FALSE, $colors = FALSE, $debug = FALSE)
139
    {
140
        parent::__construct($out);
141
 
142
        if (is_bool($verbose)) {
143
            $this->verbose = $verbose;
144
        } else {
145
            throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean');
146
        }
147
 
148
        if (is_bool($colors)) {
149
            $this->colors = $colors;
150
        } else {
151
            throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'boolean');
152
        }
153
 
154
        if (is_bool($debug)) {
155
            $this->debug = $debug;
156
        } else {
157
            throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'boolean');
158
        }
159
    }
160
 
161
    /**
162
     * @param  PHPUnit_Framework_TestResult $result
163
     */
164
    public function printResult(PHPUnit_Framework_TestResult $result)
165
    {
166
        $this->printHeader($result->time());
167
 
168
        if ($result->errorCount() > 0) {
169
            $this->printErrors($result);
170
        }
171
 
172
        if ($result->failureCount() > 0) {
173
            if ($result->errorCount() > 0) {
174
                print "\n--\n\n";
175
            }
176
 
177
            $this->printFailures($result);
178
        }
179
 
180
        if ($this->verbose) {
181
            if ($result->notImplementedCount() > 0) {
182
                if ($result->failureCount() > 0) {
183
                    print "\n--\n\n";
184
                }
185
 
186
                $this->printIncompletes($result);
187
            }
188
 
189
            if ($result->skippedCount() > 0) {
190
                if ($result->notImplementedCount() > 0) {
191
                    print "\n--\n\n";
192
                }
193
 
194
                $this->printSkipped($result);
195
            }
196
        }
197
 
198
        $this->printFooter($result);
199
    }
200
 
201
    /**
202
     * @param  array   $defects
203
     * @param  integer $count
204
     * @param  string  $type
205
     */
206
    protected function printDefects(array $defects, $count, $type)
207
    {
208
        static $called = FALSE;
209
 
210
        if ($count == 0) {
211
            return;
212
        }
213
 
214
        $this->write(
215
          sprintf(
216
            "%sThere %s %d %s%s:\n",
217
 
218
            $called ? "\n" : '',
219
            ($count == 1) ? 'was' : 'were',
220
            $count,
221
            $type,
222
            ($count == 1) ? '' : 's'
223
          )
224
        );
225
 
226
        $i = 1;
227
 
228
        foreach ($defects as $defect) {
229
            $this->printDefect($defect, $i++);
230
        }
231
 
232
        $called = TRUE;
233
    }
234
 
235
    /**
236
     * @param  PHPUnit_Framework_TestFailure $defect
237
     * @param  integer                       $count
238
     */
239
    protected function printDefect(PHPUnit_Framework_TestFailure $defect, $count)
240
    {
241
        $this->printDefectHeader($defect, $count);
242
        $this->printDefectTrace($defect);
243
    }
244
 
245
    /**
246
     * @param  PHPUnit_Framework_TestFailure $defect
247
     * @param  integer                       $count
248
     */
249
    protected function printDefectHeader(PHPUnit_Framework_TestFailure $defect, $count)
250
    {
251
        $failedTest = $defect->failedTest();
252
 
253
        if ($failedTest instanceof PHPUnit_Framework_SelfDescribing) {
254
            $testName = $failedTest->toString();
255
        } else {
256
            $testName = get_class($failedTest);
257
        }
258
 
259
        $this->write(
260
          sprintf(
261
            "\n%d) %s\n",
262
 
263
            $count,
264
            $testName
265
          )
266
        );
267
    }
268
 
269
    /**
270
     * @param  PHPUnit_Framework_TestFailure $defect
271
     */
272
    protected function printDefectTrace(PHPUnit_Framework_TestFailure $defect)
273
    {
274
        $this->write(
275
          $defect->getExceptionAsString() . "\n" .
276
          PHPUnit_Util_Filter::getFilteredStacktrace(
277
            $defect->thrownException(),
278
            FALSE
279
          )
280
        );
281
    }
282
 
283
    /**
284
     * @param  PHPUnit_Framework_TestResult  $result
285
     */
286
    protected function printErrors(PHPUnit_Framework_TestResult $result)
287
    {
288
        $this->printDefects($result->errors(), $result->errorCount(), 'error');
289
    }
290
 
291
    /**
292
     * @param  PHPUnit_Framework_TestResult  $result
293
     */
294
    protected function printFailures(PHPUnit_Framework_TestResult $result)
295
    {
296
        $this->printDefects(
297
          $result->failures(),
298
          $result->failureCount(),
299
          'failure'
300
        );
301
    }
302
 
303
    /**
304
     * @param  PHPUnit_Framework_TestResult  $result
305
     */
306
    protected function printIncompletes(PHPUnit_Framework_TestResult $result)
307
    {
308
        $this->printDefects(
309
          $result->notImplemented(),
310
          $result->notImplementedCount(),
311
          'incomplete test'
312
        );
313
    }
314
 
315
    /**
316
     * @param  PHPUnit_Framework_TestResult  $result
317
     * @since  Method available since Release 3.0.0
318
     */
319
    protected function printSkipped(PHPUnit_Framework_TestResult $result)
320
    {
321
        $this->printDefects(
322
          $result->skipped(),
323
          $result->skippedCount(),
324
          'skipped test'
325
        );
326
    }
327
 
328
    /**
329
     * @param float $timeElapsed
330
     */
331
    protected function printHeader($timeElapsed)
332
    {
333
        if (isset($_SERVER['REQUEST_TIME'])) {
334
            $timeElapsed = PHPUnit_Util_Timer::secondsToTimeString(
335
              time() - $_SERVER['REQUEST_TIME']
336
            );
337
        } else {
338
            $timeElapsed = PHPUnit_Util_Timer::secondsToTimeString(
339
              $timeElapsed
340
            );
341
        }
342
 
343
        if (function_exists('memory_get_peak_usage')) {
344
            $memory = sprintf(
345
              ', Memory: %4.2fMb',
346
              memory_get_peak_usage(TRUE) / 1048576
347
            );
348
        } else {
349
            $memory = '';
350
        }
351
 
352
        $this->write(
353
          sprintf(
354
            "%sTime: %s%s\n\n",
355
            $this->verbose ? "\n" : "\n\n",
356
            $timeElapsed,
357
            $memory
358
          )
359
        );
360
    }
361
 
362
    /**
363
     * @param  PHPUnit_Framework_TestResult  $result
364
     */
365
    protected function printFooter(PHPUnit_Framework_TestResult $result)
366
    {
367
        if ($result->wasSuccessful() &&
368
            $result->allCompletlyImplemented() &&
369
            $result->noneSkipped()) {
370
            if ($this->colors) {
371
                $this->write("\x1b[30;42m\x1b[2K");
372
            }
373
 
374
            $this->write(
375
              sprintf(
376
                "OK (%d test%s, %d assertion%s)\n",
377
 
378
                count($result),
379
                (count($result) == 1) ? '' : 's',
380
                $this->numAssertions,
381
                ($this->numAssertions == 1) ? '' : 's'
382
              )
383
            );
384
 
385
            if ($this->colors) {
386
                $this->write("\x1b[0m\x1b[2K");
387
            }
388
        }
389
 
390
        else if ((!$result->allCompletlyImplemented() ||
391
                  !$result->noneSkipped())&&
392
                 $result->wasSuccessful()) {
393
            if ($this->colors) {
394
                $this->write(
395
                  "\x1b[30;43m\x1b[2KOK, but incomplete or skipped tests!\n" .
396
                  "\x1b[0m\x1b[30;43m\x1b[2K"
397
                );
398
            } else {
399
                $this->write("OK, but incomplete or skipped tests!\n");
400
            }
401
 
402
            $this->write(
403
              sprintf(
404
                "Tests: %d, Assertions: %d%s%s.\n",
405
 
406
                count($result),
407
                $this->numAssertions,
408
                $this->getCountString(
409
                  $result->notImplementedCount(), 'Incomplete'
410
                ),
411
                $this->getCountString(
412
                  $result->skippedCount(), 'Skipped'
413
                )
414
              )
415
            );
416
 
417
            if ($this->colors) {
418
                $this->write("\x1b[0m\x1b[2K");
419
            }
420
        }
421
 
422
        else {
423
            $this->write("\n");
424
 
425
            if ($this->colors) {
426
                $this->write(
427
                  "\x1b[37;41m\x1b[2KFAILURES!\n\x1b[0m\x1b[37;41m\x1b[2K"
428
                );
429
            } else {
430
                $this->write("FAILURES!\n");
431
            }
432
 
433
            $this->write(
434
              sprintf(
435
                "Tests: %d, Assertions: %s%s%s%s%s.\n",
436
 
437
                count($result),
438
                $this->numAssertions,
439
                $this->getCountString($result->failureCount(), 'Failures'),
440
                $this->getCountString($result->errorCount(), 'Errors'),
441
                $this->getCountString(
442
                  $result->notImplementedCount(), 'Incomplete'
443
                ),
444
                $this->getCountString($result->skippedCount(), 'Skipped')
445
              )
446
            );
447
 
448
            if ($this->colors) {
449
                $this->write("\x1b[0m\x1b[2K");
450
            }
451
        }
452
    }
453
 
454
    /**
455
     * @param  integer $count
456
     * @param  string  $name
457
     * @return string
458
     * @since  Method available since Release 3.0.0
459
     */
460
    protected function getCountString($count, $name)
461
    {
462
        $string = '';
463
 
464
        if ($count > 0) {
465
            $string = sprintf(
466
              ', %s: %d',
467
 
468
              $name,
469
              $count
470
            );
471
        }
472
 
473
        return $string;
474
    }
475
 
476
    /**
477
     */
478
    public function printWaitPrompt()
479
    {
480
        $this->write("\n<RETURN> to continue\n");
481
    }
482
 
483
    /**
484
     * An error occurred.
485
     *
486
     * @param  PHPUnit_Framework_Test $test
487
     * @param  Exception              $e
488
     * @param  float                  $time
489
     */
490
    public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
491
    {
492
        $this->writeProgress('E');
493
        $this->lastTestFailed = TRUE;
494
    }
495
 
496
    /**
497
     * A failure occurred.
498
     *
499
     * @param  PHPUnit_Framework_Test                 $test
500
     * @param  PHPUnit_Framework_AssertionFailedError $e
501
     * @param  float                                  $time
502
     */
503
    public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
504
    {
505
        $this->writeProgress('F');
506
        $this->lastTestFailed = TRUE;
507
    }
508
 
509
    /**
510
     * Incomplete test.
511
     *
512
     * @param  PHPUnit_Framework_Test $test
513
     * @param  Exception              $e
514
     * @param  float                  $time
515
     */
516
    public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
517
    {
518
        $this->writeProgress('I');
519
        $this->lastTestFailed = TRUE;
520
    }
521
 
522
    /**
523
     * Skipped test.
524
     *
525
     * @param  PHPUnit_Framework_Test $test
526
     * @param  Exception              $e
527
     * @param  float                  $time
528
     * @since  Method available since Release 3.0.0
529
     */
530
    public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
531
    {
532
        $this->writeProgress('S');
533
        $this->lastTestFailed = TRUE;
534
    }
535
 
536
    /**
537
     * A testsuite started.
538
     *
539
     * @param  PHPUnit_Framework_TestSuite $suite
540
     * @since  Method available since Release 2.2.0
541
     */
542
    public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
543
    {
544
        if ($this->numTests == -1) {
545
            $this->numTests      = count($suite);
546
            $this->numTestsWidth = strlen((string)$this->numTests);
547
        } else {
548
            $this->indent++;
549
        }
550
 
551
        if ($this->verbose) {
552
            $name = $suite->getName();
553
 
554
            if (empty($name)) {
555
                $name = 'Test Suite';
556
            } else {
557
                $name = preg_replace( '(^.*::(.*?)$)', '\\1', $name );
558
            }
559
 
560
            $this->write(
561
              sprintf(
562
                "%s%s%s",
563
 
564
                $this->lastEvent == self::EVENT_TESTSUITE_END ||
565
                $suite instanceof PHPUnit_Framework_TestSuite_DataProvider ?
566
                "\n" :
567
                '',
568
                str_repeat(' ', $this->indent),
569
                $name
570
              )
571
            );
572
 
573
            $this->writeNewLine();
574
        }
575
 
576
        $this->lastEvent = self::EVENT_TESTSUITE_START;
577
    }
578
 
579
    /**
580
     * A testsuite ended.
581
     *
582
     * @param  PHPUnit_Framework_TestSuite $suite
583
     * @since  Method available since Release 2.2.0
584
     */
585
    public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
586
    {
587
        $this->indent--;
588
 
589
        if ($this->verbose) {
590
            if ($this->lastEvent != self::EVENT_TESTSUITE_END) {
591
                $this->writeNewLine();
592
            }
593
        }
594
 
595
        $this->lastEvent = self::EVENT_TESTSUITE_END;
596
    }
597
 
598
    /**
599
     * A test started.
600
     *
601
     * @param  PHPUnit_Framework_Test $test
602
     */
603
    public function startTest(PHPUnit_Framework_Test $test)
604
    {
605
        $this->lastEvent = self::EVENT_TEST_START;
606
 
607
        if ($this->debug) {
608
            $this->write(
609
              sprintf(
610
                "\nStarting test '%s'.\n", PHPUnit_Util_Test::describe($test)
611
              )
612
            );
613
        }
614
    }
615
 
616
    /**
617
     * A test ended.
618
     *
619
     * @param  PHPUnit_Framework_Test $test
620
     * @param  float                  $time
621
     */
622
    public function endTest(PHPUnit_Framework_Test $test, $time)
623
    {
624
        if (!$this->lastTestFailed) {
625
            $this->writeProgress('.');
626
        }
627
 
628
        if ($test instanceof PHPUnit_Framework_TestCase) {
629
            $this->numAssertions += $test->getNumAssertions();
630
        }
631
 
632
        $this->lastEvent      = self::EVENT_TEST_END;
633
        $this->lastTestFailed = FALSE;
634
    }
635
 
636
    /**
637
     * @param  string $progress
638
     */
639
    protected function writeProgress($progress)
640
    {
641
        $this->write($progress);
642
        $this->column++;
643
        $this->numTestsRun++;
644
 
645
        if ($this->column == 60) {
646
            if (!$this->verbose) {
647
                $this->write(
648
                  sprintf(
649
                    ' %' . $this->numTestsWidth . 'd / %' .
650
                           $this->numTestsWidth . "d",
651
 
652
                    $this->numTestsRun,
653
                    $this->numTests
654
                  )
655
                );
656
            }
657
 
658
            $this->writeNewLine();
659
        }
660
    }
661
 
662
    protected function writeNewLine()
663
    {
664
        $this->write("\n");
665
 
666
        if ($this->verbose) {
667
            $this->column = $this->indent;
668
            $this->write(str_repeat(' ', max(0, $this->indent)));
669
        } else {
670
            $this->column = 0;
671
        }
672
    }
673
}
674
?>