Index: modules/simpletest/tests/form.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/form.test,v
retrieving revision 1.72
diff -u -p -r1.72 form.test
--- modules/simpletest/tests/form.test	4 Oct 2010 18:00:46 -0000	1.72
+++ modules/simpletest/tests/form.test	23 Oct 2010 13:53:15 -0000
@@ -123,6 +123,46 @@ class FormsTestCase extends DrupalWebTes
   }
 
   /**
+   * Tests #required with custom validation errors.
+   *
+   * @see form_test_validate_required_form()
+   */
+  function testRequiredValidation() {
+    $form = $form_state = array();
+    $form = form_test_validate_required_form($form, $form_state);
+
+    // Verify that a custom #required error can be set.
+    $edit = array();
+    $this->drupalPost('form-test/validate-required', $edit, 'Submit');
+
+    foreach (element_children($form) as $key) {
+      if (isset($form[$key]['#required_error'])) {
+        $this->assertNoText(t('!name field is required.', array('!name' => $form[$key]['#title'])));
+        $this->assertText($form[$key]['#required_error']);
+      }
+    }
+    $this->assertNoText(t('An illegal choice has been detected. Please contact the site administrator.'));
+
+    // Verify that no custom validation error appears with valid values.
+    $edit = array(
+      'element' => $this->randomString(),
+      'form' => $this->randomString(),
+      'radios' => 'foo',
+      'checkboxes[foo]' => TRUE,
+      'select' => 'foo',
+    );
+    $this->drupalPost('form-test/validate-required', $edit, 'Submit');
+
+    foreach (element_children($form) as $key) {
+      if (isset($form[$key]['#required_error'])) {
+        $this->assertNoText(t('!name field is required.', array('!name' => $form[$key]['#title'])));
+        $this->assertNoText($form[$key]['#required_error']);
+      }
+    }
+    $this->assertNoText(t('An illegal choice has been detected. Please contact the site administrator.'));
+  }
+
+  /**
    * Test default value handling for checkboxes.
    *
    * @see _form_test_checkbox()
Index: modules/simpletest/tests/form_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/form_test.module,v
retrieving revision 1.52
diff -u -p -r1.52 form_test.module
--- modules/simpletest/tests/form_test.module	20 Oct 2010 01:15:58 -0000	1.52
+++ modules/simpletest/tests/form_test.module	23 Oct 2010 13:51:53 -0000
@@ -24,6 +24,12 @@ function form_test_menu() {
     'access arguments' => array('access content'),
     'type' => MENU_CALLBACK,
   );
+  $items['form-test/validate-required'] = array(
+    'title' => 'Form #required validation',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('form_test_validate_required_form'),
+    'access callback' => TRUE,
+  );
   $items['form-test/limit-validation-errors'] = array(
     'title' => 'Form validation with some error suppression',
     'page callback' => 'drupal_get_form',
@@ -304,6 +310,75 @@ function form_test_validate_form_validat
 }
 
 /**
+ * Form constructor for simple #required tests.
+ */
+function form_test_validate_required_form($form, &$form_state) {
+  $form['element'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Name',
+    '#required' => TRUE,
+    '#required_error' => t('Please enter a name.'),
+    '#element_validate' => array('form_test_validate_required_form_element_validate'),
+  );
+  $form['form'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Title',
+    '#required' => TRUE,
+    '#required_error' => t('Please enter a title.'),
+  );
+  $form['radios'] = array(
+    '#type' => 'radios',
+    '#title' => 'Radios',
+    '#options' => drupal_map_assoc(array('foo', 'bar')),
+    '#required' => TRUE,
+    '#required_error' => t('Please choose an option.'),
+    '#element_validate' => array('form_test_validate_required_form_element_validate'),
+  );
+  $form['checkboxes'] = array(
+    '#type' => 'checkboxes',
+    '#title' => 'Checkboxes',
+    '#options' => drupal_map_assoc(array('foo', 'bar')),
+    '#required' => TRUE,
+    '#required_error' => t('Please choose at least one option.'),
+    '#element_validate' => array('form_test_validate_required_form_element_validate'),
+  );
+  $form['select'] = array(
+    '#type' => 'select',
+    '#title' => 'Select',
+    '#options' => drupal_map_assoc(array('foo', 'bar')),
+    '#required' => TRUE,
+    '#required_error' => t('Please select something.'),
+    '#element_validate' => array('form_test_validate_required_form_element_validate'),
+  );
+  $form['actions'] = array('#type' => 'actions');
+  $form['actions']['submit'] = array('#type' => 'submit', '#value' => 'Submit');
+  return $form;
+}
+
+/**
+ * Form element validation handler for 'Name' field in form_test_validate_required_form().
+ */
+function form_test_validate_required_form_element_validate($element, &$form_state) {
+  // Set a custom validation error on the #required element.
+  if (is_string($element['#value']) && $element['#value'] === '') {
+    form_error($element, $element['#required_error']);
+  }
+  elseif (empty($element['#value'])) {
+    form_error($element, $element['#required_error']);
+  }
+}
+
+/**
+ * Form validation handler for 'Title' field in form_test_validate_required_form().
+ */
+function form_test_validate_required_form_validate($form, &$form_state) {
+  // Set a custom validation error on the #required element.
+  if ($form_state['values']['form'] === '') {
+    form_error($form['form'], $form['form']['#required_error']);
+  }
+}
+
+/**
  * Builds a simple form with a button triggering partial validation.
  */
 function form_test_limit_validation_errors_form($form, &$form_state) {
