From be30af0e2339907e73e6e6b884eda0ad8e6743bf Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Sat, 20 Feb 2021 16:14:19 +0100 Subject: [PATCH] MDL-71036 phpunit: Remove custom autoloader Custom autoloaders are deprecated with PHPUnit 9 and will be removed with PHPUnit 10. Since PHPUnit 8.5 custom autoloaders don't do much because that version removed the ability to launch unit tests by class name and that's exactly the reason we had a custom autoloader (to map class names to files within our tests). See MDL-67673 about when direct use of classes was deprecated (8.5), now removed (9.5). So, as far as it's unused, removing it now, test still can be selectively using any of: - a relative path to file (although there are some restrictions comming with PHPUnit 9, see https://github.com/sebastianbergmann/phpunit/issues/4105 - using --filter, to point to any classname[::method] - using --testsuite to run a complete suite - using --config to point to custom components. Also, commented out the lib/ajax/tests directory because it doesn't exist / is empty and PHPUnit 9 emits error when a configured test directory does not exist. See https://github.com/sebastianbergmann/phpunit/issues/4493. Alternative was to completely remove the configuration line, but decided to keep it around in case some day we want to add some test there. --- lib/phpunit/bootstrap.php | 1 - lib/phpunit/classes/autoloader.php | 203 ----------------------------- phpunit.xml.dist | 3 +- 3 files changed, 1 insertion(+), 206 deletions(-) delete mode 100644 lib/phpunit/classes/autoloader.php diff --git a/lib/phpunit/bootstrap.php b/lib/phpunit/bootstrap.php index d0261e2d6e32f..f3ca297b13284 100644 --- a/lib/phpunit/bootstrap.php +++ b/lib/phpunit/bootstrap.php @@ -50,7 +50,6 @@ require_once(__DIR__.'/bootstraplib.php'); require_once(__DIR__.'/../testing/lib.php'); -require_once(__DIR__.'/classes/autoloader.php'); if (isset($_SERVER['REMOTE_ADDR'])) { phpunit_bootstrap_error(1, 'Unit tests can be executed only from command line!'); diff --git a/lib/phpunit/classes/autoloader.php b/lib/phpunit/classes/autoloader.php deleted file mode 100644 index 50052db4fd90a..0000000000000 --- a/lib/phpunit/classes/autoloader.php +++ /dev/null @@ -1,203 +0,0 @@ -. - -/** - * PHPUnit autoloader for Moodle. - * - * @package core - * @category phpunit - * @copyright 2013 Petr Skoda {@link http://skodak.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -/** - * Class phpunit_autoloader. - * - * Please notice that phpunit testcases obey frankenstyle naming rules, - * that is full component prefix + _testcase postfix. The files are expected - * in tests directory inside each component. There are some extra tests - * directories which require both classname and file path. - * - * Examples: - * - * vendor/bin/phpunit core_component_testcase - * vendor/bin/phpunit lib/tests/component_test.php - * vendor/bin/phpunit core_component_testcase lib/tests/component_test.php - * - * @package core - * @category phpunit - * @copyright 2013 Petr Skoda {@link http://skodak.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class phpunit_autoloader implements \PHPUnit\Runner\TestSuiteLoader { - public function load(string $suiteClassName, string $suiteClassFile = ''): ReflectionClass { - global $CFG; - - // Let's guess what user entered on the commandline... - if ($suiteClassFile) { - // This means they either entered the class+path or path only. - if (strpos($suiteClassName, '/') !== false) { - // Class names can not contain slashes, - // user entered only path without testcase class name. - return $this->guess_class_from_path($suiteClassFile); - } - if (strpos($suiteClassName, '\\') !== false and strpos($suiteClassFile, $suiteClassName.'.php') !== false) { - // This must be backslashed windows path. - return $this->guess_class_from_path($suiteClassFile); - } - } - - if (class_exists($suiteClassName, false)) { - $class = new ReflectionClass($suiteClassName); - return $class; - } - - if ($suiteClassFile) { - PHPUnit\Util\Fileloader::checkAndLoad($suiteClassFile); - if (class_exists($suiteClassName, false)) { - $class = new ReflectionClass($suiteClassName); - return $class; - } - - throw new PHPUnit\Framework\Exception( - sprintf("Class '%s' could not be found in '%s'.", $suiteClassName, $suiteClassFile) - ); - } - - /* - * Try standard testcase naming rules based on frankenstyle component: - * 1/ test classes should use standard frankenstyle class names plus suffix "_testcase" - * 2/ test classes should be stored in files with suffix "_test" - */ - - $parts = explode('_', $suiteClassName); - $suffix = end($parts); - $component = ''; - - if ($suffix === 'testcase') { - unset($parts[key($parts)]); - while($parts) { - if (!$component) { - $component = array_shift($parts); - } else { - $component = $component . '_' . array_shift($parts); - } - // Try standard plugin and core subsystem locations. - if ($fulldir = core_component::get_component_directory($component)) { - $testfile = implode('_', $parts); - $fullpath = "{$fulldir}/tests/{$testfile}_test.php"; - if (is_readable($fullpath)) { - include_once($fullpath); - if (class_exists($suiteClassName, false)) { - $class = new ReflectionClass($suiteClassName); - return $class; - } - } - } - } - // The last option is testsuite directories in main phpunit.xml file. - $xmlfile = "$CFG->dirroot/phpunit.xml"; - if (is_readable($xmlfile) and $xml = file_get_contents($xmlfile)) { - $dom = new DOMDocument(); - $dom->loadXML($xml); - $nodes = $dom->getElementsByTagName('testsuite'); - foreach ($nodes as $node) { - /** @var DOMNode $node */ - $suitename = trim($node->attributes->getNamedItem('name')->nodeValue); - if (strpos($suitename, 'core') !== 0 or strpos($suitename, ' ') !== false) { - continue; - } - // This is a nasty hack: testsuit names are sometimes used as prefix for testcases - // in non-standard core subsystem locations. - if (strpos($suiteClassName, $suitename) !== 0) { - continue; - } - foreach ($node->childNodes as $dirnode) { - /** @var DOMNode $dirnode */ - $dir = trim($dirnode->textContent); - if (!$dir) { - continue; - } - $dir = $CFG->dirroot.'/'.$dir; - $parts = explode('_', $suitename); - $prefix = ''; - while ($parts) { - if ($prefix) { - $prefix = $prefix.'_'.array_shift($parts); - } else { - $prefix = array_shift($parts); - } - $filename = substr($suiteClassName, strlen($prefix)+1); - $filename = preg_replace('/testcase$/', 'test', $filename); - if (is_readable("$dir/$filename.php")) { - include_once("$dir/$filename.php"); - if (class_exists($suiteClassName, false)) { - $class = new ReflectionClass($suiteClassName); - return $class; - } - } - } - } - } - } - } - - throw new PHPUnit\Framework\Exception( - sprintf("Class '%s' could not be found in '%s'.", $suiteClassName, $suiteClassFile) - ); - } - - 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); - } - - public function reload(ReflectionClass $aClass): ReflectionClass { - return $aClass; - } -} diff --git a/phpunit.xml.dist b/phpunit.xml.dist index e12def32e830f..a141504f3a94e 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -16,7 +16,6 @@ stopOnSkipped="false" beStrictAboutTestsThatDoNotTestAnything="false" beStrictAboutOutputDuringTests="true" - testSuiteLoaderClass="phpunit_autoloader" > @@ -45,7 +44,7 @@ lib/tests - lib/ajax/tests + favourites/tests