Index: modules/simpletest/tests/form.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/form.test,v
retrieving revision 1.13
diff -u -r1.13 form.test
--- modules/simpletest/tests/form.test 2 Jun 2009 13:47:26 -0000 1.13
+++ modules/simpletest/tests/form.test 13 Jun 2009 20:11:57 -0000
@@ -10,22 +10,29 @@
public static function getInfo() {
return array(
- 'name' => t('Required field validation'),
- 'description' => t('Carriage returns, tabs, and spaces are not valid content for a required field.'),
+ 'name' => t('Field validation'),
+ 'description' => t('Test various field validation mechanisms.'),
'group' => t('Form API'),
);
}
+
+ function setUp() {
+ return parent::setUp('form_test');
+ }
/**
* Check several empty values for required forms elements.
*
+ * Carriage returns, tabs, spaces, and unchecked checkbox elements are not
+ * valid content for a required field.
+ *
* If the form field is found in form_get_errors() then the test pass.
*/
function testRequiredFields() {
- // Originates from http://drupal.org/node/117748
// Sets of empty strings and arrays
$empty_strings = array('""' => "", '"\n"' => "\n", '" "' => " ", '"\t"' => "\t", '" \n\t "' => " \n\t ", '"\n\n\n\n\n"' => "\n\n\n\n\n");
$empty_arrays = array('array()' => array());
+ $empty_checkbox = array(NULL);
$elements['textfield']['element'] = array('#title' => $this->randomName(), '#type' => 'textfield', '#required' => TRUE);
$elements['textfield']['empty_values'] = $empty_strings;
@@ -42,6 +49,9 @@
$elements['radios']['element'] = array('#title' => $this->randomName(), '#type' => 'radios', '#required' => TRUE, '#options' => array($this->randomName(), $this->randomName(), $this->randomName()));
$elements['radios']['empty_values'] = $empty_arrays;
+ $elements['checkbox']['element'] = array('#title' => $this->randomName(), '#type' => 'checkbox', '#required' => TRUE, '#title' => $this->randomName());
+ $elements['checkbox']['empty_values'] = $empty_checkbox;
+
$elements['checkboxes']['element'] = array('#title' => $this->randomName(), '#type' => 'checkboxes', '#required' => TRUE, '#options' => array($this->randomName(), $this->randomName(), $this->randomName()));
$elements['checkboxes']['empty_values'] = $empty_arrays;
@@ -72,42 +82,32 @@
// Clear the expected form error messages so they don't appear as exceptions.
drupal_get_messages();
}
-}
-
-/**
- * Test form type functions for expected behavior.
- */
-class FormsTestTypeCase extends DrupalUnitTestCase {
- public static function getInfo() {
- return array(
- 'name' => t('Form type-specific tests'),
- 'description' => t('Test form type functions for expected behavior.'),
- 'group' => t('Form API'),
- );
- }
/**
- * Test form_type_checkbox_value() function for expected behavior.
+ * Test default value handling for checkboxes.
+ *
+ * @see form_test_checkbox().
*/
- function testFormCheckboxValue() {
- $form['#return_value'] = $return_value = $this->randomName();
- $form['#default_value'] = $default_value = $this->randomName();
- // Element is disabled , and $edit is not empty.
- $form['#disabled'] = TRUE;
- $edit = array(1);
- $this->assertEqual(form_type_checkbox_value($form, $edit), $default_value, t('form_type_checkbox_value() returns the default value when #disabled is set.'));
-
- // Element is not disabled, $edit is not empty.
- unset($form['#disabled']);
- $this->assertEqual(form_type_checkbox_value($form, $edit), $return_value, t('form_type_checkbox_value() returns the return value when #disabled is not set.'));
-
- // Element is not disabled, $edit is empty.
- $edit = array();
- $this->assertIdentical(form_type_checkbox_value($form, $edit), 0, t('form_type_checkbox_value() returns 0 when #disabled is not set, and $edit is empty.'));
+ function testCheckBoxProcessing() {
+ // First, try to submit without the required checkbox.
+ $this->drupalPost('form-test/checkbox', array(), t('Submit'));
+ if ($this->assertRaw(t('!name field is required.', array('!name' => 'required_checkbox')), t('A required checkbox is actually mandatory'))) {
+ // Now try to submit the form correctly.
+ $this->drupalPost(NULL, array('required_checkbox' => 1), t('Submit'));
+ }
- // $edit is FALSE.
- $edit = FALSE;
- $this->assertNull(form_type_checkbox_value($form, $edit), t('form_type_checkbox_value() returns NULL when $edit is FALSE'));
+ $values = json_decode($this->drupalGetContent(), TRUE);
+ $expected_values = array(
+ 'disabled_checkbox_on' => 'disabled_checkbox_on',
+ 'disabled_checkbox_off' => '',
+ 'checkbox_on' => 'checkbox_on',
+ 'checkbox_off' => '',
+ 'zero_checkbox_on' => '0',
+ 'zero_checkbox_off' => '',
+ );
+ foreach ($expected_values as $widget => $expected_value) {
+ $this->assertEqual($values[$widget], $expected_value, t('Checkbox %widget returns expected value (expected: %expected, got: %value)', array('%widget' => var_export($widget, TRUE), '%expected' => var_export($expected_value, TRUE), '%value' => var_export($values[$widget], TRUE))));
+ }
}
}
Index: modules/simpletest/tests/form_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/form_test.module,v
retrieving revision 1.7
diff -u -r1.7 form_test.module
--- modules/simpletest/tests/form_test.module 27 May 2009 18:34:00 -0000 1.7
+++ modules/simpletest/tests/form_test.module 13 Jun 2009 20:11:57 -0000
@@ -66,6 +66,14 @@
'type' => MENU_CALLBACK,
);
+ $items['form-test/checkbox'] = array(
+ 'title' => t('Form test'),
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('_form_test_checkbox'),
+ 'access callback' => TRUE,
+ 'type' => MENU_CALLBACK,
+ );
+
return $items;
}
@@ -168,6 +176,83 @@
}
/**
+ * Build a form to test a checkbox.
+ */
+function _form_test_checkbox() {
+ $form = array();
+
+ // A required checkbox.
+ $form['required_checkbox'] = array(
+ '#type' => 'checkbox',
+ '#required' => TRUE,
+ '#title' => 'required_checkbox',
+ );
+
+ // A disabled checkbox should get its default value back.
+ $form['disabled_checkbox_on'] = array(
+ '#type' => 'checkbox',
+ '#disabled' => TRUE,
+ '#return_value' => 'disabled_checkbox_on',
+ '#default_value' => 'disabled_checkbox_on',
+ '#title' => 'disabled_checkbox_on',
+ );
+ $form['disabled_checkbox_off'] = array(
+ '#type' => 'checkbox',
+ '#disabled' => TRUE,
+ '#return_value' => 'disabled_checkbox_off',
+ '#default_value' => NULL,
+ '#title' => 'disabled_checkbox_off',
+ );
+
+ // A checkbox is active when #default_value == #return_value.
+ $form['checkbox_on'] = array(
+ '#type' => 'checkbox',
+ '#return_value' => 'checkbox_on',
+ '#default_value' => 'checkbox_on',
+ '#title' => 'checkbox_on',
+ );
+
+ // But inactive in any other case.
+ $form['checkbox_off'] = array(
+ '#type' => 'checkbox',
+ '#return_value' => 'checkbox_off',
+ '#default_value' => 'checkbox_on',
+ '#title' => 'checkbox_off',
+ );
+
+ // Checkboxes with a #return_value of '0' are supported.
+ $form['zero_checkbox_on'] = array(
+ '#type' => 'checkbox',
+ '#return_value' => '0',
+ '#default_value' => '0',
+ '#title' => 'zero_checkbox_on',
+ );
+
+ // In that case, passing a #default_value != '0' means that the checkbox is off.
+ $form['zero_checkbox_off'] = array(
+ '#type' => 'checkbox',
+ '#return_value' => '0',
+ '#default_value' => 1,
+ '#title' => 'zero_checkbox_off',
+ );
+
+ $form['op'] = array(
+ '#type' => 'submit',
+ '#value' => t('Submit')
+ );
+
+ return $form;
+}
+
+/**
+ * Return the form values by JSON.
+ */
+function _form_test_checkbox_submit($form_id, &$form_state) {
+ drupal_json($form_state['values']);
+ exit;
+}
+
+/**
* Process the tableselect #multiple = TRUE submitted values.
*/
function _form_test_tableselect_multiple_true_form_submit($form, &$form_state) {
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.339
diff -u -r1.339 form.inc
--- includes/form.inc 2 Jun 2009 13:47:25 -0000 1.339
+++ includes/form.inc 13 Jun 2009 20:11:57 -0000
@@ -1256,11 +1256,20 @@
*/
function form_type_checkbox_value($form, $edit = FALSE) {
if ($edit !== FALSE) {
- if (empty($form['#disabled'])) {
- return !empty($edit) ? $form['#return_value'] : 0;
+ if (isset($edit)) {
+ // A value is passed by the browser: the checkbox is on.
+ return $form['#return_value'];
}
else {
- return $form['#default_value'];
+ if (!empty($form['#disabled'])) {
+ // Disabled checkbox values are not passed by the browser,
+ // use default instead.
+ return $form['#default_value'];
+ }
+ else {
+ // The checkbox is off.
+ return '';
+ }
}
}
}
@@ -2049,17 +2058,19 @@
* @ingroup themeable
*/
function theme_checkbox($element) {
+ $t = get_t();
_form_set_class($element, array('form-checkbox'));
$checkbox = '';
if (!is_null($element['#title'])) {
- $checkbox = '';
+ $required = !empty($element['#required']) ? ' *' : '';
+ $checkbox = '';
}
return $checkbox;
@@ -2112,7 +2123,7 @@
'#processed' => TRUE,
'#title' => $choice,
'#return_value' => $key,
- '#default_value' => isset($value[$key]),
+ '#default_value' => isset($value[$key]) ? $key : NULL,
'#attributes' => $element['#attributes'],
'#ahah' => isset($element['#ahah']) ? $element['#ahah'] : NULL,
);