Issue #2293767 by tstoeckler: Allow PSR-4 test classes to be used in Drupal 7.

merge-requests/26/head
David Rothstein 2015-03-29 16:59:36 -04:00
parent ab19278643
commit 731a540f83
8 changed files with 117 additions and 25 deletions

View File

@ -1,6 +1,8 @@
Drupal 7.36, xxxx-xx-xx (development version) Drupal 7.36, xxxx-xx-xx (development version)
----------------------- -----------------------
- Changed the Simpletest module to allow PSR-4 test classes to be used in
Drupal 7.
- Fixed a fatal error that occurred when using the Comment module's "Unpublish - Fixed a fatal error that occurred when using the Comment module's "Unpublish
comment containing keyword(s)" action. comment containing keyword(s)" action.
- Changed the "lang" attribute on language links to "xml:lang" so it validates - Changed the "lang" attribute on language links to "xml:lang" so it validates

View File

@ -328,25 +328,32 @@ function simpletest_test_get_all() {
// Also discover PSR-0 test classes, if the PHP version allows it. // Also discover PSR-0 test classes, if the PHP version allows it.
if (version_compare(PHP_VERSION, '5.3') > 0) { if (version_compare(PHP_VERSION, '5.3') > 0) {
// Select all PSR-0 classes in the Tests namespace of all modules. // Select all PSR-0 and PSR-4 classes in the Tests namespace of all
// modules.
$system_list = db_query("SELECT name, filename FROM {system}")->fetchAllKeyed(); $system_list = db_query("SELECT name, filename FROM {system}")->fetchAllKeyed();
foreach ($system_list as $name => $filename) { foreach ($system_list as $name => $filename) {
// Build directory in which the test files would reside. $module_dir = DRUPAL_ROOT . '/' . dirname($filename);
$tests_dir = DRUPAL_ROOT . '/' . dirname($filename) . '/lib/Drupal/' . $name . '/Tests'; // Search both the 'lib/Drupal/mymodule' directory (for PSR-0 classes)
// Scan it for test files if it exists. // and the 'src' directory (for PSR-4 classes).
if (is_dir($tests_dir)) { foreach(array('lib/Drupal/' . $name, 'src') as $subdir) {
$files = file_scan_directory($tests_dir, '/.*\.php/'); // Build directory in which the test files would reside.
if (!empty($files)) { $tests_dir = $module_dir . '/' . $subdir . '/Tests';
$basedir = DRUPAL_ROOT . '/' . dirname($filename) . '/lib/'; // Scan it for test files if it exists.
foreach ($files as $file) { if (is_dir($tests_dir)) {
// Convert the file name into the namespaced class name. $files = file_scan_directory($tests_dir, '/.*\.php/');
$replacements = array( if (!empty($files)) {
'/' => '\\', foreach ($files as $file) {
$basedir => '', // Convert the file name into the namespaced class name.
'.php' => '', $replacements = array(
); '/' => '\\',
$classes[] = strtr($file->uri, $replacements); $module_dir . '/' => '',
'lib/' => '',
'src/' => 'Drupal\\' . $name . '\\',
'.php' => '',
);
$classes[] = strtr($file->uri, $replacements);
}
} }
} }
} }
@ -406,17 +413,20 @@ function simpletest_classloader_register() {
// Only register PSR-0 class loading if we are on PHP 5.3 or higher. // Only register PSR-0 class loading if we are on PHP 5.3 or higher.
if (version_compare(PHP_VERSION, '5.3') > 0) { if (version_compare(PHP_VERSION, '5.3') > 0) {
spl_autoload_register('_simpletest_autoload_psr0'); spl_autoload_register('_simpletest_autoload_psr4_psr0');
} }
} }
/** /**
* Autoload callback to find PSR-0 test classes. * Autoload callback to find PSR-4 and PSR-0 test classes.
*
* Looks in the 'src/Tests' and in the 'lib/Drupal/mymodule/Tests' directory of
* modules for the class.
* *
* This will only work on classes where the namespace is of the pattern * This will only work on classes where the namespace is of the pattern
* "Drupal\$extension\Tests\.." * "Drupal\$extension\Tests\.."
*/ */
function _simpletest_autoload_psr0($class) { function _simpletest_autoload_psr4_psr0($class) {
// Static cache for extension paths. // Static cache for extension paths.
// This cache is lazily filled as soon as it is needed. // This cache is lazily filled as soon as it is needed.
@ -446,14 +456,26 @@ function _simpletest_autoload_psr0($class) {
$namespace = substr($class, 0, $nspos); $namespace = substr($class, 0, $nspos);
$classname = substr($class, $nspos + 1); $classname = substr($class, $nspos + 1);
// Build the filepath where we expect the class to be defined. // Try the PSR-4 location first, and the PSR-0 location as a fallback.
$path = dirname($extensions[$extension]) . '/lib/' . // Build the PSR-4 filepath where we expect the class to be defined.
str_replace('\\', '/', $namespace) . '/' . $psr4_path = dirname($extensions[$extension]) . '/src/' .
str_replace('\\', '/', substr($namespace, strlen('Drupal\\' . $extension . '\\'))) . '/' .
str_replace('_', '/', $classname) . '.php'; str_replace('_', '/', $classname) . '.php';
// Include the file, if it does exist. // Include the file, if it does exist.
if (file_exists($path)) { if (file_exists($psr4_path)) {
include $path; include $psr4_path;
}
else {
// Build the PSR-0 filepath where we expect the class to be defined.
$psr0_path = dirname($extensions[$extension]) . '/lib/' .
str_replace('\\', '/', $namespace) . '/' .
str_replace('_', '/', $classname) . '.php';
// Include the file, if it does exist.
if (file_exists($psr0_path)) {
include $psr0_path;
}
} }
} }
} }

View File

@ -703,7 +703,9 @@ class SimpleTestDiscoveryTestCase extends DrupalWebTestCase {
$classes_all = simpletest_test_get_all(); $classes_all = simpletest_test_get_all();
foreach (array( foreach (array(
'Drupal\\simpletest\\Tests\\PSR0WebTest', 'Drupal\\simpletest\\Tests\\PSR0WebTest',
'Drupal\\simpletest\\Tests\\PSR4WebTest',
'Drupal\\psr_0_test\\Tests\\ExampleTest', 'Drupal\\psr_0_test\\Tests\\ExampleTest',
'Drupal\\psr_4_test\\Tests\\ExampleTest',
) as $class) { ) as $class) {
$this->assert(!empty($classes_all['SimpleTest'][$class]), t('Class @class must be discovered by simpletest_test_get_all().', array('@class' => $class))); $this->assert(!empty($classes_all['SimpleTest'][$class]), t('Class @class must be discovered by simpletest_test_get_all().', array('@class' => $class)));
} }
@ -726,15 +728,20 @@ class SimpleTestDiscoveryTestCase extends DrupalWebTestCase {
// Don't expect PSR-0 tests to be discovered on older PHP versions. // Don't expect PSR-0 tests to be discovered on older PHP versions.
return; return;
} }
// This one is provided by simpletest itself via PSR-0. // These are provided by simpletest itself via PSR-0 and PSR-4.
$this->assertText('PSR0 web test'); $this->assertText('PSR0 web test');
$this->assertText('PSR4 web test');
$this->assertText('PSR0 example test: PSR-0 in disabled modules.'); $this->assertText('PSR0 example test: PSR-0 in disabled modules.');
$this->assertText('PSR4 example test: PSR-4 in disabled modules.');
$this->assertText('PSR0 example test: PSR-0 in nested subfolders.'); $this->assertText('PSR0 example test: PSR-0 in nested subfolders.');
$this->assertText('PSR4 example test: PSR-4 in nested subfolders.');
// Test each test individually. // Test each test individually.
foreach (array( foreach (array(
'Drupal\\psr_0_test\\Tests\\ExampleTest', 'Drupal\\psr_0_test\\Tests\\ExampleTest',
'Drupal\\psr_0_test\\Tests\\Nested\\NestedExampleTest', 'Drupal\\psr_0_test\\Tests\\Nested\\NestedExampleTest',
'Drupal\\psr_4_test\\Tests\\ExampleTest',
'Drupal\\psr_4_test\\Tests\\Nested\\NestedExampleTest',
) as $class) { ) as $class) {
$this->drupalGet('admin/config/development/testing'); $this->drupalGet('admin/config/development/testing');
$edit = array($class => TRUE); $edit = array($class => TRUE);

View File

@ -0,0 +1,18 @@
<?php
namespace Drupal\simpletest\Tests;
class PSR4WebTest extends \DrupalWebTestCase {
public static function getInfo() {
return array(
'name' => 'PSR4 web test',
'description' => 'We want to assert that this PSR-4 test case is being discovered.',
'group' => 'SimpleTest',
);
}
function testArithmetics() {
$this->assert(1 + 1 == 2, '1 + 1 == 2');
}
}

View File

@ -0,0 +1,6 @@
name = PSR-4 Test cases
description = Test classes to be discovered by simpletest.
core = 7.x
hidden = TRUE
package = Testing

View File

@ -0,0 +1 @@
<?php

View File

@ -0,0 +1,18 @@
<?php
namespace Drupal\psr_4_test\Tests;
class ExampleTest extends \DrupalWebTestCase {
public static function getInfo() {
return array(
'name' => 'PSR4 example test: PSR-4 in disabled modules.',
'description' => 'We want to assert that this test case is being discovered.',
'group' => 'SimpleTest',
);
}
function testArithmetics() {
$this->assert(1 + 1 == 2, '1 + 1 == 2');
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace Drupal\psr_4_test\Tests\Nested;
class NestedExampleTest extends \DrupalWebTestCase {
public static function getInfo() {
return array(
'name' => 'PSR4 example test: PSR-4 in nested subfolders.',
'description' => 'We want to assert that this PSR-4 test case is being discovered.',
'group' => 'SimpleTest',
);
}
function testArithmetics() {
$this->assert(1 + 1 == 2, '1 + 1 == 2');
}
}