. */ /** * Include parent class definition */ require_once 'PHPUnit/Framework/TestSuite.php'; /** * Parent class for test suites * * @package CiviCRM */ class CiviTestSuite extends PHPUnit_Framework_TestSuite { /** * Simple name based constructor * @param string $theClass * @param string $name */ public function __construct($theClass = '', $name = '') { if (empty($name)) { $name = str_replace('_', ' ', get_class($this) ); // also split AllTests to All Tests $name = str_replace('AllTests', 'All Tests', $name); } parent::__construct($name); // also load the class loader require_once 'CRM/Core/ClassLoader.php'; CRM_Core_ClassLoader::singleton()->register(); } /** * Test suite setup */ protected function setUp() { //print __METHOD__ . "\n"; } /** * Test suite teardown */ protected function tearDown() { //print __METHOD__ . "\n"; } /** * suppress failed test error issued by phpunit when it finds * a test suite with no tests */ public function testNothing() { } /** * @param $myfile * @return \PHPUnit_Framework_TestSuite */ protected function implSuite($myfile) { $name = str_replace('_', ' ', get_class($this) ); // also split AllTests to All Tests $name = str_replace('AllTests', 'All Tests', $name); $suite = new PHPUnit_Framework_TestSuite($name); $this->addAllTests($suite, $myfile, new SplFileInfo(dirname($myfile)) ); return $suite; } /** * Add all test classes *Test and all test suites *Tests in subdirectories * * @param PHPUnit_Framework_TestSuite $suite * Test suite object to add tests to * @param $myfile * @param SplFileInfo $dirInfo * object to scan * * @return void */ protected function addAllTests( PHPUnit_Framework_TestSuite &$suite, $myfile, SplFileInfo $dirInfo ) { //echo get_class($this)."::addAllTests($myfile,".$dirInfo->getRealPath().")\n"; if (!$dirInfo->isReadable() || !$dirInfo->isDir() ) { return; } // Pass 1: Check all *Tests.php files $addTests = array(); // array(callable) //echo "start Pass 1 on {$dirInfo->getRealPath()}\n"; $dir = new DirectoryIterator($dirInfo->getRealPath()); foreach ($dir as $fileInfo) { if ($fileInfo->isReadable() && $fileInfo->isFile() && preg_match('/Tests.php$/', $fileInfo->getFilename() ) ) { if ($fileInfo->getRealPath() == $myfile) { // Don't create an infinite loop //echo "ignoring {$fileInfo->getRealPath()}\n"; continue; } //echo "checking file ".$fileInfo->getRealPath( )."\n"; // This is a file with a name ending in 'Tests.php'. // Get all classes defined in the file and add those // with a class name ending in 'Test' to the test suite $oldClassNames = get_declared_classes(); require_once $fileInfo->getRealPath(); $newClassNames = get_declared_classes(); foreach (array_diff($newClassNames, $oldClassNames ) as $name) { if (preg_match('/Tests$/', $name)) { $addTests[] = $name . '::suite'; } } } } sort($addTests); foreach ($addTests as $addTest) { $suite->addTest(call_user_func($addTest)); } // Pass 2: Scan all subdirectories $addAllTests = array(); // array(array(0 => $suite, 1 => $file, 2 => SplFileinfo)) $dir = new DirectoryIterator($dirInfo->getRealPath()); //echo "start Pass 2 on {$dirInfo->getRealPath()}\n"; foreach ($dir as $fileInfo) { if ($fileInfo->isDir() && (substr($fileInfo->getFilename(), 0, 1) != '.') ) { // This is a directory that may contain tests so scan it $addAllTests[] = clone $fileInfo; } } //$addAllTests = CRM_Utils_Array::crmArraySortByField($addAllTests, '1'); usort($addAllTests, function ($a, $b) { return strnatcmp($a->getRealPath(), $b->getRealPath()); }); foreach ($addAllTests as $addAllTest) { $this->addAllTests($suite, $myfile, $addAllTest); } // Pass 3: Check all *Test.php files in this directory //echo "start Pass 3 on {$dirInfo->getRealPath()}\n"; $addTestSuites = array(); // array(className) $dir = new DirectoryIterator($dirInfo->getRealPath()); foreach ($dir as $fileInfo) { if ($fileInfo->isReadable() && $fileInfo->isFile() && preg_match('/Test.php$/', $fileInfo->getFilename() ) ) { //echo "checking file ".$fileInfo->getRealPath( )."\n"; // This is a file with a name ending in 'Tests?.php'. // Get all classes defined in the file and add those // with a class name ending in 'Test' to the test suite $oldClassNames = get_declared_classes(); require_once $fileInfo->getRealPath(); $newClassNames = get_declared_classes(); foreach (array_diff($newClassNames, $oldClassNames ) as $name) { if (strpos($fileInfo->getRealPath(), strtr($name, '_\\', '//') . ".php") !== FALSE) { if (preg_match('/Test$/', $name)) { $addTestSuites[] = $name; } } } } } sort($addTestSuites); foreach ($addTestSuites as $addTestSuite) { $suite->addTestSuite($addTestSuite); } // print_r(array($prefix, 'addTests' => $addTests, 'addAllTests' => $addAllTests, 'addTestSuites' => $addTestSuites)); } }