diff --git a/core/tests/Drupal/KernelTests/Setup/Commands/SetupDrupalTestScriptTest.php b/core/tests/Drupal/KernelTests/Setup/Commands/SetupDrupalTestScriptTest.php index 668439cf17..c356efb94b 100644 --- a/core/tests/Drupal/KernelTests/Setup/Commands/SetupDrupalTestScriptTest.php +++ b/core/tests/Drupal/KernelTests/Setup/Commands/SetupDrupalTestScriptTest.php @@ -4,6 +4,8 @@ use Drupal\KernelTests\KernelTestBase; use Drupal\Setup\Commands\TestInstallationSetupApplication; +use GuzzleHttp\Client; +use GuzzleHttp\Psr7\Request; use Symfony\Component\Console\Tester\ApplicationTester; /** @@ -17,20 +19,31 @@ */ class SetupDrupalTestScriptTest extends KernelTestBase { + /** + * {@inheritdoc} + */ + protected function setUp() { + // Disable the usual kernel test setup process, as we want to run a custom + // command to install Drupal. + $this->root = static::getDrupalRoot(); + } + /** * @coversNothing */ public function testInstallScript() { - $autoloader = dirname(dirname(dirname(__DIR__))) . '/bootstrap.php'; - $app = new TestInstallationSetupApplication($autoloader); + $autoloader = $this->root . '/autoload.php'; + $app = new TestInstallationSetupApplication(require $autoloader); $app->setAutoExit(FALSE); $app_tester = new ApplicationTester($app); $app_tester->run( - ['command' => 'setup-drupal-test'], + [ + 'command' => 'setup-drupal-test', + '--setup_file' => __DIR__ . '/SetupDrupalTestScript.php', + ], [ 'interactive' => FALSE, - 'setup_file' => __DIR__ . '/SetupDrupalTestScript.php', ] ); @@ -38,6 +51,14 @@ public function testInstallScript() { $this->assertNotRegExp('/AlreadyInstalledException/', $app_tester->getDisplay()); $this->assertRegExp('/simpletest/', $app_tester->getDisplay()); $this->assertEqual(0, $app_tester->getStatusCode()); + + $http_client = new Client(); + $request = (new Request('GET', getenv('SIMPLETEST_BASE_URL') . '/test-page')) + ->withHeader('User-Agent', trim($app_tester->getDisplay())); + + $response = $http_client->send($request); + // Ensure the test_page_test module got installed. + $this->assertContains('Test page | Drupal', (string) $response->getBody()); } } diff --git a/core/tests/Drupal/Setup/Commands/TestInstallationSetupApplication.php b/core/tests/Drupal/Setup/Commands/TestInstallationSetupApplication.php index 94b42c6ec9..09761e00b0 100644 --- a/core/tests/Drupal/Setup/Commands/TestInstallationSetupApplication.php +++ b/core/tests/Drupal/Setup/Commands/TestInstallationSetupApplication.php @@ -17,8 +17,9 @@ class TestInstallationSetupApplication extends Application { /** * SetupDrupalApplication constructor. */ - public function __construct() { + public function __construct($autoloader) { parent::__construct('setup-drupal-test', '0.0.1'); + $this->setAutoloader($autoloader); } /** diff --git a/core/tests/Drupal/Setup/TestInstallationSetup.php b/core/tests/Drupal/Setup/TestInstallationSetup.php index 714b2815e4..f2fd50f0b2 100644 --- a/core/tests/Drupal/Setup/TestInstallationSetup.php +++ b/core/tests/Drupal/Setup/TestInstallationSetup.php @@ -91,23 +91,20 @@ protected function installDrupal() { * The setup file. */ protected function executeSetupFile($setup_file) { - $classes = static::fileGetPhpClasses($setup_file); + $class = static::fileGetPhpClass($setup_file); - if (empty($classes)) { + if (empty($class)) { throw new \InvalidArgumentException(sprintf('You need to define a class implementing \Drupal\Setup\TestSetupInterface')); } - if (count($classes) > 1) { - throw new \InvalidArgumentException(sprintf('You need to define a single class implementing \Drupal\Setup\TestSetupInterface')); - } require_once $setup_file; - if (!is_subclass_of($classes[0], TestSetupInterface::class)) { + if (!is_subclass_of($class, TestSetupInterface::class)) { throw new \InvalidArgumentException(sprintf('You need to define a class implementing \Drupal\Setup\TestSetupInterface')); } /** @var \Drupal\Setup\TestSetupInterface $instance */ - $instance = new $classes[0]; + $instance = new $class; $instance->setup(); } @@ -117,37 +114,52 @@ protected function executeSetupFile($setup_file) { * @param string $filepath * The file path. * - * @return string[] - * An array of PHP classes. + * @return string|null + * Returns a PHP class. */ - protected static function fileGetPhpClasses($filepath) { + protected static function fileGetPhpClass($filepath) { $php_code = file_get_contents($filepath); - $classes = static::extractClassesFromPhp($php_code); - return $classes; + return static::extractClassesFromPhp($php_code); } /** * @param string $php_code * PHP code to parse. * - * @return string[] - * An array of PHP classes. + * @return string + * A PHP class. */ protected static function extractClassesFromPhp($php_code) { - $classes = array(); $tokens = token_get_all($php_code); - $count = count($tokens); - for ($i = 2; $i < $count; $i++) { - if ($tokens[$i - 2][0] == T_CLASS - && $tokens[$i - 1][0] == T_WHITESPACE - && $tokens[$i][0] == T_STRING - ) { - - $class_name = $tokens[$i][1]; - $classes[] = $class_name; + + $class = $namespace = ''; + + for ($i = 0; $i < count($tokens); $i++) { + if ($tokens[$i][0] === T_NAMESPACE) { + for ($j = $i + 1; $j < count($tokens); $j++) { + if ($tokens[$j][0] === T_STRING) { + $namespace .= '\\' . $tokens[$j][1]; + } + else { + if ($tokens[$j] === '{' || $tokens[$j] === ';') { + break; + } + } + } } + + if ($tokens[$i][0] === T_CLASS) { + for ($j = $i + 1; $j < count($tokens); $j++) { + if ($tokens[$j] === '{') { + $class = $tokens[$i + 2][1]; + } + } + } + } + + if ($namespace && $class) { + return $namespace . '\\' . $class; } - return $classes; } /**