diff --git a/Unit_testing/PHPUnit/Framework/TestCase.php b/Unit_testing/PHPUnit/Framework/TestCase.php new file mode 100644 index 0000000..1563997 --- /dev/null +++ b/Unit_testing/PHPUnit/Framework/TestCase.php @@ -0,0 +1,1898 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright 2001-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +/** + * A TestCase defines the fixture to run multiple tests. + * + * To define a TestCase + * + * 1) Implement a subclass of PHPUnit_Framework_TestCase. + * 2) Define instance variables that store the state of the fixture. + * 3) Initialize the fixture state by overriding setUp(). + * 4) Clean-up after a test by overriding tearDown(). + * + * Each test runs in its own fixture so there can be no side effects + * among test runs. + * + * Here is an example: + * + * + * value1 = 2; + * $this->value2 = 3; + * } + * } + * ?> + * + * + * For each test implement a method which interacts with the fixture. + * Verify the expected results with assertions specified by calling + * assert with a boolean. + * + * + * assertTrue($this->value1 + $this->value2 == 5); + * } + * ?> + * + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright 2001-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +abstract class PHPUnit_Framework_TestCase extends PHPUnit_Framework_Assert implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing +{ + /** + * Enable or disable the backup and restoration of the $GLOBALS array. + * Overwrite this attribute in a child class of TestCase. + * Setting this attribute in setUp() has no effect! + * + * @var boolean + */ + protected $backupGlobals = NULL; + + /** + * @var array + */ + protected $backupGlobalsBlacklist = array(); + + /** + * Enable or disable the backup and restoration of static attributes. + * Overwrite this attribute in a child class of TestCase. + * Setting this attribute in setUp() has no effect! + * + * @var boolean + */ + protected $backupStaticAttributes = NULL; + + /** + * @var array + */ + protected $backupStaticAttributesBlacklist = array(); + + /** + * Whether or not this test is to be run in a separate PHP process. + * + * @var boolean + */ + protected $runTestInSeparateProcess = NULL; + + /** + * Whether or not this test should preserve the global state when + * running in a separate PHP process. + * + * @var boolean + */ + protected $preserveGlobalState = TRUE; + + /** + * Whether or not this test is running in a separate PHP process. + * + * @var boolean + */ + private $inIsolation = FALSE; + + /** + * @var array + */ + private $data = array(); + + /** + * @var string + */ + private $dataName = ''; + + /** + * @var boolean + */ + private $useErrorHandler = NULL; + + /** + * @var boolean + */ + private $useOutputBuffering = NULL; + + /** + * The name of the expected Exception. + * + * @var mixed + */ + private $expectedException = NULL; + + /** + * The message of the expected Exception. + * + * @var string + */ + private $expectedExceptionMessage = ''; + + /** + * The code of the expected Exception. + * + * @var integer + */ + private $expectedExceptionCode; + + /** + * The required preconditions for a test. + * + * @var array + */ + private $required = array( + 'PHP' => NULL, + 'PHPUnit' => NULL, + 'functions' => array(), + 'extensions' => array() + ); + + /** + * The name of the test case. + * + * @var string + */ + private $name = NULL; + + /** + * @var array + */ + private $dependencies = array(); + + /** + * @var array + */ + private $dependencyInput = array(); + + /** + * @var array + */ + private $iniSettings = array(); + + /** + * @var array + */ + private $locale = array(); + + /** + * @var array + */ + private $mockObjects = array(); + + /** + * @var integer + */ + private $status; + + /** + * @var string + */ + private $statusMessage = ''; + + /** + * @var integer + */ + private $numAssertions = 0; + + /** + * @var PHPUnit_Framework_TestResult + */ + private $result; + + /** + * @var mixed + */ + private $testResult; + + /** + * @var string + */ + private $output = ''; + + /** + * @var string + */ + private $outputExpectedRegex = NULL; + + /** + * @var string + */ + private $outputExpectedString = NULL; + + /** + * @var bool + */ + private $hasPerformedExpectationsOnOutput = FALSE; + + /** + * @var mixed + */ + private $outputCallback = FALSE; + + /** + * @var boolean + */ + private $outputBufferingActive = FALSE; + + /** + * Constructs a test case with the given name. + * + * @param string $name + * @param array $data + * @param string $dataName + */ + public function __construct($name = NULL, array $data = array(), $dataName = '') + { + if ($name !== NULL) { + $this->setName($name); + } + + $this->data = $data; + $this->dataName = $dataName; + } + + /** + * Returns a string representation of the test case. + * + * @return string + */ + public function toString() + { + $class = new ReflectionClass($this); + + $buffer = sprintf( + '%s::%s', + + $class->name, + $this->getName(FALSE) + ); + + return $buffer . $this->getDataSetAsString(); + } + + /** + * Counts the number of test cases executed by run(TestResult result). + * + * @return integer + */ + public function count() + { + return 1; + } + + /** + * Returns the annotations for this test. + * + * @return array + * @since Method available since Release 3.4.0 + */ + public function getAnnotations() + { + return PHPUnit_Util_Test::parseTestMethodAnnotations( + get_class($this), $this->name + ); + } + + /** + * Gets the name of a TestCase. + * + * @param boolean $withDataSet + * @return string + */ + public function getName($withDataSet = TRUE) + { + if ($withDataSet) { + return $this->name . $this->getDataSetAsString(FALSE); + } else { + return $this->name; + } + } + + /** + * Returns the size of the test. + * + * @return integer + * @since Method available since Release 3.6.0 + */ + public function getSize() + { + return PHPUnit_Util_Test::getSize( + get_class($this), $this->getName(FALSE) + ); + } + + /** + * @return string + * @since Method available since Release 3.6.0 + */ + public function getActualOutput() + { + if (!$this->outputBufferingActive) { + return $this->output; + } else { + return ob_get_contents(); + } + } + + /** + * @return string + * @since Method available since Release 3.6.0 + */ + public function hasOutput() + { + if (strlen($this->output) === 0) { + return FALSE; + } + + if ($this->outputExpectedString !== NULL || + $this->outputExpectedRegex !== NULL || + $this->hasPerformedExpectationsOnOutput) { + return FALSE; + } + + return TRUE; + } + + /** + * @param string $expectedRegex + * @since Method available since Release 3.6.0 + */ + public function expectOutputRegex($expectedRegex) + { + if ($this->outputExpectedString !== NULL) { + throw new PHPUnit_Framework_Exception; + } + + if (is_string($expectedRegex) || is_null($expectedRegex)) { + $this->outputExpectedRegex = $expectedRegex; + } + } + + /** + * @param string $expectedString + * @since Method available since Release 3.6.0 + */ + public function expectOutputString($expectedString) + { + if ($this->outputExpectedRegex !== NULL) { + throw new PHPUnit_Framework_Exception; + } + + if (is_string($expectedString) || is_null($expectedString)) { + $this->outputExpectedString = $expectedString; + } + } + + /** + * @return bool + * @since Method available since Release 3.6.5 + */ + public function hasPerformedExpectationsOnOutput() + { + return $this->hasPerformedExpectationsOnOutput; + } + + /** + * @return string + * @since Method available since Release 3.2.0 + */ + public function getExpectedException() + { + return $this->expectedException; + } + + /** + * @param mixed $exceptionName + * @param string $exceptionMessage + * @param integer $exceptionCode + * @since Method available since Release 3.2.0 + */ + public function setExpectedException($exceptionName, $exceptionMessage = '', $exceptionCode = NULL) + { + $this->expectedException = $exceptionName; + $this->expectedExceptionMessage = $exceptionMessage; + $this->expectedExceptionCode = $exceptionCode; + } + + /** + * @since Method available since Release 3.4.0 + */ + protected function setExpectedExceptionFromAnnotation() + { + try { + $expectedException = PHPUnit_Util_Test::getExpectedException( + get_class($this), $this->name + ); + + if ($expectedException !== FALSE) { + $this->setExpectedException( + $expectedException['class'], + $expectedException['message'], + $expectedException['code'] + ); + } + } + + catch (ReflectionException $e) { + } + } + + /** + * @param boolean $useErrorHandler + * @since Method available since Release 3.4.0 + */ + public function setUseErrorHandler($useErrorHandler) + { + $this->useErrorHandler = $useErrorHandler; + } + + /** + * @since Method available since Release 3.4.0 + */ + protected function setUseErrorHandlerFromAnnotation() + { + try { + $useErrorHandler = PHPUnit_Util_Test::getErrorHandlerSettings( + get_class($this), $this->name + ); + + if ($useErrorHandler !== NULL) { + $this->setUseErrorHandler($useErrorHandler); + } + } + + catch (ReflectionException $e) { + } + } + + /** + * @param boolean $useOutputBuffering + * @since Method available since Release 3.4.0 + */ + public function setUseOutputBuffering($useOutputBuffering) + { + $this->useOutputBuffering = $useOutputBuffering; + } + + /** + * @since Method available since Release 3.4.0 + */ + protected function setUseOutputBufferingFromAnnotation() + { + try { + $useOutputBuffering = PHPUnit_Util_Test::getOutputBufferingSettings( + get_class($this), $this->name + ); + + if ($useOutputBuffering !== NULL) { + $this->setUseOutputBuffering($useOutputBuffering); + } + } + + catch (ReflectionException $e) { + } + } + + /** + * @since Method available since Release 3.6.0 + */ + protected function setRequirementsFromAnnotation() + { + try { + $requirements = PHPUnit_Util_Test::getRequirements( + get_class($this), $this->name + ); + + if (isset($requirements['PHP'])) { + $this->required['PHP'] = $requirements['PHP']; + } + + if (isset($requirements['PHPUnit'])) { + $this->required['PHPUnit'] = $requirements['PHPUnit']; + } + + if (isset($requirements['extensions'])) { + $this->required['extensions'] = $requirements['extensions']; + } + + if (isset($requirements['functions'])) { + $this->required['functions'] = $requirements['functions']; + } + } + + catch (ReflectionException $e) { + } + } + + /** + * @since Method available since Release 3.6.0 + */ + protected function checkRequirements() + { + $this->setRequirementsFromAnnotation(); + + $missingRequirements = array(); + + if ($this->required['PHP'] && + version_compare(PHP_VERSION, $this->required['PHP'], '<')) { + $missingRequirements[] = sprintf( + 'PHP %s (or later) is required.', + $this->required['PHP'] + ); + } + + $phpunitVersion = PHPUnit_Runner_Version::id(); + if ($this->required['PHPUnit'] && + version_compare($phpunitVersion, $this->required['PHPUnit'], '<')) { + $missingRequirements[] = sprintf( + 'PHPUnit %s (or later) is required.', + $this->required['PHPUnit'] + ); + } + + foreach ($this->required['functions'] as $requiredFunction) { + if (!function_exists($requiredFunction)) { + $missingRequirements[] = sprintf( + 'Function %s is required.', + $requiredFunction + ); + } + } + + foreach ($this->required['extensions'] as $requiredExtension) { + if (!extension_loaded($requiredExtension)) { + $missingRequirements[] = sprintf( + 'Extension %s is required.', + $requiredExtension + ); + } + } + + if ($missingRequirements) { + $this->markTestSkipped( + implode( + PHP_EOL, + $missingRequirements + ) + ); + } + } + + /** + * Returns the status of this test. + * + * @return integer + * @since Method available since Release 3.1.0 + */ + public function getStatus() + { + return $this->status; + } + + /** + * Returns the status message of this test. + * + * @return string + * @since Method available since Release 3.3.0 + */ + public function getStatusMessage() + { + return $this->statusMessage; + } + + /** + * Returns whether or not this test has failed. + * + * @return boolean + * @since Method available since Release 3.0.0 + */ + public function hasFailed() + { + $status = $this->getStatus(); + + return $status == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE || + $status == PHPUnit_Runner_BaseTestRunner::STATUS_ERROR; + } + + /** + * Runs the test case and collects the results in a TestResult object. + * If no TestResult object is passed a new one will be created. + * + * @param PHPUnit_Framework_TestResult $result + * @return PHPUnit_Framework_TestResult + * @throws PHPUnit_Framework_Exception + */ + public function run(PHPUnit_Framework_TestResult $result = NULL) + { + if ($result === NULL) { + $result = $this->createResult(); + } + + if (!$this instanceof PHPUnit_Framework_Warning) { + $this->setTestResultObject($result); + $this->setUseErrorHandlerFromAnnotation(); + $this->setUseOutputBufferingFromAnnotation(); + } + + if ($this->useErrorHandler !== NULL) { + $oldErrorHandlerSetting = $result->getConvertErrorsToExceptions(); + $result->convertErrorsToExceptions($this->useErrorHandler); + } + + if (!$this instanceof PHPUnit_Framework_Warning && !$this->handleDependencies()) { + return; + } + + if ($this->runTestInSeparateProcess === TRUE && + $this->inIsolation !== TRUE && + !$this instanceof PHPUnit_Extensions_SeleniumTestCase && + !$this instanceof PHPUnit_Extensions_PhptTestCase) { + $class = new ReflectionClass($this); + + $template = new Text_Template( + sprintf( + '%s%sProcess%sTestCaseMethod.tpl', + + __DIR__, + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR + ) + ); + + if ($this->preserveGlobalState) { + $constants = PHPUnit_Util_GlobalState::getConstantsAsString(); + $globals = PHPUnit_Util_GlobalState::getGlobalsAsString(); + $includedFiles = PHPUnit_Util_GlobalState::getIncludedFilesAsString(); + } else { + $constants = ''; + $globals = ''; + $includedFiles = ''; + } + + if ($result->getCollectCodeCoverageInformation()) { + $coverage = 'TRUE'; + } else { + $coverage = 'FALSE'; + } + + if ($result->isStrict()) { + $strict = 'TRUE'; + } else { + $strict = 'FALSE'; + } + + if (defined('PHPUNIT_COMPOSER_INSTALL')) { + $composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, TRUE); + } else { + $composerAutoload = '\'\''; + } + + if (defined('__PHPUNIT_PHAR__')) { + $phar = var_export(__PHPUNIT_PHAR__, TRUE); + } else { + $phar = '\'\''; + } + + $data = var_export(serialize($this->data), TRUE); + $dependencyInput = var_export(serialize($this->dependencyInput), TRUE); + $includePath = var_export(get_include_path(), TRUE); + // must do these fixes because TestCaseMethod.tpl has unserialize('{data}') in it, and we can't break BC + // the lines above used to use addcslashes() rather than var_export(), which breaks null byte escape sequences + $data = "'." . $data . ".'"; + $dependencyInput = "'." . $dependencyInput . ".'"; + $includePath = "'." . $includePath . ".'"; + + $template->setVar( + array( + 'composerAutoload' => $composerAutoload, + 'phar' => $phar, + 'filename' => $class->getFileName(), + 'className' => $class->getName(), + 'methodName' => $this->name, + 'collectCodeCoverageInformation' => $coverage, + 'data' => $data, + 'dataName' => $this->dataName, + 'dependencyInput' => $dependencyInput, + 'constants' => $constants, + 'globals' => $globals, + 'include_path' => $includePath, + 'included_files' => $includedFiles, + 'strict' => $strict + ) + ); + + $this->prepareTemplate($template); + + $php = PHPUnit_Util_PHP::factory(); + $php->runJob($template->render(), $this, $result); + } else { + $result->run($this); + } + + if ($this->useErrorHandler !== NULL) { + $result->convertErrorsToExceptions($oldErrorHandlerSetting); + } + + $this->result = NULL; + + return $result; + } + + /** + * Runs the bare test sequence. + */ + public function runBare() + { + $this->numAssertions = 0; + + // Backup the $GLOBALS array and static attributes. + if ($this->runTestInSeparateProcess !== TRUE && + $this->inIsolation !== TRUE) { + if ($this->backupGlobals === NULL || + $this->backupGlobals === TRUE) { + PHPUnit_Util_GlobalState::backupGlobals( + $this->backupGlobalsBlacklist + ); + } + + if ($this->backupStaticAttributes === TRUE) { + PHPUnit_Util_GlobalState::backupStaticAttributes( + $this->backupStaticAttributesBlacklist + ); + } + } + + // Start output buffering. +/* + ob_start(); + $this->outputBufferingActive = TRUE; +*/ + + // Clean up stat cache. + clearstatcache(); + + // Backup the cwd + $currentWorkingDirectory = getcwd(); + + try { + if ($this->inIsolation) { + $this->setUpBeforeClass(); + } + + $this->setExpectedExceptionFromAnnotation(); + $this->setUp(); + $this->checkRequirements(); + $this->assertPreConditions(); + $this->testResult = $this->runTest(); + $this->verifyMockObjects(); + $this->assertPostConditions(); + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_PASSED; + } + + catch (PHPUnit_Framework_IncompleteTest $e) { + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE; + $this->statusMessage = $e->getMessage(); + } + + catch (PHPUnit_Framework_SkippedTest $e) { + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED; + $this->statusMessage = $e->getMessage(); + } + + catch (PHPUnit_Framework_AssertionFailedError $e) { + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE; + $this->statusMessage = $e->getMessage(); + } + + catch (Exception $e) { + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_ERROR; + $this->statusMessage = $e->getMessage(); + } + + // Clean up the mock objects. + $this->mockObjects = array(); + + // Tear down the fixture. An exception raised in tearDown() will be + // caught and passed on when no exception was raised before. + try { + $this->tearDown(); + + if ($this->inIsolation) { + $this->tearDownAfterClass(); + } + } + + catch (Exception $_e) { + if (!isset($e)) { + $e = $_e; + } + } + + // Stop output buffering. +/* + if ($this->outputCallback === FALSE) { + $this->output = ob_get_contents(); + } else { + $this->output = call_user_func_array( + $this->outputCallback, array(ob_get_contents()) + ); + } + + ob_end_clean(); + $this->outputBufferingActive = FALSE; +*/ + + // Clean up stat cache. + clearstatcache(); + + // Restore the cwd if it was changed by the test + if ($currentWorkingDirectory != getcwd()) { + chdir($currentWorkingDirectory); + } + + // Restore the $GLOBALS array and static attributes. + if ($this->runTestInSeparateProcess !== TRUE && + $this->inIsolation !== TRUE) { + if ($this->backupGlobals === NULL || + $this->backupGlobals === TRUE) { + PHPUnit_Util_GlobalState::restoreGlobals( + $this->backupGlobalsBlacklist + ); + } + + if ($this->backupStaticAttributes === TRUE) { + PHPUnit_Util_GlobalState::restoreStaticAttributes(); + } + } + + // Clean up INI settings. + foreach ($this->iniSettings as $varName => $oldValue) { + ini_set($varName, $oldValue); + } + + $this->iniSettings = array(); + + // Clean up locale settings. + foreach ($this->locale as $category => $locale) { + setlocale($category, $locale); + } + + // Perform assertion on output. + if (!isset($e)) { + try { + if ($this->outputExpectedRegex !== NULL) { + $this->hasPerformedExpectationsOnOutput = TRUE; + $this->assertRegExp($this->outputExpectedRegex, $this->output); + $this->outputExpectedRegex = NULL; + } + + else if ($this->outputExpectedString !== NULL) { + $this->hasPerformedExpectationsOnOutput = TRUE; + $this->assertEquals($this->outputExpectedString, $this->output); + $this->outputExpectedString = NULL; + } + } + + catch (Exception $_e) { + $e = $_e; + } + } + + // Workaround for missing "finally". + if (isset($e)) { + $this->onNotSuccessfulTest($e); + } + } + + /** + * Override to run the test and assert its state. + * + * @return mixed + * @throws PHPUnit_Framework_Exception + */ + protected function runTest() + { + if ($this->name === NULL) { + throw new PHPUnit_Framework_Exception( + 'PHPUnit_Framework_TestCase::$name must not be NULL.' + ); + } + + try { + $class = new ReflectionClass($this); + $method = $class->getMethod($this->name); + } + + catch (ReflectionException $e) { + $this->fail($e->getMessage()); + } + + try { + $testResult = $method->invokeArgs( + $this, array_merge($this->data, $this->dependencyInput) + ); + } + + catch (Exception $e) { + $checkException = FALSE; + + if (is_string($this->expectedException)) { + $checkException = TRUE; + + if ($e instanceof PHPUnit_Framework_Exception) { + $checkException = FALSE; + } + + $reflector = new ReflectionClass($this->expectedException); + + if ($this->expectedException == 'PHPUnit_Framework_Exception' || + $reflector->isSubclassOf('PHPUnit_Framework_Exception')) { + $checkException = TRUE; + } + } + + if ($checkException) { + $this->assertThat( + $e, + new PHPUnit_Framework_Constraint_Exception( + $this->expectedException + ) + ); + + if (is_string($this->expectedExceptionMessage) && + !empty($this->expectedExceptionMessage)) { + $this->assertThat( + $e, + new PHPUnit_Framework_Constraint_ExceptionMessage( + $this->expectedExceptionMessage + ) + ); + } + + if ($this->expectedExceptionCode !== NULL) { + $this->assertThat( + $e, + new PHPUnit_Framework_Constraint_ExceptionCode( + $this->expectedExceptionCode + ) + ); + } + + return; + } else { + throw $e; + } + } + + if ($this->expectedException !== NULL) { + $this->assertThat( + NULL, + new PHPUnit_Framework_Constraint_Exception( + $this->expectedException + ) + ); + } + + return $testResult; + } + + /** + * Verifies the mock object expectations. + * + * @since Method available since Release 3.5.0 + */ + protected function verifyMockObjects() + { + foreach ($this->mockObjects as $mockObject) { + if ($mockObject->__phpunit_hasMatchers()) { + $this->numAssertions++; + } + + $mockObject->__phpunit_verify(); + $mockObject->__phpunit_cleanup(); + } + } + + /** + * Sets the name of a TestCase. + * + * @param string + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Sets the dependencies of a TestCase. + * + * @param array $dependencies + * @since Method available since Release 3.4.0 + */ + public function setDependencies(array $dependencies) + { + $this->dependencies = $dependencies; + } + + /** + * Sets + * + * @param array $dependencyInput + * @since Method available since Release 3.4.0 + */ + public function setDependencyInput(array $dependencyInput) + { + $this->dependencyInput = $dependencyInput; + } + + /** + * Calling this method in setUp() has no effect! + * + * @param boolean $backupGlobals + * @since Method available since Release 3.3.0 + */ + public function setBackupGlobals($backupGlobals) + { + if (is_null($this->backupGlobals) && is_bool($backupGlobals)) { + $this->backupGlobals = $backupGlobals; + } + } + + /** + * Calling this method in setUp() has no effect! + * + * @param boolean $backupStaticAttributes + * @since Method available since Release 3.4.0 + */ + public function setBackupStaticAttributes($backupStaticAttributes) + { + if (is_null($this->backupStaticAttributes) && + is_bool($backupStaticAttributes)) { + $this->backupStaticAttributes = $backupStaticAttributes; + } + } + + /** + * @param boolean $runTestInSeparateProcess + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.4.0 + */ + public function setRunTestInSeparateProcess($runTestInSeparateProcess) + { + if (is_bool($runTestInSeparateProcess)) { + if ($this->runTestInSeparateProcess === NULL) { + $this->runTestInSeparateProcess = $runTestInSeparateProcess; + } + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * @param boolean $preserveGlobalState + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.4.0 + */ + public function setPreserveGlobalState($preserveGlobalState) + { + if (is_bool($preserveGlobalState)) { + $this->preserveGlobalState = $preserveGlobalState; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * @param boolean $inIsolation + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.4.0 + */ + public function setInIsolation($inIsolation) + { + if (is_bool($inIsolation)) { + $this->inIsolation = $inIsolation; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * @return mixed + * @since Method available since Release 3.4.0 + */ + public function getResult() + { + return $this->testResult; + } + + /** + * @param mixed $result + * @since Method available since Release 3.4.0 + */ + public function setResult($result) + { + $this->testResult = $result; + } + + /** + * @param callable $callback + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.6.0 + */ + public function setOutputCallback($callback) + { + if (!is_callable($callback)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'callback'); + } + + $this->outputCallback = $callback; + } + + /** + * @return PHPUnit_Framework_TestResult + * @since Method available since Release 3.5.7 + */ + public function getTestResultObject() + { + return $this->result; + } + + /** + * @param PHPUnit_Framework_TestResult $result + * @since Method available since Release 3.6.0 + */ + public function setTestResultObject(PHPUnit_Framework_TestResult $result) + { + $this->result = $result; + } + + /** + * This method is a wrapper for the ini_set() function that automatically + * resets the modified php.ini setting to its original value after the + * test is run. + * + * @param string $varName + * @param string $newValue + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.0.0 + */ + protected function iniSet($varName, $newValue) + { + if (!is_string($varName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $currentValue = ini_set($varName, $newValue); + + if ($currentValue !== FALSE) { + $this->iniSettings[$varName] = $currentValue; + } else { + throw new PHPUnit_Framework_Exception( + sprintf( + 'INI setting "%s" could not be set to "%s".', + $varName, + $newValue + ) + ); + } + } + + /** + * This method is a wrapper for the setlocale() function that automatically + * resets the locale to its original value after the test is run. + * + * @param integer $category + * @param string $locale + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.1.0 + */ + protected function setLocale() + { + $args = func_get_args(); + + if (count($args) < 2) { + throw new PHPUnit_Framework_Exception; + } + + $category = $args[0]; + $locale = $args[1]; + + $categories = array( + LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME + ); + + if (defined('LC_MESSAGES')) { + $categories[] = LC_MESSAGES; + } + + if (!in_array($category, $categories)) { + throw new PHPUnit_Framework_Exception; + } + + if (!is_array($locale) && !is_string($locale)) { + throw new PHPUnit_Framework_Exception; + } + + $this->locale[$category] = setlocale($category, NULL); + + $result = call_user_func_array( 'setlocale', $args ); + + if ($result === FALSE) { + throw new PHPUnit_Framework_Exception( + 'The locale functionality is not implemented on your platform, ' . + 'the specified locale does not exist or the category name is ' . + 'invalid.' + ); + } + } + + /** + * Returns a mock object for the specified class. + * + * @param string $originalClassName + * @param array $methods + * @param array $arguments + * @param string $mockClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @param boolean $cloneArguments + * @return PHPUnit_Framework_MockObject_MockObject + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.0.0 + */ + public function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = FALSE) + { + $mockObject = PHPUnit_Framework_MockObject_Generator::getMock( + $originalClassName, + $methods, + $arguments, + $mockClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $cloneArguments + ); + + $this->mockObjects[] = $mockObject; + + return $mockObject; + } + + /** + * Returns a builder object to create mock objects using a fluent interface. + * + * @param string $className + * @return PHPUnit_Framework_MockObject_MockBuilder + * @since Method available since Release 3.5.0 + */ + public function getMockBuilder($className) + { + return new PHPUnit_Framework_MockObject_MockBuilder( + $this, $className + ); + } + + /** + * Mocks the specified class and returns the name of the mocked class. + * + * @param string $originalClassName + * @param array $methods + * @param array $arguments + * @param string $mockClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @param boolean $cloneArguments + * @return string + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.5.0 + */ + protected function getMockClass($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = FALSE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = FALSE) + { + $mock = $this->getMock( + $originalClassName, + $methods, + $arguments, + $mockClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $cloneArguments + ); + + return get_class($mock); + } + + /** + * Returns a mock object for the specified abstract class with all abstract + * methods of the class mocked. Concrete methods to mock can be specified with + * the last parameter + * + * @param string $originalClassName + * @param array $arguments + * @param string $mockClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @param array $mockedMethods + * @param boolean $cloneArguments + * @return PHPUnit_Framework_MockObject_MockObject + * @since Method available since Release 3.4.0 + * @throws PHPUnit_Framework_Exception + */ + public function getMockForAbstractClass($originalClassName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $mockedMethods = array(), $cloneArguments = FALSE) + { + $mockObject = PHPUnit_Framework_MockObject_Generator::getMockForAbstractClass( + $originalClassName, + $arguments, + $mockClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $mockedMethods, + $cloneArguments + ); + + $this->mockObjects[] = $mockObject; + + return $mockObject; + } + + /** + * Returns a mock object based on the given WSDL file. + * + * @param string $wsdlFile + * @param string $originalClassName + * @param string $mockClassName + * @param array $methods + * @param boolean $callOriginalConstructor + * @return PHPUnit_Framework_MockObject_MockObject + * @since Method available since Release 3.4.0 + */ + protected function getMockFromWsdl($wsdlFile, $originalClassName = '', $mockClassName = '', array $methods = array(), $callOriginalConstructor = TRUE) + { + if ($originalClassName === '') { + $originalClassName = str_replace( + '.wsdl', '', basename($wsdlFile) + ); + } + + if (!class_exists($originalClassName)) { + eval( + PHPUnit_Framework_MockObject_Generator::generateClassFromWsdl( + $wsdlFile, $originalClassName, $methods + ) + ); + } + + return $this->getMock( + $originalClassName, + $methods, + array('', array()), + $mockClassName, + $callOriginalConstructor, + FALSE, + FALSE + ); + } + + /** + * Returns an object for the specified trait. + * + * @param string $traitName + * @param array $arguments + * @param string $traitClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @param boolean $cloneArguments + * @return object + * @since Method available since Release 3.6.0 + * @throws PHPUnit_Framework_Exception + */ + protected function getObjectForTrait($traitName, array $arguments = array(), $traitClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = FALSE) + { + return PHPUnit_Framework_MockObject_Generator::getObjectForTrait( + $traitName, + $arguments, + $traitClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $cloneArguments + ); + } + + /** + * Adds a value to the assertion counter. + * + * @param integer $count + * @since Method available since Release 3.3.3 + */ + public function addToAssertionCount($count) + { + $this->numAssertions += $count; + } + + /** + * Returns the number of assertions performed by this test. + * + * @return integer + * @since Method available since Release 3.3.0 + */ + public function getNumAssertions() + { + return $this->numAssertions; + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed zero or more times. + * + * @return PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount + * @since Method available since Release 3.0.0 + */ + public static function any() + { + return new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount; + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is never executed. + * + * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount + * @since Method available since Release 3.0.0 + */ + public static function never() + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(0); + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed at least once. + * + * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce + * @since Method available since Release 3.0.0 + */ + public static function atLeastOnce() + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce; + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed exactly once. + * + * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount + * @since Method available since Release 3.0.0 + */ + public static function once() + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(1); + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed exactly $count times. + * + * @param integer $count + * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount + * @since Method available since Release 3.0.0 + */ + public static function exactly($count) + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedCount($count); + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is invoked at the given $index. + * + * @param integer $index + * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex + * @since Method available since Release 3.0.0 + */ + public static function at($index) + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex($index); + } + + /** + * + * + * @param mixed $value + * @return PHPUnit_Framework_MockObject_Stub_Return + * @since Method available since Release 3.0.0 + */ + public static function returnValue($value) + { + return new PHPUnit_Framework_MockObject_Stub_Return($value); + } + + /** + * + * + * @param array $valueMap + * @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap + * @since Method available since Release 3.6.0 + */ + public static function returnValueMap(array $valueMap) + { + return new PHPUnit_Framework_MockObject_Stub_ReturnValueMap($valueMap); + } + + /** + * + * + * @param integer $argumentIndex + * @return PHPUnit_Framework_MockObject_Stub_ReturnArgument + * @since Method available since Release 3.3.0 + */ + public static function returnArgument($argumentIndex) + { + return new PHPUnit_Framework_MockObject_Stub_ReturnArgument( + $argumentIndex + ); + } + + /** + * + * + * @param mixed $callback + * @return PHPUnit_Framework_MockObject_Stub_ReturnCallback + * @since Method available since Release 3.3.0 + */ + public static function returnCallback($callback) + { + return new PHPUnit_Framework_MockObject_Stub_ReturnCallback($callback); + } + + /** + * Returns the current object. + * + * This method is useful when mocking a fluent interface. + * + * @return PHPUnit_Framework_MockObject_Stub_ReturnSelf + * @since Method available since Release 3.6.0 + */ + public static function returnSelf() + { + return new PHPUnit_Framework_MockObject_Stub_ReturnSelf(); + } + + /** + * + * + * @param Exception $exception + * @return PHPUnit_Framework_MockObject_Stub_Exception + * @since Method available since Release 3.1.0 + */ + public static function throwException(Exception $exception) + { + return new PHPUnit_Framework_MockObject_Stub_Exception($exception); + } + + /** + * + * + * @param mixed $value, ... + * @return PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls + * @since Method available since Release 3.0.0 + */ + public static function onConsecutiveCalls() + { + $args = func_get_args(); + + return new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($args); + } + + /** + * @param mixed $data + * @return string + * @since Method available since Release 3.2.1 + */ + protected function dataToString($data) + { + $result = array(); + + // There seems to be no other way to check arrays for recursion + // http://www.php.net/manual/en/language.types.array.php#73936 + preg_match_all('/\n \[(\w+)\] => Array\s+\*RECURSION\*/', print_r($data, TRUE), $matches); + $recursiveKeys = array_unique($matches[1]); + + // Convert to valid array keys + // Numeric integer strings are automatically converted to integers + // by PHP + foreach ($recursiveKeys as $key => $recursiveKey) { + if ((string)(integer)$recursiveKey === $recursiveKey) { + $recursiveKeys[$key] = (integer)$recursiveKey; + } + } + + foreach ($data as $key => $_data) { + if (in_array($key, $recursiveKeys, TRUE)) { + $result[] = '*RECURSION*'; + } + + else if (is_array($_data)) { + $result[] = 'array(' . $this->dataToString($_data) . ')'; + } + + else if (is_object($_data)) { + $object = new ReflectionObject($_data); + + if ($object->hasMethod('__toString')) { + $result[] = (string)$_data; + } else { + $result[] = get_class($_data); + } + } + + else if (is_resource($_data)) { + $result[] = ''; + } + + else { + $result[] = var_export($_data, TRUE); + } + } + + return join(', ', $result); + } + + /** + * Gets the data set description of a TestCase. + * + * @param boolean $includeData + * @return string + * @since Method available since Release 3.3.0 + */ + protected function getDataSetAsString($includeData = TRUE) + { + $buffer = ''; + + if (!empty($this->data)) { + if (is_int($this->dataName)) { + $buffer .= sprintf(' with data set #%d', $this->dataName); + } else { + $buffer .= sprintf(' with data set "%s"', $this->dataName); + } + + if ($includeData) { + $buffer .= sprintf(' (%s)', $this->dataToString($this->data)); + } + } + + return $buffer; + } + + /** + * Creates a default TestResult object. + * + * @return PHPUnit_Framework_TestResult + */ + protected function createResult() + { + return new PHPUnit_Framework_TestResult; + } + + /** + * @since Method available since Release 3.5.4 + */ + protected function handleDependencies() + { + if (!empty($this->dependencies) && !$this->inIsolation) { + $className = get_class($this); + $passed = $this->result->passed(); + $passedKeys = array_keys($passed); + $numKeys = count($passedKeys); + + for ($i = 0; $i < $numKeys; $i++) { + $pos = strpos($passedKeys[$i], ' with data set'); + + if ($pos !== FALSE) { + $passedKeys[$i] = substr($passedKeys[$i], 0, $pos); + } + } + + $passedKeys = array_flip(array_unique($passedKeys)); + + foreach ($this->dependencies as $dependency) { + if (strpos($dependency, '::') === FALSE) { + $dependency = $className . '::' . $dependency; + } + + if (!isset($passedKeys[$dependency])) { + $this->result->addError( + $this, + new PHPUnit_Framework_SkippedTestError( + sprintf( + 'This test depends on "%s" to pass.', $dependency + ) + ), + 0 + ); + + return FALSE; + } + + if (isset($passed[$dependency])) { + if ($passed[$dependency]['size'] > $this->getSize()) { + $this->result->addError( + $this, + new PHPUnit_Framework_SkippedTestError( + 'This test depends on a test that is larger than itself.' + ), + 0 + ); + + return FALSE; + } + + $this->dependencyInput[] = $passed[$dependency]['result']; + } else { + $this->dependencyInput[] = NULL; + } + } + } + + return TRUE; + } + + /** + * This method is called before the first test of this test class is run. + * + * @since Method available since Release 3.4.0 + */ + public static function setUpBeforeClass() + { + } + + /** + * Sets up the fixture, for example, open a network connection. + * This method is called before a test is executed. + * + */ + protected function setUp() + { + } + + /** + * Performs assertions shared by all tests of a test case. + * + * This method is called before the execution of a test starts + * and after setUp() is called. + * + * @since Method available since Release 3.2.8 + */ + protected function assertPreConditions() + { + } + + /** + * Performs assertions shared by all tests of a test case. + * + * This method is called before the execution of a test ends + * and before tearDown() is called. + * + * @since Method available since Release 3.2.8 + */ + protected function assertPostConditions() + { + } + + /** + * Tears down the fixture, for example, close a network connection. + * This method is called after a test is executed. + */ + protected function tearDown() + { + } + + /** + * This method is called after the last test of this test class is run. + * + * @since Method available since Release 3.4.0 + */ + public static function tearDownAfterClass() + { + } + + /** + * This method is called when a test method did not execute successfully. + * + * @param Exception $e + * @since Method available since Release 3.4.0 + */ + protected function onNotSuccessfulTest(Exception $e) + { + throw $e; + } + + /** + * Performs custom preparations on the process isolation template. + * + * @param Text_Template $template + * @since Method available since Release 3.4.0 + */ + protected function prepareTemplate(Text_Template $template) + { + } +}