Viewing file: Test.php (19.27 KB) -rw-rw-rw- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php /** * PHPUnit * * Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>. * 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 Util * @author Sebastian Bergmann <sebastian@phpunit.de> * @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de> * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.0.0 */
/** * Test helpers. * * @package PHPUnit * @subpackage Util * @author Sebastian Bergmann <sebastian@phpunit.de> * @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de> * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.0.0 */ class PHPUnit_Util_Test { const REGEX_DATA_PROVIDER = '/@dataProvider\s+([a-zA-Z0-9._:-\\\\x7f-\xff]+)/'; const REGEX_EXPECTED_EXCEPTION = '(@expectedException\s+([:.\w\\\\x7f-\xff]+)(?:[\t ]+(\S*))?(?:[\t ]+(\S*))?\s*$)m'; const REGEX_REQUIRES_VERSION = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<value>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m'; const REGEX_REQUIRES = '/@requires\s+(?P<name>function|extension)\s(?P<value>([^ ]+))\r?$/m';
const SMALL = 0; const MEDIUM = 1; const LARGE = 2;
private static $annotationCache = array();
protected static $templateMethods = array( 'setUp', 'assertPreConditions', 'assertPostConditions', 'tearDown' );
/** * @param PHPUnit_Framework_Test $test * @param boolean $asString * @return mixed */ public static function describe(PHPUnit_Framework_Test $test, $asString = TRUE) { if ($asString) { if ($test instanceof PHPUnit_Framework_SelfDescribing) { return $test->toString(); } else { return get_class($test); } } else { if ($test instanceof PHPUnit_Framework_TestCase) { return array( get_class($test), $test->getName() ); }
else if ($test instanceof PHPUnit_Framework_SelfDescribing) { return array('', $test->toString()); }
else { return array('', get_class($test)); } } }
/** * Returns the requirements for a test. * * @param string $className * @param string $methodName * @return array * @since Method available since Release 3.6.0 */ public static function getRequirements($className, $methodName) { $reflector = new ReflectionClass($className); $docComment = $reflector->getDocComment(); $reflector = new ReflectionMethod($className, $methodName); $docComment .= "\n" . $reflector->getDocComment(); $requires = array();
if ($count = preg_match_all(self::REGEX_REQUIRES_VERSION, $docComment, $matches)) { for ($i = 0; $i < $count; $i++) { $requires[$matches['name'][$i]] = $matches['value'][$i]; } } if ($count = preg_match_all(self::REGEX_REQUIRES, $docComment, $matches)) { for ($i = 0; $i < $count; $i++) { $name = $matches['name'][$i] . 's'; if (!isset($requires[$name])) { $requires[$name] = array(); } $requires[$name][] = $matches['value'][$i]; } }
return $requires; }
/** * Returns the expected exception for a test. * * @param string $className * @param string $methodName * @return array * @since Method available since Release 3.3.6 */ public static function getExpectedException($className, $methodName) { $reflector = new ReflectionMethod($className, $methodName); $docComment = $reflector->getDocComment(); $docComment = substr($docComment, 3, -2);
if (preg_match(self::REGEX_EXPECTED_EXCEPTION, $docComment, $matches)) { $annotations = self::parseTestMethodAnnotations( $className, $methodName );
$class = $matches[1]; $code = NULL; $message = '';
if (isset($matches[2])) { $message = trim($matches[2]); }
else if (isset($annotations['method']['expectedExceptionMessage'])) { $message = self::_parseAnnotationContent( $annotations['method']['expectedExceptionMessage'][0] ); }
if (isset($matches[3])) { $code = $matches[3]; }
else if (isset($annotations['method']['expectedExceptionCode'])) { $code = self::_parseAnnotationContent( $annotations['method']['expectedExceptionCode'][0] ); }
if (is_numeric($code)) { $code = (int)$code; }
else if (is_string($code) && defined($code)) { $code = (int)constant($code); }
return array( 'class' => $class, 'code' => $code, 'message' => $message ); }
return FALSE; }
/** * Parse annotation content to use constant/class constant values * * Constants are specified using a starting '@'. For example: @ClassName::CONST_NAME * * If the constant is not found the string is used as is to ensure maximum BC. * * @param string $message * @return string */ protected static function _parseAnnotationContent($message) { if (strpos($message, '::') !== FALSE && count(explode('::', $message) == 2)) { if (defined($message)) { $message = constant($message); } } return $message; }
/** * Returns the provided data for a method. * * @param string $className * @param string $methodName * @param string $docComment * @return mixed array|Iterator when a data provider is specified and exists * false when a data provider is specified and does not exist * null when no data provider is specified * @since Method available since Release 3.2.0 */ public static function getProvidedData($className, $methodName) { $reflector = new ReflectionMethod($className, $methodName); $docComment = $reflector->getDocComment(); $data = NULL;
if (preg_match(self::REGEX_DATA_PROVIDER, $docComment, $matches)) { $dataProviderMethodNameNamespace = explode('\\', $matches[1]); $leaf = explode('::', array_pop($dataProviderMethodNameNamespace)); $dataProviderMethodName = array_pop($leaf);
if (!empty($dataProviderMethodNameNamespace)) { $dataProviderMethodNameNamespace = join('\\', $dataProviderMethodNameNamespace) . '\\'; } else { $dataProviderMethodNameNamespace = ''; }
if (!empty($leaf)) { $dataProviderClassName = $dataProviderMethodNameNamespace . array_pop($leaf); } else { $dataProviderClassName = $className; }
$dataProviderClass = new ReflectionClass($dataProviderClassName); $dataProviderMethod = $dataProviderClass->getMethod( $dataProviderMethodName );
if ($dataProviderMethod->isStatic()) { $object = NULL; } else { $object = $dataProviderClass->newInstance(); }
if ($dataProviderMethod->getNumberOfParameters() == 0) { $data = $dataProviderMethod->invoke($object); } else { $data = $dataProviderMethod->invoke($object, $methodName); } }
if ($data !== NULL) { foreach ($data as $key => $value) { if (!is_array($value)) { throw new PHPUnit_Framework_Exception( sprintf( 'Data set %s is invalid.', is_int($key) ? '#' . $key : '"' . $key . '"' ) ); } } }
return $data; }
/** * @param string $className * @param string $methodName * @return array * @throws ReflectionException * @since Method available since Release 3.4.0 */ public static function parseTestMethodAnnotations($className, $methodName = '') { if (!isset(self::$annotationCache[$className])) { $class = new ReflectionClass($className); self::$annotationCache[$className] = self::parseAnnotations($class->getDocComment()); }
if (!empty($methodName) && !isset(self::$annotationCache[$className . '::' . $methodName])) { try { $method = new ReflectionMethod($className, $methodName); $annotations = self::parseAnnotations($method->getDocComment()); } catch (ReflectionException $e) { $annotations = array(); } self::$annotationCache[$className . '::' . $methodName] = $annotations; }
return array( 'class' => self::$annotationCache[$className], 'method' => !empty($methodName) ? self::$annotationCache[$className . '::' . $methodName] : array() ); }
/** * @param string $docblock * @return array * @since Method available since Release 3.4.0 */ private static function parseAnnotations($docblock) { $annotations = array(); // Strip away the docblock header and footer to ease parsing of one line annotations $docblock = substr($docblock, 3, -2);
if (preg_match_all('/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?$/m', $docblock, $matches)) { $numMatches = count($matches[0]);
for ($i = 0; $i < $numMatches; ++$i) { $annotations[$matches['name'][$i]][] = $matches['value'][$i]; } }
return $annotations; }
/** * Returns the backup settings for a test. * * @param string $className * @param string $methodName * @return array * @since Method available since Release 3.4.0 */ public static function getBackupSettings($className, $methodName) { return array( 'backupGlobals' => self::getBooleanAnnotationSetting( $className, $methodName, 'backupGlobals' ), 'backupStaticAttributes' => self::getBooleanAnnotationSetting( $className, $methodName, 'backupStaticAttributes' ) ); }
/** * Returns the dependencies for a test class or method. * * @param string $className * @param string $methodName * @return array * @since Method available since Release 3.4.0 */ public static function getDependencies($className, $methodName) { $annotations = self::parseTestMethodAnnotations( $className, $methodName );
$dependencies = array();
if (isset($annotations['class']['depends'])) { $dependencies = $annotations['class']['depends']; }
if (isset($annotations['method']['depends'])) { $dependencies = array_merge( $dependencies, $annotations['method']['depends'] ); }
return array_unique($dependencies); }
/** * Returns the error handler settings for a test. * * @param string $className * @param string $methodName * @return boolean * @since Method available since Release 3.4.0 */ public static function getErrorHandlerSettings($className, $methodName) { return self::getBooleanAnnotationSetting( $className, $methodName, 'errorHandler' ); }
/** * Returns the groups for a test class or method. * * @param string $className * @param string $methodName * @return array * @since Method available since Release 3.2.0 */ public static function getGroups($className, $methodName = '') { $annotations = self::parseTestMethodAnnotations( $className, $methodName );
$groups = array();
if (isset($annotations['method']['author'])) { $groups = $annotations['method']['author']; }
else if (isset($annotations['class']['author'])) { $groups = $annotations['class']['author']; }
if (isset($annotations['class']['group'])) { $groups = array_merge($groups, $annotations['class']['group']); }
if (isset($annotations['method']['group'])) { $groups = array_merge($groups, $annotations['method']['group']); }
if (isset($annotations['class']['ticket'])) { $groups = array_merge($groups, $annotations['class']['ticket']); }
if (isset($annotations['method']['ticket'])) { $groups = array_merge($groups, $annotations['method']['ticket']); }
foreach (array('small', 'medium', 'large') as $size) { if (isset($annotations['method'][$size])) { $groups[] = $size; }
else if (isset($annotations['class'][$size])) { $groups[] = $size; } }
return array_unique($groups); }
/** * Returns the size of the test. * * @param string $className * @param string $methodName * @return integer * @since Method available since Release 3.6.0 */ public static function getSize($className, $methodName) { $groups = array_flip(self::getGroups($className, $methodName)); $size = self::SMALL; $class = new ReflectionClass($className);
if ((class_exists('PHPUnit_Extensions_Database_TestCase', FALSE) && $class->isSubclassOf('PHPUnit_Extensions_Database_TestCase')) || (class_exists('PHPUnit_Extensions_SeleniumTestCase', FALSE) && $class->isSubclassOf('PHPUnit_Extensions_SeleniumTestCase'))) { $size = self::LARGE; }
else if (isset($groups['medium'])) { $size = self::MEDIUM; }
else if (isset($groups['large'])) { $size = self::LARGE; }
return $size; }
/** * Returns the tickets for a test class or method. * * @param string $className * @param string $methodName * @return array * @since Method available since Release 3.4.0 */ public static function getTickets($className, $methodName) { $annotations = self::parseTestMethodAnnotations( $className, $methodName );
$tickets = array();
if (isset($annotations['class']['ticket'])) { $tickets = $annotations['class']['ticket']; }
if (isset($annotations['method']['ticket'])) { $tickets = array_merge($tickets, $annotations['method']['ticket']); }
return array_unique($tickets); }
/** * Returns the output buffering settings for a test. * * @param string $className * @param string $methodName * @return boolean * @since Method available since Release 3.4.0 */ public static function getOutputBufferingSettings($className, $methodName) { return self::getBooleanAnnotationSetting( $className, $methodName, 'outputBuffering' ); }
/** * Returns the process isolation settings for a test. * * @param string $className * @param string $methodName * @return boolean * @since Method available since Release 3.4.1 */ public static function getProcessIsolationSettings($className, $methodName) { $annotations = self::parseTestMethodAnnotations( $className, $methodName );
if (isset($annotations['class']['runTestsInSeparateProcesses']) || isset($annotations['method']['runInSeparateProcess'])) { return TRUE; } else { return FALSE; } }
/** * Returns the preserve global state settings for a test. * * @param string $className * @param string $methodName * @return boolean * @since Method available since Release 3.4.0 */ public static function getPreserveGlobalStateSettings($className, $methodName) { return self::getBooleanAnnotationSetting( $className, $methodName, 'preserveGlobalState' ); }
/** * @param string $className * @param string $methodName * @param string $settingName * @return boolean * @since Method available since Release 3.4.0 */ private static function getBooleanAnnotationSetting($className, $methodName, $settingName) { $annotations = self::parseTestMethodAnnotations( $className, $methodName );
$result = NULL;
if (isset($annotations['class'][$settingName])) { if ($annotations['class'][$settingName][0] == 'enabled') { $result = TRUE; }
else if ($annotations['class'][$settingName][0] == 'disabled') { $result = FALSE; } }
if (isset($annotations['method'][$settingName])) { if ($annotations['method'][$settingName][0] == 'enabled') { $result = TRUE; }
else if ($annotations['method'][$settingName][0] == 'disabled') { $result = FALSE; } }
return $result; } }
|