/** * Initialize Task. * This method includes any necessary PHPUnit2 libraries and triggers * appropriate error if they cannot be found. This is not done in header * because we may want this class to be loaded w/o triggering an error. */ function init() { if (version_compare(PHP_VERSION, '5.0.3') < 0) { throw new BuildException("PHPUnit2Task requires PHP version >= 5.0.3.", $this->getLocation()); } /** * Determine PHPUnit version number */ @(include_once 'PHPUnit/Runner/Version.php'); @(include_once 'PHPUnit2/Runner/Version.php'); if (class_exists('PHPUnit_Runner_Version')) { $version = PHPUnit_Runner_Version::id(); } elseif (class_exists('PHPUnit2_Runner_Version')) { $version = PHPUnit2_Runner_Version::id(); } else { throw new BuildException("PHPUnit task depends on PHPUnit 2 or 3 package being installed.", $this->getLocation()); } if (version_compare($version, "3.0.0") >= 0) { PHPUnitUtil::$installedVersion = 3; if (version_compare($version, "3.2.0") >= 0) { PHPUnitUtil::$installedMinorVersion = 2; } } else { PHPUnitUtil::$installedVersion = 2; } /** * Other dependencies that should only be loaded when class is actually used. */ require_once 'phing/tasks/ext/phpunit/PHPUnitTestRunner.php'; require_once 'phing/tasks/ext/phpunit/BatchTest.php'; require_once 'phing/tasks/ext/phpunit/FormatterElement.php'; /** * Add some defaults to the PHPUnit filter */ if (PHPUnitUtil::$installedVersion == 3) { require_once 'PHPUnit/Framework.php'; require_once 'PHPUnit/Util/Filter.php'; // point PHPUnit_MAIN_METHOD define to non-existing method if (!defined('PHPUnit_MAIN_METHOD')) { define('PHPUnit_MAIN_METHOD', 'PHPUnitTask::undefined'); } PHPUnit_Util_Filter::addFileToFilter('PHPUnitTask.php', 'PHING'); PHPUnit_Util_Filter::addFileToFilter('PHPUnitTestRunner.php', 'PHING'); PHPUnit_Util_Filter::addFileToFilter('phing/Task.php', 'PHING'); PHPUnit_Util_Filter::addFileToFilter('phing/Target.php', 'PHING'); PHPUnit_Util_Filter::addFileToFilter('phing/Project.php', 'PHING'); PHPUnit_Util_Filter::addFileToFilter('phing/Phing.php', 'PHING'); PHPUnit_Util_Filter::addFileToFilter('phing.php', 'PHING'); } else { require_once 'PHPUnit2/Framework.php'; require_once 'PHPUnit2/Util/Filter.php'; PHPUnit2_Util_Filter::addFileToFilter('PHPUnitTask.php'); PHPUnit2_Util_Filter::addFileToFilter('PHPUnitTestRunner.php'); PHPUnit2_Util_Filter::addFileToFilter('phing/Task.php'); PHPUnit2_Util_Filter::addFileToFilter('phing/Target.php'); PHPUnit2_Util_Filter::addFileToFilter('phing/Project.php'); PHPUnit2_Util_Filter::addFileToFilter('phing/Phing.php'); PHPUnit2_Util_Filter::addFileToFilter('phing.php'); } }
public function testQueryParamBooleansEncoding() { $params = ['active' => true, 'deactivated' => false]; $result = PHPUnitUtil::callMethod(self::$httpClient, 'encodeQueryParams', array($params)); $expectation = ['active' => 'true', 'deactivated' => 'false']; $this->assertEquals($result, $expectation); }
/** * Initialize Task. * This method includes any necessary PHPUnit2 libraries and triggers * appropriate error if they cannot be found. This is not done in header * because we may want this class to be loaded w/o triggering an error. */ function init() { if (version_compare(PHP_VERSION, '5.0.3') < 0) { throw new BuildException("PHPUnit2Task requires PHP version >= 5.0.3.", $this->getLocation()); } /** * Ugly hack to get PHPUnit version number */ $config = new PEAR_Config(); $registry = new PEAR_Registry($config->get('php_dir')); $pkg_info = $registry->_packageInfo("PHPUnit", null, "pear.phpunit.de"); if ($pkg_info != NULL) { if (version_compare($pkg_info['version']['api'], "3.0.0") >= 0) { PHPUnitUtil::$installedVersion = 3; } else { PHPUnitUtil::$installedVersion = 2; } } else { /** * Try to find PHPUnit2 */ require_once 'PHPUnit2/Util/Filter.php'; if (!class_exists('PHPUnit2_Util_Filter')) { throw new BuildException("PHPUnit2Task depends on PEAR PHPUnit2 package being installed.", $this->getLocation()); } PHPUnitUtil::$installedVersion = 2; } // other dependencies that should only be loaded when class is actually used. require_once 'phing/tasks/ext/phpunit/PHPUnitTestRunner.php'; require_once 'phing/tasks/ext/phpunit/BatchTest.php'; require_once 'phing/tasks/ext/phpunit/FormatterElement.php'; //require_once 'phing/tasks/ext/phpunit/SummaryPHPUnit2ResultFormatter.php'; // add some defaults to the PHPUnit filter if (PHPUnitUtil::$installedVersion == 3) { require_once 'PHPUnit/Util/Filter.php'; // point PHPUnit_MAIN_METHOD define to non-existing method define('PHPUnit_MAIN_METHOD', 'PHPUnitTask::undefined'); PHPUnit_Util_Filter::addFileToFilter('PHPUnitTask.php', 'PHING'); PHPUnit_Util_Filter::addFileToFilter('PHPUnitTestRunner.php', 'PHING'); PHPUnit_Util_Filter::addFileToFilter('phing/Task.php', 'PHING'); PHPUnit_Util_Filter::addFileToFilter('phing/Target.php', 'PHING'); PHPUnit_Util_Filter::addFileToFilter('phing/Project.php', 'PHING'); PHPUnit_Util_Filter::addFileToFilter('phing/Phing.php', 'PHING'); PHPUnit_Util_Filter::addFileToFilter('phing.php', 'PHING'); } else { require_once 'PHPUnit2/Util/Filter.php'; PHPUnit2_Util_Filter::addFileToFilter('PHPUnitTask.php'); PHPUnit2_Util_Filter::addFileToFilter('PHPUnitTestRunner.php'); PHPUnit2_Util_Filter::addFileToFilter('phing/Task.php'); PHPUnit2_Util_Filter::addFileToFilter('phing/Target.php'); PHPUnit2_Util_Filter::addFileToFilter('phing/Project.php'); PHPUnit2_Util_Filter::addFileToFilter('phing/Phing.php'); PHPUnit2_Util_Filter::addFileToFilter('phing.php'); } }
/** * Returns an array of test cases and test suites that are declared * by the files included by the filesets * * @return array an array of PHPUnit(2)_Framework_TestCase or PHPUnit(2)_Framework_TestSuite classes. */ function elements() { $filenames = $this->getFilenames(); $declaredClasses = array(); foreach ($filenames as $filename) { $definedClasses = PHPUnitUtil::getDefinedClasses($filename, $this->classpath); foreach ($definedClasses as $definedClass) { $this->project->log("(PHPUnit) Adding {$definedClass} (from {$filename}) to tests.", Project::MSG_DEBUG); } $declaredClasses = array_merge($declaredClasses, $definedClasses); } $elements = array_filter($declaredClasses, array($this, "filterTests")); return $elements; }
protected function transformCoverageInformation($filename, $coverageInformation) { $classes = PHPUnitUtil::getDefinedClasses($filename, $this->classpath); if (is_array($classes)) { foreach ($classes as $classname) { $reflection = new ReflectionClass($classname); $methods = $reflection->getMethods(); $classElement = $this->doc->createElement('class'); $classElement->setAttribute('name', $reflection->getName()); $this->addClassToPackage($reflection->getName(), $classElement); $classStartLine = $reflection->getStartLine(); $methodscovered = 0; $methodcount = 0; // Strange PHP5 reflection bug, classes without parent class or implemented interfaces seem to start one line off if ($reflection->getParentClass() == NULL && count($reflection->getInterfaces()) == 0) { unset($coverageInformation[$classStartLine + 1]); } else { unset($coverageInformation[$classStartLine]); } reset($coverageInformation); foreach ($methods as $method) { // PHP5 reflection considers methods of a parent class to be part of a subclass, we don't if ($method->getDeclaringClass()->getName() != $reflection->getName()) { continue; } // small fix for XDEBUG_CC_UNUSED if (isset($coverageInformation[$method->getStartLine()])) { unset($coverageInformation[$method->getStartLine()]); } if (isset($coverageInformation[$method->getEndLine()])) { unset($coverageInformation[$method->getEndLine()]); } if ($method->isAbstract()) { continue; } $linenr = key($coverageInformation); while ($linenr !== null && $linenr < $method->getStartLine()) { next($coverageInformation); $linenr = key($coverageInformation); } if (current($coverageInformation) > 0 && $method->getStartLine() <= $linenr && $linenr <= $method->getEndLine()) { $methodscovered++; } $methodcount++; } $statementcount = count($coverageInformation); $statementscovered = count(array_filter($coverageInformation, array($this, 'filterCovered'))); $classElement->appendChild($this->transformSourceFile($filename, $coverageInformation, $classStartLine)); $classElement->setAttribute('methodcount', $methodcount); $classElement->setAttribute('methodscovered', $methodscovered); $classElement->setAttribute('statementcount', $statementcount); $classElement->setAttribute('statementscovered', $statementscovered); $classElement->setAttribute('totalcount', $methodcount + $statementcount); $classElement->setAttribute('totalcovered', $methodscovered + $statementscovered); } } }
/** * Calculates the coverage threshold * * @param string $filename The filename to analyse * @param array $coverageInformation Array with coverage information * @throws BuildException */ protected function calculateCoverageThreshold($filename, $coverageInformation) { $classes = PHPUnitUtil::getDefinedClasses($filename, $this->_classpath); if (is_array($classes)) { foreach ($classes as $className) { // Skip class if excluded from coverage threshold validation if ($this->_excludes !== null) { if (in_array($className, $this->_excludes->getExcludedClasses())) { continue; } } $reflection = new ReflectionClass($className); $classStartLine = $reflection->getStartLine(); // Strange PHP5 reflection bug, classes without parent class // or implemented interfaces seem to start one line off if ($reflection->getParentClass() === null && count($reflection->getInterfaces()) === 0) { unset($coverageInformation[$classStartLine + 1]); } else { unset($coverageInformation[$classStartLine]); } reset($coverageInformation); $methods = $reflection->getMethods(); foreach ($methods as $method) { // PHP5 reflection considers methods of a parent class // to be part of a subclass, we don't if ($method->getDeclaringClass()->getName() != $reflection->getName()) { continue; } // Skip method if excluded from coverage threshold validation if ($this->_excludes !== null) { $excludedMethods = $this->_excludes->getExcludedMethods(); if (isset($excludedMethods[$className])) { if (in_array($method->getName(), $excludedMethods[$className]) || in_array($method->getName() . '()', $excludedMethods[$className])) { continue; } } } $methodStartLine = $method->getStartLine(); $methodEndLine = $method->getEndLine(); // small fix for XDEBUG_CC_UNUSED if (isset($coverageInformation[$methodStartLine])) { unset($coverageInformation[$methodStartLine]); } if (isset($coverageInformation[$methodEndLine])) { unset($coverageInformation[$methodEndLine]); } if ($method->isAbstract()) { continue; } $lineNr = key($coverageInformation); while ($lineNr !== null && $lineNr < $methodStartLine) { next($coverageInformation); $lineNr = key($coverageInformation); } $methodStatementsCovered = 0; $methodStatementCount = 0; while ($lineNr !== null && $lineNr <= $methodEndLine) { $methodStatementCount++; $lineCoverageInfo = $coverageInformation[$lineNr]; // set covered when CODE is other than -1 (not executed) if ($lineCoverageInfo > 0 || $lineCoverageInfo === -2) { $methodStatementsCovered++; } next($coverageInformation); $lineNr = key($coverageInformation); } if ($methodStatementCount > 0) { $methodCoverage = $methodStatementsCovered / $methodStatementCount * 100; } else { $methodCoverage = 0; } if ($methodCoverage < $this->_perMethod && !$method->isAbstract()) { throw new BuildException('The coverage (' . round($methodCoverage, 2) . '%) ' . 'for method "' . $method->getName() . '" is lower' . ' than the specified threshold (' . $this->_perMethod . '%), see file: "' . $filename . '"'); } elseif ($methodCoverage < $this->_perMethod && $method->isAbstract() && $this->_verbose === true) { $this->log('Skipped coverage threshold for abstract method "' . $method->getName() . '"'); } // store the minimum coverage value for logging (see #466) if ($this->_minMethodCoverageFound !== null) { if ($this->_minMethodCoverageFound > $methodCoverage) { $this->_minMethodCoverageFound = $methodCoverage; } } else { $this->_minMethodCoverageFound = $methodCoverage; } } $classStatementCount = count($coverageInformation); $classStatementsCovered = count(array_filter($coverageInformation, array($this, 'filterCovered'))); if ($classStatementCount > 0) { $classCoverage = $classStatementsCovered / $classStatementCount * 100; } else { $classCoverage = 0; } if ($classCoverage < $this->_perClass && !$reflection->isAbstract()) { throw new BuildException('The coverage (' . round($classCoverage, 2) . '%) for class "' . $reflection->getName() . '" is lower than the ' . 'specified threshold (' . $this->_perClass . '%), ' . 'see file: "' . $filename . '"'); } elseif ($classCoverage < $this->_perClass && $reflection->isAbstract() && $this->_verbose === true) { $this->log('Skipped coverage threshold for abstract class "' . $reflection->getName() . '"'); } // store the minimum coverage value for logging (see #466) if ($this->_minClassCoverageFound !== null) { if ($this->_minClassCoverageFound > $classCoverage) { $this->_minClassCoverageFound = $classCoverage; } } else { $this->_minClassCoverageFound = $classCoverage; } $this->_projectStatementCount += $classStatementCount; $this->_projectStatementsCovered += $classStatementsCovered; } } }
/** * Transforms the coverage information * * @param string $filename The filename * @param array $coverageInformation Array with covergae information * * @author Michiel Rook <*****@*****.**> * @author Benjamin Schultz <*****@*****.**> * @return void */ protected function transformCoverageInformation($filename, $coverageInformation) { $classes = PHPUnitUtil::getDefinedClasses($filename, $this->classpath); if (is_array($classes)) { foreach ($classes as $classname) { $reflection = new ReflectionClass($classname); $methods = $reflection->getMethods(); if (method_exists($reflection, 'getShortName')) { $className = $reflection->getShortName(); } else { $className = $reflection->getName(); } $classElement = $this->doc->createElement('class'); $classElement->setAttribute('name', $className); $packageName = PHPUnitUtil::getPackageName($reflection->getName()); $subpackageName = PHPUnitUtil::getSubpackageName($reflection->getName()); if ($subpackageName !== null) { $this->addSubpackageToPackage($packageName, $subpackageName); $this->addClassToSubpackage($className, $classElement); } else { $this->addClassToPackage($packageName, $classElement); } $classStartLine = $reflection->getStartLine(); $methodscovered = 0; $methodcount = 0; // Strange PHP5 reflection bug, classes without parent class or implemented interfaces seem to start one line off if ($reflection->getParentClass() == NULL && count($reflection->getInterfaces()) == 0) { unset($coverageInformation[$classStartLine + 1]); } else { unset($coverageInformation[$classStartLine]); } // Remove out-of-bounds info unset($coverageInformation[0]); reset($coverageInformation); foreach ($methods as $method) { // PHP5 reflection considers methods of a parent class to be part of a subclass, we don't if ($method->getDeclaringClass()->getName() != $reflection->getName()) { continue; } // small fix for XDEBUG_CC_UNUSED if (isset($coverageInformation[$method->getStartLine()])) { unset($coverageInformation[$method->getStartLine()]); } if (isset($coverageInformation[$method->getEndLine()])) { unset($coverageInformation[$method->getEndLine()]); } if ($method->isAbstract()) { continue; } $linenr = key($coverageInformation); while ($linenr !== null && $linenr < $method->getStartLine()) { next($coverageInformation); $linenr = key($coverageInformation); } $methodCoveredCount = 0; $methodTotalCount = 0; $methodHasCoveredLine = false; while ($linenr !== null && $linenr <= $method->getEndLine()) { $methodTotalCount++; $methodHasCoveredLine = true; // set covered when CODE is other than -1 (not executed) if ($coverageInformation[$linenr] > 0 || $coverageInformation[$linenr] == -2) { $methodCoveredCount++; } next($coverageInformation); $linenr = key($coverageInformation); } if ($methodTotalCount == $methodCoveredCount && $methodHasCoveredLine) { $methodscovered++; } $methodcount++; } $statementcount = count(array_filter($coverageInformation, create_function('$var', 'return ($var != -2);'))); $statementscovered = count(array_filter($coverageInformation, create_function('$var', 'return ($var >= 0);'))); $classElement->appendChild($this->transformSourceFile($filename, $coverageInformation, $classStartLine)); $classElement->setAttribute('methodcount', $methodcount); $classElement->setAttribute('methodscovered', $methodscovered); $classElement->setAttribute('statementcount', $statementcount); $classElement->setAttribute('statementscovered', $statementscovered); $classElement->setAttribute('totalcount', $methodcount + $statementcount); $classElement->setAttribute('totalcovered', $methodscovered + $statementscovered); } } }
/** * Returns an array of PHPUnit2_Framework_TestCase classes that are declared * by the files included by the filesets * * @return array an array of PHPUnit2_Framework_TestCase classes. */ function elements() { $filenames = $this->getFilenames(); $declaredClasses = array(); foreach ($filenames as $filename) { $definedClasses = PHPUnitUtil::getDefinedClasses($filename, $this->classpath); $declaredClasses = array_merge($declaredClasses, $definedClasses); } $elements = array_filter($declaredClasses, array($this, "filterTests")); return $elements; }
/** * Adds a class to their subpackage * * @param string $classname The name of the class * @param DOMNode $element The dom node to append to the subpackage element * * @author Benjamin Schultz <*****@*****.**> * @return void */ protected function addClassToSubpackage($classname, $element) { $subpackageName = PHPUnitUtil::getSubpackageName($classname); $subpackage = $this->getSubpackageElement($subpackageName); if ($subpackage === null) { $subpackage = $this->doc->createElement('subpackage'); $subpackage->setAttribute('name', $subpackageName); $this->doc->documentElement->appendChild($subpackage); } $subpackage->appendChild($element); }