]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - tests/PHPUnit/PHPUnit/Framework/TestResult.php
Release 6.2.0
[Github/sugarcrm.git] / tests / PHPUnit / PHPUnit / Framework / TestResult.php
1 <?php
2 /**
3  * PHPUnit
4  *
5  * Copyright (c) 2002-2011, Sebastian Bergmann <sebastian@phpunit.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  * @package    PHPUnit
38  * @subpackage Framework
39  * @author     Sebastian Bergmann <sebastian@phpunit.de>
40  * @copyright  2002-2011 Sebastian Bergmann <sebastian@phpunit.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 'PHP/CodeCoverage.php';
47 require_once 'PHP/Timer.php';
48
49 /**
50  * A TestResult collects the results of executing a test case.
51  *
52  * @package    PHPUnit
53  * @subpackage Framework
54  * @author     Sebastian Bergmann <sebastian@phpunit.de>
55  * @copyright  2002-2011 Sebastian Bergmann <sebastian@phpunit.de>
56  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
57  * @version    Release: 3.5.13
58  * @link       http://www.phpunit.de/
59  * @since      Class available since Release 2.0.0
60  */
61 class PHPUnit_Framework_TestResult implements Countable
62 {
63     /**
64      * @var boolean
65      */
66     protected static $xdebugLoaded = NULL;
67
68     /**
69      * @var boolean
70      */
71     protected static $useXdebug = NULL;
72
73     /**
74      * @var array
75      */
76     protected $passed = array();
77
78     /**
79      * @var array
80      */
81     protected $errors = array();
82
83     /**
84      * @var array
85      */
86     protected $deprecatedFeatures = array();
87
88     /**
89      * @var array
90      */
91     protected $failures = array();
92
93     /**
94      * @var array
95      */
96     protected $notImplemented = array();
97
98     /**
99      * @var array
100      */
101     protected $skipped = array();
102
103     /**
104      * @var array
105      */
106     protected $listeners = array();
107
108     /**
109      * @var integer
110      */
111     protected $runTests = 0;
112
113     /**
114      * @var float
115      */
116     protected $time = 0;
117
118     /**
119      * @var PHPUnit_Framework_TestSuite
120      */
121     protected $topTestSuite = NULL;
122
123     /**
124      * Code Coverage information.
125      *
126      * @var array
127      */
128     protected $codeCoverage;
129
130     /**
131      * @var boolean
132      */
133     protected $collectCodeCoverageInformation = FALSE;
134
135     /**
136      * @var boolean
137      */
138     protected $collectRawCodeCoverageInformation = FALSE;
139
140     /**
141      * @var array
142      */
143     protected $rawCodeCoverageInformation = array();
144
145     /**
146      * @var boolean
147      */
148     protected $convertErrorsToExceptions = TRUE;
149
150     /**
151      * @var boolean
152      */
153     protected $stop = FALSE;
154
155     /**
156      * @var boolean
157      */
158     protected $stopOnError = FALSE;
159
160     /**
161      * @var boolean
162      */
163     protected $stopOnFailure = FALSE;
164
165     /**
166      * @var boolean
167      */
168     protected $strictMode = FALSE;
169
170     /**
171      * @var boolean
172      */
173     protected $stopOnIncomplete = FALSE;
174
175     /**
176      * @var boolean
177      */
178     protected $stopOnSkipped = FALSE;
179
180     /**
181      * @var boolean
182      */
183     protected $lastTestFailed = FALSE;
184
185     /**
186      * @param PHP_CodeCoverage $codeCoverage
187      */
188     public function __construct(PHP_CodeCoverage $codeCoverage = NULL)
189     {
190         if ($codeCoverage === NULL) {
191             $codeCoverage = PHP_CodeCoverage::getInstance();
192         }
193
194         $this->codeCoverage = $codeCoverage;
195     }
196
197     /**
198      * Registers a TestListener.
199      *
200      * @param  PHPUnit_Framework_TestListener
201      */
202     public function addListener(PHPUnit_Framework_TestListener $listener)
203     {
204         $this->listeners[] = $listener;
205     }
206
207     /**
208      * Unregisters a TestListener.
209      *
210      * @param  PHPUnit_Framework_TestListener $listener
211      */
212     public function removeListener(PHPUnit_Framework_TestListener $listener)
213     {
214         foreach ($this->listeners as $key => $_listener) {
215             if ($listener === $_listener) {
216                 unset($this->listeners[$key]);
217             }
218         }
219     }
220
221     /**
222      * Flushes all flushable TestListeners.
223      *
224      * @since  Method available since Release 3.0.0
225      */
226     public function flushListeners()
227     {
228         foreach ($this->listeners as $listener) {
229             if ($listener instanceof PHPUnit_Util_Printer) {
230                 $listener->flush();
231             }
232         }
233     }
234
235     /**
236      * Adds an error to the list of errors.
237      *
238      * @param  PHPUnit_Framework_Test $test
239      * @param  Exception              $e
240      * @param  float                  $time
241      */
242     public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
243     {
244         if ($e instanceof PHPUnit_Framework_IncompleteTest) {
245             $this->notImplemented[] = new PHPUnit_Framework_TestFailure(
246               $test, $e
247             );
248
249             $notifyMethod = 'addIncompleteTest';
250
251             if ($this->stopOnIncomplete) {
252                 $this->stop();
253             }
254         }
255
256         else if ($e instanceof PHPUnit_Framework_SkippedTest) {
257             $this->skipped[] = new PHPUnit_Framework_TestFailure($test, $e);
258             $notifyMethod    = 'addSkippedTest';
259
260             if ($this->stopOnSkipped) {
261                 $this->stop();
262             }
263         }
264
265         else {
266             $this->errors[] = new PHPUnit_Framework_TestFailure($test, $e);
267             $notifyMethod   = 'addError';
268
269             if ($this->stopOnError || $this->stopOnFailure) {
270                 $this->stop();
271             }
272         }
273
274         foreach ($this->listeners as $listener) {
275             $listener->$notifyMethod($test, $e, $time);
276         }
277
278         $this->lastTestFailed = TRUE;
279         $this->time          += $time;
280     }
281
282     /**
283      * Adds a failure to the list of failures.
284      * The passed in exception caused the failure.
285      *
286      * @param  PHPUnit_Framework_Test                 $test
287      * @param  PHPUnit_Framework_AssertionFailedError $e
288      * @param  float                                  $time
289      */
290     public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
291     {
292         if ($e instanceof PHPUnit_Framework_IncompleteTest) {
293             $this->notImplemented[] = new PHPUnit_Framework_TestFailure(
294               $test, $e
295             );
296
297             $notifyMethod = 'addIncompleteTest';
298
299             if ($this->stopOnIncomplete) {
300                 $this->stop();
301             }
302         }
303
304         else if ($e instanceof PHPUnit_Framework_SkippedTest) {
305             $this->skipped[] = new PHPUnit_Framework_TestFailure($test, $e);
306             $notifyMethod    = 'addSkippedTest';
307
308             if ($this->stopOnSkipped) {
309                 $this->stop();
310             }
311         }
312
313         else {
314             $this->failures[] = new PHPUnit_Framework_TestFailure($test, $e);
315             $notifyMethod     = 'addFailure';
316
317             if ($this->stopOnFailure) {
318                 $this->stop();
319             }
320         }
321
322         foreach ($this->listeners as $listener) {
323             $listener->$notifyMethod($test, $e, $time);
324         }
325
326         $this->lastTestFailed = TRUE;
327         $this->time          += $time;
328     }
329
330     /**
331      * Adds a deprecated feature notice to the list of deprecated features used during run
332      *
333      * @param PHPUnit_Util_DeprecatedFeature $deprecatedFeature
334      */
335     public function addDeprecatedFeature(PHPUnit_Util_DeprecatedFeature $deprecatedFeature)
336     {
337         $this->deprecatedFeatures[] = $deprecatedFeature;
338     }
339
340     /**
341      * Informs the result that a testsuite will be started.
342      *
343      * @param  PHPUnit_Framework_TestSuite $suite
344      * @since  Method available since Release 2.2.0
345      */
346     public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
347     {
348         if ($this->topTestSuite === NULL) {
349             $this->topTestSuite = $suite;
350         }
351
352         foreach ($this->listeners as $listener) {
353             $listener->startTestSuite($suite);
354         }
355     }
356
357     /**
358      * Informs the result that a testsuite was completed.
359      *
360      * @param  PHPUnit_Framework_TestSuite $suite
361      * @since  Method available since Release 2.2.0
362      */
363     public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
364     {
365         foreach ($this->listeners as $listener) {
366             $listener->endTestSuite($suite);
367         }
368     }
369
370     /**
371      * Informs the result that a test will be started.
372      *
373      * @param  PHPUnit_Framework_Test $test
374      */
375     public function startTest(PHPUnit_Framework_Test $test)
376     {
377         $this->lastTestFailed = FALSE;
378         $this->runTests      += count($test);
379
380         foreach ($this->listeners as $listener) {
381             $listener->startTest($test);
382         }
383     }
384
385     /**
386      * Informs the result that a test was completed.
387      *
388      * @param  PHPUnit_Framework_Test $test
389      * @param  float                  $time
390      */
391     public function endTest(PHPUnit_Framework_Test $test, $time)
392     {
393         foreach ($this->listeners as $listener) {
394             $listener->endTest($test, $time);
395         }
396
397         if (!$this->lastTestFailed && $test instanceof PHPUnit_Framework_TestCase) {
398             $this->passed[get_class($test) . '::' . $test->getName()] = $test->getResult();
399             $this->time                                              += $time;
400         }
401     }
402
403     /**
404      * Returns TRUE if no incomplete test occured.
405      *
406      * @return boolean
407      */
408     public function allCompletlyImplemented()
409     {
410         return $this->notImplementedCount() == 0;
411     }
412
413     /**
414      * Gets the number of incomplete tests.
415      *
416      * @return integer
417      */
418     public function notImplementedCount()
419     {
420         return count($this->notImplemented);
421     }
422
423     /**
424      * Returns an Enumeration for the incomplete tests.
425      *
426      * @return array
427      */
428     public function notImplemented()
429     {
430         return $this->notImplemented;
431     }
432
433     /**
434      * Returns TRUE if no test has been skipped.
435      *
436      * @return boolean
437      * @since  Method available since Release 3.0.0
438      */
439     public function noneSkipped()
440     {
441         return $this->skippedCount() == 0;
442     }
443
444     /**
445      * Gets the number of skipped tests.
446      *
447      * @return integer
448      * @since  Method available since Release 3.0.0
449      */
450     public function skippedCount()
451     {
452         return count($this->skipped);
453     }
454
455     /**
456      * Returns an Enumeration for the skipped tests.
457      *
458      * @return array
459      * @since  Method available since Release 3.0.0
460      */
461     public function skipped()
462     {
463         return $this->skipped;
464     }
465
466     /**
467      * Gets the number of detected errors.
468      *
469      * @return integer
470      */
471     public function errorCount()
472     {
473         return count($this->errors);
474     }
475
476     /**
477      * Returns an Enumeration for the errors.
478      *
479      * @return array
480      */
481     public function errors()
482     {
483         return $this->errors;
484     }
485
486     /**
487      * Returns an Enumeration for the deprecated features used.
488      *
489      * @return array
490      * @since  Method available since Release 3.5.7
491      */
492     public function deprecatedFeatures()
493     {
494         return $this->deprecatedFeatures;
495     }
496
497     /**
498      * Returns an Enumeration for the deprecated features used.
499      *
500      * @return array
501      * @since  Method available since Release 3.5.7
502      */
503     public function deprecatedFeaturesCount()
504     {
505         return count($this->deprecatedFeatures);
506     }
507
508     /**
509      * Gets the number of detected failures.
510      *
511      * @return integer
512      */
513     public function failureCount()
514     {
515         return count($this->failures);
516     }
517
518     /**
519      * Returns an Enumeration for the failures.
520      *
521      * @return array
522      */
523     public function failures()
524     {
525         return $this->failures;
526     }
527
528     /**
529      * Returns the names of the tests that have passed.
530      *
531      * @return array
532      * @since  Method available since Release 3.4.0
533      */
534     public function passed()
535     {
536         return $this->passed;
537     }
538
539     /**
540      * Returns the (top) test suite.
541      *
542      * @return PHPUnit_Framework_TestSuite
543      * @since  Method available since Release 3.0.0
544      */
545     public function topTestSuite()
546     {
547         return $this->topTestSuite;
548     }
549
550     /**
551      * Enables or disables the collection of Code Coverage information.
552      *
553      * @param  boolean $flag
554      * @throws InvalidArgumentException
555      * @since  Method available since Release 2.3.0
556      */
557     public function collectCodeCoverageInformation($flag)
558     {
559         if (is_bool($flag)) {
560             $this->collectCodeCoverageInformation = $flag;
561         } else {
562             throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
563         }
564     }
565
566     /**
567      * Enables or disables the collection of raw Code Coverage information.
568      *
569      * @param  boolean $flag
570      * @throws InvalidArgumentException
571      * @since  Method available since Release 3.4.0
572      */
573     public function collectRawCodeCoverageInformation($flag)
574     {
575         if (is_bool($flag)) {
576             $this->collectRawCodeCoverageInformation = $flag;
577
578             if ($flag === TRUE) {
579                 $this->collectCodeCoverageInformation = $flag;
580             }
581         } else {
582             throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
583         }
584     }
585
586     /**
587      * Returns whether code coverage information should be collected.
588      *
589      * @return boolean If code coverage should be collected
590      * @since  Method available since Release 3.2.0
591      */
592     public function getCollectCodeCoverageInformation()
593     {
594         return $this->collectCodeCoverageInformation;
595     }
596
597     /**
598      * Returns the raw Code Coverage information.
599      *
600      * @return array
601      * @since  Method available since Release 3.4.0
602      */
603     public function getRawCodeCoverageInformation()
604     {
605         return $this->rawCodeCoverageInformation;
606     }
607
608     /**
609      * Returns the strict mode configuration option
610      *
611      * @return boolean
612      */
613     public function isStrict()
614     {
615         return $this->strictMode;
616     }
617
618     /**
619      * Runs a TestCase.
620      *
621      * @param  PHPUnit_Framework_Test $test
622      */
623     public function run(PHPUnit_Framework_Test $test)
624     {
625         PHPUnit_Framework_Assert::resetCount();
626
627         $error      = FALSE;
628         $failure    = FALSE;
629         $incomplete = FALSE;
630         $skipped    = FALSE;
631
632         $this->startTest($test);
633
634         $errorHandlerSet = FALSE;
635
636         if ($this->convertErrorsToExceptions) {
637             $oldErrorHandler = set_error_handler(
638               array('PHPUnit_Util_ErrorHandler', 'handleError'),
639               E_ALL | E_STRICT
640             );
641
642             if ($oldErrorHandler === NULL) {
643                 $errorHandlerSet = TRUE;
644             } else {
645                 restore_error_handler();
646             }
647         }
648
649         if (self::$xdebugLoaded === NULL) {
650             self::$xdebugLoaded = extension_loaded('xdebug');
651             self::$useXdebug    = self::$xdebugLoaded;
652         }
653
654         $useXdebug = self::$useXdebug &&
655                      $this->collectCodeCoverageInformation &&
656                      !$test instanceof PHPUnit_Extensions_SeleniumTestCase &&
657                      !$test instanceof PHPUnit_Framework_Warning;
658
659         if ($useXdebug) {
660             $this->codeCoverage->start($test);
661         }
662
663         PHP_Timer::start();
664
665         try {
666             $test->runBare();
667         }
668
669         catch (PHPUnit_Framework_AssertionFailedError $e) {
670             $failure = TRUE;
671
672             if ($e instanceof PHPUnit_Framework_IncompleteTestError) {
673                 $incomplete = TRUE;
674             }
675
676             else if ($e instanceof PHPUnit_Framework_SkippedTestError) {
677                 $skipped = TRUE;
678             }
679         }
680
681         catch (Exception $e) {
682             $error = TRUE;
683         }
684
685         $time = PHP_Timer::stop();
686         $test->addToAssertionCount(PHPUnit_Framework_Assert::getCount());
687
688         if ($this->strictMode && $test->getNumAssertions() == 0) {
689             $incomplete = TRUE;
690         }
691
692         if ($useXdebug) {
693             $data = $this->codeCoverage->stop(FALSE);
694
695             if (!$incomplete && !$skipped) {
696                 if ($this->collectRawCodeCoverageInformation) {
697                     $this->rawCodeCoverageInformation[] = $data;
698                 } else {
699                     $filterGroups = array('DEFAULT', 'TESTS');
700
701                     if (!defined('PHPUNIT_TESTSUITE')) {
702                         $filterGroups[] = 'PHPUNIT';
703                     }
704
705                     $this->codeCoverage->append($data, $test, $filterGroups);
706                 }
707             }
708
709             unset($data);
710         }
711
712         if ($errorHandlerSet === TRUE) {
713             restore_error_handler();
714         }
715
716         if ($error === TRUE) {
717             $this->addError($test, $e, $time);
718         }
719
720         else if ($failure === TRUE) {
721             $this->addFailure($test, $e, $time);
722         }
723
724         else if ($this->strictMode && $test->getNumAssertions() == 0) {
725             $this->addFailure(
726               $test,
727               new PHPUnit_Framework_IncompleteTestError(
728                 'This test did not perform any assertions'
729               ),
730               $time
731             );
732         }
733
734         $this->endTest($test, $time);
735     }
736
737     /**
738      * Gets the number of run tests.
739      *
740      * @return integer
741      */
742     public function count()
743     {
744         return $this->runTests;
745     }
746
747     /**
748      * Checks whether the test run should stop.
749      *
750      * @return boolean
751      */
752     public function shouldStop()
753     {
754         return $this->stop;
755     }
756
757     /**
758      * Marks that the test run should stop.
759      *
760      */
761     public function stop()
762     {
763         $this->stop = TRUE;
764     }
765
766     /**
767      * Returns the PHP_CodeCoverage object.
768      *
769      * @return PHP_CodeCoverage
770      * @since  Method available since Release 3.5.0
771      */
772     public function getCodeCoverage()
773     {
774         return $this->codeCoverage;
775     }
776
777     /**
778      * Enables or disables the error-to-exception conversion.
779      *
780      * @param  boolean $flag
781      * @throws InvalidArgumentException
782      * @since  Method available since Release 3.2.14
783      */
784     public function convertErrorsToExceptions($flag)
785     {
786         if (is_bool($flag)) {
787             $this->convertErrorsToExceptions = $flag;
788         } else {
789             throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
790         }
791     }
792
793     /**
794      * Returns the error-to-exception conversion setting.
795      *
796      * @return boolean
797      * @since  Method available since Release 3.4.0
798      */
799     public function getConvertErrorsToExceptions()
800     {
801         return $this->convertErrorsToExceptions;
802     }
803
804     /**
805      * Enables or disables the stopping when an error occurs.
806      *
807      * @param  boolean $flag
808      * @throws InvalidArgumentException
809      * @since  Method available since Release 3.5.0
810      */
811     public function stopOnError($flag)
812     {
813         if (is_bool($flag)) {
814             $this->stopOnError = $flag;
815         } else {
816             throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
817         }
818     }
819
820     /**
821      * Enables or disables the stopping when a failure occurs.
822      *
823      * @param  boolean $flag
824      * @throws InvalidArgumentException
825      * @since  Method available since Release 3.1.0
826      */
827     public function stopOnFailure($flag)
828     {
829         if (is_bool($flag)) {
830             $this->stopOnFailure = $flag;
831         } else {
832             throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
833         }
834     }
835
836     /**
837      * Enables or disables the strict mode.
838      *
839      * When active
840      *   * Tests that do not assert anything will be marked as incomplete.
841      *   * Tests that are incomplete or skipped yield no code coverage.
842      *
843      * @param  boolean $flag
844      * @throws InvalidArgumentException
845      * @since  Method available since Release 3.5.2
846      */
847     public function strictMode($flag)
848     {
849         if (is_bool($flag)) {
850             $this->strictMode = $flag;
851         } else {
852             throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
853         }
854     }
855
856     /**
857      * Enables or disables the stopping for incomplete tests.
858      *
859      * @param  boolean $flag
860      * @throws InvalidArgumentException
861      * @since  Method available since Release 3.5.0
862      */
863     public function stopOnIncomplete($flag)
864     {
865         if (is_bool($flag)) {
866             $this->stopOnIncomplete = $flag;
867         } else {
868             throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
869         }
870     }
871
872     /**
873      * Enables or disables the stopping for skipped tests.
874      *
875      * @param  boolean $flag
876      * @throws InvalidArgumentException
877      * @since  Method available since Release 3.1.0
878      */
879     public function stopOnSkipped($flag)
880     {
881         if (is_bool($flag)) {
882             $this->stopOnSkipped = $flag;
883         } else {
884             throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
885         }
886     }
887
888     /**
889      * Returns the time spent running the tests.
890      *
891      * @return float
892      */
893     public function time()
894     {
895         return $this->time;
896     }
897
898     /**
899      * Returns whether the entire test was successful or not.
900      *
901      * @return boolean
902      */
903     public function wasSuccessful()
904     {
905         return empty($this->errors) && empty($this->failures);
906     }
907 }