638f4251375e2b7d6abf127f3ef53c87f812aee0
[yaffs-website] / vendor / phpunit / phpunit / src / Framework / TestCase.php
1 <?php
2 /*
3  * This file is part of PHPUnit.
4  *
5  * (c) Sebastian Bergmann <sebastian@phpunit.de>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 use SebastianBergmann\GlobalState\Snapshot;
12 use SebastianBergmann\GlobalState\Restorer;
13 use SebastianBergmann\GlobalState\Blacklist;
14 use SebastianBergmann\Diff\Differ;
15 use SebastianBergmann\Exporter\Exporter;
16 use Prophecy\Exception\Prediction\PredictionException;
17 use Prophecy\Prophet;
18
19 /**
20  * A TestCase defines the fixture to run multiple tests.
21  *
22  * To define a TestCase
23  *
24  *   1) Implement a subclass of PHPUnit_Framework_TestCase.
25  *   2) Define instance variables that store the state of the fixture.
26  *   3) Initialize the fixture state by overriding setUp().
27  *   4) Clean-up after a test by overriding tearDown().
28  *
29  * Each test runs in its own fixture so there can be no side effects
30  * among test runs.
31  *
32  * Here is an example:
33  *
34  * <code>
35  * <?php
36  * class MathTest extends PHPUnit_Framework_TestCase
37  * {
38  *     public $value1;
39  *     public $value2;
40  *
41  *     protected function setUp()
42  *     {
43  *         $this->value1 = 2;
44  *         $this->value2 = 3;
45  *     }
46  * }
47  * ?>
48  * </code>
49  *
50  * For each test implement a method which interacts with the fixture.
51  * Verify the expected results with assertions specified by calling
52  * assert with a boolean.
53  *
54  * <code>
55  * <?php
56  * public function testPass()
57  * {
58  *     $this->assertTrue($this->value1 + $this->value2 == 5);
59  * }
60  * ?>
61  * </code>
62  *
63  * @since Class available since Release 2.0.0
64  */
65 abstract class PHPUnit_Framework_TestCase extends PHPUnit_Framework_Assert implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing
66 {
67     /**
68      * Enable or disable the backup and restoration of the $GLOBALS array.
69      * Overwrite this attribute in a child class of TestCase.
70      * Setting this attribute in setUp() has no effect!
71      *
72      * @var bool
73      */
74     protected $backupGlobals = null;
75
76     /**
77      * @var array
78      */
79     protected $backupGlobalsBlacklist = array();
80
81     /**
82      * Enable or disable the backup and restoration of static attributes.
83      * Overwrite this attribute in a child class of TestCase.
84      * Setting this attribute in setUp() has no effect!
85      *
86      * @var bool
87      */
88     protected $backupStaticAttributes = null;
89
90     /**
91      * @var array
92      */
93     protected $backupStaticAttributesBlacklist = array();
94
95     /**
96      * Whether or not this test is to be run in a separate PHP process.
97      *
98      * @var bool
99      */
100     protected $runTestInSeparateProcess = null;
101
102     /**
103      * Whether or not this test should preserve the global state when
104      * running in a separate PHP process.
105      *
106      * @var bool
107      */
108     protected $preserveGlobalState = true;
109
110     /**
111      * Whether or not this test is running in a separate PHP process.
112      *
113      * @var bool
114      */
115     private $inIsolation = false;
116
117     /**
118      * @var array
119      */
120     private $data = array();
121
122     /**
123      * @var string
124      */
125     private $dataName = '';
126
127     /**
128      * @var bool
129      */
130     private $useErrorHandler = null;
131
132     /**
133      * The name of the expected Exception.
134      *
135      * @var mixed
136      */
137     private $expectedException = null;
138
139     /**
140      * The message of the expected Exception.
141      *
142      * @var string
143      */
144     private $expectedExceptionMessage = '';
145
146     /**
147      * The regex pattern to validate the expected Exception message.
148      *
149      * @var string
150      */
151     private $expectedExceptionMessageRegExp = '';
152
153     /**
154      * The code of the expected Exception.
155      *
156      * @var int
157      */
158     private $expectedExceptionCode;
159
160     /**
161      * The name of the test case.
162      *
163      * @var string
164      */
165     private $name = null;
166
167     /**
168      * @var array
169      */
170     private $dependencies = array();
171
172     /**
173      * @var array
174      */
175     private $dependencyInput = array();
176
177     /**
178      * @var array
179      */
180     private $iniSettings = array();
181
182     /**
183      * @var array
184      */
185     private $locale = array();
186
187     /**
188      * @var array
189      */
190     private $mockObjects = array();
191
192     /**
193      * @var array
194      */
195     private $mockObjectGenerator = null;
196
197     /**
198      * @var int
199      */
200     private $status;
201
202     /**
203      * @var string
204      */
205     private $statusMessage = '';
206
207     /**
208      * @var int
209      */
210     private $numAssertions = 0;
211
212     /**
213      * @var PHPUnit_Framework_TestResult
214      */
215     private $result;
216
217     /**
218      * @var mixed
219      */
220     private $testResult;
221
222     /**
223      * @var string
224      */
225     private $output = '';
226
227     /**
228      * @var string
229      */
230     private $outputExpectedRegex = null;
231
232     /**
233      * @var string
234      */
235     private $outputExpectedString = null;
236
237     /**
238      * @var mixed
239      */
240     private $outputCallback = false;
241
242     /**
243      * @var bool
244      */
245     private $outputBufferingActive = false;
246
247     /**
248      * @var int
249      */
250     private $outputBufferingLevel;
251
252     /**
253      * @var SebastianBergmann\GlobalState\Snapshot
254      */
255     private $snapshot;
256
257     /**
258      * @var Prophecy\Prophet
259      */
260     private $prophet;
261
262     /**
263      * @var bool
264      */
265     private $disallowChangesToGlobalState = false;
266
267     /**
268      * Constructs a test case with the given name.
269      *
270      * @param string $name
271      * @param array  $data
272      * @param string $dataName
273      */
274     public function __construct($name = null, array $data = array(), $dataName = '')
275     {
276         if ($name !== null) {
277             $this->setName($name);
278         }
279
280         $this->data                = $data;
281         $this->dataName            = $dataName;
282     }
283
284     /**
285      * Returns a string representation of the test case.
286      *
287      * @return string
288      */
289     public function toString()
290     {
291         $class = new ReflectionClass($this);
292
293         $buffer = sprintf(
294             '%s::%s',
295             $class->name,
296             $this->getName(false)
297         );
298
299         return $buffer . $this->getDataSetAsString();
300     }
301
302     /**
303      * Counts the number of test cases executed by run(TestResult result).
304      *
305      * @return int
306      */
307     public function count()
308     {
309         return 1;
310     }
311
312     /**
313      * Returns the annotations for this test.
314      *
315      * @return array
316      *
317      * @since Method available since Release 3.4.0
318      */
319     public function getAnnotations()
320     {
321         return PHPUnit_Util_Test::parseTestMethodAnnotations(
322             get_class($this),
323             $this->name
324         );
325     }
326
327     /**
328      * Gets the name of a TestCase.
329      *
330      * @param bool $withDataSet
331      *
332      * @return string
333      */
334     public function getName($withDataSet = true)
335     {
336         if ($withDataSet) {
337             return $this->name . $this->getDataSetAsString(false);
338         } else {
339             return $this->name;
340         }
341     }
342
343     /**
344      * Returns the size of the test.
345      *
346      * @return int
347      *
348      * @since  Method available since Release 3.6.0
349      */
350     public function getSize()
351     {
352         return PHPUnit_Util_Test::getSize(
353             get_class($this),
354             $this->getName(false)
355         );
356     }
357
358     /**
359      * @return string
360      *
361      * @since  Method available since Release 3.6.0
362      */
363     public function getActualOutput()
364     {
365         if (!$this->outputBufferingActive) {
366             return $this->output;
367         } else {
368             return ob_get_contents();
369         }
370     }
371
372     /**
373      * @return bool
374      *
375      * @since  Method available since Release 3.6.0
376      */
377     public function hasOutput()
378     {
379         if (strlen($this->output) === 0) {
380             return false;
381         }
382
383         if ($this->hasExpectationOnOutput()) {
384             return false;
385         }
386
387         return true;
388     }
389
390     /**
391      * @param string $expectedRegex
392      *
393      * @since Method available since Release 3.6.0
394      *
395      * @throws PHPUnit_Framework_Exception
396      */
397     public function expectOutputRegex($expectedRegex)
398     {
399         if ($this->outputExpectedString !== null) {
400             throw new PHPUnit_Framework_Exception;
401         }
402
403         if (is_string($expectedRegex) || is_null($expectedRegex)) {
404             $this->outputExpectedRegex = $expectedRegex;
405         }
406     }
407
408     /**
409      * @param string $expectedString
410      *
411      * @since Method available since Release 3.6.0
412      */
413     public function expectOutputString($expectedString)
414     {
415         if ($this->outputExpectedRegex !== null) {
416             throw new PHPUnit_Framework_Exception;
417         }
418
419         if (is_string($expectedString) || is_null($expectedString)) {
420             $this->outputExpectedString = $expectedString;
421         }
422     }
423
424     /**
425      * @return bool
426      *
427      * @since Method available since Release 3.6.5
428      * @deprecated
429      */
430     public function hasPerformedExpectationsOnOutput()
431     {
432         return $this->hasExpectationOnOutput();
433     }
434
435     /**
436      * @return bool
437      *
438      * @since Method available since Release 4.3.3
439      */
440     public function hasExpectationOnOutput()
441     {
442         return is_string($this->outputExpectedString) || is_string($this->outputExpectedRegex);
443     }
444
445     /**
446      * @return string
447      *
448      * @since  Method available since Release 3.2.0
449      */
450     public function getExpectedException()
451     {
452         return $this->expectedException;
453     }
454
455     /**
456      * @param mixed  $exceptionName
457      * @param string $exceptionMessage
458      * @param int    $exceptionCode
459      *
460      * @since  Method available since Release 3.2.0
461      */
462     public function setExpectedException($exceptionName, $exceptionMessage = '', $exceptionCode = null)
463     {
464         $this->expectedException        = $exceptionName;
465         $this->expectedExceptionMessage = $exceptionMessage;
466         $this->expectedExceptionCode    = $exceptionCode;
467     }
468
469     /**
470      * @param mixed  $exceptionName
471      * @param string $exceptionMessageRegExp
472      * @param int    $exceptionCode
473      *
474      * @since Method available since Release 4.3.0
475      */
476     public function setExpectedExceptionRegExp($exceptionName, $exceptionMessageRegExp = '', $exceptionCode = null)
477     {
478         $this->expectedException              = $exceptionName;
479         $this->expectedExceptionMessageRegExp = $exceptionMessageRegExp;
480         $this->expectedExceptionCode          = $exceptionCode;
481     }
482
483     /**
484      * @since  Method available since Release 3.4.0
485      */
486     protected function setExpectedExceptionFromAnnotation()
487     {
488         try {
489             $expectedException = PHPUnit_Util_Test::getExpectedException(
490                 get_class($this),
491                 $this->name
492             );
493
494             if ($expectedException !== false) {
495                 $this->setExpectedException(
496                     $expectedException['class'],
497                     $expectedException['message'],
498                     $expectedException['code']
499                 );
500
501                 if (!empty($expectedException['message_regex'])) {
502                     $this->setExpectedExceptionRegExp(
503                         $expectedException['class'],
504                         $expectedException['message_regex'],
505                         $expectedException['code']
506                     );
507                 }
508             }
509         } catch (ReflectionException $e) {
510         }
511     }
512
513     /**
514      * @param bool $useErrorHandler
515      *
516      * @since Method available since Release 3.4.0
517      */
518     public function setUseErrorHandler($useErrorHandler)
519     {
520         $this->useErrorHandler = $useErrorHandler;
521     }
522
523     /**
524      * @since Method available since Release 3.4.0
525      */
526     protected function setUseErrorHandlerFromAnnotation()
527     {
528         try {
529             $useErrorHandler = PHPUnit_Util_Test::getErrorHandlerSettings(
530                 get_class($this),
531                 $this->name
532             );
533
534             if ($useErrorHandler !== null) {
535                 $this->setUseErrorHandler($useErrorHandler);
536             }
537         } catch (ReflectionException $e) {
538         }
539     }
540
541     /**
542      * @since Method available since Release 3.6.0
543      */
544     protected function checkRequirements()
545     {
546         if (!$this->name || !method_exists($this, $this->name)) {
547             return;
548         }
549
550         $missingRequirements = PHPUnit_Util_Test::getMissingRequirements(
551             get_class($this),
552             $this->name
553         );
554
555         if (!empty($missingRequirements)) {
556             $this->markTestSkipped(implode(PHP_EOL, $missingRequirements));
557         }
558     }
559
560     /**
561      * Returns the status of this test.
562      *
563      * @return int
564      *
565      * @since  Method available since Release 3.1.0
566      */
567     public function getStatus()
568     {
569         return $this->status;
570     }
571
572     /**
573      * Returns the status message of this test.
574      *
575      * @return string
576      *
577      * @since  Method available since Release 3.3.0
578      */
579     public function getStatusMessage()
580     {
581         return $this->statusMessage;
582     }
583
584     /**
585      * Returns whether or not this test has failed.
586      *
587      * @return bool
588      *
589      * @since  Method available since Release 3.0.0
590      */
591     public function hasFailed()
592     {
593         $status = $this->getStatus();
594
595         return $status == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE ||
596                $status == PHPUnit_Runner_BaseTestRunner::STATUS_ERROR;
597     }
598
599     /**
600      * Runs the test case and collects the results in a TestResult object.
601      * If no TestResult object is passed a new one will be created.
602      *
603      * @param PHPUnit_Framework_TestResult $result
604      *
605      * @return PHPUnit_Framework_TestResult
606      *
607      * @throws PHPUnit_Framework_Exception
608      */
609     public function run(PHPUnit_Framework_TestResult $result = null)
610     {
611         if ($result === null) {
612             $result = $this->createResult();
613         }
614
615         if (!$this instanceof PHPUnit_Framework_Warning) {
616             $this->setTestResultObject($result);
617             $this->setUseErrorHandlerFromAnnotation();
618         }
619
620         if ($this->useErrorHandler !== null) {
621             $oldErrorHandlerSetting = $result->getConvertErrorsToExceptions();
622             $result->convertErrorsToExceptions($this->useErrorHandler);
623         }
624
625         if (!$this instanceof PHPUnit_Framework_Warning && !$this->handleDependencies()) {
626             return;
627         }
628
629         if ($this->runTestInSeparateProcess === true &&
630             $this->inIsolation !== true &&
631             !$this instanceof PHPUnit_Extensions_SeleniumTestCase &&
632             !$this instanceof PHPUnit_Extensions_PhptTestCase) {
633             $class = new ReflectionClass($this);
634
635             $template = new Text_Template(
636                 __DIR__ . '/../Util/PHP/Template/TestCaseMethod.tpl'
637             );
638
639             if ($this->preserveGlobalState) {
640                 $constants     = PHPUnit_Util_GlobalState::getConstantsAsString();
641                 $globals       = PHPUnit_Util_GlobalState::getGlobalsAsString();
642                 $includedFiles = PHPUnit_Util_GlobalState::getIncludedFilesAsString();
643                 $iniSettings   = PHPUnit_Util_GlobalState::getIniSettingsAsString();
644             } else {
645                 $constants     = '';
646                 if (!empty($GLOBALS['__PHPUNIT_BOOTSTRAP'])) {
647                     $globals     = '$GLOBALS[\'__PHPUNIT_BOOTSTRAP\'] = ' . var_export($GLOBALS['__PHPUNIT_BOOTSTRAP'], true) . ";\n";
648                 } else {
649                     $globals     = '';
650                 }
651                 $includedFiles = '';
652                 $iniSettings   = '';
653             }
654
655             $coverage                                = $result->getCollectCodeCoverageInformation()       ? 'true' : 'false';
656             $isStrictAboutTestsThatDoNotTestAnything = $result->isStrictAboutTestsThatDoNotTestAnything() ? 'true' : 'false';
657             $isStrictAboutOutputDuringTests          = $result->isStrictAboutOutputDuringTests()          ? 'true' : 'false';
658             $isStrictAboutTestSize                   = $result->isStrictAboutTestSize()                   ? 'true' : 'false';
659             $isStrictAboutTodoAnnotatedTests         = $result->isStrictAboutTodoAnnotatedTests()         ? 'true' : 'false';
660
661             if (defined('PHPUNIT_COMPOSER_INSTALL')) {
662                 $composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, true);
663             } else {
664                 $composerAutoload = '\'\'';
665             }
666
667             if (defined('__PHPUNIT_PHAR__')) {
668                 $phar = var_export(__PHPUNIT_PHAR__, true);
669             } else {
670                 $phar = '\'\'';
671             }
672
673             if ($result->getCodeCoverage()) {
674                 $codeCoverageFilter = $result->getCodeCoverage()->filter();
675             } else {
676                 $codeCoverageFilter = null;
677             }
678
679             $data               = var_export(serialize($this->data), true);
680             $dataName           = var_export($this->dataName, true);
681             $dependencyInput    = var_export(serialize($this->dependencyInput), true);
682             $includePath        = var_export(get_include_path(), true);
683             $codeCoverageFilter = var_export(serialize($codeCoverageFilter), true);
684             // must do these fixes because TestCaseMethod.tpl has unserialize('{data}') in it, and we can't break BC
685             // the lines above used to use addcslashes() rather than var_export(), which breaks null byte escape sequences
686             $data               = "'." . $data . ".'";
687             $dataName           = "'.(" . $dataName . ").'";
688             $dependencyInput    = "'." . $dependencyInput . ".'";
689             $includePath        = "'." . $includePath . ".'";
690             $codeCoverageFilter = "'." . $codeCoverageFilter . ".'";
691
692             $configurationFilePath = (isset($GLOBALS['__PHPUNIT_CONFIGURATION_FILE']) ? $GLOBALS['__PHPUNIT_CONFIGURATION_FILE'] : '');
693
694             $template->setVar(
695                 array(
696                     'composerAutoload'                        => $composerAutoload,
697                     'phar'                                    => $phar,
698                     'filename'                                => $class->getFileName(),
699                     'className'                               => $class->getName(),
700                     'methodName'                              => $this->name,
701                     'collectCodeCoverageInformation'          => $coverage,
702                     'data'                                    => $data,
703                     'dataName'                                => $dataName,
704                     'dependencyInput'                         => $dependencyInput,
705                     'constants'                               => $constants,
706                     'globals'                                 => $globals,
707                     'include_path'                            => $includePath,
708                     'included_files'                          => $includedFiles,
709                     'iniSettings'                             => $iniSettings,
710                     'isStrictAboutTestsThatDoNotTestAnything' => $isStrictAboutTestsThatDoNotTestAnything,
711                     'isStrictAboutOutputDuringTests'          => $isStrictAboutOutputDuringTests,
712                     'isStrictAboutTestSize'                   => $isStrictAboutTestSize,
713                     'isStrictAboutTodoAnnotatedTests'         => $isStrictAboutTodoAnnotatedTests,
714                     'codeCoverageFilter'                      => $codeCoverageFilter,
715                     'configurationFilePath'                   => $configurationFilePath
716                 )
717             );
718
719             $this->prepareTemplate($template);
720
721             $php = PHPUnit_Util_PHP::factory();
722             $php->runTestJob($template->render(), $this, $result);
723         } else {
724             $result->run($this);
725         }
726
727         if ($this->useErrorHandler !== null) {
728             $result->convertErrorsToExceptions($oldErrorHandlerSetting);
729         }
730
731         $this->result = null;
732
733         return $result;
734     }
735
736     /**
737      * Runs the bare test sequence.
738      */
739     public function runBare()
740     {
741         $this->numAssertions = 0;
742
743         $this->snapshotGlobalState();
744         $this->startOutputBuffering();
745         clearstatcache();
746         $currentWorkingDirectory = getcwd();
747
748         $hookMethods = PHPUnit_Util_Test::getHookMethods(get_class($this));
749
750         try {
751             $hasMetRequirements = false;
752             $this->checkRequirements();
753             $hasMetRequirements = true;
754
755             if ($this->inIsolation) {
756                 foreach ($hookMethods['beforeClass'] as $method) {
757                     $this->$method();
758                 }
759             }
760
761             $this->setExpectedExceptionFromAnnotation();
762
763             foreach ($hookMethods['before'] as $method) {
764                 $this->$method();
765             }
766
767             $this->assertPreConditions();
768             $this->testResult = $this->runTest();
769             $this->verifyMockObjects();
770             $this->assertPostConditions();
771
772             $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_PASSED;
773         } catch (PHPUnit_Framework_IncompleteTest $e) {
774             $this->status        = PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE;
775             $this->statusMessage = $e->getMessage();
776         } catch (PHPUnit_Framework_SkippedTest $e) {
777             $this->status        = PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED;
778             $this->statusMessage = $e->getMessage();
779         } catch (PHPUnit_Framework_AssertionFailedError $e) {
780             $this->status        = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
781             $this->statusMessage = $e->getMessage();
782         } catch (PredictionException $e) {
783             $this->status        = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
784             $this->statusMessage = $e->getMessage();
785         } catch (Throwable $_e) {
786             $e = $_e;
787         } catch (Exception $_e) {
788             $e = $_e;
789         }
790
791         if (isset($_e)) {
792             $this->status        = PHPUnit_Runner_BaseTestRunner::STATUS_ERROR;
793             $this->statusMessage = $_e->getMessage();
794         }
795
796         // Clean up the mock objects.
797         $this->mockObjects = array();
798         $this->prophet     = null;
799
800         // Tear down the fixture. An exception raised in tearDown() will be
801         // caught and passed on when no exception was raised before.
802         try {
803             if ($hasMetRequirements) {
804                 foreach ($hookMethods['after'] as $method) {
805                     $this->$method();
806                 }
807
808                 if ($this->inIsolation) {
809                     foreach ($hookMethods['afterClass'] as $method) {
810                         $this->$method();
811                     }
812                 }
813             }
814         } catch (Throwable $_e) {
815             if (!isset($e)) {
816                 $e = $_e;
817             }
818         } catch (Exception $_e) {
819             if (!isset($e)) {
820                 $e = $_e;
821             }
822         }
823
824         try {
825             $this->stopOutputBuffering();
826         } catch (PHPUnit_Framework_RiskyTestError $_e) {
827             if (!isset($e)) {
828                 $e = $_e;
829             }
830         }
831
832         clearstatcache();
833
834         if ($currentWorkingDirectory != getcwd()) {
835             chdir($currentWorkingDirectory);
836         }
837
838         $this->restoreGlobalState();
839
840         // Clean up INI settings.
841         foreach ($this->iniSettings as $varName => $oldValue) {
842             ini_set($varName, $oldValue);
843         }
844
845         $this->iniSettings = array();
846
847         // Clean up locale settings.
848         foreach ($this->locale as $category => $locale) {
849             setlocale($category, $locale);
850         }
851
852         // Perform assertion on output.
853         if (!isset($e)) {
854             try {
855                 if ($this->outputExpectedRegex !== null) {
856                     $this->assertRegExp($this->outputExpectedRegex, $this->output);
857                 } elseif ($this->outputExpectedString !== null) {
858                     $this->assertEquals($this->outputExpectedString, $this->output);
859                 }
860             } catch (Throwable $_e) {
861                 $e = $_e;
862             } catch (Exception $_e) {
863                 $e = $_e;
864             }
865         }
866
867         // Workaround for missing "finally".
868         if (isset($e)) {
869             if ($e instanceof PredictionException) {
870                 $e = new PHPUnit_Framework_AssertionFailedError($e->getMessage());
871             }
872
873             if (!$e instanceof Exception) {
874                 // Rethrow Error directly on PHP 7 as onNotSuccessfulTest does not support it
875                 throw $e;
876             }
877
878             $this->onNotSuccessfulTest($e);
879         }
880     }
881
882     /**
883      * Override to run the test and assert its state.
884      *
885      * @return mixed
886      *
887      * @throws Exception|PHPUnit_Framework_Exception
888      * @throws PHPUnit_Framework_Exception
889      */
890     protected function runTest()
891     {
892         if ($this->name === null) {
893             throw new PHPUnit_Framework_Exception(
894                 'PHPUnit_Framework_TestCase::$name must not be null.'
895             );
896         }
897
898         try {
899             $class  = new ReflectionClass($this);
900             $method = $class->getMethod($this->name);
901         } catch (ReflectionException $e) {
902             $this->fail($e->getMessage());
903         }
904
905         try {
906             $testResult = $method->invokeArgs(
907                 $this,
908                 array_merge($this->data, $this->dependencyInput)
909             );
910         } catch (Throwable $_e) {
911             $e = $_e;
912         } catch (Exception $_e) {
913             $e = $_e;
914         }
915
916         if (isset($e)) {
917             $checkException = false;
918
919             if (!($e instanceof PHPUnit_Framework_SkippedTestError) && is_string($this->expectedException)) {
920                 $checkException = true;
921
922                 if ($e instanceof PHPUnit_Framework_Exception) {
923                     $checkException = false;
924                 }
925
926                 $reflector = new ReflectionClass($this->expectedException);
927
928                 if ($this->expectedException === 'PHPUnit_Framework_Exception' ||
929                     $this->expectedException === '\PHPUnit_Framework_Exception' ||
930                     $reflector->isSubclassOf('PHPUnit_Framework_Exception')) {
931                     $checkException = true;
932                 }
933             }
934
935             if ($checkException) {
936                 $this->assertThat(
937                     $e,
938                     new PHPUnit_Framework_Constraint_Exception(
939                         $this->expectedException
940                     )
941                 );
942
943                 if (is_string($this->expectedExceptionMessage) &&
944                     !empty($this->expectedExceptionMessage)) {
945                     $this->assertThat(
946                         $e,
947                         new PHPUnit_Framework_Constraint_ExceptionMessage(
948                             $this->expectedExceptionMessage
949                         )
950                     );
951                 }
952
953                 if (is_string($this->expectedExceptionMessageRegExp) &&
954                     !empty($this->expectedExceptionMessageRegExp)) {
955                     $this->assertThat(
956                         $e,
957                         new PHPUnit_Framework_Constraint_ExceptionMessageRegExp(
958                             $this->expectedExceptionMessageRegExp
959                         )
960                     );
961                 }
962
963                 if ($this->expectedExceptionCode !== null) {
964                     $this->assertThat(
965                         $e,
966                         new PHPUnit_Framework_Constraint_ExceptionCode(
967                             $this->expectedExceptionCode
968                         )
969                     );
970                 }
971
972                 return;
973             } else {
974                 throw $e;
975             }
976         }
977
978         if ($this->expectedException !== null) {
979             $this->assertThat(
980                 null,
981                 new PHPUnit_Framework_Constraint_Exception(
982                     $this->expectedException
983                 )
984             );
985         }
986
987         return $testResult;
988     }
989
990     /**
991      * Verifies the mock object expectations.
992      *
993      * @since Method available since Release 3.5.0
994      */
995     protected function verifyMockObjects()
996     {
997         foreach ($this->mockObjects as $mockObject) {
998             if ($mockObject->__phpunit_hasMatchers()) {
999                 $this->numAssertions++;
1000             }
1001
1002             $mockObject->__phpunit_verify();
1003         }
1004
1005         if ($this->prophet !== null) {
1006             try {
1007                 $this->prophet->checkPredictions();
1008             } catch (Throwable $e) {
1009                 /* Intentionally left empty */
1010             } catch (Exception $e) {
1011                 /* Intentionally left empty */
1012             }
1013
1014             foreach ($this->prophet->getProphecies() as $objectProphecy) {
1015                 foreach ($objectProphecy->getMethodProphecies() as $methodProphecies) {
1016                     foreach ($methodProphecies as $methodProphecy) {
1017                         $this->numAssertions += count($methodProphecy->getCheckedPredictions());
1018                     }
1019                 }
1020             }
1021
1022             if (isset($e)) {
1023                 throw $e;
1024             }
1025         }
1026     }
1027
1028     /**
1029      * Sets the name of a TestCase.
1030      *
1031      * @param  string
1032      */
1033     public function setName($name)
1034     {
1035         $this->name = $name;
1036     }
1037
1038     /**
1039      * Sets the dependencies of a TestCase.
1040      *
1041      * @param array $dependencies
1042      *
1043      * @since  Method available since Release 3.4.0
1044      */
1045     public function setDependencies(array $dependencies)
1046     {
1047         $this->dependencies = $dependencies;
1048     }
1049
1050     /**
1051      * Returns true if the tests has dependencies
1052      *
1053      * @return bool
1054      *
1055      * @since Method available since Release 4.0.0
1056      */
1057     public function hasDependencies()
1058     {
1059         return count($this->dependencies) > 0;
1060     }
1061
1062     /**
1063      * Sets
1064      *
1065      * @param array $dependencyInput
1066      *
1067      * @since  Method available since Release 3.4.0
1068      */
1069     public function setDependencyInput(array $dependencyInput)
1070     {
1071         $this->dependencyInput = $dependencyInput;
1072     }
1073
1074     /**
1075      * @param bool $disallowChangesToGlobalState
1076      *
1077      * @since Method available since Release 4.6.0
1078      */
1079     public function setDisallowChangesToGlobalState($disallowChangesToGlobalState)
1080     {
1081         $this->disallowChangesToGlobalState = $disallowChangesToGlobalState;
1082     }
1083
1084     /**
1085      * Calling this method in setUp() has no effect!
1086      *
1087      * @param bool $backupGlobals
1088      *
1089      * @since  Method available since Release 3.3.0
1090      */
1091     public function setBackupGlobals($backupGlobals)
1092     {
1093         if (is_null($this->backupGlobals) && is_bool($backupGlobals)) {
1094             $this->backupGlobals = $backupGlobals;
1095         }
1096     }
1097
1098     /**
1099      * Calling this method in setUp() has no effect!
1100      *
1101      * @param bool $backupStaticAttributes
1102      *
1103      * @since  Method available since Release 3.4.0
1104      */
1105     public function setBackupStaticAttributes($backupStaticAttributes)
1106     {
1107         if (is_null($this->backupStaticAttributes) &&
1108             is_bool($backupStaticAttributes)) {
1109             $this->backupStaticAttributes = $backupStaticAttributes;
1110         }
1111     }
1112
1113     /**
1114      * @param bool $runTestInSeparateProcess
1115      *
1116      * @throws PHPUnit_Framework_Exception
1117      *
1118      * @since  Method available since Release 3.4.0
1119      */
1120     public function setRunTestInSeparateProcess($runTestInSeparateProcess)
1121     {
1122         if (is_bool($runTestInSeparateProcess)) {
1123             if ($this->runTestInSeparateProcess === null) {
1124                 $this->runTestInSeparateProcess = $runTestInSeparateProcess;
1125             }
1126         } else {
1127             throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
1128         }
1129     }
1130
1131     /**
1132      * @param bool $preserveGlobalState
1133      *
1134      * @throws PHPUnit_Framework_Exception
1135      *
1136      * @since  Method available since Release 3.4.0
1137      */
1138     public function setPreserveGlobalState($preserveGlobalState)
1139     {
1140         if (is_bool($preserveGlobalState)) {
1141             $this->preserveGlobalState = $preserveGlobalState;
1142         } else {
1143             throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
1144         }
1145     }
1146
1147     /**
1148      * @param bool $inIsolation
1149      *
1150      * @throws PHPUnit_Framework_Exception
1151      *
1152      * @since  Method available since Release 3.4.0
1153      */
1154     public function setInIsolation($inIsolation)
1155     {
1156         if (is_bool($inIsolation)) {
1157             $this->inIsolation = $inIsolation;
1158         } else {
1159             throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
1160         }
1161     }
1162
1163     /**
1164      * @return bool
1165      *
1166      * @since  Method available since Release 4.3.0
1167      */
1168     public function isInIsolation()
1169     {
1170         return $this->inIsolation;
1171     }
1172
1173     /**
1174      * @return mixed
1175      *
1176      * @since  Method available since Release 3.4.0
1177      */
1178     public function getResult()
1179     {
1180         return $this->testResult;
1181     }
1182
1183     /**
1184      * @param mixed $result
1185      *
1186      * @since  Method available since Release 3.4.0
1187      */
1188     public function setResult($result)
1189     {
1190         $this->testResult = $result;
1191     }
1192
1193     /**
1194      * @param callable $callback
1195      *
1196      * @throws PHPUnit_Framework_Exception
1197      *
1198      * @since Method available since Release 3.6.0
1199      */
1200     public function setOutputCallback($callback)
1201     {
1202         if (!is_callable($callback)) {
1203             throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'callback');
1204         }
1205
1206         $this->outputCallback = $callback;
1207     }
1208
1209     /**
1210      * @return PHPUnit_Framework_TestResult
1211      *
1212      * @since  Method available since Release 3.5.7
1213      */
1214     public function getTestResultObject()
1215     {
1216         return $this->result;
1217     }
1218
1219     /**
1220      * @param PHPUnit_Framework_TestResult $result
1221      *
1222      * @since Method available since Release 3.6.0
1223      */
1224     public function setTestResultObject(PHPUnit_Framework_TestResult $result)
1225     {
1226         $this->result = $result;
1227     }
1228
1229     /**
1230      * This method is a wrapper for the ini_set() function that automatically
1231      * resets the modified php.ini setting to its original value after the
1232      * test is run.
1233      *
1234      * @param string $varName
1235      * @param string $newValue
1236      *
1237      * @throws PHPUnit_Framework_Exception
1238      *
1239      * @since  Method available since Release 3.0.0
1240      */
1241     protected function iniSet($varName, $newValue)
1242     {
1243         if (!is_string($varName)) {
1244             throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
1245         }
1246
1247         $currentValue = ini_set($varName, $newValue);
1248
1249         if ($currentValue !== false) {
1250             $this->iniSettings[$varName] = $currentValue;
1251         } else {
1252             throw new PHPUnit_Framework_Exception(
1253                 sprintf(
1254                     'INI setting "%s" could not be set to "%s".',
1255                     $varName,
1256                     $newValue
1257                 )
1258             );
1259         }
1260     }
1261
1262     /**
1263      * This method is a wrapper for the setlocale() function that automatically
1264      * resets the locale to its original value after the test is run.
1265      *
1266      * @param int    $category
1267      * @param string $locale
1268      *
1269      * @throws PHPUnit_Framework_Exception
1270      *
1271      * @since  Method available since Release 3.1.0
1272      */
1273     protected function setLocale()
1274     {
1275         $args = func_get_args();
1276
1277         if (count($args) < 2) {
1278             throw new PHPUnit_Framework_Exception;
1279         }
1280
1281         $category = $args[0];
1282         $locale   = $args[1];
1283
1284         $categories = array(
1285             LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME
1286         );
1287
1288         if (defined('LC_MESSAGES')) {
1289             $categories[] = LC_MESSAGES;
1290         }
1291
1292         if (!in_array($category, $categories)) {
1293             throw new PHPUnit_Framework_Exception;
1294         }
1295
1296         if (!is_array($locale) && !is_string($locale)) {
1297             throw new PHPUnit_Framework_Exception;
1298         }
1299
1300         $this->locale[$category] = setlocale($category, null);
1301
1302         $result = call_user_func_array('setlocale', $args);
1303
1304         if ($result === false) {
1305             throw new PHPUnit_Framework_Exception(
1306                 'The locale functionality is not implemented on your platform, ' .
1307                 'the specified locale does not exist or the category name is ' .
1308                 'invalid.'
1309             );
1310         }
1311     }
1312
1313     /**
1314      * Returns a mock object for the specified class.
1315      *
1316      * @param string     $originalClassName       Name of the class to mock.
1317      * @param array|null $methods                 When provided, only methods whose names are in the array
1318      *                                            are replaced with a configurable test double. The behavior
1319      *                                            of the other methods is not changed.
1320      *                                            Providing null means that no methods will be replaced.
1321      * @param array      $arguments               Parameters to pass to the original class' constructor.
1322      * @param string     $mockClassName           Class name for the generated test double class.
1323      * @param bool       $callOriginalConstructor Can be used to disable the call to the original class' constructor.
1324      * @param bool       $callOriginalClone       Can be used to disable the call to the original class' clone constructor.
1325      * @param bool       $callAutoload            Can be used to disable __autoload() during the generation of the test double class.
1326      * @param bool       $cloneArguments
1327      * @param bool       $callOriginalMethods
1328      * @param object     $proxyTarget
1329      *
1330      * @return PHPUnit_Framework_MockObject_MockObject
1331      *
1332      * @throws PHPUnit_Framework_Exception
1333      *
1334      * @since  Method available since Release 3.0.0
1335      */
1336     public function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false, $callOriginalMethods = false, $proxyTarget = null)
1337     {
1338         $mockObject = $this->getMockObjectGenerator()->getMock(
1339             $originalClassName,
1340             $methods,
1341             $arguments,
1342             $mockClassName,
1343             $callOriginalConstructor,
1344             $callOriginalClone,
1345             $callAutoload,
1346             $cloneArguments,
1347             $callOriginalMethods,
1348             $proxyTarget
1349         );
1350
1351         $this->mockObjects[] = $mockObject;
1352
1353         return $mockObject;
1354     }
1355
1356     /**
1357      * Returns a builder object to create mock objects using a fluent interface.
1358      *
1359      * @param string $className
1360      *
1361      * @return PHPUnit_Framework_MockObject_MockBuilder
1362      *
1363      * @since  Method available since Release 3.5.0
1364      */
1365     public function getMockBuilder($className)
1366     {
1367         return new PHPUnit_Framework_MockObject_MockBuilder($this, $className);
1368     }
1369
1370     /**
1371      * Mocks the specified class and returns the name of the mocked class.
1372      *
1373      * @param string $originalClassName
1374      * @param array  $methods
1375      * @param array  $arguments
1376      * @param string $mockClassName
1377      * @param bool   $callOriginalConstructor
1378      * @param bool   $callOriginalClone
1379      * @param bool   $callAutoload
1380      * @param bool   $cloneArguments
1381      *
1382      * @return string
1383      *
1384      * @throws PHPUnit_Framework_Exception
1385      *
1386      * @since  Method available since Release 3.5.0
1387      */
1388     protected function getMockClass($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = false, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false)
1389     {
1390         $mock = $this->getMock(
1391             $originalClassName,
1392             $methods,
1393             $arguments,
1394             $mockClassName,
1395             $callOriginalConstructor,
1396             $callOriginalClone,
1397             $callAutoload,
1398             $cloneArguments
1399         );
1400
1401         return get_class($mock);
1402     }
1403
1404     /**
1405      * Returns a mock object for the specified abstract class with all abstract
1406      * methods of the class mocked. Concrete methods are not mocked by default.
1407      * To mock concrete methods, use the 7th parameter ($mockedMethods).
1408      *
1409      * @param string $originalClassName
1410      * @param array  $arguments
1411      * @param string $mockClassName
1412      * @param bool   $callOriginalConstructor
1413      * @param bool   $callOriginalClone
1414      * @param bool   $callAutoload
1415      * @param array  $mockedMethods
1416      * @param bool   $cloneArguments
1417      *
1418      * @return PHPUnit_Framework_MockObject_MockObject
1419      *
1420      * @since  Method available since Release 3.4.0
1421      *
1422      * @throws PHPUnit_Framework_Exception
1423      */
1424     public function getMockForAbstractClass($originalClassName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = array(), $cloneArguments = false)
1425     {
1426         $mockObject = $this->getMockObjectGenerator()->getMockForAbstractClass(
1427             $originalClassName,
1428             $arguments,
1429             $mockClassName,
1430             $callOriginalConstructor,
1431             $callOriginalClone,
1432             $callAutoload,
1433             $mockedMethods,
1434             $cloneArguments
1435         );
1436
1437         $this->mockObjects[] = $mockObject;
1438
1439         return $mockObject;
1440     }
1441
1442     /**
1443      * Returns a mock object based on the given WSDL file.
1444      *
1445      * @param string $wsdlFile
1446      * @param string $originalClassName
1447      * @param string $mockClassName
1448      * @param array  $methods
1449      * @param bool   $callOriginalConstructor
1450      * @param array  $options                 An array of options passed to SOAPClient::_construct
1451      *
1452      * @return PHPUnit_Framework_MockObject_MockObject
1453      *
1454      * @since  Method available since Release 3.4.0
1455      */
1456     protected function getMockFromWsdl($wsdlFile, $originalClassName = '', $mockClassName = '', array $methods = array(), $callOriginalConstructor = true, array $options = array())
1457     {
1458         if ($originalClassName === '') {
1459             $originalClassName = str_replace('.wsdl', '', basename($wsdlFile));
1460         }
1461
1462         if (!class_exists($originalClassName)) {
1463             eval(
1464             $this->getMockObjectGenerator()->generateClassFromWsdl(
1465                 $wsdlFile,
1466                 $originalClassName,
1467                 $methods,
1468                 $options
1469             )
1470             );
1471         }
1472
1473         return $this->getMock(
1474             $originalClassName,
1475             $methods,
1476             array('', $options),
1477             $mockClassName,
1478             $callOriginalConstructor,
1479             false,
1480             false
1481         );
1482     }
1483
1484     /**
1485      * Returns a mock object for the specified trait with all abstract methods
1486      * of the trait mocked. Concrete methods to mock can be specified with the
1487      * `$mockedMethods` parameter.
1488      *
1489      * @param string $traitName
1490      * @param array  $arguments
1491      * @param string $mockClassName
1492      * @param bool   $callOriginalConstructor
1493      * @param bool   $callOriginalClone
1494      * @param bool   $callAutoload
1495      * @param array  $mockedMethods
1496      * @param bool   $cloneArguments
1497      *
1498      * @return PHPUnit_Framework_MockObject_MockObject
1499      *
1500      * @since  Method available since Release 4.0.0
1501      *
1502      * @throws PHPUnit_Framework_Exception
1503      */
1504     public function getMockForTrait($traitName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = array(), $cloneArguments = false)
1505     {
1506         $mockObject = $this->getMockObjectGenerator()->getMockForTrait(
1507             $traitName,
1508             $arguments,
1509             $mockClassName,
1510             $callOriginalConstructor,
1511             $callOriginalClone,
1512             $callAutoload,
1513             $mockedMethods,
1514             $cloneArguments
1515         );
1516
1517         $this->mockObjects[] = $mockObject;
1518
1519         return $mockObject;
1520     }
1521
1522     /**
1523      * Returns an object for the specified trait.
1524      *
1525      * @param string $traitName
1526      * @param array  $arguments
1527      * @param string $traitClassName
1528      * @param bool   $callOriginalConstructor
1529      * @param bool   $callOriginalClone
1530      * @param bool   $callAutoload
1531      * @param bool   $cloneArguments
1532      *
1533      * @return object
1534      *
1535      * @since  Method available since Release 3.6.0
1536      *
1537      * @throws PHPUnit_Framework_Exception
1538      */
1539     protected function getObjectForTrait($traitName, array $arguments = array(), $traitClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false)
1540     {
1541         return $this->getMockObjectGenerator()->getObjectForTrait(
1542             $traitName,
1543             $arguments,
1544             $traitClassName,
1545             $callOriginalConstructor,
1546             $callOriginalClone,
1547             $callAutoload,
1548             $cloneArguments
1549         );
1550     }
1551
1552     /**
1553      * @param string|null $classOrInterface
1554      *
1555      * @return \Prophecy\Prophecy\ObjectProphecy
1556      *
1557      * @throws \LogicException
1558      *
1559      * @since  Method available since Release 4.5.0
1560      */
1561     protected function prophesize($classOrInterface = null)
1562     {
1563         return $this->getProphet()->prophesize($classOrInterface);
1564     }
1565
1566     /**
1567      * Adds a value to the assertion counter.
1568      *
1569      * @param int $count
1570      *
1571      * @since Method available since Release 3.3.3
1572      */
1573     public function addToAssertionCount($count)
1574     {
1575         $this->numAssertions += $count;
1576     }
1577
1578     /**
1579      * Returns the number of assertions performed by this test.
1580      *
1581      * @return int
1582      *
1583      * @since  Method available since Release 3.3.0
1584      */
1585     public function getNumAssertions()
1586     {
1587         return $this->numAssertions;
1588     }
1589
1590     /**
1591      * Returns a matcher that matches when the method is executed
1592      * zero or more times.
1593      *
1594      * @return PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount
1595      *
1596      * @since  Method available since Release 3.0.0
1597      */
1598     public static function any()
1599     {
1600         return new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
1601     }
1602
1603     /**
1604      * Returns a matcher that matches when the method is never executed.
1605      *
1606      * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
1607      *
1608      * @since  Method available since Release 3.0.0
1609      */
1610     public static function never()
1611     {
1612         return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(0);
1613     }
1614
1615     /**
1616      * Returns a matcher that matches when the method is executed
1617      * at least N times.
1618      *
1619      * @param int $requiredInvocations
1620      *
1621      * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount
1622      *
1623      * @since  Method available since Release 4.2.0
1624      */
1625     public static function atLeast($requiredInvocations)
1626     {
1627         return new PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount(
1628             $requiredInvocations
1629         );
1630     }
1631
1632     /**
1633      * Returns a matcher that matches when the method is executed at least once.
1634      *
1635      * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce
1636      *
1637      * @since  Method available since Release 3.0.0
1638      */
1639     public static function atLeastOnce()
1640     {
1641         return new PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce;
1642     }
1643
1644     /**
1645      * Returns a matcher that matches when the method is executed exactly once.
1646      *
1647      * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
1648      *
1649      * @since  Method available since Release 3.0.0
1650      */
1651     public static function once()
1652     {
1653         return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(1);
1654     }
1655
1656     /**
1657      * Returns a matcher that matches when the method is executed
1658      * exactly $count times.
1659      *
1660      * @param int $count
1661      *
1662      * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
1663      *
1664      * @since  Method available since Release 3.0.0
1665      */
1666     public static function exactly($count)
1667     {
1668         return new PHPUnit_Framework_MockObject_Matcher_InvokedCount($count);
1669     }
1670
1671     /**
1672      * Returns a matcher that matches when the method is executed
1673      * at most N times.
1674      *
1675      * @param int $allowedInvocations
1676      *
1677      * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount
1678      *
1679      * @since  Method available since Release 4.2.0
1680      */
1681     public static function atMost($allowedInvocations)
1682     {
1683         return new PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount(
1684             $allowedInvocations
1685         );
1686     }
1687
1688     /**
1689      * Returns a matcher that matches when the method is executed
1690      * at the given index.
1691      *
1692      * @param int $index
1693      *
1694      * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex
1695      *
1696      * @since  Method available since Release 3.0.0
1697      */
1698     public static function at($index)
1699     {
1700         return new PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex($index);
1701     }
1702
1703     /**
1704      * @param mixed $value
1705      *
1706      * @return PHPUnit_Framework_MockObject_Stub_Return
1707      *
1708      * @since  Method available since Release 3.0.0
1709      */
1710     public static function returnValue($value)
1711     {
1712         return new PHPUnit_Framework_MockObject_Stub_Return($value);
1713     }
1714
1715     /**
1716      * @param array $valueMap
1717      *
1718      * @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap
1719      *
1720      * @since  Method available since Release 3.6.0
1721      */
1722     public static function returnValueMap(array $valueMap)
1723     {
1724         return new PHPUnit_Framework_MockObject_Stub_ReturnValueMap($valueMap);
1725     }
1726
1727     /**
1728      * @param int $argumentIndex
1729      *
1730      * @return PHPUnit_Framework_MockObject_Stub_ReturnArgument
1731      *
1732      * @since  Method available since Release 3.3.0
1733      */
1734     public static function returnArgument($argumentIndex)
1735     {
1736         return new PHPUnit_Framework_MockObject_Stub_ReturnArgument(
1737             $argumentIndex
1738         );
1739     }
1740
1741     /**
1742      * @param mixed $callback
1743      *
1744      * @return PHPUnit_Framework_MockObject_Stub_ReturnCallback
1745      *
1746      * @since  Method available since Release 3.3.0
1747      */
1748     public static function returnCallback($callback)
1749     {
1750         return new PHPUnit_Framework_MockObject_Stub_ReturnCallback($callback);
1751     }
1752
1753     /**
1754      * Returns the current object.
1755      *
1756      * This method is useful when mocking a fluent interface.
1757      *
1758      * @return PHPUnit_Framework_MockObject_Stub_ReturnSelf
1759      *
1760      * @since  Method available since Release 3.6.0
1761      */
1762     public static function returnSelf()
1763     {
1764         return new PHPUnit_Framework_MockObject_Stub_ReturnSelf();
1765     }
1766
1767     /**
1768      * @param Exception $exception
1769      *
1770      * @return PHPUnit_Framework_MockObject_Stub_Exception
1771      *
1772      * @since  Method available since Release 3.1.0
1773      */
1774     public static function throwException(Exception $exception)
1775     {
1776         return new PHPUnit_Framework_MockObject_Stub_Exception($exception);
1777     }
1778
1779     /**
1780      * @param mixed $value, ...
1781      *
1782      * @return PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls
1783      *
1784      * @since  Method available since Release 3.0.0
1785      */
1786     public static function onConsecutiveCalls()
1787     {
1788         $args = func_get_args();
1789
1790         return new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($args);
1791     }
1792
1793     /**
1794      * Gets the data set description of a TestCase.
1795      *
1796      * @param bool $includeData
1797      *
1798      * @return string
1799      *
1800      * @since  Method available since Release 3.3.0
1801      */
1802     protected function getDataSetAsString($includeData = true)
1803     {
1804         $buffer = '';
1805
1806         if (!empty($this->data)) {
1807             if (is_int($this->dataName)) {
1808                 $buffer .= sprintf(' with data set #%d', $this->dataName);
1809             } else {
1810                 $buffer .= sprintf(' with data set "%s"', $this->dataName);
1811             }
1812
1813             $exporter = new Exporter;
1814
1815             if ($includeData) {
1816                 $buffer .= sprintf(' (%s)', $exporter->shortenedRecursiveExport($this->data));
1817             }
1818         }
1819
1820         return $buffer;
1821     }
1822
1823     /**
1824      * Creates a default TestResult object.
1825      *
1826      * @return PHPUnit_Framework_TestResult
1827      */
1828     protected function createResult()
1829     {
1830         return new PHPUnit_Framework_TestResult;
1831     }
1832
1833     /**
1834      * @since Method available since Release 3.5.4
1835      */
1836     protected function handleDependencies()
1837     {
1838         if (!empty($this->dependencies) && !$this->inIsolation) {
1839             $className  = get_class($this);
1840             $passed     = $this->result->passed();
1841             $passedKeys = array_keys($passed);
1842             $numKeys    = count($passedKeys);
1843
1844             for ($i = 0; $i < $numKeys; $i++) {
1845                 $pos = strpos($passedKeys[$i], ' with data set');
1846
1847                 if ($pos !== false) {
1848                     $passedKeys[$i] = substr($passedKeys[$i], 0, $pos);
1849                 }
1850             }
1851
1852             $passedKeys = array_flip(array_unique($passedKeys));
1853
1854             foreach ($this->dependencies as $dependency) {
1855                 if (strpos($dependency, '::') === false) {
1856                     $dependency = $className . '::' . $dependency;
1857                 }
1858
1859                 if (!isset($passedKeys[$dependency])) {
1860                     $this->result->addError(
1861                         $this,
1862                         new PHPUnit_Framework_SkippedTestError(
1863                             sprintf(
1864                                 'This test depends on "%s" to pass.',
1865                                 $dependency
1866                             )
1867                         ),
1868                         0
1869                     );
1870
1871                     return false;
1872                 }
1873
1874                 if (isset($passed[$dependency])) {
1875                     if ($passed[$dependency]['size'] != PHPUnit_Util_Test::UNKNOWN &&
1876                         $this->getSize() != PHPUnit_Util_Test::UNKNOWN &&
1877                         $passed[$dependency]['size'] > $this->getSize()) {
1878                         $this->result->addError(
1879                             $this,
1880                             new PHPUnit_Framework_SkippedTestError(
1881                                 'This test depends on a test that is larger than itself.'
1882                             ),
1883                             0
1884                         );
1885
1886                         return false;
1887                     }
1888
1889                     $this->dependencyInput[$dependency] = $passed[$dependency]['result'];
1890                 } else {
1891                     $this->dependencyInput[$dependency] = null;
1892                 }
1893             }
1894         }
1895
1896         return true;
1897     }
1898
1899     /**
1900      * This method is called before the first test of this test class is run.
1901      *
1902      * @since Method available since Release 3.4.0
1903      */
1904     public static function setUpBeforeClass()
1905     {
1906     }
1907
1908     /**
1909      * Sets up the fixture, for example, open a network connection.
1910      * This method is called before a test is executed.
1911      */
1912     protected function setUp()
1913     {
1914     }
1915
1916     /**
1917      * Performs assertions shared by all tests of a test case.
1918      *
1919      * This method is called before the execution of a test starts
1920      * and after setUp() is called.
1921      *
1922      * @since  Method available since Release 3.2.8
1923      */
1924     protected function assertPreConditions()
1925     {
1926     }
1927
1928     /**
1929      * Performs assertions shared by all tests of a test case.
1930      *
1931      * This method is called before the execution of a test ends
1932      * and before tearDown() is called.
1933      *
1934      * @since  Method available since Release 3.2.8
1935      */
1936     protected function assertPostConditions()
1937     {
1938     }
1939
1940     /**
1941      * Tears down the fixture, for example, close a network connection.
1942      * This method is called after a test is executed.
1943      */
1944     protected function tearDown()
1945     {
1946     }
1947
1948     /**
1949      * This method is called after the last test of this test class is run.
1950      *
1951      * @since Method available since Release 3.4.0
1952      */
1953     public static function tearDownAfterClass()
1954     {
1955     }
1956
1957     /**
1958      * This method is called when a test method did not execute successfully.
1959      *
1960      * @param Exception $e
1961      *
1962      * @since Method available since Release 3.4.0
1963      *
1964      * @throws Exception
1965      */
1966     protected function onNotSuccessfulTest(Exception $e)
1967     {
1968         throw $e;
1969     }
1970
1971     /**
1972      * Performs custom preparations on the process isolation template.
1973      *
1974      * @param Text_Template $template
1975      *
1976      * @since Method available since Release 3.4.0
1977      */
1978     protected function prepareTemplate(Text_Template $template)
1979     {
1980     }
1981
1982     /**
1983      * Get the mock object generator, creating it if it doesn't exist.
1984      *
1985      * @return PHPUnit_Framework_MockObject_Generator
1986      */
1987     protected function getMockObjectGenerator()
1988     {
1989         if (null === $this->mockObjectGenerator) {
1990             $this->mockObjectGenerator = new PHPUnit_Framework_MockObject_Generator;
1991         }
1992
1993         return $this->mockObjectGenerator;
1994     }
1995
1996     /**
1997      * @since Method available since Release 4.2.0
1998      */
1999     private function startOutputBuffering()
2000     {
2001         while (!defined('PHPUNIT_TESTSUITE') && ob_get_level() > 0) {
2002             ob_end_clean();
2003         }
2004
2005         ob_start();
2006
2007         $this->outputBufferingActive = true;
2008         $this->outputBufferingLevel  = ob_get_level();
2009     }
2010
2011     /**
2012      * @since Method available since Release 4.2.0
2013      */
2014     private function stopOutputBuffering()
2015     {
2016         if (ob_get_level() != $this->outputBufferingLevel) {
2017             while (ob_get_level() > 0) {
2018                 ob_end_clean();
2019             }
2020
2021             throw new PHPUnit_Framework_RiskyTestError(
2022                 'Test code or tested code did not (only) close its own output buffers'
2023             );
2024         }
2025
2026         $output = ob_get_contents();
2027
2028         if ($this->outputCallback === false) {
2029             $this->output = $output;
2030         } else {
2031             $this->output = call_user_func_array(
2032                 $this->outputCallback,
2033                 array($output)
2034             );
2035         }
2036
2037         ob_end_clean();
2038
2039         $this->outputBufferingActive = false;
2040         $this->outputBufferingLevel  = ob_get_level();
2041     }
2042
2043     private function snapshotGlobalState()
2044     {
2045         $backupGlobals = $this->backupGlobals === null || $this->backupGlobals === true;
2046
2047         if ($this->runTestInSeparateProcess || $this->inIsolation ||
2048             (!$backupGlobals && !$this->backupStaticAttributes)) {
2049             return;
2050         }
2051
2052         $this->snapshot = $this->createGlobalStateSnapshot($backupGlobals);
2053     }
2054
2055     private function restoreGlobalState()
2056     {
2057         if (!$this->snapshot instanceof Snapshot) {
2058             return;
2059         }
2060
2061         $backupGlobals = $this->backupGlobals === null || $this->backupGlobals === true;
2062
2063         if ($this->disallowChangesToGlobalState) {
2064             try {
2065                 $this->compareGlobalStateSnapshots(
2066                     $this->snapshot,
2067                     $this->createGlobalStateSnapshot($backupGlobals)
2068                 );
2069             } catch (PHPUnit_Framework_RiskyTestError $rte) {
2070                 // Intentionally left empty
2071             }
2072         }
2073
2074         $restorer = new Restorer;
2075
2076         if ($backupGlobals) {
2077             $restorer->restoreGlobalVariables($this->snapshot);
2078         }
2079
2080         if ($this->backupStaticAttributes) {
2081             $restorer->restoreStaticAttributes($this->snapshot);
2082         }
2083
2084         $this->snapshot = null;
2085
2086         if (isset($rte)) {
2087             throw $rte;
2088         }
2089     }
2090
2091     /**
2092      * @param bool $backupGlobals
2093      *
2094      * @return Snapshot
2095      */
2096     private function createGlobalStateSnapshot($backupGlobals)
2097     {
2098         $blacklist = new Blacklist;
2099
2100         foreach ($this->backupGlobalsBlacklist as $globalVariable) {
2101             $blacklist->addGlobalVariable($globalVariable);
2102         }
2103
2104         if (!defined('PHPUNIT_TESTSUITE')) {
2105             $blacklist->addClassNamePrefix('PHPUnit');
2106             $blacklist->addClassNamePrefix('File_Iterator');
2107             $blacklist->addClassNamePrefix('PHP_CodeCoverage');
2108             $blacklist->addClassNamePrefix('PHP_Invoker');
2109             $blacklist->addClassNamePrefix('PHP_Timer');
2110             $blacklist->addClassNamePrefix('PHP_Token');
2111             $blacklist->addClassNamePrefix('Symfony');
2112             $blacklist->addClassNamePrefix('Text_Template');
2113             $blacklist->addClassNamePrefix('Doctrine\Instantiator');
2114
2115             foreach ($this->backupStaticAttributesBlacklist as $class => $attributes) {
2116                 foreach ($attributes as $attribute) {
2117                     $blacklist->addStaticAttribute($class, $attribute);
2118                 }
2119             }
2120         }
2121
2122         return new Snapshot(
2123             $blacklist,
2124             $backupGlobals,
2125             $this->backupStaticAttributes,
2126             false,
2127             false,
2128             false,
2129             false,
2130             false,
2131             false,
2132             false
2133         );
2134     }
2135
2136     /**
2137      * @param Snapshot $before
2138      * @param Snapshot $after
2139      *
2140      * @throws PHPUnit_Framework_RiskyTestError
2141      */
2142     private function compareGlobalStateSnapshots(Snapshot $before, Snapshot $after)
2143     {
2144         $backupGlobals = $this->backupGlobals === null || $this->backupGlobals === true;
2145
2146         if ($backupGlobals) {
2147             $this->compareGlobalStateSnapshotPart(
2148                 $before->globalVariables(),
2149                 $after->globalVariables(),
2150                 "--- Global variables before the test\n+++ Global variables after the test\n"
2151             );
2152
2153             $this->compareGlobalStateSnapshotPart(
2154                 $before->superGlobalVariables(),
2155                 $after->superGlobalVariables(),
2156                 "--- Super-global variables before the test\n+++ Super-global variables after the test\n"
2157             );
2158         }
2159
2160         if ($this->backupStaticAttributes) {
2161             $this->compareGlobalStateSnapshotPart(
2162                 $before->staticAttributes(),
2163                 $after->staticAttributes(),
2164                 "--- Static attributes before the test\n+++ Static attributes after the test\n"
2165             );
2166         }
2167     }
2168
2169     /**
2170      * @param array  $before
2171      * @param array  $after
2172      * @param string $header
2173      *
2174      * @throws PHPUnit_Framework_RiskyTestError
2175      */
2176     private function compareGlobalStateSnapshotPart(array $before, array $after, $header)
2177     {
2178         if ($before != $after) {
2179             $differ   = new Differ($header);
2180             $exporter = new Exporter;
2181
2182             $diff = $differ->diff(
2183                 $exporter->export($before),
2184                 $exporter->export($after)
2185             );
2186
2187             throw new PHPUnit_Framework_RiskyTestError(
2188                 $diff
2189             );
2190         }
2191     }
2192
2193     /**
2194      * @return Prophecy\Prophet
2195      *
2196      * @since Method available since Release 4.5.0
2197      */
2198     private function getProphet()
2199     {
2200         if ($this->prophet === null) {
2201             $this->prophet = new Prophet;
2202         }
2203
2204         return $this->prophet;
2205     }
2206 }