=== added file 'includes/graph.inc' --- includes/graph.inc 1970-01-01 00:00:00 +0000 +++ includes/graph.inc 2008-09-29 19:54:15 +0000 @@ -0,0 +1,60 @@ + $data) { + $roots = array_diff_key($roots, $data['edges']); + } + } + foreach ($roots as $start) { + if (!empty($graph[$start]['edges'])) { + _drupal_depth_first_search($graph, $start); + } + } +} + +function _drupal_depth_first_search(&$graph, $start, $reverse_path = array()) { + $reverse_path[$start] = TRUE; + $graph[$start]['paths'] = array(); + foreach ($graph[$start]['edges'] as $end => $v) { + $graph[$start]['paths'][$end] = TRUE; + if (!isset($graph[$end]['reverse_paths'])) { + $graph[$end]['reverse_paths'] = array(); + } + $graph[$end]['reverse_paths'] += $reverse_path; + if (isset($graph[$end]['reverse_paths'][$end])) { + echo 'cycle'; + exit; + } + $graph[$start]['paths'] += _drupal_depth_first_search($graph, $end, $reverse_path); + } + return $graph[$start]['paths']; +} === modified file 'includes/module.inc' --- includes/module.inc 2008-10-12 04:30:05 +0000 +++ includes/module.inc 2008-10-13 00:26:05 +0000 @@ -138,69 +138,34 @@ function module_rebuild_cache() { } /** - * Find dependencies any level deep and fill in dependents information too. - * - * If module A depends on B which in turn depends on C then this function will - * add C to the list of modules A depends on. This will be repeated until - * module A has a list of all modules it depends on. If it depends on itself, - * called a circular dependency, that's marked by adding a nonexistent module, - * called -circular- to this list of modules. Because this does not exist, - * it'll be impossible to switch module A on. - * - * Also we fill in a dependents array in $file->info. Using the names above, - * the dependents array of module B lists A. + * Find dependencies any level deep and fill in required by information too. * * @param $files * The array of filesystem objects used to rebuild the cache. * @return - * The same array with dependencies and dependents added where applicable. + * The same array with the new keys for each module: + * depends_on is an array with the keys being the modules that this module + * depends on. + * required_by is an array with the keys being the modules that will not work + * without this module. */ function _module_build_dependencies($files) { - do { - $new_dependency = FALSE; - foreach ($files as $filename => $file) { - // We will modify this object (module A, see doxygen for module A, B, C). - $file = &$files[$filename]; - if (isset($file->info['dependencies']) && is_array($file->info['dependencies'])) { - foreach ($file->info['dependencies'] as $dependency_name) { - // This is a nonexistent module. - if ($dependency_name == '-circular-' || !isset($files[$dependency_name])) { - continue; - } - // $dependency_name is module B (again, see doxygen). - $files[$dependency_name]->info['dependents'][$filename] = $filename; - $dependency = $files[$dependency_name]; - if (isset($dependency->info['dependencies']) && is_array($dependency->info['dependencies'])) { - // Let's find possible C modules. - foreach ($dependency->info['dependencies'] as $candidate) { - if (array_search($candidate, $file->info['dependencies']) === FALSE) { - // Is this a circular dependency? - if ($candidate == $filename) { - // As a module name can not contain dashes, this makes - // impossible to switch on the module. - $candidate = '-circular-'; - // Do not display the message or add -circular- more than once. - if (array_search($candidate, $file->info['dependencies']) !== FALSE) { - continue; - } - drupal_set_message(t('%module is part of a circular dependency. This is not supported and you will not be able to switch it on.', array('%module' => $file->info['name'])), 'error'); - } - else { - // We added a new dependency to module A. The next loop will - // be able to use this as "B module" thus finding even - // deeper dependencies. - $new_dependency = TRUE; - } - $file->info['dependencies'][] = $candidate; - } - } - } - } + include_once DRUPAL_ROOT .'/includes/graph.inc'; + $roots = $files; + foreach ($files as $filename => $file) { + $graph[$file->name]['edges'] = array(); + if (isset($file->info['dependencies']) && is_array($file->info['dependencies'])) { + foreach ($file->info['dependencies'] as $dependency_name) { + $graph[$file->name]['edges'][$dependency_name] = TRUE; + unset($roots[$dependency_name]); } - // Don't forget to break the reference. - unset($file); } - } while ($new_dependency); + } + drupal_depth_first_search($graph, array_keys($roots)); + foreach ($graph as $module => $data) { + $files[$module]->required_by= isset($data['reverse_paths']) ? $data['reverse_paths'] : array(); + $files[$module]->depends_on = isset($data['paths']) ? $data['paths'] : array(); + } return $files; } === modified file 'modules/simpletest/drupal_web_test_case.php' --- modules/simpletest/drupal_web_test_case.php 2008-10-12 08:30:05 +0000 +++ modules/simpletest/drupal_web_test_case.php 2008-10-13 02:51:27 +0000 @@ -1703,4 +1703,36 @@ class DrupalWebTestCase { $match = is_array($code) ? in_array($curl_code, $code) : $curl_code == $code; return $this->assertTrue($match, $message ? $message : t('HTTP response expected !code, actual !curl_code', array('!code' => $code, '!curl_code' => $curl_code)), t('Browser')); } + + /** + * Assert that the given XPath expression can be found within the document. + * + * @param $expression + * The XPath expression to test for. + * @param $message + * Message to display. + * @param $group + * The group this message belongs to. + * @return + * TRUE on pass, FALSE on fail. + */ + function assertXPath($expression, $message = '', $group = 'Other') { + return $this->_assert((bool)$this->xpath($expression), $message, $group); + } + + /** + * Assert that the given XPath expression can't be found within the document. + * + * @param $expression + * The XPath expression to test for. + * @param $message + * Message to display. + * @param $group + * The group this message belongs to. + * @return + * TRUE on pass, FALSE on fail. + */ + function assertNoXpath($expression, $message = '', $group = 'Other') { + return $this->_assert((bool)!$this->xpath($expression), $message, $group); + } } === modified file 'modules/system/system.admin.inc' --- modules/system/system.admin.inc 2008-10-12 04:30:05 +0000 +++ modules/system/system.admin.inc 2008-10-13 01:54:56 +0000 @@ -592,9 +592,10 @@ function _system_is_incompatible(&$incom * description and dependencies. * @see drupal_parse_info_file for information on module.info descriptors. * - * Dependency checking is performed to ensure that a module cannot be enabled if the module has - * disabled dependencies and also to ensure that the module cannot be disabled if the module has - * enabled dependents. + * Dependency checking is performed to ensure that: + * a module can not be enabled if there are disabled modules it requires. + * a module can not be disabled if there are enabled modules which depend on + * it. * * @param $form_state * An associative array containing the current state of the form. @@ -628,11 +629,10 @@ function system_modules($form_state = ar // and if there are unfilled dependencies, then form_state['storage'] is // filled, triggering a rebuild. In this case we need to show a confirm // form. - return system_modules_confirm_form($files, $form_state['storage']); + return system_modules_confirm_form($form_state['storage']); } $dependencies = array(); $modules = array(); - $form['modules'] = array('#tree' => TRUE); // Used when checking if module implements a help page. $help_arg = module_exists('help') ? drupal_help_arg() : FALSE; @@ -641,19 +641,18 @@ function system_modules($form_state = ar foreach ($files as $filename => $module) { $extra = array(); $extra['enabled'] = (bool) $module->status; - // If this module has dependencies, add them to the array. - if (is_array($module->info['dependencies'])) { - foreach ($module->info['dependencies'] as $dependency) { - if (!isset($files[$dependency])) { - $extra['dependencies'][$dependency] = drupal_ucfirst($dependency) . t(' (missing)'); - $extra['disabled'] = TRUE; - } - elseif (!$files[$dependency]->status) { - $extra['dependencies'][$dependency] = $files[$dependency]->info['name'] . t(' (disabled)'); - } - else { - $extra['dependencies'][$dependency] = $files[$dependency]->info['name'] . t(' (enabled)'); - } + // If this module depends on other modules, then list those along with + // their status (missing, disabled, enabled). + foreach ($module->depends_on as $dependency => $v) { + if (!isset($files[$dependency])) { + $extra['depends_on'][$dependency] = drupal_ucfirst($dependency) . t(' (missing)'); + $extra['disabled'] = TRUE; + } + elseif (!$files[$dependency]->status) { + $extra['depends_on'][$dependency] = $files[$dependency]->info['name'] . t(' (disabled)'); + } + else { + $extra['depends_on'][$dependency] = $files[$dependency]->info['name'] . t(' (enabled)'); } } // Generate link for module's help page, if there is one. @@ -663,18 +662,19 @@ function system_modules($form_state = ar $extra['help'] = theme('more_help_link', url("admin/help/$filename")); } } - // Mark dependents disabled so user can not remove modules being depended on. + // If this module is required by others then list those and make it + // impossible to disable this one. $dependents = array(); - foreach ($module->info['dependents'] as $dependent) { - if ($files[$dependent]->status == 1) { - $extra['dependents'][] = $files[$dependent]->info['name'] . t(' (enabled)'); + foreach ($module->required_by as $required_by => $v) { + if ($files[$required_by]->status == 1) { + $extra['required_by'][] = $files[$required_by]->info['name'] . t(' (enabled)'); $extra['disabled'] = TRUE; } else { - $extra['dependents'][] = $files[$dependent]->info['name'] . t(' (disabled)'); + $extra['required_by'][] = $files[$required_by]->info['name'] . t(' (disabled)'); } } - $form['modules'][$module->info['package']][$filename] = _system_modules_build_row($module->info, $extra); + $form['modules'][$module->info['package']][$filename] = _system_modules_build_row($module->name, $module->info, $extra); } // Add basic information to the fieldsets. foreach (element_children($form['modules']) as $package) { @@ -711,14 +711,14 @@ function system_sort_modules_by_info_nam /** * Build a table row for the system modules page. */ -function _system_modules_build_row($info, $extra) { +function _system_modules_build_row($module_name, $info, $extra) { // Add in the defaults. $extra += array( - 'dependencies' => array(), - 'dependents' => array(), 'disabled' => FALSE, 'enabled' => FALSE, 'help' => '', + 'depends_on' => array(), + 'required_by' => array(), ); $form = array( '#tree' => TRUE, @@ -733,8 +733,8 @@ function _system_modules_build_row($info $form['version'] = array( '#markup' => $info['version'], ); - $form['#dependencies'] = $extra['dependencies']; - $form['#dependents'] = $extra['dependents']; + $form['#depends_on'] = $extra['depends_on']; + $form['#required_by'] = $extra['required_by']; // Check the compatibilities. $compatible = TRUE; @@ -765,6 +765,7 @@ function _system_modules_build_row($info '#type' => 'checkbox', '#title' => t('Enable'), '#default_value' => $extra['enabled'], + '#parents' => array('modules', $module_name), ); if ($extra['disabled']) { $form['enable']['#disabled'] = TRUE; @@ -783,10 +784,28 @@ function _system_modules_build_row($info '#markup' => $extra['help'], ); } + return $form; } /** + * This function returns which action is necessary for a module to be enabled. + * + * @param $module + * The name of the module. + * @return + * Either 'install' or 'enable' or nothing if it's already enabled. + */ +function system_modules_action($module) { + if (drupal_get_installed_schema_version($module) == SCHEMA_UNINSTALLED && drupal_check_module($module)) { + return 'install'; + } + elseif (!module_exists($module)) { + return 'enable'; + } +} + +/** * Display confirmation form for dependencies. * * @param $modules @@ -797,33 +816,15 @@ function _system_modules_build_row($info * form field values from the previous screen. * @ingroup forms */ -function system_modules_confirm_form($modules, $storage) { - $form = array(); - $items = array(); - - $form['validation_modules'] = array('#type' => 'value', '#value' => $modules); - $form['status']['#tree'] = TRUE; - - foreach ($storage['dependencies'] as $info) { - $t_argument = array( - '@module' => $info['name'], - '@dependencies' => implode(', ', $info['dependencies']), - ); - $items[] = format_plural(count($info['dependencies']), 'You must enable the @dependencies module to install @module.', 'You must enable the @dependencies modules to install @module.', $t_argument); - } - $form['text'] = array('#markup' => theme('item_list', $items)); - - if ($form) { - // Set some default form values - $form = confirm_form( - $form, - t('Some required modules must be enabled'), - 'admin/build/modules', - t('Would you like to continue with enabling the above?'), - t('Continue'), - t('Cancel')); - return $form; - } +function system_modules_confirm_form($storage) { + return confirm_form( + array('text' => array('#markup' => $storage['text'])), + t('Some required modules must be enabled'), + 'admin/build/modules', + t('Would you like to continue with enabling the above?'), + t('Continue'), + t('Cancel')); + return $form; } /** @@ -832,116 +833,88 @@ function system_modules_confirm_form($mo function system_modules_submit($form, &$form_state) { include_once DRUPAL_ROOT . '/includes/install.inc'; $modules = array(); - // If we're not coming from the confirmation form, build the list of modules. - if (!isset($form_state['storage'])) { - foreach ($form_state['values']['modules'] as $group_name => $group) { - foreach ($group as $module => $enabled) { - $modules[$module] = array('group' => $group_name, 'enabled' => $enabled['enable']); - } - } - } - else { - // If we are coming from the confirmation form, fetch - // the modules out of $form_state. - $modules = $form_state['storage']['modules']; - } + // If we're not coming from the confirmation form, get the list of modules + // submitted in the form. + // If we are coming from the confirmation form, fetch the modules out of + // $form_state. + $confirmation_done = !empty($form_state['storage']); + $modules = $form_state[$confirmation_done ? 'storage' : 'values']['modules']; // Get a list of all modules, for building dependencies with. $files = module_rebuild_cache(); - // The modules to be enabled. - $modules_to_be_enabled = array(); + // The modules to be enabled or installed. + $new_modules = array(); // The modules to be disabled. $disable_modules = array(); - // The modules to be installed. - $new_modules = array(); - // The un-met dependencies. - $dependencies = array(); - // Go through each module, finding out - // if we should enable, install, or disable it, - // and if it has any un-met dependencies. - foreach ($modules as $name => $module) { - // If it's enabled, find out whether to just - // enable it, or install it. - if ($module['enabled']) { - if (drupal_get_installed_schema_version($name) == SCHEMA_UNINSTALLED) { - $new_modules[$name] = $name; - } - elseif (!module_exists($name)) { - $modules_to_be_enabled[$name] = $name; - } - // If we're not coming from a confirmation form, - // search dependencies. Otherwise, the user will have already - // approved of the depdent modules being enabled. - if (empty($form_state['storage'])) { - foreach ($form['modules'][$module['group']][$name]['#dependencies'] as $dependency => $string) { - if (!$modules[$dependency]['enabled']) { - if (!isset($dependencies[$name])) { - $dependencies[$name]['name'] = $files[$name]->info['name']; - } - $dependencies[$name]['dependencies'][$dependency] = $files[$dependency]->info['name']; - } - $modules[$dependency] = array('group' => $files[$dependency]->info['package'], 'enabled' => TRUE); + // If more modules are needed than what the user requested. + $more_modules = array(); + // Build up a list of items to confirm. + $confirm_items = array(); + // The modules checked in the form. + $modules_checked = array_filter($modules); + // Go through each module marked as enabled, finding out if we should enable + // or install it and if we need to enable the modules it depends on. + foreach ($modules_checked as $name => $v) { + if ($action = system_modules_action($name)) { + $new_modules[$action][$name] = $name; + // If we're not coming from a confirmation form, check whether we need + // enable more modules. + if (!$confirmation_done && $files[$name]->depends_on) { + $depends_on = array(); + foreach (array_diff_key($files[$name]->depends_on, $modules_checked) as $more_module => $v) { + // We need to postpone this module as it depends on a module that's + // not yet enabled. + unset($new_modules[$action][$name]); + // Store it for later. + $form_state['storage']['modules'][$name] = TRUE; + $form_state['storage']['modules'][$more_module] = TRUE; + $depends_on[] = $files[$more_module]->name; + } + if ($depends_on) { + $t_argument = array( + '@module' => $files[$name]->name, + '@depends_on' => implode(', ', $depends_on), + ); + $confirm_items[] = format_plural(count($depends_on), 'You must enable the @depends_on module to install @module.', 'You must enable the @depends_on modules to install @module.', $t_argument); } } } } - // A second loop is necessary, otherwise the modules set to be enabled in the - // previous loop would not be found. - foreach ($modules as $name => $module) { - if (module_exists($name) && !$module['enabled']) { - $disable_modules[$name] = $name; - } + if ($confirm_items) { + $form_state['storage']['text'] = theme('item_list', $confirm_items); } - if ($dependencies) { - // If there where un-met dependencies and they haven't confirmed don't process - // the submission yet. Store the form submission data needed later. - if (!isset($form_state['values']['confirm'])) { - $form_state['storage'] = array('dependencies' => $dependencies, 'modules' => $modules); - return; - } - // Otherwise, install or enable the modules. - else { - $dependencies = $form_storage['dependencies']; - foreach ($dependencies as $info) { - foreach ($info['dependencies'] as $dependency => $name) { - if (drupal_get_installed_schema_version($name) == SCHEMA_UNINSTALLED) { - $new_modules[$name] = $name; - } - else { - $modules_to_be_enabled[$name] = $name; - } - } - } + else { + // If we have no dependencies, or the dependencies are confirmed + // to be installed, we don't need the temporary storage anymore. + unset($form_state['storage']); + } + foreach ($modules as $name => $enabled) { + if (!$enabled && module_exists($name)) { + $new_modules['disable'][$name] = $name; } } - // If we have no dependencies, or the dependencies are confirmed - // to be installed, we don't need the temporary storage anymore. - unset($form_state['storage']); - - $old_module_list = module_list(); + $saved = FALSE; // Enable the modules needing enabling. - if (!empty($modules_to_be_enabled)) { - module_enable($modules_to_be_enabled); + if (!empty($new_modules['enable'])) { + module_enable($new_modules['enable']); + $saved = TRUE; } // Disable the modules that need disabling. - if (!empty($disable_modules)) { - module_disable($disable_modules); + if (!empty($new_modules['disable'])) { + module_disable($new_modules['disable']); + $saved = TRUE; } - // Install new modules. - if (!empty($new_modules)) { - foreach ($new_modules as $key => $module) { - if (!drupal_check_module($module)) { - unset($new_modules[$key]); - } - } - drupal_install_modules($new_modules); + if (!empty($new_modules['install'])) { + drupal_install_modules($new_modules['install']); + $saved = TRUE; } - $current_module_list = module_list(TRUE, FALSE); - if ($old_module_list != $current_module_list) { + // Reset module list. + module_list(TRUE, FALSE); + if ($saved) { drupal_set_message(t('The configuration options have been saved.')); } @@ -2096,11 +2069,11 @@ function theme_system_modules_fieldset($ } // Add the description, along with any dependencies. $description .= drupal_render($module['description']); - if ($module['#dependencies']) { - $description .= '
' . t('Depends on: ') . implode(', ', $module['#dependencies']) . '
'; + if ($module['#depends_on']) { + $description .= '
' . t('Depends on: ') . implode(', ', $module['#depends_on']) . '
'; } - if ($module['#dependents']) { - $description .= '
' . t('Required by: ') . implode(', ', $module['#dependents']) . '
'; + if ($module['#required_by']) { + $description .= '
' . t('Required by: ') . implode(', ', $module['#required_by']) . '
'; } $row[] = array('data' => $description, 'class' => 'description'); $rows[] = $row; === modified file 'modules/system/system.test' --- modules/system/system.test 2008-10-12 06:27:01 +0000 +++ modules/system/system.test 2008-10-13 03:06:52 +0000 @@ -10,7 +10,7 @@ class EnableDisableCoreTestCase extends function getInfo() { return array( 'name' => t('Module list functionality'), - 'description' => t('Enable/disable core module and confirm table creation/deletion. Enable module without dependency enabled. Attempt disabling of required modules.'), + 'description' => t('Enable/disable core module and confirm table creation/deletion. Enable module without dependency enabled.'), 'group' => t('System') ); } @@ -19,111 +19,63 @@ class EnableDisableCoreTestCase extends * Implementation of setUp(). */ function setUp() { - parent::setUp('system_test'); + parent::setUp(); $this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer site configuration')); $this->drupalLogin($this->admin_user); } /** - * Enable a module, check the database for related tables, disable module, - * check for related tables, unistall module, check for related tables. - * Also check for invocation of the hook_module_action hook. + * Enable a module, with and without dependencies. */ function testEnableDisable() { - // Enable aggregator, and check tables. - $this->assertModules(array('aggregator'), FALSE); - $this->assertTableCount('aggregator', FALSE); + module_disable(array('aggregator', 'forum', 'comment', 'taxonomy')); + $this->assertModules(array('aggregator', 'forum', 'comment', 'taxonomy'), FALSE); - // Install (and enable) aggregator module. - $edit = array(); - $edit['modules[Core][aggregator][enable]'] = 'aggregator'; + // Make sure enabling a module without a dependency works. + $edit['modules[aggregator]'] = 'aggregator'; $this->drupalPost('admin/build/modules', $edit, t('Save configuration')); $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.')); - - // Check that hook_modules_installed and hook_modules_enabled hooks were invoked and check tables. - $this->assertText(t('hook_modules_installed fired for aggregator'), t('hook_modules_installed fired.')); - $this->assertText(t('hook_modules_enabled fired for aggregator'), t('hook_modules_enabled fired.')); $this->assertModules(array('aggregator'), TRUE); - $this->assertTableCount('aggregator', TRUE); - // Disable aggregator, check tables, uninstall aggregator, check tables. + // Enable the forum module, and get the confirm form. $edit = array(); - $edit['modules[Core][aggregator][enable]'] = FALSE; + $edit['modules[forum]'] = 'forum'; $this->drupalPost('admin/build/modules', $edit, t('Save configuration')); + file_put_contents('/tmp/t.html', $this->_content); + $this->assertText(t('You must enable the @dependencies modules to install @module.', array('@dependencies' => 'taxonomy, comment', '@module' => 'forum')), t("Confirmation page shows up.")); + $this->pass($this->plain_text); + $this->drupalPost(NULL, array(), t('Continue')); $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.')); + $this->assertModules(array('forum', 'comment', 'taxonomy'), TRUE); - // Check that hook_modules_disabled hook was invoked and check tables. - $this->assertText(t('hook_modules_disabled fired for aggregator'), t('hook_modules_disabled fired.')); - $this->assertModules(array('aggregator'), FALSE); - $this->assertTableCount('aggregator', TRUE); - - // Uninstall the module. - $edit = array(); - $edit['uninstall[aggregator]'] = 'aggregator'; - $this->drupalPost('admin/build/modules/uninstall', $edit, t('Uninstall')); - - $this->drupalPost(NULL, NULL, t('Uninstall')); - $this->assertText(t('The selected modules have been uninstalled.'), t('Modules status has been updated.')); - - // Check that hook_modules_uninstalled hook was invoked and check tables. - $this->assertText(t('hook_modules_uninstalled fired for aggregator'), t('hook_modules_uninstalled fired.')); - $this->assertModules(array('aggregator'), FALSE); - $this->assertTableCount('aggregator', FALSE); - } + // Make sure we can't disable comment and taxonomy modules. + $this->drupalGet('admin/build/modules'); + $this->assertXPath('//input[@id="edit-modules-comment" and @disabled="disabled"]', t('Disabling the comment module isn\'t allowed')); + $this->assertXPath('//input[@id="edit-modules-taxonomy" and @disabled="disabled"]', t('Disabling the taxonomy module isn\'t allowed')); + file_put_contents('/tmp/t1.html', $this->_content); - /** - * Attempt to enable translation module without locale enabled. - */ - function testEnableWithoutDependency () { - // Attempt to enable content translation without locale enabled. + // Disable forum module. $edit = array(); - $edit['modules[Core][translation][enable]'] = 'translation'; + $edit['modules[forum]'] = FALSE; $this->drupalPost('admin/build/modules', $edit, t('Save configuration')); - $this->assertText(t('Some required modules must be enabled'), t('Dependecy required.')); - - $this->assertModules(array('translation', 'locale'), FALSE); - - // Assert that the locale tables weren't enabled. - $this->assertTableCount('languages', FALSE); - $this->assertTableCount('locale', FALSE); - - $this->drupalPost(NULL, NULL, t('Continue')); $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.')); + $this->assertModules(array('forum'), FALSE); + $this->assertModules(array('comment', 'taxonomy'), TRUE); - $this->assertModules(array('translation', 'locale'), TRUE); - - // Assert that the locale tables were enabled. - $this->assertTableCount('languages', TRUE); - $this->assertTableCount('locale', TRUE); - } - - /** - * Assert that core required modules cannot be disabled. - */ - function testDisableRequired() { - $required_modules = drupal_required_modules(); - $this->drupalGet('admin/build/modules'); - foreach($required_modules as $module) { - // Check to make sure the checkbox for required module is not found. - $this->assertNoFieldByName('modules[Core][' . $module . '][enable]'); - } - } - - /** - * Assert tables that begin with the specified base table name. - * - * @param string $base_table Begginning of table name to look for. - * @param boolean $count Assert tables that match specified base table. - * @return boolean Tables with specified base table. - */ - function assertTableCount($base_table, $count) { - $match_count = simpletest_get_like_tables($base_table, TRUE); + // Disable others. + $edit['modules[comment]'] = FALSE; + $edit['modules[taxonomy]'] = FALSE; + $this->drupalPost('admin/build/modules', $edit, t('Save configuration')); + $this->assertModules(array('comment', 'taxonomy'), FALSE); - if ($count) { - return $this->assertTrue($match_count, t('Tables matching "@base_table" found.', array('@base_table' => $base_table))); - } - return $this->assertFalse($match_count, t('Tables matching "@base_table" not found.', array('@base_table' => $base_table))); + // Enable all three and don't get a confirm form. + $edit['modules[comment]'] = 'comment'; + $edit['modules[taxonomy]'] = 'taxonomy'; + $edit['modules[forum]'] = 'forum'; + $this->drupalPost('admin/build/modules', $edit, t('Save configuration')); + $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.')); + $this->assertModules(array('forum', 'comment', 'taxonomy'), TRUE); } /**