summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/registry.inc23
-rw-r--r--modules/aggregator/aggregator.info1
-rw-r--r--modules/block/block.api.php46
-rw-r--r--modules/block/block.info1
-rw-r--r--modules/block/block.module125
-rw-r--r--modules/block/block.test31
-rw-r--r--modules/blog/blog.info1
-rw-r--r--modules/blogapi/blogapi.info1
-rw-r--r--modules/book/book.info1
-rw-r--r--modules/comment/comment.info1
-rw-r--r--modules/contact/contact.info1
-rw-r--r--modules/dblog/dblog.info1
-rw-r--r--modules/field/field.info1
-rw-r--r--modules/field/modules/field_sql_storage/field_sql_storage.info1
-rw-r--r--modules/field/modules/text/text.info3
-rw-r--r--modules/filter/filter.info1
-rw-r--r--modules/forum/forum.info1
-rw-r--r--modules/help/help.info1
-rw-r--r--modules/locale/locale.info1
-rw-r--r--modules/menu/menu.info1
-rw-r--r--modules/node/node.info1
-rw-r--r--modules/openid/openid.info1
-rw-r--r--modules/path/path.info1
-rw-r--r--modules/php/php.info1
-rw-r--r--modules/poll/poll.info1
-rw-r--r--modules/profile/profile.info1
-rw-r--r--modules/simpletest/simpletest.info23
-rw-r--r--modules/simpletest/simpletest.module120
-rw-r--r--modules/simpletest/simpletest.pages.inc17
-rw-r--r--modules/simpletest/tests/graph.test2
-rw-r--r--modules/statistics/statistics.info1
-rw-r--r--modules/syslog/syslog.info1
-rw-r--r--modules/system/system.api.php53
-rw-r--r--modules/system/system.info1
-rw-r--r--modules/taxonomy/taxonomy.info1
-rw-r--r--modules/tracker/tracker.info1
-rw-r--r--modules/translation/translation.info1
-rw-r--r--modules/trigger/trigger.info1
-rw-r--r--modules/upload/upload.info1
-rw-r--r--modules/user/user.info1
-rwxr-xr-xscripts/run-tests.sh12
41 files changed, 371 insertions, 114 deletions
diff --git a/includes/registry.inc b/includes/registry.inc
index cfc7ae118..89de42356 100644
--- a/includes/registry.inc
+++ b/includes/registry.inc
@@ -45,11 +45,19 @@ function _registry_rebuild() {
system_get_files_database($modules, 'module');
// Get the list of files we are going to parse.
$files = array();
- foreach ($modules as $module) {
+ foreach ($modules as &$module) {
+ $dir = dirname($module->filepath);
+
+ // Store the module directory for use in hook_registry_files_alter().
+ $module->dir = $dir;
+
+ // Parse the .info file for all modules, reguardless of their status so the
+ // list of files can then be used in hook_registry_files_alter()
+ // implementations.
+ $module->info = drupal_parse_info_file($dir . '/' . $module->name . '.info');
+
if ($module->status) {
- // Parse .info file only for enabled modules.
- $module->info = drupal_parse_info_file(dirname($module->filepath) . '/' . $module->name . '.info');
- $dir = dirname($module->filepath);
+ // Add files for enabled modules to the registry.
foreach ($module->info['files'] as $file) {
$files["$dir/$file"] = array('module' => $module->name, 'weight' => $module->weight);
}
@@ -59,6 +67,13 @@ function _registry_rebuild() {
$files["$filename"] = array('module' => '', 'weight' => 0);
}
+ // Allow modules to manually modify the list of files before the registry
+ // parses them. The $modules array provides the .info file information, which
+ // includes the list of files registered to each module. Any files in the
+ // list can then be added to the list of files that the registry will parse,
+ // or modify attributes of a file.
+ drupal_alter('registry_files', $files, $modules);
+
foreach (registry_get_parsed_files() as $filename => $file) {
// Add the md5 to those files we've already parsed.
if (isset($files[$filename])) {
diff --git a/modules/aggregator/aggregator.info b/modules/aggregator/aggregator.info
index fb65a7fa9..2b75e247a 100644
--- a/modules/aggregator/aggregator.info
+++ b/modules/aggregator/aggregator.info
@@ -11,3 +11,4 @@ files[] = aggregator.fetcher.inc
files[] = aggregator.parser.inc
files[] = aggregator.processor.inc
files[] = aggregator.install
+files[] = aggregator.test
diff --git a/modules/block/block.api.php b/modules/block/block.api.php
index 5540302e8..c1f5d6145 100644
--- a/modules/block/block.api.php
+++ b/modules/block/block.api.php
@@ -172,5 +172,51 @@ function hook_block_view($delta = '') {
}
/**
+ * Act on blocks prior to rendering.
+ *
+ * This hook allows you to add, remove or modify blocks in the block list. The
+ * block list contains the block definitions not the rendered blocks. The blocks
+ * are rendered after the modules have had a chance to manipulate the block
+ * list.
+ * Alternatively you can set $block->content here, which will override the
+ * content of the block and prevent hook_block_view() from running.
+ *
+ * @param $blocks
+ * An array of $blocks, keyed by $bid
+ *
+ * This example shows how to achieve language specific visibility setting for
+ * blocks.
+ */
+function hook_block_list_alter(&$blocks) {
+ global $language, $theme_key;
+
+ $result = db_query('SELECT module, delta, language FROM {my_table}');
+ $block_languages = array();
+ foreach ($result as $record) {
+ $block_languages[$record->module][$record->delta][$record->language] = TRUE;
+ }
+
+ foreach ($blocks as $key => $block) {
+ // Any module using this alter should inspect the data before changing it,
+ // to ensure it is what they expect.
+ if ($block->theme != $theme_key || $block->status != 1) {
+ // This block was added by a contrib module, leave it in the list.
+ continue;
+ }
+
+ if (!isset($block_languages[$block->module][$block->delta])) {
+ // No language setting for this block, leave it in the list.
+ continue;
+ }
+
+ if (!isset($block_languages[$block->module][$block->delta][$language->language])) {
+ // This block should not be displayed with the active language, remove
+ // from the list.
+ unset($blocks[$key]);
+ }
+ }
+}
+
+/**
* @} End of "addtogroup hooks".
*/
diff --git a/modules/block/block.info b/modules/block/block.info
index a74f5d721..bb14187aa 100644
--- a/modules/block/block.info
+++ b/modules/block/block.info
@@ -8,3 +8,4 @@ core = 7.x
files[] = block.module
files[] = block.admin.inc
files[] = block.install
+files[] = block.test
diff --git a/modules/block/block.module b/modules/block/block.module
index 13e9821ad..800737298 100644
--- a/modules/block/block.module
+++ b/modules/block/block.module
@@ -586,30 +586,64 @@ function block_list($region) {
* Load blocks information from the database.
*/
function _block_load_blocks() {
- global $user, $theme_key;
+ global $theme_key;
- $blocks = array();
- $rids = array_keys($user->roles);
$query = db_select('block', 'b');
- $query->leftJoin('block_role', 'r', 'b.module = r.module AND b.delta = r.delta');
$result = $query
- ->distinct()
->fields('b')
->condition('b.theme', $theme_key)
->condition('b.status', 1)
- ->condition(db_or()
- ->condition('r.rid', $rids, 'IN')
- ->isNull('r.rid')
- )
->orderBy('b.region')
->orderBy('b.weight')
->orderBy('b.module')
->addTag('block_load')
->execute();
- foreach ($result as $block) {
- if (!isset($blocks[$block->region])) {
- $blocks[$block->region] = array();
+
+ $block_list = $result->fetchAllAssoc('bid');
+ // Allow modules to modify the block list.
+ drupal_alter('block_list', $block_list);
+
+ $blocks = array();
+ foreach ($block_list as $block) {
+ $blocks[$block->region]["{$block->module}_{$block->delta}"] = $block;
+ }
+ return $blocks;
+}
+
+/**
+ * Implement hook_block_list_alter().
+ *
+ * Check the page, role and user specific visibilty settings. Remove the block
+ * if the visibility conditions are not met.
+ */
+function block_block_list_alter(&$blocks) {
+ global $user, $theme_key;
+
+ // Build an array of roles for each block.
+ $block_roles = array();
+ $result = db_query('SELECT module, delta, rid FROM {block_role}');
+ foreach ($result as $record) {
+ $block_roles[$record->module][$record->delta][] = $record->rid;
+ }
+
+ foreach ($blocks as $key => $block) {
+ if ($block->theme != $theme_key || $block->status != 1) {
+ // This block was added by a contrib module, leave it in the list.
+ continue;
}
+
+ // If a block has no roles associated, it is displayed for every role.
+ // For blocks with roles associated, if none of the user's roles matches
+ // the settings from this block, remove it from the block list.
+ if (!isset($block_roles[$block->module][$block->delta])) {
+ // No roles associated.
+ }
+ elseif (!array_intersect($block_roles[$block->module][$block->delta], array_keys($user->roles))) {
+ // No match.
+ unset($blocks[$key]);
+ continue;
+ }
+
// Use the user's block visibility setting, if necessary.
if ($block->custom != 0) {
if ($user->uid && isset($user->block[$block->module][$block->delta])) {
@@ -622,6 +656,10 @@ function _block_load_blocks() {
else {
$enabled = TRUE;
}
+ if (!$enabled) {
+ unset($blocks[$key]);
+ continue;
+ }
// Match path if necessary.
if ($block->pages) {
@@ -647,12 +685,10 @@ function _block_load_blocks() {
else {
$page_match = TRUE;
}
- $block->enabled = $enabled;
- $block->page_match = $page_match;
- $blocks[$block->region]["{$block->module}_{$block->delta}"] = $block;
+ if (!$page_match) {
+ unset($blocks[$key]);
+ }
}
-
- return $blocks;
}
/**
@@ -668,38 +704,39 @@ function _block_render_blocks($region_blocks) {
foreach ($region_blocks as $key => $block) {
// Render the block content if it has not been created already.
if (!isset($block->content)) {
- // Erase the block from the static array - we'll put it back if it has content.
+ // Erase the block from the static array - we'll put it back if it has
+ // content.
unset($region_blocks[$key]);
- if ($block->enabled && $block->page_match) {
- // Try fetching the block from cache. Block caching is not compatible with
- // node_access modules. We also preserve the submission of forms in blocks,
- // by fetching from cache only if the request method is 'GET' (or 'HEAD').
- if (!count(module_implements('node_grants')) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD') && ($cid = _block_get_cache_id($block)) && ($cache = cache_get($cid, 'cache_block'))) {
- $array = $cache->data;
- }
- else {
- $array = module_invoke($block->module, 'block_view', $block->delta);
- if (isset($cid)) {
- cache_set($cid, $array, 'cache_block', CACHE_TEMPORARY);
- }
+ // Try fetching the block from cache. Block caching is not compatible
+ // with node_access modules. We also preserve the submission of forms in
+ // blocks, by fetching from cache only if the request method is 'GET'
+ // (or 'HEAD').
+ if (!count(module_implements('node_grants')) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD') && ($cid = _block_get_cache_id($block)) && ($cache = cache_get($cid, 'cache_block'))) {
+ $array = $cache->data;
+ }
+ else {
+ $array = module_invoke($block->module, 'block_view', $block->delta);
+ if (isset($cid)) {
+ cache_set($cid, $array, 'cache_block', CACHE_TEMPORARY);
}
+ }
- if (isset($array) && is_array($array)) {
- foreach ($array as $k => $v) {
- $block->$k = $v;
- }
+ if (isset($array) && is_array($array)) {
+ foreach ($array as $k => $v) {
+ $block->$k = $v;
}
- if (isset($block->content) && $block->content) {
- // Override default block title if a custom display title is present.
- if ($block->title) {
- // Check plain here to allow module generated titles to keep any markup.
- $block->subject = $block->title == '<none>' ? '' : check_plain($block->title);
- }
- if (!isset($block->subject)) {
- $block->subject = '';
- }
- $region_blocks["{$block->module}_{$block->delta}"] = $block;
+ }
+ if (isset($block->content) && $block->content) {
+ // Override default block title if a custom display title is present.
+ if ($block->title) {
+ // Check plain here to allow module generated titles to keep any
+ // markup.
+ $block->subject = $block->title == '<none>' ? '' : check_plain($block->title);
+ }
+ if (!isset($block->subject)) {
+ $block->subject = '';
}
+ $region_blocks["{$block->module}_{$block->delta}"] = $block;
}
}
}
diff --git a/modules/block/block.test b/modules/block/block.test
index 9dcd199b6..73d256ac0 100644
--- a/modules/block/block.test
+++ b/modules/block/block.test
@@ -100,6 +100,37 @@ class BlockTestCase extends DrupalWebTestCase {
}
/**
+ * Test block visibility.
+ */
+ function testBlockVisibility() {
+ $block = array();
+ $block['title'] = 'Syndicate';
+ $block['module'] = 'node';
+ $block['delta'] = 'syndicate';
+
+ // Set the block to be hidden on any user path, and to be shown only to
+ // authenticated users.
+ $edit = array();
+ $edit['pages'] = 'user*';
+ $edit['roles[2]'] = TRUE;
+ $this->drupalPost('admin/build/block/configure/' . $block['module'] . '/' . $block['delta'], $edit, t('Save block'));
+
+ // Move block to the left sidebar.
+ $this->moveBlockToRegion($block, $this->regions[1]);
+
+ $this->drupalGet('');
+ $this->assertText('Syndicate', t('Block was displayed on the front page.'));
+
+ $this->drupalGet('user*');
+ $this->assertNoText('Syndicate', t('Block was not displayed according to block visibility rules.'));
+
+ // Confirm that the block is not displayed to anonymous users.
+ $this->drupalLogout();
+ $this->drupalGet('');
+ $this->assertNoText('Syndicate', t('Block was not displayed to anonymous users.'));
+ }
+
+ /**
* Test configuring and moving a module-define block to specific regions.
*/
function testBlock() {
diff --git a/modules/blog/blog.info b/modules/blog/blog.info
index 2d047f304..938993c0e 100644
--- a/modules/blog/blog.info
+++ b/modules/blog/blog.info
@@ -7,3 +7,4 @@ version = VERSION
core = 7.x
files[] = blog.module
files[] = blog.pages.inc
+files[] = blog.test
diff --git a/modules/blogapi/blogapi.info b/modules/blogapi/blogapi.info
index 257ffd25b..87e365e5b 100644
--- a/modules/blogapi/blogapi.info
+++ b/modules/blogapi/blogapi.info
@@ -7,3 +7,4 @@ version = VERSION
core = 7.x
files[] = blogapi.module
files[] = blogapi.install
+files[] = blogapi.test
diff --git a/modules/book/book.info b/modules/book/book.info
index e44458005..b30b4a59e 100644
--- a/modules/book/book.info
+++ b/modules/book/book.info
@@ -9,3 +9,4 @@ files[] = book.module
files[] = book.admin.inc
files[] = book.pages.inc
files[] = book.install
+files[] = book.test
diff --git a/modules/comment/comment.info b/modules/comment/comment.info
index 762371307..71a62e3ed 100644
--- a/modules/comment/comment.info
+++ b/modules/comment/comment.info
@@ -9,3 +9,4 @@ files[] = comment.module
files[] = comment.admin.inc
files[] = comment.pages.inc
files[] = comment.install
+files[] = comment.test
diff --git a/modules/contact/contact.info b/modules/contact/contact.info
index 750e18176..fda41ae0f 100644
--- a/modules/contact/contact.info
+++ b/modules/contact/contact.info
@@ -8,3 +8,4 @@ files[] = contact.module
files[] = contact.admin.inc
files[] = contact.pages.inc
files[] = contact.install
+files[] = contact.test
diff --git a/modules/dblog/dblog.info b/modules/dblog/dblog.info
index 5e9d284a7..6b9f82390 100644
--- a/modules/dblog/dblog.info
+++ b/modules/dblog/dblog.info
@@ -7,3 +7,4 @@ core = 7.x
files[] = dblog.module
files[] = dblog.admin.inc
files[] = dblog.install
+files[] = dblog.test
diff --git a/modules/field/field.info b/modules/field/field.info
index 76f6687b3..9c06c1760 100644
--- a/modules/field/field.info
+++ b/modules/field/field.info
@@ -11,5 +11,6 @@ files[] = field.info.inc
files[] = field.default.inc
files[] = field.attach.inc
files[] = field.form.inc
+files[] = field.test
dependencies[] = field_sql_storage
required = TRUE
diff --git a/modules/field/modules/field_sql_storage/field_sql_storage.info b/modules/field/modules/field_sql_storage/field_sql_storage.info
index 4d0f4a575..5587fbe32 100644
--- a/modules/field/modules/field_sql_storage/field_sql_storage.info
+++ b/modules/field/modules/field_sql_storage/field_sql_storage.info
@@ -6,4 +6,5 @@ version = VERSION
core = 7.x
files[] = field_sql_storage.module
files[] = field_sql_storage.install
+files[] = field_sql_storage.test
required = TRUE
diff --git a/modules/field/modules/text/text.info b/modules/field/modules/text/text.info
index 328bfc3f8..17a676025 100644
--- a/modules/field/modules/text/text.info
+++ b/modules/field/modules/text/text.info
@@ -4,4 +4,5 @@ description = Defines simple text field types.
package = Core - fields
version = VERSION
core = 7.x
-files[]=text.module
+files[] = text.module
+files[] = text.test
diff --git a/modules/filter/filter.info b/modules/filter/filter.info
index 05d996a0b..ecd3de188 100644
--- a/modules/filter/filter.info
+++ b/modules/filter/filter.info
@@ -8,4 +8,5 @@ files[] = filter.module
files[] = filter.admin.inc
files[] = filter.pages.inc
files[] = filter.install
+files[] = filter.test
required = TRUE
diff --git a/modules/forum/forum.info b/modules/forum/forum.info
index 27c588bc7..ff4621a5f 100644
--- a/modules/forum/forum.info
+++ b/modules/forum/forum.info
@@ -10,3 +10,4 @@ files[] = forum.module
files[] = forum.admin.inc
files[] = forum.pages.inc
files[] = forum.install
+files[] = forum.test
diff --git a/modules/help/help.info b/modules/help/help.info
index e5ece02c6..4c84b2621 100644
--- a/modules/help/help.info
+++ b/modules/help/help.info
@@ -6,3 +6,4 @@ version = VERSION
core = 7.x
files[] = help.module
files[] = help.admin.inc
+files[] = help.test
diff --git a/modules/locale/locale.info b/modules/locale/locale.info
index 2638c4960..02b86521d 100644
--- a/modules/locale/locale.info
+++ b/modules/locale/locale.info
@@ -6,3 +6,4 @@ version = VERSION
core = 7.x
files[] = locale.module
files[] = locale.install
+files[] = locale.test
diff --git a/modules/menu/menu.info b/modules/menu/menu.info
index 31bd386e6..f3db2a75b 100644
--- a/modules/menu/menu.info
+++ b/modules/menu/menu.info
@@ -7,3 +7,4 @@ core = 7.x
files[] = menu.module
files[] = menu.admin.inc
files[] = menu.install
+files[] = menu.test
diff --git a/modules/node/node.info b/modules/node/node.info
index 975b5dcc5..2f62a9901 100644
--- a/modules/node/node.info
+++ b/modules/node/node.info
@@ -9,4 +9,5 @@ files[] = content_types.inc
files[] = node.admin.inc
files[] = node.pages.inc
files[] = node.install
+files[] = node.test
required = TRUE
diff --git a/modules/openid/openid.info b/modules/openid/openid.info
index 4d14448a0..9335fa8ba 100644
--- a/modules/openid/openid.info
+++ b/modules/openid/openid.info
@@ -9,3 +9,4 @@ files[] = openid.inc
files[] = openid.pages.inc
files[] = xrds.inc
files[] = openid.install
+files[] = openid.test
diff --git a/modules/path/path.info b/modules/path/path.info
index 7453923d8..ee05f40f0 100644
--- a/modules/path/path.info
+++ b/modules/path/path.info
@@ -6,3 +6,4 @@ version = VERSION
core = 7.x
files[] = path.module
files[] = path.admin.inc
+files[] = path.test
diff --git a/modules/php/php.info b/modules/php/php.info
index e353bf9b8..2f1588340 100644
--- a/modules/php/php.info
+++ b/modules/php/php.info
@@ -6,3 +6,4 @@ version = VERSION
core = 7.x
files[] = php.module
files[] = php.install
+files[] = php.test
diff --git a/modules/poll/poll.info b/modules/poll/poll.info
index 9aff7b502..d59cc9b93 100644
--- a/modules/poll/poll.info
+++ b/modules/poll/poll.info
@@ -7,3 +7,4 @@ core = 7.x
files[] = poll.module
files[] = poll.pages.inc
files[] = poll.install
+files[] = poll.test
diff --git a/modules/profile/profile.info b/modules/profile/profile.info
index 522284781..7e6e511ec 100644
--- a/modules/profile/profile.info
+++ b/modules/profile/profile.info
@@ -8,3 +8,4 @@ files[] = profile.module
files[] = profile.admin.inc
files[] = profile.pages.inc
files[] = profile.install
+files[] = profile.test
diff --git a/modules/simpletest/simpletest.info b/modules/simpletest/simpletest.info
index 0fefa967d..a90e5dd2c 100644
--- a/modules/simpletest/simpletest.info
+++ b/modules/simpletest/simpletest.info
@@ -7,3 +7,26 @@ core = 7.x
files[] = simpletest.module
files[] = simpletest.pages.inc
files[] = simpletest.install
+files[] = simpletest.test
+files[] = drupal_web_test_case.php
+
+; Tests in tests directory.
+files[] = tests/actions.test
+files[] = tests/batch.test
+files[] = tests/bootstrap.test
+files[] = tests/cache.test
+files[] = tests/common.test
+files[] = tests/database_test.test
+files[] = tests/error.test
+files[] = tests/file.test
+files[] = tests/form.test
+files[] = tests/graph.test
+files[] = tests/image.test
+files[] = tests/menu.test
+files[] = tests/module.test
+files[] = tests/registry.test
+files[] = tests/schema.test
+files[] = tests/session.test
+files[] = tests/theme.test
+files[] = tests/unicode.test
+files[] = tests/xmlrpc.test
diff --git a/modules/simpletest/simpletest.module b/modules/simpletest/simpletest.module
index 1300c2416..630ddb3f3 100644
--- a/modules/simpletest/simpletest.module
+++ b/modules/simpletest/simpletest.module
@@ -139,9 +139,6 @@ function simpletest_run_tests($test_list, $reporter = 'drupal') {
* Batch operation callback.
*/
function _simpletest_batch_operation($test_list_init, $test_id, &$context) {
- // Ensure that all classes are loaded before we unserialize some instances.
- simpletest_get_all_tests();
-
// Get working values.
if (!isset($context['sandbox']['max'])) {
// First iteration: initialize working values.
@@ -200,65 +197,94 @@ function _simpletest_batch_finished($success, $results, $operations, $elapsed) {
}
/**
- * Get a list of all of the tests.
+ * Get a list of all of the tests provided by the system.
+ *
+ * The list of test classes is loaded from the registry where it looks for
+ * files ending in ".test". Once loaded the test list is cached and stored in
+ * a static variable. In order to list tests provided by disabled modules
+ * hook_registry_files_alter() is used to forcefully add them to the registry.
*
* @return
- * An array of tests, with the class name as the keys and the instantiated
- * versions of the classes as the values.
+ * An array of tests keyed with the groups specified in each of the tests
+ * getInfo() method and then keyed by the test class. An example of the array
+ * structure is provided below.
+ *
+ * @code
+ * $groups['Blog'] => array(
+ * 'BlogTestCase' => array(
+ * 'name' => 'Blog functionality',
+ * 'description' => 'Create, view, edit, delete, ...',
+ * 'group' => 'Blog',
+ * ),
+ * );
+ * @endcode
+ * @see simpletest_registry_files_alter()
*/
-function simpletest_get_all_tests() {
- static $classes;
- if (!isset($classes)) {
- require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'simpletest') . '/drupal_web_test_case.php';
- $files = array();
- foreach (array_keys(system_get_module_data()) as $module) {
- $module_path = drupal_get_path('module', $module);
- $test = $module_path . "/$module.test";
- if (file_exists($test)) {
- $files[] = $test;
- }
+function simpletest_test_get_all() {
+ $groups = &drupal_static(__FUNCTION__);
+
+ if (!$groups) {
+ // Load test information from cache if available, otherwise retrieve the
+ // information from each tests getInfo() method.
+ if ($cache = cache_get('simpletest', 'cache')) {
+ $groups = $cache->data;
+ }
+ else {
+ // Select all clases in files ending with .test.
+ $classes = db_select('registry')
+ ->fields('registry', array('name'))
+ ->condition('type', 'class')
+ ->condition('filename', '%.test', 'LIKE')
+ ->execute();
- $tests_directory = $module_path . '/tests';
- if (is_dir($tests_directory)) {
- foreach (file_scan_directory($tests_directory, '/\.test$/') as $file) {
- $files[] = $file->filepath;
+ $groups = array();
+
+ // Check that each class has a getInfo() method and store the information
+ // in an array keyed with the group specified in the test information.
+ foreach ($classes as $class) {
+ $class = $class->name;
+ if (class_exists($class) && method_exists($class, 'getInfo')) {
+ // Valid test class, retrieve test information.
+ $info = call_user_func(array($class, 'getInfo'));
+
+ // Initialize test groups.
+ if (!isset($groups[$info['group']])) {
+ $groups[$info['group']] = array();
+ }
+ $groups[$info['group']][$class] = $info;
}
}
- }
-
- $existing_classes = get_declared_classes();
- foreach ($files as $file) {
- include_once DRUPAL_ROOT . '/' . $file;
- }
- $classes = array_values(array_diff(get_declared_classes(), $existing_classes));
- foreach ($classes as $key => $class) {
- if (!is_subclass_of($class, 'DrupalTestCase') || !method_exists($class, 'getInfo')) {
- unset($classes[$key]);
+ // Sort the groups and tests within the groups by name.
+ uksort($groups, 'strnatcasecmp');
+ foreach ($groups as $group => &$tests) {
+ uksort($tests, 'strnatcasecmp');
}
+
+ cache_set('simpletest', $groups);
}
}
- if (count($classes) == 0) {
- drupal_set_message('No test cases found.', 'error');
- return FALSE;
- }
- return $classes;
+ return $groups;
}
/**
- * Categorize the tests into groups.
+ * Implementation of hook_registry_files_alter().
*
- * @param $tests
- * A list of tests from simpletest_get_all_tests.
- * @see simpletest_get_all_tests.
+ * Add the test files for disabled modules so that we get a list containing
+ * all the avialable tests.
*/
-function simpletest_categorize_tests($tests) {
- $groups = array();
- foreach ($tests as $test) {
- $info = call_user_func(array($test, 'getInfo'));
- $groups[$info['group']][$test] = $info;
+function simpletest_registry_files_alter(&$files, $modules) {
+ foreach ($modules as $module) {
+ // Only add test files for disabled modules, as enabled modules should
+ // already include any test files they provide.
+ if (!$module->status) {
+ $dir = $module->dir;
+ foreach ($module->info['files'] as $file) {
+ if (substr($file, -5) == '.test') {
+ $files["$dir/$file"] = array('module' => $module->name, 'weight' => $module->weight);
+ }
+ }
+ }
}
- uksort($groups, 'strnatcasecmp');
- return $groups;
}
/**
diff --git a/modules/simpletest/simpletest.pages.inc b/modules/simpletest/simpletest.pages.inc
index 24a779348..2df1765fa 100644
--- a/modules/simpletest/simpletest.pages.inc
+++ b/modules/simpletest/simpletest.pages.inc
@@ -12,10 +12,6 @@
function simpletest_test_form() {
$form = array();
- // Categorize the tests for display.
- $uncategorized_tests = simpletest_get_all_tests();
- $tests = simpletest_categorize_tests($uncategorized_tests);
-
$form['tests'] = array(
'#type' => 'fieldset',
'#title' => t('Tests'),
@@ -27,13 +23,14 @@ function simpletest_test_form() {
);
// Generate the list of tests arranged by group.
- foreach ($tests as $group_name => $test_group) {
- $form['tests']['table'][$group_name] = array(
+ $groups = simpletest_test_get_all();
+ foreach ($groups as $group => $tests) {
+ $form['tests']['table'][$group] = array(
'#collapsed' => TRUE,
);
- foreach ($test_group as $class => $info) {
- $form['tests']['table'][$group_name][$class] = array(
+ foreach ($tests as $class => $info) {
+ $form['tests']['table'][$group][$class] = array(
'#type' => 'checkbox',
'#title' => $info['name'],
'#description' => $info['description'],
@@ -166,9 +163,6 @@ function theme_simpletest_test_table($table) {
* Run selected tests.
*/
function simpletest_test_form_submit($form, &$form_state) {
- // Ensure that all classes are loaded before we create instances to get test information and run.
- simpletest_get_all_tests();
-
// Get list of tests.
$tests_list = array();
foreach ($form_state['values'] as $class_name => $value) {
@@ -200,7 +194,6 @@ function simpletest_result_form(&$form_state, $test_id) {
// Load all classes and include CSS.
drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css');
- simpletest_get_all_tests();
// Keep track of which test cases passed or failed.
$filter = array(
diff --git a/modules/simpletest/tests/graph.test b/modules/simpletest/tests/graph.test
index a5ed9314b..b3270f843 100644
--- a/modules/simpletest/tests/graph.test
+++ b/modules/simpletest/tests/graph.test
@@ -23,7 +23,7 @@ class GraphUnitTest extends DrupalUnitTestCase {
*/
function testDepthFirstSearch() {
// Provoke the inclusion of graph.inc.
- drupal_function_exists('drupal_depth_first_search');
+ require_once 'includes/graph.inc';
// The sample graph used is:
// 1 --> 2 --> 3 5 ---> 6
diff --git a/modules/statistics/statistics.info b/modules/statistics/statistics.info
index aaeb7d015..a3a509124 100644
--- a/modules/statistics/statistics.info
+++ b/modules/statistics/statistics.info
@@ -8,3 +8,4 @@ files[] = statistics.module
files[] = statistics.admin.inc
files[] = statistics.pages.inc
files[] = statistics.install
+files[] = statistics.test
diff --git a/modules/syslog/syslog.info b/modules/syslog/syslog.info
index 55ff66b26..ff6246aee 100644
--- a/modules/syslog/syslog.info
+++ b/modules/syslog/syslog.info
@@ -5,3 +5,4 @@ package = Core
version = VERSION
core = 7.x
files[] = syslog.module
+files[] = syslog.test
diff --git a/modules/system/system.api.php b/modules/system/system.api.php
index 0efcedbc3..1349a7b8f 100644
--- a/modules/system/system.api.php
+++ b/modules/system/system.api.php
@@ -1701,5 +1701,58 @@ function hook_disable() {
}
/**
+ * Perform necessary alterations to the list of files parsed by the registry.
+ *
+ * Modules can manually modify the list of files before the registry parses
+ * them. The $modules array provides the .info file information, which includes
+ * the list of files registered to each module. Any files in the list can then
+ * be added to the list of files that the registry will parse, or modify
+ * attributes of a file.
+ *
+ * A necessary alteration made by the core SimpleTest module is to force .test
+ * files provided by disabled modules into the list of files parsed by the
+ * registry.
+ *
+ * @param $files
+ * List of files to be parsed by the registry. The list will contain
+ * files found in each enabled module's info file and the core includes
+ * directory. The array is keyed by the file path and contains an array of
+ * the related module's name and weight as used internally by
+ * _registry_rebuild() and related functions.
+ *
+ * For example:
+ * @code
+ * $files["modules/system/system.module"] = array(
+ * 'module' => 'system',
+ * 'weight' => 0,
+ * );
+ * @endcode
+ * @param $modules
+ * List of all the modules provided as returned by drupal_system_listing().
+ * The list also contains the .info file information in the property 'info'.
+ * An additional 'dir' property has been added to the module information
+ * which provides the path to the directory in which the module resides. The
+ * example shows how to take advantage of the property both properties.
+ *
+ * @see _registry_rebuild()
+ * @see drupal_system_listing()
+ * @see simpletest_test_get_all()
+ */
+function hook_registry_files_alter(&$files, $module_cache) {
+ foreach ($modules as $module) {
+ // Only add test files for disabled modules, as enabled modules should
+ // already include any test files they provide.
+ if (!$module->status) {
+ $dir = $module->dir;
+ foreach ($module->info['files'] as $file) {
+ if (substr($file, -5) == '.test') {
+ $files["$dir/$file"] = array('module' => $module->name, 'weight' => $module->weight);
+ }
+ }
+ }
+ }
+}
+
+/**
* @} End of "addtogroup hooks".
*/
diff --git a/modules/system/system.info b/modules/system/system.info
index 0afcdaf9a..9c93a0960 100644
--- a/modules/system/system.info
+++ b/modules/system/system.info
@@ -9,4 +9,5 @@ files[] = system.admin.inc
files[] = system.queue.inc
files[] = image.gd.inc
files[] = system.install
+files[] = system.test
required = TRUE
diff --git a/modules/taxonomy/taxonomy.info b/modules/taxonomy/taxonomy.info
index 4d05fc442..35dfa1480 100644
--- a/modules/taxonomy/taxonomy.info
+++ b/modules/taxonomy/taxonomy.info
@@ -8,3 +8,4 @@ files[] = taxonomy.module
files[] = taxonomy.admin.inc
files[] = taxonomy.pages.inc
files[] = taxonomy.install
+files[] = taxonomy.test
diff --git a/modules/tracker/tracker.info b/modules/tracker/tracker.info
index b26cff055..f70550d37 100644
--- a/modules/tracker/tracker.info
+++ b/modules/tracker/tracker.info
@@ -7,3 +7,4 @@ version = VERSION
core = 7.x
files[] = tracker.module
files[] = tracker.pages.inc
+files[] = tracker.test
diff --git a/modules/translation/translation.info b/modules/translation/translation.info
index 63c2c1c63..3f6841c2a 100644
--- a/modules/translation/translation.info
+++ b/modules/translation/translation.info
@@ -7,3 +7,4 @@ version = VERSION
core = 7.x
files[] = translation.module
files[] = translation.pages.inc
+files[] = translation.test
diff --git a/modules/trigger/trigger.info b/modules/trigger/trigger.info
index 9ba7439f4..e097d59de 100644
--- a/modules/trigger/trigger.info
+++ b/modules/trigger/trigger.info
@@ -7,3 +7,4 @@ core = 7.x
files[] = trigger.module
files[] = trigger.admin.inc
files[] = trigger.install
+files[] = trigger.test
diff --git a/modules/upload/upload.info b/modules/upload/upload.info
index 92d04e09a..d5039f521 100644
--- a/modules/upload/upload.info
+++ b/modules/upload/upload.info
@@ -7,3 +7,4 @@ core = 7.x
files[] = upload.module
files[] = upload.admin.inc
files[] = upload.install
+files[] = upload.test
diff --git a/modules/user/user.info b/modules/user/user.info
index 98ef2dfb0..d4c24fa77 100644
--- a/modules/user/user.info
+++ b/modules/user/user.info
@@ -8,4 +8,5 @@ files[] = user.module
files[] = user.admin.inc
files[] = user.pages.inc
files[] = user.install
+files[] = user.test
required = TRUE
diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh
index 795c67886..ada07c75c 100755
--- a/scripts/run-tests.sh
+++ b/scripts/run-tests.sh
@@ -44,8 +44,11 @@ if ($args['clean']) {
}
// Load SimpleTest files.
-$all_tests = simpletest_get_all_tests();
-$groups = simpletest_categorize_tests($all_tests);
+$groups = simpletest_test_get_all();
+$all_tests = array();
+foreach ($groups as $group => $tests) {
+ $all_tests = array_merge($all_tests, array_keys($tests));
+}
$test_list = array();
if ($args['list']) {
@@ -54,8 +57,8 @@ if ($args['list']) {
echo "-------------------------------\n\n";
foreach ($groups as $group => $tests) {
echo $group . "\n";
- foreach ($tests as $class_name => $info) {
- echo " - " . $info['name'] . ' (' . $class_name . ')' . "\n";
+ foreach ($tests as $class => $info) {
+ echo " - " . $info['name'] . ' (' . $class . ')' . "\n";
}
}
exit;
@@ -339,7 +342,6 @@ function simpletest_script_execute_batch() {
* Run a single test (assume a Drupal bootstrapped environment).
*/
function simpletest_script_run_one_test($test_id, $test_class) {
- simpletest_get_all_tests();
$test = new $test_class($test_id);
$test->run();
$info = $test->getInfo();