Commit 9b82787b authored by Dries's avatar Dries

- Patch #243773 by chx, catch, boombatower, yched, dmitrig01, et al: use the...

- Patch #243773 by chx, catch, boombatower, yched, dmitrig01, et al: use the batch API for running the tests instead of an all-in-one approach.  Great work.
parent 22c0a0a4
......@@ -22,6 +22,13 @@ function _batch_page() {
// Register database update for end of processing.
register_shutdown_function('_batch_shutdown');
// Add batch-specific css.
foreach ($batch['sets'] as $batch_set) {
foreach ($batch_set['css'] as $css) {
drupal_add_css($css);
}
}
$op = isset($_REQUEST['op']) ? $_REQUEST['op'] : '';
$output = NULL;
switch ($op) {
......
......@@ -2387,6 +2387,7 @@ function form_clean_id($id = NULL, $flush = FALSE) {
* 'operations' and 'finished' functions, for instance if they don't
* reside in the original '.module' file. The path should be relative to
* the base_path(), and thus should be built using drupal_get_path().
* 'css' : an array of paths to CSS files to be used on the progress page.
*
* Operations are added as new batch sets. Batch sets are used to ensure
* clean code independence, ensuring that several batches submitted by
......@@ -2419,6 +2420,7 @@ function batch_set($batch_definition) {
'init_message' => $t('Initializing.'),
'progress_message' => $t('Remaining @remaining of @total.'),
'error_message' => $t('An error has occurred.'),
'css' => array(),
);
$batch_set = $init + $batch_definition + $defaults;
......
<?php
// $Id$
class ContactTestCase extends DrupalWebTestCase {
/**
* Test the sitewide contact form.
*/
class ContactSitewideTestCase extends DrupalWebTestCase {
/**
* Implementation of getInfo().
*/
function getInfo() {
return array(
'name' => t('Contact functionality'),
'description' => t('Test site-wide contact form and personal contact form functionality.'),
'name' => t('Site-wide contact form'),
'description' => t('Tests site-wide contact form functionality.'),
'group' => t('Contact'),
);
}
......@@ -110,60 +114,6 @@ class ContactTestCase extends DrupalWebTestCase {
$this->deleteCategories();
}
/**
* Test personal contact form.
*/
function testPersonalContact() {
$admin_user = $this->drupalCreateUser(array('administer site-wide contact form'));
$this->drupalLogin($admin_user);
// Enable the personal contact form.
$edit = array();
$edit['contact_default_status'] = TRUE;
$this->drupalPost('admin/build/contact/settings', $edit, t('Save configuration'));
$this->assertText(t('The configuration options have been saved.'), t('Setting successfully saved.'));
// Reload variables.
$this->drupalLogout();
// Create web users and attempt to use personal contact forms with default set to true.
$web_user1 = $this->drupalCreateUser(array());
$web_user2 = $this->drupalCreateUser(array());
$this->drupalLogin($web_user1);
$this->drupalGet('user/' . $web_user2->uid . '/contact');
$this->assertResponse(200, t('Access to personal contact form granted.'));
$edit = array();
$edit['subject'] = $this->randomName(16);
$edit['message'] = $this->randomName(64);
$this->drupalPost(NULL, $edit, t('Send e-mail'));
$this->assertText(t('The message has been sent.'), t('Message sent.'));
$this->drupalLogout();
$this->drupalLogin($admin_user);
// Disable the personal contact form.
$edit = array();
$edit['contact_default_status'] = FALSE;
$this->drupalPost('admin/build/contact/settings', $edit, t('Save configuration'));
$this->assertText(t('The configuration options have been saved.'), t('Setting successfully saved.'));
// Reload variables.
$this->drupalLogout();
// Create web users and attempt to use personal contact forms with default set to false.
$web_user3 = $this->drupalCreateUser(array());
$web_user4 = $this->drupalCreateUser(array());
$this->drupalLogin($web_user3);
$this->drupalGet('user/' . $web_user4->uid . '/contact');
$this->assertResponse(403, t('Access to personal contact form denied.'));
}
/**
* Add a category.
*
......@@ -249,3 +199,81 @@ class ContactTestCase extends DrupalWebTestCase {
$this->assertText(t('The changes have been saved.'), t(' [permission] Saved changes.'));
}
}
/**
* Test the personal contact form.
*/
class ContactPersonalTestCase extends DrupalWebTestCase {
/**
* Implementation of getInfo().
*/
function getInfo() {
return array(
'name' => t('Personal contact form'),
'description' => t('Tests personal contact form functionality.'),
'group' => t('Contact'),
);
}
/**
* Implementation of setUp().
*/
function setUp() {
parent::setUp('contact');
}
/**
* Test personal contact form.
*/
function testPersonalContact() {
$admin_user = $this->drupalCreateUser(array('administer site-wide contact form'));
$this->drupalLogin($admin_user);
// Enable the personal contact form.
$edit = array();
$edit['contact_default_status'] = TRUE;
$this->drupalPost('admin/build/contact/settings', $edit, t('Save configuration'));
$this->assertText(t('The configuration options have been saved.'), t('Setting successfully saved.'));
// Reload variables.
$this->drupalLogout();
// Create web users and attempt to use personal contact forms with default set to true.
$web_user1 = $this->drupalCreateUser(array());
$web_user2 = $this->drupalCreateUser(array());
$this->drupalLogin($web_user1);
$this->drupalGet('user/' . $web_user2->uid . '/contact');
$this->assertResponse(200, t('Access to personal contact form granted.'));
$edit = array();
$edit['subject'] = $this->randomName(16);
$edit['message'] = $this->randomName(64);
$this->drupalPost(NULL, $edit, t('Send e-mail'));
$this->assertText(t('The message has been sent.'), t('Message sent.'));
$this->drupalLogout();
$this->drupalLogin($admin_user);
// Disable the personal contact form.
$edit = array();
$edit['contact_default_status'] = FALSE;
$this->drupalPost('admin/build/contact/settings', $edit, t('Save configuration'));
$this->assertText(t('The configuration options have been saved.'), t('Setting successfully saved.'));
// Reload variables.
$this->drupalLogout();
// Create web users and attempt to use personal contact forms with default set to false.
$web_user3 = $this->drupalCreateUser(array());
$web_user4 = $this->drupalCreateUser(array());
$this->drupalLogin($web_user3);
$this->drupalGet('user/' . $web_user4->uid . '/contact');
$this->assertResponse(403, t('Access to personal contact form denied.'));
}
}
\ No newline at end of file
<?php
// $Id$
/**
* Base PHP test case class.
*/
class PHPTestCase extends DrupalWebTestCase {
/**
* Implementation of getInfo().
*/
function getInfo() {
return array(
'name' => t('PHP filter functionality'),
'description' => t('Make sure that PHP filter evaluates PHP code when enabled and that users who don\'t have access to filter can\'t see it'),
'group' => t('PHP'),
);
}
/**
* Implementation of getInfo().
......@@ -28,6 +21,37 @@ class PHPTestCase extends DrupalWebTestCase {
$this->assertText('PHP code', t('On PHP code filter page.'));
}
/**
* Create a test node with PHP code in the body.
*
* @param stdObject User object to create node for.
* @return stdObject Node object.
*/
function createNodeWithCode($user) {
$node = $this->drupalCreateNode(array('uid' => $user->uid));
$edit = array();
$edit['body'] = '<?php print "SimpleTest PHP was executed!"; ?>';
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
$this->assertRaw(t('Page %title has been updated.', array('%title' => $node->title)), t('PHP code inserted into node.'));
return $node;
}
}
/**
* Tests to make sure the PHP filter actually evaluates PHP code when used.
*/
class PHPFitlerTestCase extends PHPTestCase {
/**
* Implementation of getInfo().
*/
function getInfo() {
return array(
'name' => t('PHP filter functionality'),
'description' => t('Make sure that PHP filter properly evaluates PHP code when enabled.'),
'group' => t('PHP'),
);
}
/**
* Make sure that the PHP filter evaluates PHP code when used.
*/
......@@ -57,6 +81,22 @@ class PHPTestCase extends DrupalWebTestCase {
$this->assertNoText('print', t('PHP code isn\'t displayed.'));
$this->assertText('SimpleTest PHP was executed!', t('PHP code has been evaluated.'));
}
}
/**
* Tests to make sure access to the PHP filter is properly restricted.
*/
class PHPAccessTestCase extends PHPTestCase {
/**
* Implementation of getInfo().
*/
function getInfo() {
return array(
'name' => t('PHP filter access check'),
'description' => t('Make sure that users who don\'t have access to the PHP filter can\'t see it.'),
'group' => t('PHP'),
);
}
/**
* Make sure that user can't use the PHP filter when not given access.
......@@ -75,19 +115,4 @@ class PHPTestCase extends DrupalWebTestCase {
$this->drupalGet('node/' . $node->nid . '/edit');
$this->assertNoFieldByName('format', '3', t('Format not available.'));
}
/**
* Create a test node with PHP code in the body.
*
* @param stdObject User object to create node for.
* @return stdObject Node object.
*/
function createNodeWithCode($user) {
$node = $this->drupalCreateNode(array('uid' => $user->uid));
$edit = array();
$edit['body'] = '<?php print "SimpleTest PHP was executed!"; ?>';
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
$this->assertRaw(t('Page %title has been updated.', array('%title' => $node->title)), t('PHP code inserted into node.'));
return $node;
}
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -25,11 +25,11 @@ table#simpletest-form-table tr.simpletest-group td {
}
div.simpletest-pass {
background: #b6ffb6;
color: #33a333;
}
div.simpletest-fail {
background: #ffc9c9;
color: #a30000;
}
tr.simpletest-pass.odd {
......
......@@ -5,6 +5,7 @@
* Implementation of hook_install().
*/
function simpletest_install() {
drupal_install_schema('simpletest');
// Check for files directory.
$path = file_directory_path() . '/simpletest';
if (file_check_directory($path, FILE_CREATE_DIRECTORY)) {
......@@ -95,6 +96,7 @@ function simpletest_uninstall() {
variable_del('simpletest_httpauth_username');
variable_del('simpletest_httpauth_pass');
variable_del('simpletest_devel');
drupal_uninstall_schema('simpletest');
}
/**
......@@ -133,3 +135,125 @@ function simpletest_requirements($phase) {
return $requirements;
}
function simpletest_schema() {
$schema['simpletest'] = array(
'description' => t('Stores simpletest messages'),
'fields' => array(
'message_id' => array(
'type' => 'serial',
'not null' => TRUE,
'description' => t('Primary Key: Unique simpletest message ID.'),
),
'test_id' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'description' => t('Test id, messages belonging to the same id are reported together'),
),
'test_class' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
'description' => t('The name of the class that created this message.'),
),
'status' => array(
'type' => 'varchar',
'length' => 9,
'not null' => TRUE,
'default' => '',
'description' => t('Message status. Core understands pass, fail, exception.'),
),
'message' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
'description' => t('The message itself.'),
),
'message_group' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
'description' => t('The message group this message belongs to. For example: warning, browser, user.'),
),
'caller' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
'description' => t('Name of the caller function or method that created this message.'),
),
'line' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'description' => t('Line number of the caller.'),
),
'file' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
'description' => t('Name of the file where the caller is.'),
),
),
'primary key' => array('message_id'),
'indexes' => array(
'reporter' => array('test_class, message_id'),
),
);
$schema['simpletest_test_id'] = array(
'description' => t('Stores simpletest test IDs.'),
'fields' => array(
'message_id' => array(
'type' => 'serial',
'not null' => TRUE,
'description' => t('Primary Key: Unique simpletest ID.'),
),
),
'primary key' => array('message_id'),
);
return $schema;
}
/**
* Create the simpletest tables.
*/
function simpletest_update_7000() {
$ret = array();
$schema = array();
$schema['simpletest'] = array(
'fields' => array(
'message_id' => array('type' => 'serial', 'not null' => TRUE),
'test_id' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
'test_class' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
'status' => array('type' => 'varchar', 'length' => 9, 'not null' => TRUE, 'default' => ''),
'message' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
'message_group' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
'caller' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
'line' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
'file' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
),
'primary key' => array('message_id'),
'indexes' => array(
'reporter' => array('test_class, message_id'),
),
);
$schema['simpletest_test_id'] = array(
'fields' => array(
'message_id' => array('type' => 'serial', 'not null' => TRUE),
),
'primary key' => array('message_id'),
);
foreach ($schema as $name => $definition) {
db_create_table($ret, $name, $definition);
}
return $ret;
}
\ No newline at end of file
This diff is collapsed.
......@@ -62,7 +62,6 @@ class SimpleTestTestCase extends DrupalWebTestCase {
else {
// Run this test from web interface.
$this->drupalGet('admin/build/testing');
$this->assertText(t('It is strongly suggested to run the tests with the first user!'));
$edit = array();
$edit['SimpleTestTestCase'] = TRUE;
......@@ -89,11 +88,11 @@ class SimpleTestTestCase extends DrupalWebTestCase {
* Confirm that the stub test produced the desired results.
*/
function confirmStubTestResults() {
$this->assertAssertion($this->pass, '[Other]', 'Pass');
$this->assertAssertion($this->fail, '[Other]', 'Fail');
$this->assertAssertion($this->pass, 'Other', 'Pass');
$this->assertAssertion($this->fail, 'Other', 'Fail');
$this->assertAssertion(t('Created permissions: @perms', array('@perms' => $this->valid_permission)), '[Role]', 'Pass');
$this->assertAssertion(t('Invalid permission %permission.', array('%permission' => $this->invalid_permission)), '[Role]', 'Fail');
$this->assertAssertion(t('Created permissions: @perms', array('@perms' => $this->valid_permission)), 'Role', 'Pass');
$this->assertAssertion(t('Invalid permission %permission.', array('%permission' => $this->invalid_permission)), 'Role', 'Fail');
}
/**
......@@ -128,16 +127,17 @@ class SimpleTestTestCase extends DrupalWebTestCase {
if ($this->parse()) {
if ($fieldset = $this->getResultFieldSet()) {
// Code assumes this is the only test in group.
$results['summary'] = $this->asText($fieldset->div[1]);
$results['summary'] = $this->asText($fieldset->div);
$results['name'] = $this->asText($fieldset->fieldset->legend);
$results['assertions'] = array();
$tbody = $fieldset->fieldset->div[2]->table->tbody;
$tbody = $fieldset->fieldset->table->tbody;
foreach ($tbody->tr as $row) {
$assertion = array();
$assertion['message'] = $this->asText($row->td[0]);
$assertion['type'] = $this->asText($row->td[1]);
$assertion['status'] = $this->asText($row->td[2]);
$ok_url = (url('misc/watchdog-ok.png') == 'misc/watchdog-ok.png') ? 'misc/watchdog-ok.png' : (base_path() . 'misc/watchdog-ok.png');
$assertion['status'] = ($row->td[5]->img['src'] == $ok_url) ? 'Pass' : 'Fail';
$results['assertions'][] = $assertion;
}
}
......@@ -164,10 +164,15 @@ class SimpleTestTestCase extends DrupalWebTestCase {
/**
* Extract the text contained by the element.
*
* @param SimpleXMLElement $element Element to extract text from.
* @return string Extracted text.
* @param $element
* Element to extract text from.
* @return
* Extracted text.
*/
function asText(SimpleXMLElement $element) {
if (!is_object($element)) {
return $this->fail('The element is not an element.');
}
return trim(strip_tags($element->asXML()));
}
......
#!/usr/bin/php
#!/Applications/MAMP/bin/php5/bin/php
<?php
// $Id$
......@@ -37,9 +37,6 @@
need this parameter if Drupal is in a subdirectory on your
localhost and you have not set \$base_url in settings.php.
--reporter Immediatly preceeds the name of the output reporter to use. This
Defaults to "text", while other options include "xml" and "html".
--all Run all available tests.
--class Run tests identified by speficic class names.
......@@ -67,6 +64,7 @@
$clean = FALSE;
$all = FALSE;
$class_names = FALSE;
$verbose = FALSE;
$test_names = array();
while ($param = array_shift($_SERVER['argv'])) {
......@@ -89,12 +87,6 @@
case '--clean':
$clean = TRUE;
break;
case '--reporter':
$reporter = array_shift($_SERVER['argv']);
if (!in_array($reporter, array("text", "xml", "html"))) {
$reporter = "text";
}
break;
default:
$test_names += explode(',', $param);
break;
......@@ -116,8 +108,7 @@
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
if (!module_exists('simpletest')) {
echo("ERROR: The simpletest module must be enabled before this script can run.\n");
exit;
die(t('Error: The simpletest module must be enabled before this script can run.') ."\n");
}
if ($clean) {
......@@ -131,34 +122,28 @@
exit;
}
// Run tests as user #1.
$GLOBALS['user'] = user_load(1);
//Load simpletest files
$total_test = &simpletest_get_total_test();
$test_instances = $total_test->getTestInstances();
if ($list) {
// Display all availabe tests.
echo("Available test groups:\n----------------------\n");
foreach ($test_instances as $group_test) {
echo($group_test->getLabel() . "\n");
}
exit;
}
$tests = simpletest_get_all_tests();
$test_list = array();
if ($all) {
$test_list = NULL;
$test_list = $tests;
}
else {
if ($class_names) {
$test_list = _run_tests_check_classes($test_names, $test_instances);
else if ($class_names) {
foreach ($test_names as $test) {
if (isset($tests[$test])) {
$test_list[$test] = $tests[$test];
}
}
else {
$test_list = _run_tests_find_classes($test_names, $test_instances);
}
else {
$groups = simpletest_categorize_tests($tests);
foreach ($test_names as $test) {
if (isset($groups[$test])) {
$test_list += $groups[$test];
}
}
}
if (empty($test_list) && !$all) {
echo("ERROR: No valid tests were specified.\n");
exit;
......@@ -171,55 +156,30 @@
}
// Tell the user about what tests are to be run.
if (!$all && $reporter == 'text') {
if (!$all) {
echo("Tests to be run:\n");
foreach ($test_list as $name) {
echo("- " . $name . "\n");
foreach ($test_list as $instance) {
$info = $instance->getInfo();
echo("- " . $info['name'] . "\n");
}
echo("\n");
}
simpletest_run_tests(array_keys($test_list), $reporter);
db_query('INSERT INTO {simpletest_test_id} VALUES (default)');
$test_id = db_last_insert_id('simpletest_test_id', 'test_id');
// Utility functions:
/**
* Check that each class name exists as a test, return the list of valid ones.
*/
function _run_tests_check_classes($test_names, $test_instances) {
$test_list = array();
$test_names = array_flip($test_names);
foreach ($test_instances as $group_test) {
$tests = $group_test->getTestInstances();
foreach ($tests as $test) {
$class = get_class($test);
$info = $test->getInfo();
if (isset($test_names[$class])) {
$test_list[$class] = $info['name'];
}
}
}
return $test_list;
}
$test_results = array('#pass' => 0, '#fail' => 0, '#exception' => 0);
/**
* Check that each group name exists, return the list of class in valid groups.
*/
function _run_tests_find_classes($test_names, &$test_instances) {
$test_list = array();
$test_names = array_flip($test_names);
uasort($test_instances, 'simpletest_compare_instances');
foreach ($test_instances as $group_test) {
$group = $group_test->getLabel();
if (isset($test_names[$group])) {
$tests = $group_test->getTestInstances();
foreach ($tests as $test) {
$info = $test->getInfo();
$test_list[get_class($test)] = $info['name'];
}
}
foreach ($test_list as $class => $instance) {
$instance = new $class($test_id);
$instance->run();
$info = $instance->getInfo();
$test_results[$class] = $instance->_results;
foreach ($test_results[$class] as $key => $value) {
$test_results[$key] += $value;
}
return $test_list;
echo(t('@name: @summary', array('@name' => $info['name'], '@summary' => _simpletest_format_summary_line($test_results[$class]))) . "\n");
}
echo(_simpletest_format_summary_line($test_results) . "\n");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment