From 612665b15ef4a94c07e43e4abece15139cf16bf5 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Thu, 2 Feb 2017 16:37:31 +0000
Subject: [PATCH] Issue #2605664 by Torenware, Mile23, alexpott, Taran2L,
 neclimdul, Yogesh Pawar, mark.creamer, donquixote, dawehner, klausi: Align
 TestDiscovery and bootstrap.php's non-permissive loading of PSR-4 namespaces
 for traits

---
 core/modules/simpletest/src/TestDiscovery.php |  4 +++
 .../simpletest/tests/src/Traits/TestTrait.php | 32 +++++++++++++++++++
 .../tests/src/Unit/TraitAccessTest.php        | 25 +++++++++++++++
 core/tests/bootstrap.php                      | 19 +++++++++--
 4 files changed, 77 insertions(+), 3 deletions(-)
 create mode 100644 core/modules/simpletest/tests/src/Traits/TestTrait.php
 create mode 100644 core/modules/simpletest/tests/src/Unit/TraitAccessTest.php

diff --git a/core/modules/simpletest/src/TestDiscovery.php b/core/modules/simpletest/src/TestDiscovery.php
index ae5dc525880d..02bf7071fbc6 100644
--- a/core/modules/simpletest/src/TestDiscovery.php
+++ b/core/modules/simpletest/src/TestDiscovery.php
@@ -119,6 +119,10 @@ public function registerTestNamespaces() {
       $this->testNamespaces["Drupal\\Tests\\$name\\Kernel\\"][] = "$base_path/tests/src/Kernel";
       $this->testNamespaces["Drupal\\Tests\\$name\\Functional\\"][] = "$base_path/tests/src/Functional";
       $this->testNamespaces["Drupal\\Tests\\$name\\FunctionalJavascript\\"][] = "$base_path/tests/src/FunctionalJavascript";
+
+      // Add discovery for traits which are shared between different test
+      // suites.
+      $this->testNamespaces["Drupal\\Tests\\$name\\Traits\\"][] = "$base_path/tests/src/Traits";
     }
 
     foreach ($this->testNamespaces as $prefix => $paths) {
diff --git a/core/modules/simpletest/tests/src/Traits/TestTrait.php b/core/modules/simpletest/tests/src/Traits/TestTrait.php
new file mode 100644
index 000000000000..eeac4963ecc5
--- /dev/null
+++ b/core/modules/simpletest/tests/src/Traits/TestTrait.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Drupal\Tests\simpletest\Traits;
+
+/**
+ * A nothing trait, but declared in the Drupal\Tests namespace.
+ *
+ * We use this trait to test autoloading of traits outside of the normal test
+ * suite namespaces.
+ *
+ * @see \Drupal\Tests\simpletest\Unit\TraitAccessTest
+ */
+trait TestTrait {
+
+  /**
+   * Random string for a not very interesting trait.
+   *
+   * @var string
+   */
+  protected $stuff = 'stuff';
+
+  /**
+   * Return a test string to a trait user.
+   *
+   * @return string
+   *   Just a random sort of string.
+   */
+  protected function getStuff() {
+    return $this->stuff;
+  }
+
+}
diff --git a/core/modules/simpletest/tests/src/Unit/TraitAccessTest.php b/core/modules/simpletest/tests/src/Unit/TraitAccessTest.php
new file mode 100644
index 000000000000..dbaffbf9ab01
--- /dev/null
+++ b/core/modules/simpletest/tests/src/Unit/TraitAccessTest.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Drupal\Tests\simpletest\Unit;
+
+use Drupal\Tests\UnitTestCase;
+use Drupal\Tests\simpletest\Traits\TestTrait;
+
+/**
+ * Test whether traits are autoloaded during PHPUnit discovery time.
+ *
+ * @group simpletest
+ */
+class TraitAccessTest extends UnitTestCase {
+
+  use TestTrait;
+
+  /**
+   * @coversNothing
+   */
+  public function testSimpleStuff() {
+    $stuff = $this->getStuff();
+    $this->assertSame($stuff, 'stuff', "Same old stuff");
+  }
+
+}
diff --git a/core/tests/bootstrap.php b/core/tests/bootstrap.php
index 9aeb1d79f047..a2b4921a4525 100644
--- a/core/tests/bootstrap.php
+++ b/core/tests/bootstrap.php
@@ -77,15 +77,28 @@ function drupal_phpunit_contrib_extension_directory_roots($root = NULL) {
  *   An associative array of extension directories, keyed by their namespace.
  */
 function drupal_phpunit_get_extension_namespaces($dirs) {
+  $suite_names = ['Unit', 'Kernel', 'Functional', 'FunctionalJavascript'];
   $namespaces = array();
   foreach ($dirs as $extension => $dir) {
     if (is_dir($dir . '/src')) {
       // Register the PSR-4 directory for module-provided classes.
       $namespaces['Drupal\\' . $extension . '\\'][] = $dir . '/src';
     }
-    if (is_dir($dir . '/tests/src')) {
-      // Register the PSR-4 directory for PHPUnit test classes.
-      $namespaces['Drupal\\Tests\\' . $extension . '\\'][] = $dir . '/tests/src';
+    $test_dir = $dir . '/tests/src';
+    if (is_dir($test_dir)) {
+      foreach ($suite_names as $suite_name) {
+        $suite_dir = $test_dir . '/' . $suite_name;
+        if (is_dir($suite_dir)) {
+          // Register the PSR-4 directory for PHPUnit-based suites.
+          $namespaces['Drupal\\Tests\\' . $extension . '\\' . $suite_name . '\\'][] = $suite_dir;
+        }
+      }
+      // Extensions can have a \Drupal\extension\Traits namespace for
+      // cross-suite trait code.
+      $trait_dir = $test_dir . '/Traits';
+      if (is_dir($trait_dir)) {
+        $namespaces['Drupal\\Tests\\' . $extension . '\\Traits\\'][] = $trait_dir;
+      }
     }
   }
   return $namespaces;
-- 
GitLab