/** * Run the runner. * * This will get a singleton instance of the class and configure * it according to the given configuration and any $_REQUEST * overriding parameters. * * It will configure it to use a {@link PHPUnit_Html_Printer} object * as the default output printer. * * @param array $arguments configuration * @return void */ public static function run($arguments = array()) { $_arguments = array('tpldir' => null, 'test' => null, 'testFile' => null, 'coverageClover' => null, 'coverageHtml' => null, 'filter' => null, 'groups' => null, 'excludeGroups' => null, 'processInsolation' => null, 'syntaxCheck' => false, 'stopOnError' => false, 'stopOnFailure' => false, 'stopOnIncomplete' => false, 'stopOnSkipped' => false, 'noGlobalsBackup' => true, 'staticBackup' => true, 'syntaxCheck' => false, 'bootstrap' => null, 'configuration' => null, 'noConfiguration' => false, 'strict' => false); $printer = new PHPUnit_Html_Printer($arguments['tpldir']); try { $arguments = $arguments ? array_merge($_arguments, array_intersect_key($arguments, $_arguments)) : $_arguments; $arguments['backupGlobals'] = !$arguments['noGlobalsBackup']; unset($arguments['noGlobalsBackup']); $arguments['backupStaticAttributes'] = !$arguments['staticBackup']; unset($arguments['staticBackup']); $arguments['useDefaultConfiguration'] = !$arguments['noConfiguration']; unset($arguments['noConfiguration']); if (isset($arguments['coverageHtml'])) { $arguments['reportDirectory'] = $arguments['coverageHtml']; unset($arguments['coverageHtml']); } if (!isset($arguments['test']) && !isset($arguments['testFile'])) { $arguments['test'] = getcwd(); } $arguments['printer'] = $printer; $arguments['listeners'] = array(new PHPUnit_Util_DeprecatedFeature_Logger()); if ($arguments['bootstrap']) { PHPUnit_Util_Fileloader::checkAndLoad($arguments['bootstrap'], $arguments['syntaxCheck']); } $runner = new PHPUnit_Html_TestRunner(); $suite = $runner->getTest($arguments['test'], $arguments['testFile'], $arguments['syntaxCheck']); unset($arguments['test']); unset($arguments['testFile']); $result = $runner->doRun($suite, $arguments); $arguments['printer']->printResult($result); } catch (Exception $e) { $printer->printAborted($e); } }
/** * Loads a bootstrap file. * * @param string $filename * @param boolean $syntaxCheck * @see PHPUnit_TextUI_Command::handleBootstrap() * @since Method available since Release 2.16.0 */ protected function handleBootstrap($filename, $syntaxCheck = false) { try { PHPUnit_Util_Fileloader::checkAndLoad($filename, $syntaxCheck); } catch (RuntimeException $e) { PHPUnit_TextUI_TestRunner::showError($e->getMessage()); } }
public static function main($configFile) { $arguments = array('listGroups' => FALSE, 'loader' => NULL, 'useDefaultConfiguration' => TRUE, 'configuration' => $configFile); $configuration = PHPUnit_Util_Configuration::getInstance($configFile); $configuration->handlePHPConfiguration(); $phpunit = $configuration->getPHPUnitConfiguration(); if (isset($phpunit['bootstrap'])) { PHPUnit_Util_Fileloader::load($phpunit['bootstrap']); } $testSuite = $configuration->getTestSuiteConfiguration(); return self::runTest($testSuite, $arguments); }
/** * @param string $suiteClassName * @param string $suiteClassFile * @return ReflectionClass * @throws RuntimeException */ public function load($suiteClassName, $suiteClassFile = '') { $suiteClassName = str_replace('.php', '', $suiteClassName); if (empty($suiteClassFile)) { $suiteClassFile = PHPUnit_Util_Filesystem::classNameToFilename($suiteClassName); } if (!class_exists($suiteClassName, FALSE)) { PHPUnit_Util_Class::collectStart(); $filename = PHPUnit_Util_Fileloader::checkAndLoad($suiteClassFile); $loadedClasses = PHPUnit_Util_Class::collectEnd(); } if (!class_exists($suiteClassName, FALSE) && !empty($loadedClasses)) { $offset = 0 - strlen($suiteClassName); foreach ($loadedClasses as $loadedClass) { $class = new ReflectionClass($loadedClass); if (substr($loadedClass, $offset) === $suiteClassName && $class->getFileName() == $filename) { $suiteClassName = $loadedClass; break; } } } if (!class_exists($suiteClassName, FALSE) && !empty($loadedClasses)) { $testCaseClass = 'PHPUnit_Framework_TestCase'; foreach ($loadedClasses as $loadedClass) { $class = new ReflectionClass($loadedClass); $classFile = $class->getFileName(); if ($class->isSubclassOf($testCaseClass) && !$class->isAbstract()) { $suiteClassName = $loadedClass; $testCaseClass = $loadedClass; if ($classFile == realpath($suiteClassFile)) { break; } } if ($class->hasMethod('suite')) { $method = $class->getMethod('suite'); if (!$method->isAbstract() && $method->isPublic() && $method->isStatic()) { $suiteClassName = $loadedClass; if ($classFile == realpath($suiteClassFile)) { break; } } } } } if (class_exists($suiteClassName, FALSE)) { $class = new ReflectionClass($suiteClassName); $filePath = $GLOBALS['base_dir'] . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'phpunit' . DIRECTORY_SEPARATOR . $suiteClassFile; if ($class->getFileName() == realpath($filePath)) { return $class; } } throw new PHPUnit_Framework_Exception(sprintf('Class %s could not be found in %s.', $suiteClassName, $suiteClassFile)); }
/** * * @param string $suiteClassName * @param string $suiteClassFile * * @return ReflectionClass * * @throws PHPUnit_Framework_Exception */ public function load($suiteClassName, $suiteClassFile = '') { $suiteClassName = str_replace('.php', '', $suiteClassName); if (empty($suiteClassFile)) { $suiteClassFile = PHPUnit_Util_Filesystem::classNameToFilename($suiteClassName); } if (!class_exists($suiteClassName, false)) { $loadedClasses = get_declared_classes(); $filename = PHPUnit_Util_Fileloader::checkAndLoad($suiteClassFile); $loadedClasses = array_values(array_diff(get_declared_classes(), $loadedClasses)); } if (!class_exists($suiteClassName, false) && !empty($loadedClasses)) { $offset = 0 - strlen($suiteClassName); foreach ($loadedClasses as $loadedClass) { $class = new ReflectionClass($loadedClass); if (substr($loadedClass, $offset) === $suiteClassName && $class->getFileName() == $filename) { $suiteClassName = $loadedClass; break; } } } if (!class_exists($suiteClassName, false) && !empty($loadedClasses)) { $testCaseClass = 'PHPUnit_Framework_TestCase'; foreach ($loadedClasses as $loadedClass) { $class = new ReflectionClass($loadedClass); $classFile = $class->getFileName(); if ($class->isSubclassOf($testCaseClass) && !$class->isAbstract()) { $suiteClassName = $loadedClass; $testCaseClass = $loadedClass; if ($classFile == realpath($suiteClassFile)) { break; } } if ($class->hasMethod('suite')) { $method = $class->getMethod('suite'); if (!$method->isAbstract() && $method->isPublic() && $method->isStatic()) { $suiteClassName = $loadedClass; if ($classFile == realpath($suiteClassFile)) { break; } } } } } if (class_exists($suiteClassName, false)) { $class = new ReflectionClass($suiteClassName); if ($class->getFileName() == realpath($suiteClassFile)) { return $class; } } throw new PHPUnit_Framework_Exception(sprintf("Class '%s' could not be found in '%s'.", $suiteClassName, $suiteClassFile)); }
/** * @return array * @access public */ public function collectTests() { $includePathsIterator = new AppendIterator(); $result = array(); $includePaths = PHPUnit_Util_Fileloader::getIncludePaths(); foreach ($includePaths as $includePath) { $includePathsIterator->append(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($includePath))); } $filterIterator = new PHPUnit_Util_FilterIterator($includePathsIterator); if ($this->filterIterator !== NULL) { $class = new ReflectionClass($this->filterIterator); $filterIterator = $class->newInstance($filterIterator); } foreach ($filterIterator as $file) { $result[] = $file; } return $result; }
/** * @param PHPUnit_Framework_Test $suite * @param array $arguments * @return PHPUnit_Framework_TestResult */ public function doRun(PHPUnit_Framework_Test $suite, array $arguments = array()) { $this->handleConfiguration($arguments); if (isset($arguments['bootstrap'])) { PHPUnit_Util_Fileloader::load($arguments['bootstrap']); } if (is_integer($arguments['repeat'])) { $suite = new PHPUnit_Extensions_RepeatedTest($suite, $arguments['repeat'], $arguments['filter'], $arguments['groups'], $arguments['excludeGroups']); } $result = $this->createTestResult(); if (!$arguments['convertErrorsToExceptions']) { $result->convertErrorsToExceptions(FALSE); } if (!$arguments['convertNoticesToExceptions']) { PHPUnit_Framework_Error_Notice::$enabled = FALSE; } if (!$arguments['convertWarningsToExceptions']) { PHPUnit_Framework_Error_Warning::$enabled = FALSE; } if ($arguments['stopOnFailure']) { $result->stopOnFailure(TRUE); } if ($this->printer === NULL) { if (isset($arguments['printer']) && $arguments['printer'] instanceof PHPUnit_Util_Printer) { $this->printer = $arguments['printer']; } else { $this->printer = new PHPUnit_TextUI_ResultPrinter(NULL, $arguments['verbose'], $arguments['colors'], $arguments['debug']); } } if (!$this->printer instanceof PHPUnit_Util_Log_TAP) { $this->printer->write(PHPUnit_Runner_Version::getVersionString() . "\n\n"); } foreach ($arguments['listeners'] as $listener) { $result->addListener($listener); } $result->addListener($this->printer); if (isset($arguments['storyHTMLFile'])) { require_once 'PHPUnit/Extensions/Story/ResultPrinter/HTML.php'; $result->addListener(new PHPUnit_Extensions_Story_ResultPrinter_HTML($arguments['storyHTMLFile'])); } if (isset($arguments['storyTextFile'])) { require_once 'PHPUnit/Extensions/Story/ResultPrinter/Text.php'; $result->addListener(new PHPUnit_Extensions_Story_ResultPrinter_Text($arguments['storyTextFile'])); } if (isset($arguments['testdoxHTMLFile'])) { require_once 'PHPUnit/Util/TestDox/ResultPrinter/HTML.php'; $result->addListener(new PHPUnit_Util_TestDox_ResultPrinter_HTML($arguments['testdoxHTMLFile'])); } if (isset($arguments['testdoxTextFile'])) { require_once 'PHPUnit/Util/TestDox/ResultPrinter/Text.php'; $result->addListener(new PHPUnit_Util_TestDox_ResultPrinter_Text($arguments['testdoxTextFile'])); } if (isset($arguments['graphvizLogfile'])) { if (PHPUnit_Util_Filesystem::fileExistsInIncludePath('Image/GraphViz.php')) { require_once 'PHPUnit/Util/Log/GraphViz.php'; $result->addListener(new PHPUnit_Util_Log_GraphViz($arguments['graphvizLogfile'])); } } if ((isset($arguments['coverageClover']) || isset($arguments['coverageSource']) || isset($arguments['metricsXML']) || isset($arguments['pmdXML']) || isset($arguments['reportDirectory'])) && extension_loaded('xdebug')) { $result->collectCodeCoverageInformation(TRUE); } if (isset($arguments['jsonLogfile'])) { require_once 'PHPUnit/Util/Log/JSON.php'; $result->addListener(new PHPUnit_Util_Log_JSON($arguments['jsonLogfile'])); } if (isset($arguments['tapLogfile'])) { require_once 'PHPUnit/Util/Log/TAP.php'; $result->addListener(new PHPUnit_Util_Log_TAP($arguments['tapLogfile'])); } if (isset($arguments['xmlLogfile'])) { require_once 'PHPUnit/Util/Log/XML.php'; $result->addListener(new PHPUnit_Util_Log_XML($arguments['xmlLogfile'], $arguments['logIncompleteSkipped'])); } if (isset($arguments['testDatabaseDSN']) && isset($arguments['testDatabaseLogRevision']) && extension_loaded('pdo')) { $writeToTestDatabase = TRUE; } else { $writeToTestDatabase = FALSE; } if ($writeToTestDatabase) { $dbh = PHPUnit_Util_PDO::factory($arguments['testDatabaseDSN']); require_once 'PHPUnit/Util/Log/Database.php'; $dbListener = PHPUnit_Util_Log_Database::getInstance($dbh, $arguments['testDatabaseLogRevision'], isset($arguments['testDatabaseLogInfo']) ? $arguments['testDatabaseLogInfo'] : ''); $result->addListener($dbListener); $result->collectCodeCoverageInformation(TRUE); } $suite->run($result, $arguments['filter'], $arguments['groups'], $arguments['excludeGroups']); $result->flushListeners(); if ($this->printer instanceof PHPUnit_TextUI_ResultPrinter) { $this->printer->printResult($result); } if (extension_loaded('tokenizer') && extension_loaded('xdebug')) { if (isset($arguments['coverageClover'])) { $this->printer->write("\nWriting code coverage data to XML file, this may take a moment."); require_once 'PHPUnit/Util/Log/CodeCoverage/XML/Clover.php'; $writer = new PHPUnit_Util_Log_CodeCoverage_XML_Clover($arguments['coverageClover']); $writer->process($result); $this->printer->write("\n"); } if (isset($arguments['coverageSource'])) { $this->printer->write("\nWriting code coverage data to XML files, this may take a moment."); require_once 'PHPUnit/Util/Log/CodeCoverage/XML/Source.php'; $writer = new PHPUnit_Util_Log_CodeCoverage_XML_Source($arguments['coverageSource']); $writer->process($result); $this->printer->write("\n"); } if ($writeToTestDatabase) { $this->printer->write("\nStoring code coverage and software metrics data in database.\nThis may take a moment."); require_once 'PHPUnit/Util/Log/CodeCoverage/Database.php'; $testDb = new PHPUnit_Util_Log_CodeCoverage_Database($dbh); $testDb->storeCodeCoverage($result, $dbListener->getRunId(), $arguments['testDatabaseLogRevision'], $arguments['testDatabasePrefix']); $this->printer->write("\n"); } if (isset($arguments['metricsXML'])) { $this->printer->write("\nWriting metrics report XML file, this may take a moment."); require_once 'PHPUnit/Util/Log/Metrics.php'; $writer = new PHPUnit_Util_Log_Metrics($arguments['metricsXML']); $writer->process($result); $this->printer->write("\n"); } if (isset($arguments['pmdXML'])) { require_once 'PHPUnit/Util/Log/PMD.php'; $writer = new PHPUnit_Util_Log_PMD($arguments['pmdXML'], $arguments['pmd']); $this->printer->write("\nWriting violations report XML file, this may take a moment."); $writer->process($result); require_once 'PHPUnit/Util/Log/CPD.php'; $writer = new PHPUnit_Util_Log_CPD(str_replace('.xml', '-cpd.xml', $arguments['pmdXML'])); $writer->process($result, $arguments['cpdMinLines'], $arguments['cpdMinMatches']); $this->printer->write("\n"); } if (isset($arguments['reportDirectory'])) { $this->printer->write("\nGenerating code coverage report, this may take a moment."); unset($suite); PHPUnit_Util_Report::render($result, $arguments['reportDirectory'], $arguments['reportCharset'], $arguments['reportYUI'], $arguments['reportHighlight'], $arguments['reportLowUpperBound'], $arguments['reportHighLowerBound']); $this->printer->write("\n"); } } $this->pause($arguments['wait']); return $result; }
/** * @param string $suiteClassName * @param string $suiteClassFile * @param boolean $syntaxCheck * @return ReflectionClass * @throws RuntimeException */ public function load($suiteClassName, $suiteClassFile = '', $syntaxCheck = TRUE) { $suiteClassName = str_replace('.php', '', $suiteClassName); if (empty($suiteClassFile)) { $suiteClassFile = str_replace(array('_', '\\'), DIRECTORY_SEPARATOR, $suiteClassName) . '.php'; } if (!class_exists($suiteClassName, FALSE)) { if (!file_exists($suiteClassFile)) { $includePaths = explode(PATH_SEPARATOR, get_include_path()); foreach ($includePaths as $includePath) { $file = $includePath . DIRECTORY_SEPARATOR . $suiteClassFile; if (file_exists($file)) { $suiteClassFile = $file; break; } } } PHPUnit_Util_Class::collectStart(); PHPUnit_Util_Fileloader::checkAndLoad($suiteClassFile, $syntaxCheck); $loadedClasses = PHPUnit_Util_Class::collectEnd(); } if (!class_exists($suiteClassName, FALSE) && !empty($loadedClasses)) { $offset = 0 - strlen($suiteClassName); foreach ($loadedClasses as $loadedClass) { if (substr($loadedClass, $offset) === $suiteClassName) { $suiteClassName = $loadedClass; break; } } } if (!class_exists($suiteClassName, FALSE) && !empty($loadedClasses)) { $testCaseClass = 'PHPUnit_Framework_TestCase'; foreach ($loadedClasses as $loadedClass) { $class = new ReflectionClass($loadedClass); if ($class->isSubclassOf($testCaseClass)) { $suiteClassName = $loadedClass; $testCaseClass = $loadedClass; if ($class->getFileName() == realpath($suiteClassFile)) { break; } } if ($class->hasMethod('suite')) { $method = $class->getMethod('suite'); if (!$method->isAbstract() && $method->isPublic() && $method->isStatic()) { $suiteClassName = $loadedClass; break; } } } } if (class_exists($suiteClassName, FALSE)) { $class = new ReflectionClass($suiteClassName); if ($class->getFileName() == realpath($suiteClassFile)) { return $class; } } throw new RuntimeException(sprintf('Class %s could not be found in %s.', $suiteClassName, $suiteClassFile)); }
/** * Handles the command-line arguments. * * A child class of PHPUnit_TextUI_Command can hook into the argument * parsing by adding the switch(es) to the $longOptions array and point to a * callback method that handles the switch(es) in the child class like this * * <code> * <?php * class MyCommand extends PHPUnit_TextUI_Command * { * public function __construct() * { * $this->longOptions['--my-switch'] = 'myHandler'; * } * * // --my-switch foo -> myHandler('foo') * protected function myHandler($value) * { * } * } * </code> * * @param array $argv */ protected function handleArguments(array $argv) { try { $this->options = PHPUnit_Util_Getopt::getopt($argv, 'd:c:', array_keys($this->longOptions)); } catch (RuntimeException $e) { PHPUnit_TextUI_TestRunner::showError($e->getMessage()); } $skeletonClass = FALSE; $skeletonTest = FALSE; foreach ($this->options[0] as $option) { switch ($option[0]) { case '--colors': $this->arguments['colors'] = TRUE; break; case '--bootstrap': $this->arguments['bootstrap'] = $option[1]; break; case 'c': case '--configuration': $this->arguments['configuration'] = $option[1]; break; case '--coverage-clover': if (extension_loaded('tokenizer') && extension_loaded('xdebug')) { $this->arguments['coverageClover'] = $option[1]; } else { if (!extension_loaded('tokenizer')) { $this->showMessage('The tokenizer extension is not loaded.'); } else { $this->showMessage('The Xdebug extension is not loaded.'); } } break; case '--coverage-html': if (extension_loaded('tokenizer') && extension_loaded('xdebug')) { $this->arguments['reportDirectory'] = $option[1]; } else { if (!extension_loaded('tokenizer')) { $this->showMessage('The tokenizer extension is not loaded.'); } else { $this->showMessage('The Xdebug extension is not loaded.'); } } break; case 'd': $ini = explode('=', $option[1]); if (isset($ini[0])) { if (isset($ini[1])) { ini_set($ini[0], $ini[1]); } else { ini_set($ini[0], TRUE); } } break; case '--debug': $this->arguments['debug'] = TRUE; break; case '--help': $this->showHelp(); exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); break; case '--filter': $this->arguments['filter'] = $option[1]; break; case '--group': $this->arguments['groups'] = explode(',', $option[1]); break; case '--exclude-group': $this->arguments['excludeGroups'] = explode(',', $option[1]); break; case '--include-path': $includePath = $option[1]; break; case '--list-groups': $this->arguments['listGroups'] = TRUE; break; case '--loader': $this->arguments['loader'] = $option[1]; break; case '--log-dbus': $this->arguments['logDbus'] = TRUE; break; case '--log-json': $this->arguments['jsonLogfile'] = $option[1]; break; case '--log-junit': $this->arguments['junitLogfile'] = $option[1]; break; case '--log-tap': $this->arguments['tapLogfile'] = $option[1]; break; case '--process-isolation': $this->arguments['processIsolation'] = TRUE; break; case '--repeat': $this->arguments['repeat'] = (int) $option[1]; break; case '--stderr': $this->arguments['printer'] = new PHPUnit_TextUI_ResultPrinter('php://stderr', isset($this->arguments['verbose']) ? $this->arguments['verbose'] : FALSE); break; case '--stop-on-error': $this->arguments['stopOnError'] = TRUE; break; case '--stop-on-failure': $this->arguments['stopOnFailure'] = TRUE; break; case '--stop-on-incomplete': $this->arguments['stopOnIncomplete'] = TRUE; break; case '--stop-on-skipped': $this->arguments['stopOnSkipped'] = TRUE; break; case '--skeleton-test': $skeletonTest = TRUE; $skeletonClass = FALSE; break; case '--skeleton-class': $skeletonClass = TRUE; $skeletonTest = FALSE; break; case '--tap': $this->arguments['printer'] = new PHPUnit_Util_Log_TAP(); break; case '--testdox': $this->arguments['printer'] = new PHPUnit_Util_TestDox_ResultPrinter_Text(); break; case '--testdox-html': $this->arguments['testdoxHTMLFile'] = $option[1]; break; case '--testdox-text': $this->arguments['testdoxTextFile'] = $option[1]; break; case '--no-configuration': $this->arguments['useDefaultConfiguration'] = FALSE; break; case '--no-globals-backup': $this->arguments['backupGlobals'] = FALSE; break; case '--static-backup': $this->arguments['backupStaticAttributes'] = TRUE; break; case '--verbose': $this->arguments['verbose'] = TRUE; break; case '--version': PHPUnit_TextUI_TestRunner::printVersionString(); exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); break; case '--wait': $this->arguments['wait'] = TRUE; break; case '--strict': $this->arguments['strict'] = TRUE; break; default: $optionName = str_replace('--', '', $option[0]); if (isset($this->longOptions[$optionName])) { $handler = $this->longOptions[$optionName]; } else { if (isset($this->longOptions[$optionName . '='])) { $handler = $this->longOptions[$optionName . '=']; } } if (isset($handler) && is_callable(array($this, $handler))) { $this->{$handler}($option[1]); } } } $this->handleCustomTestSuite(); if (!isset($this->arguments['test'])) { if (isset($this->options[1][0])) { $this->arguments['test'] = $this->options[1][0]; } if (isset($this->options[1][1])) { $this->arguments['testFile'] = $this->options[1][1]; } else { $this->arguments['testFile'] = ''; } if (isset($this->arguments['test']) && is_file($this->arguments['test'])) { $this->arguments['testFile'] = realpath($this->arguments['test']); $this->arguments['test'] = substr($this->arguments['test'], 0, strrpos($this->arguments['test'], '.')); } } if (isset($includePath)) { ini_set('include_path', $includePath . PATH_SEPARATOR . ini_get('include_path')); } if (isset($this->arguments['bootstrap'])) { PHPUnit_Util_Fileloader::load($this->arguments['bootstrap']); } if ($this->arguments['loader'] !== NULL) { $this->arguments['loader'] = $this->handleLoader($this->arguments['loader']); } if (isset($this->arguments['configuration']) && is_dir($this->arguments['configuration'])) { $configurationFile = $this->arguments['configuration'] . '/phpunit.xml'; if (file_exists($configurationFile)) { $this->arguments['configuration'] = realpath($configurationFile); } else { if (file_exists($configurationFile . '.dist')) { $this->arguments['configuration'] = realpath($configurationFile . '.dist'); } } } else { if (!isset($this->arguments['configuration']) && $this->arguments['useDefaultConfiguration']) { if (file_exists('phpunit.xml')) { $this->arguments['configuration'] = realpath('phpunit.xml'); } else { if (file_exists('phpunit.xml.dist')) { $this->arguments['configuration'] = realpath('phpunit.xml.dist'); } } } } if (isset($this->arguments['configuration'])) { $configuration = PHPUnit_Util_Configuration::getInstance($this->arguments['configuration']); $phpunit = $configuration->getPHPUnitConfiguration(); if (isset($phpunit['testSuiteLoaderClass'])) { if (isset($phpunit['testSuiteLoaderFile'])) { $file = $phpunit['testSuiteLoaderFile']; } else { $file = ''; } $this->arguments['loader'] = $this->handleLoader($phpunit['testSuiteLoaderClass'], $file); } $configuration->handlePHPConfiguration(); if (!isset($this->arguments['bootstrap'])) { $phpunitConfiguration = $configuration->getPHPUnitConfiguration(); if (isset($phpunitConfiguration['bootstrap'])) { PHPUnit_Util_Fileloader::load($phpunitConfiguration['bootstrap']); } } $browsers = $configuration->getSeleniumBrowserConfiguration(); if (!empty($browsers)) { PHPUnit_Extensions_SeleniumTestCase::$browsers = $browsers; } if (!isset($this->arguments['test'])) { $testSuite = $configuration->getTestSuiteConfiguration(); if ($testSuite !== NULL) { $this->arguments['test'] = $testSuite; } } } if (isset($this->arguments['test']) && is_string($this->arguments['test']) && substr($this->arguments['test'], -5, 5) == '.phpt') { $test = new PHPUnit_Extensions_PhptTestCase($this->arguments['test']); $this->arguments['test'] = new PHPUnit_Framework_TestSuite(); $this->arguments['test']->addTest($test); } if (!isset($this->arguments['test']) || isset($this->arguments['testDatabaseLogRevision']) && !isset($this->arguments['testDatabaseDSN'])) { $this->showHelp(); exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); } if ($skeletonClass || $skeletonTest) { if (isset($this->arguments['test']) && $this->arguments['test'] !== FALSE) { PHPUnit_TextUI_TestRunner::printVersionString(); if ($skeletonClass) { $class = 'PHPUnit_Util_Skeleton_Class'; } else { $class = 'PHPUnit_Util_Skeleton_Test'; } try { $args = array(); $reflector = new ReflectionClass($class); for ($i = 0; $i <= 3; $i++) { if (isset($this->options[1][$i])) { $args[] = $this->options[1][$i]; } } $skeleton = $reflector->newInstanceArgs($args); $skeleton->write(); } catch (Exception $e) { print $e->getMessage() . "\n"; exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT); } printf('Wrote skeleton for "%s" to "%s".' . "\n", $skeleton->getOutClassName(), $skeleton->getOutSourceFile()); exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); } else { $this->showHelp(); exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); } } }
/** * Wraps both <code>addTest()</code> and <code>addTestSuite</code> * as well as the separate import statements for the user's convenience. * * If the named file cannot be read or there are no new tests that can be * added, a <code>PHPUnit_Framework_Warning</code> will be created instead, * leaving the current test run untouched. * * @param string $filename * @throws PHPUnit_Framework_Exception * @since Method available since Release 2.3.0 */ public function addTestFile($filename) { if (!is_string($filename)) { throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); } if (file_exists($filename) && substr($filename, -5) == '.phpt') { $this->addTest(new PHPUnit_Extensions_PhptTestCase($filename)); return; } // The given file may contain further stub classes in addition to the // test class itself. Figure out the actual test class. $classes = get_declared_classes(); $filename = PHPUnit_Util_Fileloader::checkAndLoad($filename); $newClasses = array_diff(get_declared_classes(), $classes); // The diff is empty in case a parent class (with test methods) is added // AFTER a child class that inherited from it. To account for that case, // cumulate all discovered classes, so the parent class may be found in // a later invocation. if ($newClasses) { // On the assumption that test classes are defined first in files, // process discovered classes in approximate LIFO order, so as to // avoid unnecessary reflection. $this->foundClasses = array_merge($newClasses, $this->foundClasses); } // The test class's name must match the filename, either in full, or as // a PEAR/PSR-0 prefixed shortname ('NameSpace_ShortName'), or as a // PSR-1 local shortname ('NameSpace\ShortName'). The comparison must be // anchored to prevent false-positive matches (e.g., 'OtherShortName'). $shortname = basename($filename, '.php'); $shortnameRegEx = '/(?:^|_|\\\\)' . preg_quote($shortname, '/') . '$/'; foreach ($this->foundClasses as $i => $className) { if (preg_match($shortnameRegEx, $className)) { $class = new ReflectionClass($className); if ($class->getFileName() == $filename) { $newClasses = [$className]; unset($this->foundClasses[$i]); break; } } } foreach ($newClasses as $className) { $class = new ReflectionClass($className); if (!$class->isAbstract()) { if ($class->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) { $method = $class->getMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME); if ($method->isStatic()) { $this->addTest($method->invoke(null, $className)); } } elseif ($class->implementsInterface('PHPUnit_Framework_Test')) { $this->addTestSuite($class); } } } $this->numTests = -1; }
/** * Wraps both <code>addTest()</code> and <code>addTestSuite</code> * as well as the separate import statements for the user's convenience. * * If the named file cannot be read or there are no new tests that can be * added, a <code>PHPUnit_Framework_Warning</code> will be created instead, * leaving the current test run untouched. * * @param string $filename * @param boolean $syntaxCheck * @param array $phptOptions Array with ini settings for the php instance * run, key being the name if the setting, * value the ini value. * @throws InvalidArgumentException */ public function addTestFile($filename, $syntaxCheck = FALSE, $phptOptions = array()) { if (!is_string($filename)) { throw \PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); } // Ensure we can read the file if (!$filename || !is_readable($filename)) { throw new \RuntimeException(sprintf('Cannot open file "%s".' . "\n", $filename)); } // Try to convert it to a relative path if (strpos($filename, getcwd()) === 0) { $filename = substr($filename, strlen(getcwd()) + 1); } else { if (strpos($filename, './') === 0) { $filename = substr($filename, strlen('./')); } } // Use stream wrapper for spec files $furl = Spec::SCHEME . '://' . $filename; // Setup the environment to collect tests \DrSlump\Spec::reset($this); \PHPUnit_Util_Fileloader::load($furl); $this->numTests = -1; }
/** * @param PHPUnit_Framework_Test $suite * @param array $arguments * @return PHPUnit_Framework_TestResult */ public function doRun(PHPUnit_Framework_Test $suite, array $arguments = array()) { $this->handleConfiguration($arguments); if (isset($arguments['bootstrap'])) { $bootstrap = PHPUnit_Util_Fileloader::load($arguments['bootstrap']); if ($bootstrap) { $GLOBALS['__PHPUNIT_BOOTSTRAP'] = $bootstrap; } } if ($arguments['backupGlobals'] === FALSE) { $suite->setBackupGlobals(FALSE); } if ($arguments['backupStaticAttributes'] === FALSE) { $suite->setBackupStaticAttributes(FALSE); } $result = $this->createTestResult(); if (!$arguments['convertErrorsToExceptions']) { $result->convertErrorsToExceptions(FALSE); } if (!$arguments['convertNoticesToExceptions']) { PHPUnit_Framework_Error_Notice::$enabled = FALSE; } if (!$arguments['convertWarningsToExceptions']) { PHPUnit_Framework_Error_Warning::$enabled = FALSE; } if ($arguments['stopOnFailure']) { $result->stopOnFailure(TRUE); } if ($this->printer === NULL) { if (isset($arguments['printer']) && $arguments['printer'] instanceof PHPUnit_Util_Printer) { $this->printer = $arguments['printer']; } else { $this->printer = new PHPUnit_TextUI_ResultPrinter(NULL, $arguments['verbose'], $arguments['colors'], $arguments['debug']); } } if (!$this->printer instanceof PHPUnit_Util_Log_TAP && !self::$versionStringPrinted) { $this->printer->write(PHPUnit_Runner_Version::getVersionString() . "\n\n"); } foreach ($arguments['listeners'] as $listener) { $result->addListener($listener); } $result->addListener($this->printer); if (isset($arguments['storyHTMLFile'])) { require_once 'PHPUnit/Extensions/Story/ResultPrinter/HTML.php'; $result->addListener(new PHPUnit_Extensions_Story_ResultPrinter_HTML($arguments['storyHTMLFile'])); } if (isset($arguments['storyTextFile'])) { require_once 'PHPUnit/Extensions/Story/ResultPrinter/Text.php'; $result->addListener(new PHPUnit_Extensions_Story_ResultPrinter_Text($arguments['storyTextFile'])); } if (isset($arguments['testdoxHTMLFile'])) { require_once 'PHPUnit/Util/TestDox/ResultPrinter/HTML.php'; $result->addListener(new PHPUnit_Util_TestDox_ResultPrinter_HTML($arguments['testdoxHTMLFile'])); } if (isset($arguments['testdoxTextFile'])) { require_once 'PHPUnit/Util/TestDox/ResultPrinter/Text.php'; $result->addListener(new PHPUnit_Util_TestDox_ResultPrinter_Text($arguments['testdoxTextFile'])); } if ((isset($arguments['coverageClover']) || isset($arguments['reportDirectory'])) && extension_loaded('xdebug')) { $result->collectCodeCoverageInformation(TRUE); } if (isset($arguments['logDbus'])) { require_once 'PHPUnit/Util/Log/DBUS.php'; $result->addListener(new PHPUnit_Util_Log_DBUS()); } if (isset($arguments['jsonLogfile'])) { require_once 'PHPUnit/Util/Log/JSON.php'; $result->addListener(new PHPUnit_Util_Log_JSON($arguments['jsonLogfile'])); } if (isset($arguments['tapLogfile'])) { require_once 'PHPUnit/Util/Log/TAP.php'; $result->addListener(new PHPUnit_Util_Log_TAP($arguments['tapLogfile'])); } if (isset($arguments['junitLogfile'])) { require_once 'PHPUnit/Util/Log/JUnit.php'; $result->addListener(new PHPUnit_Util_Log_JUnit($arguments['junitLogfile'], $arguments['logIncompleteSkipped'])); } $suite->run($result, $arguments['filter'], $arguments['groups'], $arguments['excludeGroups'], $arguments['processIsolation']); unset($suite); $result->flushListeners(); if ($this->printer instanceof PHPUnit_TextUI_ResultPrinter) { $this->printer->printResult($result); } if (extension_loaded('tokenizer') && extension_loaded('xdebug')) { if (isset($arguments['coverageClover'])) { $this->printer->write("\nWriting code coverage data to XML file, this may take " . 'a moment.'); require_once 'PHP/CodeCoverage/Report/Clover.php'; $writer = new PHP_CodeCoverage_Report_Clover(); $writer->process($result->getCodeCoverage(), $arguments['coverageClover']); $this->printer->write("\n"); unset($writer); } if (isset($arguments['reportDirectory'])) { $this->printer->write("\nGenerating code coverage report, this may take a moment."); $title = ''; if (isset($arguments['configuration'])) { $loggingConfiguration = $arguments['configuration']->getLoggingConfiguration(); if (isset($loggingConfiguration['title'])) { $title = $loggingConfiguration['title']; } } require_once 'PHP/CodeCoverage/Report/HTML.php'; $writer = new PHP_CodeCoverage_Report_HTML(); $writer->process($result->getCodeCoverage(), $arguments['reportDirectory'], $title, $arguments['reportCharset'], $arguments['reportYUI'], $arguments['reportHighlight'], $arguments['reportLowUpperBound'], $arguments['reportHighLowerBound']); $this->printer->write("\n"); unset($writer); } } $this->pause($arguments['wait']); return $result; }
/** * Wraps both <code>addTest()</code> and <code>addTestSuite</code> * as well as the separate import statements for the user's convenience. * * If the named file cannot be read or there are no new tests that can be * added, a <code>PHPUnit_Framework_Warning</code> will be created instead, * leaving the current test run untouched. * * @param string $filename * @param boolean $syntaxCheck * @param array $phptOptions Array with ini settings for the php instance * run, key being the name if the setting, * value the ini value. * @throws InvalidArgumentException * @since Method available since Release 2.3.0 * @author Stefano F. Rausch <*****@*****.**> */ public function addTestFile($filename, $syntaxCheck = FALSE, $phptOptions = array()) { if (!is_string($filename)) { throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); } if (file_exists($filename) && substr($filename, -5) == '.phpt') { $this->addTest(new PHPUnit_Extensions_PhptTestCase($filename, $phptOptions)); return; } PHPUnit_Util_Class::collectStart(); $filename = PHPUnit_Util_Fileloader::checkAndLoad($filename, $syntaxCheck); $newClasses = PHPUnit_Util_Class::collectEnd(); $baseName = str_replace('.php', '', basename($filename)); foreach ($newClasses as $className) { if (substr($className, 0 - strlen($baseName)) == $baseName) { $class = new ReflectionClass($className); if ($class->getFileName() == $filename) { $newClasses = array($className); break; } } } $testsFound = FALSE; foreach ($newClasses as $className) { $class = new ReflectionClass($className); if (!$class->isAbstract()) { if ($class->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) { $method = $class->getMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME); if ($method->isStatic()) { $this->addTest($method->invoke(NULL, $className)); $testsFound = TRUE; } } else { if ($class->implementsInterface('PHPUnit_Framework_Test')) { $this->addTestSuite($class); $testsFound = TRUE; } } } } $this->numTests = -1; }
/** * Wraps both <code>addTest()</code> and <code>addTestSuite</code> * as well as the separate import statements for the user's convenience. * * If the named file cannot be read or there are no new tests that can be * added, a <code>PHPUnit_Framework_Warning</code> will be created instead, * leaving the current test run untouched. * * @param string $filename * @param boolean $syntaxCheck * @param array $phptOptions Array with ini settings for the php instance * run, key being the name if the setting, * value the ini value. * @throws InvalidArgumentException * @access public * @since Method available since Release 2.3.0 * @author Stefano F. Rausch <*****@*****.**> */ public function addTestFile($filename, $syntaxCheck = TRUE, $phptOptions = array()) { if (!is_string($filename)) { throw new InvalidArgumentException(); } if (file_exists($filename) && substr($filename, -5) == '.phpt') { $this->addTest(new PHPUnit_Extensions_PhptTestCase($filename, $phptOptions)); return; } if (!file_exists($filename)) { $includePaths = explode(PATH_SEPARATOR, get_include_path()); foreach ($includePaths as $includePath) { $file = $includePath . DIRECTORY_SEPARATOR . $filename; if (file_exists($file)) { $filename = $file; break; } } } PHPUnit_Util_Class::collectStart(); PHPUnit_Util_Fileloader::checkAndLoad($filename, $syntaxCheck); $newClasses = PHPUnit_Util_Class::collectEnd(); $testsFound = FALSE; foreach ($newClasses as $className) { $class = new ReflectionClass($className); if (!$class->isAbstract()) { if ($class->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) { $method = $class->getMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME); if ($method->isStatic()) { $this->addTest($method->invoke(NULL, $className)); $testsFound = TRUE; } } else { if ($class->implementsInterface('PHPUnit_Framework_Test')) { $this->addTestSuite($class); $testsFound = TRUE; } } } } if (!$testsFound) { $this->addTest(new PHPUnit_Framework_Warning('No tests found in file "' . $filename . '".')); } $this->numTests = -1; }
protected static function _suite($alltests_class, $alltests_file, $sub_suite = null) { $suite_name = basename($alltests_class, "_AllTests"); $readable_name = str_replace("_", " ", $suite_name); $suite = new PHPUnit_Framework_TestSuite($readable_name); $tests = self::_getTests(dirname($alltests_file)); // trickery to get around the statics problem in php eval("\$disabled = " . $alltests_class . "::\$disabled;"); eval("\$requires_config = " . $alltests_class . "::\$requires_config;"); foreach ($tests as $test => $filename) { $test_file_path = dirname($alltests_file) . DIRECTORY_SEPARATOR . $filename; $test_class_name = $suite_name . "_" . $test; $test_class_config = ZFTestManager::getConfig($test_class_name); if (!is_null($sub_suite) && strpos($test, $sub_suite) === false) { continue; } // if test is disabled by default, and not turned on, continue if (in_array($test_class_name, $disabled) && $test_class_config['enabled'] != true) { continue; } // if test is not disabled by default, but is disabled in config, continue if (!in_array($test_class_name, $disabled) && $test_class_config['disabled'] == true) { continue; } if (in_array($test_class_name, $requires_config) && $test_class_config === null) { echo "Class {$test_class_name} is enabled, but requires config options to be set in TestConfiguration.ini.\n"; echo "See {$test_file_path} for more details.\n"; exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); } PHPUnit_Util_Fileloader::checkAndLoad($test_file_path); try { $suite->addTestSuite($test_class_name); } catch (InvalidArgumentException $e) { echo "File for {$test_class_name} was loaded, but a class named {$test_class_name} was not found.\n"; exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); } //$suite->addTestFile($test_file_path); } return $suite; }
/** * @param array $paths * @param string $suffix * @access public */ public function __construct(array $paths = array(), $suffix = 'Test.php') { if (!empty($paths)) { $this->paths = $paths; } else { $this->paths = PHPUnit_Util_Fileloader::getIncludePaths(); } $this->suffix = $suffix; }
private static function injectIntoPhpunit() { if (!class_exists(\PHPUnit_Util_Fileloader::class, false)) { return; } if (!is_callable([\PHPUnit_Util_Fileloader::class, 'setFilenameRewriteCallback'])) { if (self::$debug) { self::debug("Cannot inject into phpunit: method setFilenameRewriteCallback not found"); } return; } \PHPUnit_Util_Fileloader::setFilenameRewriteCallback([self::class, 'rewrite']); \PHPUnit_Util_Fileloader::setFilenameRestoreCallback(function ($filename) { return self::replaceFilename($filename, true); }); \PHPUnit_Util_Filter::setCustomStackTraceCallback(function ($e) { ob_start(); self::printBackTrace($e); return ob_get_clean(); }); }
public static function main() { global $isLocal; // check number of arguments $isLocal = !isset($_SERVER['HTTP_USER_AGENT']); $arguments = array('listGroups' => FALSE, 'loader' => NULL, 'useDefaultConfiguration' => TRUE); $loader = NULL; $startPos = 1; $canCountTest = true; global $config_file; if ($isLocal && $_SERVER['argv'][1] == "-config" || !$isLocal && strcmp($config_file, "") != 0 && strcmp($config_file, "/*config_xml*/") != 0) { // check if configuration specified $canCountTest = false; $path = $isLocal ? $_SERVER['argv'][2] : $config_file; //$_GET["config_xml"]; $arguments['configuration'] = $path; $startPos = 3; $configuration = PHPUnit_Util_Configuration::getInstance($path); $phpunit = $configuration->getPHPUnitConfiguration(); if (isset($phpunit['testSuiteLoaderClass'])) { if (isset($phpunit['testSuiteLoaderFile'])) { $file = $phpunit['testSuiteLoaderFile']; } else { $file = ''; } $command = new PHPUnit_TextUI_Command(); $loader = $command->handleLoader($phpunit['testSuiteLoaderClass'], $file); $arguments['loader'] = $loader; } $configuration->handlePHPConfiguration(); $phpunitConfiguration = $configuration->getPHPUnitConfiguration(); if (isset($phpunitConfiguration['bootstrap'])) { PHPUnit_Util_Fileloader::load($phpunitConfiguration['bootstrap']); } $browsers = $configuration->getSeleniumBrowserConfiguration(); if (!empty($browsers)) { require_once 'PHPUnit/Extensions/SeleniumTestCase.php'; PHPUnit_Extensions_SeleniumTestCase::$browsers = $browsers; } } if ($isLocal && $_SERVER['argv'][$startPos] == "-group" || !$isLocal && isset($_GET["groups"])) { $arguments['groups'] = explode(',', $isLocal ? $_SERVER['argv'][$startPos + 1] : $_GET["groups"]); $startPos += 2; } if ($isLocal && $_SERVER['argv'][$startPos] == "-exclude-group" || !$isLocal && isset($_GET["exclude_groups"])) { $arguments['excludeGroups'] = explode(',', $isLocal ? $_SERVER['argv'][$startPos + 1] : $_GET["exclude_groups"]); $startPos += 2; } $check = $isLocal ? $_SERVER['argv'][$startPos] : $_GET["mode"]; if ($check == "c") { $suiteClassName = $isLocal ? $_SERVER['argv'][$startPos + 1] : $_GET["class"]; $suiteClassFile = $isLocal ? $_SERVER['argv'][$startPos + 2] : $_GET["file"]; try { // $testClass = (); if ($loader == NULL) { $loader = new PHPUnit_Runner_StandardTestSuiteLoader(); } $testClass = $loader->load($suiteClassName, $suiteClassFile, FALSE); } catch (Exception $e) { myExceptionHandler($e); return; } try { // if class is a suite $suiteMethod = $testClass->getMethod('suite'); if ($suiteMethod->isAbstract() || !$suiteMethod->isPublic() || !$suiteMethod->isStatic()) { return; } try { // ?? suite does not have testName argument $test = $suiteMethod->invoke(NULL, $testClass->getName()); $test->setName($suiteClassName); if ($canCountTest) { print traceCommand("testCount", "count", (string) sizeof($test)); } self::runTest($test, $suiteClassFile, $arguments); } catch (ReflectionException $e) { myExceptionHandler($e); return; } } catch (ReflectionException $e) { $test = new PHPUnit_Framework_TestSuite($testClass); if ($canCountTest) { print traceCommand("testCount", "count", (string) sizeof($test)); } self::runTest($test, $suiteClassFile, $arguments); } } else { if ($check == "d") { // if run directory // in remote case we put this script in the test directory $suiteDirName = $isLocal ? $_SERVER['argv'][$startPos + 1] : dirname(__FILE__); if (is_dir($suiteDirName) && !is_file($suiteDirName . '.php')) { $testCollector = new PHPUnit_Runner_IncludePathTestCollector(array($suiteDirName)); // $test = new PHPUnit_Framework_TestSuite($suiteDirName); $filenames = $testCollector->collectTests(); $number = 0; $alltests = array(); foreach ($filenames as $filename) { $tests = self::collectTestsFromFile($filename); foreach ($tests as $currenttest) { $number += sizeof($currenttest); $alltests[] = $currenttest; $alltests[] = $filename; } } if ($canCountTest) { print traceCommand("testCount", "count", (string) $number); } for ($i = 0; $i < count($alltests); $i += 2) { self::runTest($alltests[$i], $alltests[$i + 1], $arguments); } return; } } else { if ($check == 'f') { // if run all in file $filename = $isLocal ? $_SERVER['argv'][$startPos + 1] : $_GET["file"]; $tests = self::collectTestsFromFile($filename); $test = new PHPUnit_Framework_TestSuite(); $number = 0; foreach ($tests as $currenttest) { if ($tests) { $test->addTest($currenttest); $number += sizeof($currenttest); } } if ($canCountTest) { print traceCommand("testCount", "count", $number); } foreach ($tests as $currentTest) { self::runTest($currentTest, $filename, $arguments); } return; } else { if ($check == 'm') { $suiteMethodName = $isLocal ? $_SERVER['argv'][$startPos + 1] : $_GET["method"]; $suiteClassName = $isLocal ? $_SERVER['argv'][$startPos + 2] : $_GET["class"]; $suiteClassFile = $isLocal ? $_SERVER['argv'][$startPos + 3] : $_GET["file"]; try { $testClass = new PHPUnit_Runner_StandardTestSuiteLoader(); $testClass = $testClass->load($suiteClassName, $suiteClassFile, FALSE); } catch (Exception $e) { myExceptionHandler($e); return; } try { // if class is a suite $suiteMethod = $testClass->getMethod($suiteMethodName); if ($suiteMethodName == 'suite') { if ($suiteMethod->isAbstract() || !$suiteMethod->isPublic() || !$suiteMethod->isStatic()) { return; } try { $test = $suiteMethod->invoke(NULL, $testClass->getName()); $test->setName($suiteClassName); if ($canCountTest) { print traceCommand("testCount", "count", (string) sizeof($test)); } self::runTest($test, $suiteClassFile, $arguments); } catch (ReflectionException $e) { myExceptionHandler($e); return; } } else { $test = PHPUnit_Framework_TestSuite::createTest($testClass, $suiteMethodName); $testSuite = new PHPUnit_Framework_TestSuite(); $testSuite->addTest($test); $testSuite->setName($suiteClassName); if ($canCountTest) { print traceCommand("testCount", "count", (string) sizeof($test)); } self::runTest($testSuite, $suiteClassFile, $arguments); } } catch (ReflectionException $e) { myExceptionHandler($e); return; } } else { if ($check == 'x') { $testSuite = $configuration->getTestSuiteConfiguration(); self::runTest($testSuite, "", $arguments); } } } } } }
/** * @param string $loaderName */ protected static function handleLoader($loaderName) { if (!class_exists($loaderName, FALSE)) { PHPUnit_Util_Fileloader::checkAndLoad(str_replace('_', '/', $loaderName) . '.php'); } if (class_exists($loaderName, FALSE)) { $class = new ReflectionClass($loaderName); if ($class->implementsInterface('PHPUnit_Runner_TestSuiteLoader') && $class->isInstantiable()) { $loader = $class->newInstance(); } } if (!isset($loader)) { PHPUnit_TextUI_TestRunner::showError(sprintf('Could not use "%s" as loader.', $loaderName)); } PHPUnit_TextUI_TestRunner::setLoader($loader); }
/** * Wraps both <code>addTest()</code> and <code>addTestSuite</code> * as well as the separate import statements for the user's convenience. * * If the named file cannot be read or there are no new tests that can be * added, a <code>PHPUnit_Framework_Warning</code> will be created instead, * leaving the current test run untouched. * * @param string $filename * @param array $phptOptions Array with ini settings for the php instance * run, key being the name if the setting, * value the ini value. * @throws PHPUnit_Framework_Exception * @since Method available since Release 2.3.0 * @author Stefano F. Rausch <*****@*****.**> */ public function addTestFile($filename, $phptOptions = array()) { if (!is_string($filename)) { throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); } if (file_exists($filename) && substr($filename, -5) == '.phpt') { $this->addTest(new PHPUnit_Extensions_PhptTestCase($filename, $phptOptions)); return; } $classes = get_declared_classes(); $filename = PHPUnit_Util_Fileloader::checkAndLoad($filename); $newClasses = array_diff(get_declared_classes(), $classes); foreach ($newClasses as $className) { $this->foundClasses[] = $className; } $baseName = str_replace('.php', '', basename($filename)); end($this->foundClasses); while ($className = current($this->foundClasses)) { if (substr($className, 0 - strlen($baseName)) == $baseName) { $class = new ReflectionClass($className); if ($class->getFileName() == $filename) { $newClasses = array($className); unset($this->foundClasses[key($this->foundClasses)]); break; } } prev($this->foundClasses); } foreach ($newClasses as $className) { $class = new ReflectionClass($className); if (!$class->isAbstract()) { if ($class->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) { $method = $class->getMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME); if ($method->isStatic()) { $this->addTest($method->invoke(null, $className)); } } elseif ($class->implementsInterface('PHPUnit_Framework_Test')) { $this->addTestSuite($class); } } } $this->numTests = -1; }
/** * Wraps both <code>addTest()</code> and <code>addTestSuite</code> * as well as the separate import statements for the user's convenience. * * If the named file cannot be read or there are no new tests that can be * added, a <code>PHPUnit_Framework_Warning</code> will be created instead, * leaving the current test run untouched. * * @param string $filename * @param array $phptOptions Array with ini settings for the php instance * run, key being the name if the setting, * value the ini value. * @throws InvalidArgumentException * @since Method available since Release 2.3.0 * @author Stefano F. Rausch <*****@*****.**> */ public function addTestFile($filename, $phptOptions = array()) { if (!is_string($filename)) { throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); } if (file_exists($filename) && substr($filename, -5) == '.phpt') { require_once 'PHPUnit/Extensions/PhptTestCase.php'; $this->addTest(new PHPUnit_Extensions_PhptTestCase($filename, $phptOptions)); return; } if (!file_exists($filename)) { $includePaths = explode(PATH_SEPARATOR, get_include_path()); foreach ($includePaths as $includePath) { $file = $includePath . DIRECTORY_SEPARATOR . $filename; if (file_exists($file)) { $filename = $file; break; } } } PHPUnit_Util_Class::collectStart(); PHPUnit_Util_Fileloader::load($filename); $newClasses = PHPUnit_Util_Class::collectEnd(); $baseName = str_replace('.php', '', basename($filename)); foreach ($newClasses as $className) { if (substr($className, 0 - strlen($baseName)) == $baseName) { $newClasses = array($className); break; } } $testsFound = FALSE; foreach ($newClasses as $className) { $class = new ReflectionClass($className); if (!$class->isAbstract()) { if ($class->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) { $method = $class->getMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME); if ($method->isStatic()) { $this->addTest($method->invoke(NULL, $className)); $testsFound = TRUE; } } else { if ($class->implementsInterface('PHPUnit_Framework_Test')) { $this->addTestSuite($class); $testsFound = TRUE; } } } } $this->numTests = -1; }
/** * @param string $suiteClassName * @param string $suiteClassFile * @param boolean $syntaxCheck * @return ReflectionClass * @throws RuntimeException */ public function load($suiteClassName, $suiteClassFile = '', $syntaxCheck = TRUE) { $suiteClassName = str_replace('.php', '', $suiteClassName); if (empty($suiteClassFile)) { $suiteClassFile = str_replace(array('_', '::'), DIRECTORY_SEPARATOR, $suiteClassName) . '.php'; } if (!class_exists($suiteClassName, FALSE)) { if (!file_exists($suiteClassFile)) { $includePaths = explode(PATH_SEPARATOR, get_include_path()); foreach ($includePaths as $includePath) { $file = $includePath . DIRECTORY_SEPARATOR . $suiteClassFile; if (file_exists($file)) { $suiteClassFile = $file; break; } } } PHPUnit_Util_Fileloader::checkAndLoad($suiteClassFile, $syntaxCheck); } if (class_exists($suiteClassName, FALSE)) { return new ReflectionClass($suiteClassName); } else { throw new RuntimeException(sprintf('Class %s could not be found in %s.', $suiteClassName, $suiteClassFile)); } }
/** * Loads a bootstrap file. * * @param string $filename */ protected function handleBootstrap($filename) { try { PHPUnit_Util_Fileloader::checkAndLoad($filename); } catch (PHPUnit_Framework_Exception $e) { PHPUnit_TextUI_TestRunner::showError($e->getMessage()); } }
/** * Include a file * * @param string $filename */ public static function loadFile($filename) { PHPUnitFileLoader::checkAndLoad($filename); }
/** * Uses a separate process to perform a syntax check on a PHP sourcefile. * * PHPUnit_Util_Fileloader::$phpBinary contains the path to the PHP * interpreter used for this. If unset, the following assumptions will * be made: * * 1. When the PHP CLI/CGI binary configured with the PEAR Installer * (php_bin configuration value) is readable, it will be used. * * 2. When PHPUnit is run using the CLI SAPI and the $_SERVER['_'] * variable does not contain the string "PHPUnit", $_SERVER['_'] * is assumed to contain the path to the current PHP interpreter * and that will be used. * * 3. When PHPUnit is run using the CLI SAPI and the $_SERVER['_'] * variable contains the string "PHPUnit", the file that $_SERVER['_'] * points is assumed to be the PHPUnit TextUI CLI wrapper script * "phpunit" and the binary set up using #! on that file's first * line of code is assumed to contain the path to the current PHP * interpreter and that will be used. * * 4. The current PHP interpreter is assumed to be in the $PATH and * to be invokable through "php". * * @param string $filename * @throws RuntimeException * @access protected * @static * @since Method available since Release 3.0.0 */ protected static function syntaxCheck($filename) { if (self::$phpBinary === NULL) { if (is_readable('@php_bin@')) { self::$phpBinary = '@php_bin@'; } else { if (PHP_SAPI == 'cli' && isset($_SERVER['_'])) { self::$phpBinary = $_SERVER['_']; if (strpos(self::$phpBinary, 'phpunit') !== FALSE) { $file = file(self::$phpBinary); $tmp = explode(' ', $file[0]); self::$phpBinary = trim($tmp[1]); } } } if (!is_readable(self::$phpBinary)) { self::$phpBinary = 'php'; } else { self::$phpBinary = escapeshellarg(self::$phpBinary); } } $command = self::$phpBinary . ' -l ' . escapeshellarg($filename); if (DIRECTORY_SEPARATOR == '\\') { $command = '"' . $command . '"'; } $output = shell_exec($command); if (strpos($output, 'Errors parsing') !== FALSE) { throw new RuntimeException($output); } }
/** * @param string $suiteClassName * @param string $suiteClassFile * @return ReflectionClass * @throws RuntimeException * @access public */ public function load($suiteClassName, $suiteClassFile = '') { $suiteClassName = str_replace('.php', '', $suiteClassName); $suiteClassFile = !empty($suiteClassFile) ? $suiteClassFile : str_replace('_', '/', $suiteClassName) . '.php'; if (!class_exists($suiteClassName, FALSE)) { if (!file_exists($suiteClassFile)) { $includePaths = PHPUnit_Util_Fileloader::getIncludePaths(); foreach ($includePaths as $includePath) { $file = $includePath . DIRECTORY_SEPARATOR . $suiteClassFile; if (file_exists($file)) { $suiteClassFile = $file; break; } } } PHPUnit_Util_Fileloader::checkAndLoad($suiteClassFile); } if (class_exists($suiteClassName, FALSE)) { return new ReflectionClass($suiteClassName); } else { throw new RuntimeException(sprintf('Class %s could not be found in %s.', $suiteClassName, $suiteClassFile)); } }
/** * Handles the command-line arguments. * * A child class of PHPUnit_TextUI_Command can hook into the argument * parsing by adding the switch(es) to the $longOptions array and point to a * callback method that handles the switch(es) in the child class like this * * <code> * <?php * class MyCommand extends PHPUnit_TextUI_Command * { * public function __construct() * { * $this->longOptions['--my-switch'] = 'myHandler'; * } * * // --my-switch foo -> myHandler('foo') * protected function myHandler($value) * { * } * } * </code> * * @param array $argv */ protected function handleArguments(array $argv) { try { $this->options = PHPUnit_Util_Getopt::getopt($argv, 'd:', array_keys($this->longOptions)); } catch (RuntimeException $e) { PHPUnit_TextUI_TestRunner::showError($e->getMessage()); } $skeletonClass = FALSE; $skeletonTest = FALSE; foreach ($this->options[0] as $option) { switch ($option[0]) { case '--ansi': $this->showMessage('The --ansi option is deprecated, please use --colors ' . 'instead.', FALSE); case '--colors': $this->arguments['colors'] = TRUE; break; case '--bootstrap': $this->arguments['bootstrap'] = $option[1]; break; case '--configuration': $this->arguments['configuration'] = $option[1]; break; case '--coverage-xml': $this->showMessage('The --coverage-xml option is deprecated, please use ' . '--coverage-clover instead.', FALSE); case '--coverage-clover': if (extension_loaded('tokenizer') && extension_loaded('xdebug')) { $this->arguments['coverageClover'] = $option[1]; } else { if (!extension_loaded('tokenizer')) { $this->showMessage('The tokenizer extension is not loaded.'); } else { $this->showMessage('The Xdebug extension is not loaded.'); } } break; case '--coverage-source': if (extension_loaded('tokenizer') && extension_loaded('xdebug')) { $this->arguments['coverageSource'] = $option[1]; } else { if (!extension_loaded('tokenizer')) { $this->showMessage('The tokenizer extension is not loaded.'); } else { $this->showMessage('The Xdebug extension is not loaded.'); } } break; case '--report': $this->showMessage('The --report option is deprecated, please use ' . '--coverage-html instead.', FALSE); case '--coverage-html': if (extension_loaded('tokenizer') && extension_loaded('xdebug')) { $this->arguments['reportDirectory'] = $option[1]; } else { if (!extension_loaded('tokenizer')) { $this->showMessage('The tokenizer extension is not loaded.'); } else { $this->showMessage('The Xdebug extension is not loaded.'); } } break; case 'd': $ini = explode('=', $option[1]); if (isset($ini[0])) { if (isset($ini[1])) { ini_set($ini[0], $ini[1]); } else { ini_set($ini[0], TRUE); } } break; case '--debug': $this->arguments['debug'] = TRUE; break; case '--help': $this->showHelp(); exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); break; case '--filter': $this->arguments['filter'] = $option[1]; break; case '--group': $this->arguments['groups'] = explode(',', $option[1]); break; case '--exclude-group': $this->arguments['excludeGroups'] = explode(',', $option[1]); break; case '--include-path': $includePath = $option[1]; break; case '--list-groups': $this->arguments['listGroups'] = TRUE; break; case '--loader': $this->arguments['loader'] = $option[1]; break; case '--log-json': $this->arguments['jsonLogfile'] = $option[1]; break; case '--log-xml': $this->showMessage('The --log-xml option is deprecated, please use ' . '--log-junit instead.', FALSE); case '--log-junit': $this->arguments['junitLogfile'] = $option[1]; break; case '--log-graphviz': $this->showMessage('The --log-graphviz functionality is deprecated and ' . 'will be removed in the future.', FALSE); if (PHPUnit_Util_Filesystem::fileExistsInIncludePath('Image/GraphViz.php')) { $this->arguments['graphvizLogfile'] = $option[1]; } else { $this->showMessage('The Image_GraphViz package is not installed.'); } break; case '--log-tap': $this->arguments['tapLogfile'] = $option[1]; break; case '--log-pmd': $this->showMessage('The --log-pmd functionality is deprecated and will be ' . 'removed in the future.', FALSE); if (extension_loaded('tokenizer') && extension_loaded('xdebug')) { $this->arguments['pmdXML'] = $option[1]; } else { if (!extension_loaded('tokenizer')) { $this->showMessage('The tokenizer extension is not loaded.'); } else { $this->showMessage('The Xdebug extension is not loaded.'); } } break; case '--log-metrics': $this->showMessage('The --log-metrics functionality is deprecated and ' . 'will be removed in the future.', FALSE); if (extension_loaded('tokenizer') && extension_loaded('xdebug')) { $this->arguments['metricsXML'] = $option[1]; } else { if (!extension_loaded('tokenizer')) { $this->showMessage('The tokenizer extension is not loaded.'); } else { $this->showMessage('The Xdebug extension is not loaded.'); } } break; case '--process-isolation': $this->arguments['processIsolation'] = TRUE; $this->arguments['syntaxCheck'] = FALSE; break; case '--repeat': $this->showMessage('The --repeat functionality is deprecated and will be ' . 'removed in the future.', FALSE); $this->arguments['repeat'] = (int) $option[1]; break; case '--stderr': $this->arguments['printer'] = new PHPUnit_TextUI_ResultPrinter('php://stderr', isset($this->arguments['verbose']) ? $this->arguments['verbose'] : FALSE); break; case '--stop-on-failure': $this->arguments['stopOnFailure'] = TRUE; break; case '--test-db-dsn': $this->showMessage('The test database functionality is deprecated and ' . 'will be removed in the future.', FALSE); if (extension_loaded('pdo')) { $this->arguments['testDatabaseDSN'] = $option[1]; } else { $this->showMessage('The PDO extension is not loaded.'); } break; case '--test-db-log-rev': if (extension_loaded('pdo')) { $this->arguments['testDatabaseLogRevision'] = $option[1]; } else { $this->showMessage('The PDO extension is not loaded.'); } break; case '--test-db-prefix': if (extension_loaded('pdo')) { $this->arguments['testDatabasePrefix'] = $option[1]; } else { $this->showMessage('The PDO extension is not loaded.'); } break; case '--test-db-log-info': if (extension_loaded('pdo')) { $this->arguments['testDatabaseLogInfo'] = $option[1]; } else { $this->showMessage('The PDO extension is not loaded.'); } break; case '--skeleton': $this->showMessage('The --skeleton option is deprecated, please use ' . '--skeleton-test instead.', FALSE); case '--skeleton-test': $skeletonTest = TRUE; $skeletonClass = FALSE; break; case '--skeleton-class': $skeletonClass = TRUE; $skeletonTest = FALSE; break; case '--tap': require_once PATH_TO_ROOT . '/test/PHPUnit/Util/Log/TAP.php'; $this->arguments['printer'] = new PHPUnit_Util_Log_TAP(); break; case '--story': require_once PATH_TO_ROOT . '/test/PHPUnit/Extensions/Story/ResultPrinter/Text.php'; $this->arguments['printer'] = new PHPUnit_Extensions_Story_ResultPrinter_Text(); break; case '--story-html': $this->arguments['storyHTMLFile'] = $option[1]; break; case '--story-text': $this->arguments['storyTextFile'] = $option[1]; break; case '--syntax-check': $this->arguments['syntaxCheck'] = TRUE; break; case '--testdox': require_once PATH_TO_ROOT . '/test/PHPUnit/Util/TestDox/ResultPrinter/Text.php'; $this->arguments['printer'] = new PHPUnit_Util_TestDox_ResultPrinter_Text(); break; case '--testdox-html': $this->arguments['testdoxHTMLFile'] = $option[1]; break; case '--testdox-text': $this->arguments['testdoxTextFile'] = $option[1]; break; case '--no-configuration': $this->arguments['useDefaultConfiguration'] = FALSE; break; case '--no-globals-backup': $this->arguments['backupGlobals'] = FALSE; break; case '--static-backup': $this->arguments['backupStaticAttributes'] = TRUE; break; case '--verbose': $this->arguments['verbose'] = TRUE; break; case '--version': PHPUnit_TextUI_TestRunner::printVersionString(); exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); break; case '--wait': $this->arguments['wait'] = TRUE; break; default: $optionName = str_replace('--', '', $option[0]); if (isset($this->longOptions[$optionName])) { $handler = $this->longOptions[$optionName]; } else { if (isset($this->longOptions[$optionName . '='])) { $handler = $this->longOptions[$optionName . '=']; } } if (isset($handler) && is_callable(array($this, $handler))) { $this->{$handler}($option[1]); } } } if (isset($this->arguments['printer']) && $this->arguments['printer'] instanceof PHPUnit_Extensions_Story_ResultPrinter_Text && isset($this->arguments['processIsolation']) && $this->arguments['processIsolation']) { $this->showMessage('The story result printer cannot be used in process isolation.'); } $this->handleCustomTestSuite(); if (!isset($this->arguments['test'])) { if (isset($this->options[1][0])) { $this->arguments['test'] = $this->options[1][0]; } if (isset($this->options[1][1])) { $this->arguments['testFile'] = $this->options[1][1]; } else { $this->arguments['testFile'] = ''; } if (isset($this->arguments['test']) && is_file($this->arguments['test'])) { $this->arguments['testFile'] = realpath($this->arguments['test']); $this->arguments['test'] = substr($this->arguments['test'], 0, strrpos($this->arguments['test'], '.')); } } if (isset($includePath)) { ini_set('include_path', $includePath . PATH_SEPARATOR . ini_get('include_path')); } if (isset($this->arguments['bootstrap'])) { PHPUnit_Util_Fileloader::load($this->arguments['bootstrap']); } if ($this->arguments['loader'] !== NULL) { $this->arguments['loader'] = $this->handleLoader($this->arguments['loader']); } if (!isset($this->arguments['configuration']) && $this->arguments['useDefaultConfiguration']) { if (file_exists('phpunit.xml')) { $this->arguments['configuration'] = realpath('phpunit.xml'); } else { if (file_exists('phpunit.xml.dist')) { $this->arguments['configuration'] = realpath('phpunit.xml.dist'); } } } if (isset($this->arguments['configuration'])) { $configuration = PHPUnit_Util_Configuration::getInstance($this->arguments['configuration']); $phpunit = $configuration->getPHPUnitConfiguration(); if (isset($phpunit['syntaxCheck'])) { $this->arguments['syntaxCheck'] = $phpunit['syntaxCheck']; } if (isset($phpunit['testSuiteLoaderClass'])) { if (isset($phpunit['testSuiteLoaderFile'])) { $file = $phpunit['testSuiteLoaderFile']; } else { $file = ''; } $this->arguments['loader'] = $this->handleLoader($phpunit['testSuiteLoaderClass'], $file); } $configuration->handlePHPConfiguration(); if (!isset($this->arguments['bootstrap'])) { $phpunitConfiguration = $configuration->getPHPUnitConfiguration(); if (isset($phpunitConfiguration['bootstrap'])) { PHPUnit_Util_Fileloader::load($phpunitConfiguration['bootstrap']); } } $browsers = $configuration->getSeleniumBrowserConfiguration(); if (!empty($browsers)) { require_once PATH_TO_ROOT . '/test/PHPUnit/Extensions/SeleniumTestCase.php'; PHPUnit_Extensions_SeleniumTestCase::$browsers = $browsers; } if (!isset($this->arguments['test'])) { $testSuite = $configuration->getTestSuiteConfiguration($this->arguments['syntaxCheck']); if ($testSuite !== NULL) { $this->arguments['test'] = $testSuite; } } } if (isset($this->arguments['test']) && is_string($this->arguments['test']) && substr($this->arguments['test'], -5, 5) == '.phpt') { require_once PATH_TO_ROOT . '/test/PHPUnit/Extensions/PhptTestCase.php'; $test = new PHPUnit_Extensions_PhptTestCase($this->arguments['test']); $this->arguments['test'] = new PHPUnit_Framework_TestSuite(); $this->arguments['test']->addTest($test); } if (!isset($this->arguments['test']) || isset($this->arguments['testDatabaseLogRevision']) && !isset($this->arguments['testDatabaseDSN'])) { $this->showHelp(); exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); } if (!isset($this->arguments['syntaxCheck'])) { $this->arguments['syntaxCheck'] = FALSE; } if ($skeletonClass || $skeletonTest) { if (isset($this->arguments['test']) && $this->arguments['test'] !== FALSE) { PHPUnit_TextUI_TestRunner::printVersionString(); if ($skeletonClass) { require_once PATH_TO_ROOT . '/test/PHPUnit/Util/Skeleton/Class.php'; $class = 'PHPUnit_Util_Skeleton_Class'; } else { require_once PATH_TO_ROOT . '/test/PHPUnit/Util/Skeleton/Test.php'; $class = 'PHPUnit_Util_Skeleton_Test'; } try { $args = array(); $reflector = new ReflectionClass($class); for ($i = 0; $i <= 3; $i++) { if (isset($this->options[1][$i])) { $args[] = $this->options[1][$i]; } } $skeleton = $reflector->newInstanceArgs($args); $skeleton->write(); } catch (Exception $e) { print $e->getMessage() . "\n"; exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT); } printf('Wrote skeleton for "%s" to "%s".' . "\n", $skeleton->getOutClassName(), $skeleton->getOutSourceFile()); exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); } else { $this->showHelp(); exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); } } }
protected function guess_class_from_path($file) { // Somebody is using just the file name, we need to look inside the file and guess the testcase // class name. Let's throw fatal error if there are more testcases in one file. $classes = get_declared_classes(); PHPUnit_Util_Fileloader::checkAndLoad($file); $includePathFilename = stream_resolve_include_path($file); $loadedClasses = array_diff(get_declared_classes(), $classes); $candidates = array(); foreach ($loadedClasses as $loadedClass) { $class = new ReflectionClass($loadedClass); if ($class->isSubclassOf('PHPUnit_Framework_TestCase') and !$class->isAbstract()) { if (realpath($includePathFilename) === realpath($class->getFileName())) { $candidates[] = $loadedClass; } } } if (count($candidates) == 0) { throw new PHPUnit_Framework_Exception(sprintf("File '%s' does not contain any test cases.", $file)); } if (count($candidates) > 1) { throw new PHPUnit_Framework_Exception(sprintf("File '%s' contains multiple test cases: " . implode(', ', $candidates), $file)); } $classname = reset($candidates); return new ReflectionClass($classname); }