comparison core/modules/simpletest/src/TestDiscovery.php @ 17:129ea1e6d783

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:21:36 +0000
parents c2387f117808
children af1871eacc83
comparison
equal deleted inserted replaced
16:c2387f117808 17:129ea1e6d783
4 4
5 use Doctrine\Common\Annotations\SimpleAnnotationReader; 5 use Doctrine\Common\Annotations\SimpleAnnotationReader;
6 use Doctrine\Common\Reflection\StaticReflectionParser; 6 use Doctrine\Common\Reflection\StaticReflectionParser;
7 use Drupal\Component\Annotation\Reflection\MockFileFinder; 7 use Drupal\Component\Annotation\Reflection\MockFileFinder;
8 use Drupal\Component\Utility\NestedArray; 8 use Drupal\Component\Utility\NestedArray;
9 use Drupal\Core\Cache\CacheBackendInterface;
10 use Drupal\Core\Extension\ExtensionDiscovery; 9 use Drupal\Core\Extension\ExtensionDiscovery;
11 use Drupal\Core\Extension\ModuleHandlerInterface; 10 use Drupal\Core\Extension\ModuleHandlerInterface;
12 use Drupal\simpletest\Exception\MissingGroupException; 11 use Drupal\simpletest\Exception\MissingGroupException;
13 use PHPUnit_Util_Test; 12 use PHPUnit_Util_Test;
14 13
23 * @var \Composer\Autoload\ClassLoader 22 * @var \Composer\Autoload\ClassLoader
24 */ 23 */
25 protected $classLoader; 24 protected $classLoader;
26 25
27 /** 26 /**
28 * Backend for caching discovery results. 27 * Statically cached list of test classes.
29 * 28 *
30 * @var \Drupal\Core\Cache\CacheBackendInterface 29 * @var array
31 */ 30 */
32 protected $cacheBackend; 31 protected $testClasses;
33 32
34 /** 33 /**
35 * Cached map of all test namespaces to respective directories. 34 * Cached map of all test namespaces to respective directories.
36 * 35 *
37 * @var array 36 * @var array
68 * The class loader. Normally Composer's ClassLoader, as included by the 67 * The class loader. Normally Composer's ClassLoader, as included by the
69 * front controller, but may also be decorated; e.g., 68 * front controller, but may also be decorated; e.g.,
70 * \Symfony\Component\ClassLoader\ApcClassLoader. 69 * \Symfony\Component\ClassLoader\ApcClassLoader.
71 * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler 70 * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
72 * The module handler. 71 * The module handler.
73 * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend 72 */
74 * (optional) Backend for caching discovery results. 73 public function __construct($root, $class_loader, ModuleHandlerInterface $module_handler) {
75 */
76 public function __construct($root, $class_loader, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend = NULL) {
77 $this->root = $root; 74 $this->root = $root;
78 $this->classLoader = $class_loader; 75 $this->classLoader = $class_loader;
79 $this->moduleHandler = $module_handler; 76 $this->moduleHandler = $module_handler;
80 $this->cacheBackend = $cache_backend;
81 } 77 }
82 78
83 /** 79 /**
84 * Registers test namespaces of all extensions and core test classes. 80 * Registers test namespaces of all extensions and core test classes.
85 * 81 *
157 */ 153 */
158 public function getTestClasses($extension = NULL, array $types = []) { 154 public function getTestClasses($extension = NULL, array $types = []) {
159 $reader = new SimpleAnnotationReader(); 155 $reader = new SimpleAnnotationReader();
160 $reader->addNamespace('Drupal\\simpletest\\Annotation'); 156 $reader->addNamespace('Drupal\\simpletest\\Annotation');
161 157
162 if (!isset($extension)) { 158 if (!isset($extension) && empty($types)) {
163 if ($this->cacheBackend && $cache = $this->cacheBackend->get('simpletest:discovery:classes')) { 159 if (!empty($this->testClasses)) {
164 return $cache->data; 160 return $this->testClasses;
165 } 161 }
166 } 162 }
167 $list = []; 163 $list = [];
168 164
169 $classmap = $this->findAllClassFiles($extension); 165 $classmap = $this->findAllClassFiles($extension);
211 foreach ($list as &$tests) { 207 foreach ($list as &$tests) {
212 uksort($tests, 'strnatcasecmp'); 208 uksort($tests, 'strnatcasecmp');
213 } 209 }
214 210
215 // Allow modules extending core tests to disable originals. 211 // Allow modules extending core tests to disable originals.
216 $this->moduleHandler->alter('simpletest', $list); 212 $this->moduleHandler->alterDeprecated('Convert your test to a PHPUnit-based one and implement test listeners. See: https://www.drupal.org/node/2939892', 'simpletest', $list);
217 213
218 if (!isset($extension)) { 214 if (!isset($extension) && empty($types)) {
219 if ($this->cacheBackend) { 215 $this->testClasses = $list;
220 $this->cacheBackend->set('simpletest:discovery:classes', $list);
221 }
222 } 216 }
223 217
224 if ($types) { 218 if ($types) {
225 $list = NestedArray::filter($list, function ($element) use ($types) { 219 $list = NestedArray::filter($list, function ($element) use ($types) {
226 return !(is_array($element) && isset($element['type']) && !in_array($element['type'], $types)); 220 return !(is_array($element) && isset($element['type']) && !in_array($element['type'], $types));
286 } 280 }
287 $flags = \FilesystemIterator::UNIX_PATHS; 281 $flags = \FilesystemIterator::UNIX_PATHS;
288 $flags |= \FilesystemIterator::SKIP_DOTS; 282 $flags |= \FilesystemIterator::SKIP_DOTS;
289 $flags |= \FilesystemIterator::FOLLOW_SYMLINKS; 283 $flags |= \FilesystemIterator::FOLLOW_SYMLINKS;
290 $flags |= \FilesystemIterator::CURRENT_AS_SELF; 284 $flags |= \FilesystemIterator::CURRENT_AS_SELF;
285 $flags |= \FilesystemIterator::KEY_AS_FILENAME;
291 286
292 $iterator = new \RecursiveDirectoryIterator($path, $flags); 287 $iterator = new \RecursiveDirectoryIterator($path, $flags);
293 $filter = new \RecursiveCallbackFilterIterator($iterator, function ($current, $key, $iterator) { 288 $filter = new \RecursiveCallbackFilterIterator($iterator, function ($current, $file_name, $iterator) {
294 if ($iterator->hasChildren()) { 289 if ($iterator->hasChildren()) {
295 return TRUE; 290 return TRUE;
296 } 291 }
297 return $current->isFile() && $current->getExtension() === 'php'; 292 // We don't want to discover abstract TestBase classes, traits or
293 // interfaces. They can be deprecated and will call @trigger_error()
294 // during discovery.
295 return
296 substr($file_name, -4) === '.php' &&
297 substr($file_name, -12) !== 'TestBase.php' &&
298 substr($file_name, -9) !== 'Trait.php' &&
299 substr($file_name, -13) !== 'Interface.php';
298 }); 300 });
299 $files = new \RecursiveIteratorIterator($filter); 301 $files = new \RecursiveIteratorIterator($filter);
300 $classes = []; 302 $classes = [];
301 foreach ($files as $fileinfo) { 303 foreach ($files as $fileinfo) {
302 $class = $namespace_prefix; 304 $class = $namespace_prefix;