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_Runner_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 (!empty($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;
}