? MISC-FIELD-CHANGES-REAPPLY.patch
? Makefile
? d6-50-nodes.sql.gz
? d7-50-nodes-new.sql.gz
? d7-50-nodes.sql.gz
? head.kpf
? patches
? scripts/OLD-generate-autoload.pl
? scripts/generate-autoload.pl
? sites/all/cck
? sites/all/modules/color
? sites/all/modules/combofield
? sites/all/modules/devel
? sites/all/modules/pbs
? sites/all/modules/taint
? sites/default/files
? sites/default/private
? sites/default/settings.php
Index: modules/field/modules/options/options.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/options/options.info,v
retrieving revision 1.3
diff -u -F^[fc] -r1.3 options.info
--- modules/field/modules/options/options.info	12 Jun 2009 08:39:36 -0000	1.3
+++ modules/field/modules/options/options.info	15 Oct 2009 21:31:18 -0000
@@ -5,4 +5,5 @@
 version = VERSION
 core = 7.x
 files[]=options.module
+files[]=options.test
 required = TRUE
Index: modules/field/modules/options/options.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/options/options.module,v
retrieving revision 1.12
diff -u -F^[fc] -r1.12 options.module
--- modules/field/modules/options/options.module	15 Oct 2009 12:44:34 -0000	1.12
+++ modules/field/modules/options/options.module	15 Oct 2009 21:31:18 -0000
@@ -131,13 +131,20 @@ function options_buttons_elements_proces
   $options = options_options($field, $instance);
   $multiple = isset($element['#multiple']) ? $element['#multiple'] : $field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED;
 
-  $value = array();
-  foreach ($element['#value'][$field_key] as $key) {
-    // Multiple (checkboxes) need the default value in the form of an array.
+  // Incoming #value is an array (checkboxes) or integer (radios).
+  $keys = $element['#value'][$field_key];
+  if (!is_array($keys)) {
+    $keys = array($keys);
+  }
+
+  // Multiple (checkboxes) need #default_value to be an array, and
+  // non-multiple (radios) need a single default value. If #value is
+  // empty we loop won't run, so initialize $value to the right type.
+  $value = $multiple ? array() : '';
+  foreach ($keys as $key) {
     if ($multiple) {
-      $value[$key] = 1;
+      $value[] = $key;
     }
-    // Non-multiple (radios) need single default value.
     else {
       $value = $key;
       break;
Index: modules/field/modules/options/options.test
===================================================================
RCS file: modules/field/modules/options/options.test
diff -N modules/field/modules/options/options.test
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/field/modules/options/options.test	15 Oct 2009 21:31:18 -0000
@@ -0,0 +1,199 @@
+<?php
+// $Id: text.test,v 1.10 2009/08/22 00:58:53 webchick Exp $
+
+class OptionsWidgetsTestCase extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name'  => 'Options widgets',
+      'description'  => "Test the Options widgets.",
+      'group' => 'Field'
+    );
+  }
+
+  function setUp() {
+    parent::setUp('field_test');
+
+    $this->list_values = array(1 => 'One', 2 => 'Two', 3 => 'Three');
+    $this->card_1 = array(
+      'field_name' => 'card_1',
+      'type' => 'list',
+      'cardinality' => 1,
+      'settings' => array(
+        'allowed_values' => "1|One\n2|Two\n3|Three\n",
+      ),
+    );
+    $this->card_1 = field_create_field($this->card_1);
+
+    $this->card_2 = array(
+      'field_name' => 'card_2',
+      'type' => 'list',
+      'cardinality' => 2,
+      'settings' => array(
+        'allowed_values' => "1|One\n2|Two\n3|Three\n",
+      ),
+    );
+    $this->card_2 = field_create_field($this->card_2);
+  }
+
+  /**
+   * Test widgets
+   */
+
+  /**
+   * Return an element from rendered HTML by id, or '' if id is not found.
+   */
+  function getTagById($html, $id) {
+    // @todo: ids sometimes have an extra -n after them; why?
+    if (preg_match('@(<[^>]*id="' . $id . '(?:-\d+)?"[^>]*/>)@i', $html, $m)) {
+      return $m[0];
+    }
+    return '';
+  }
+
+  /**
+   * Assert that a checkbox identified by $id is checked.
+   */
+  function assertIsChecked($html, $id) {
+    $input = $this->getTagById($html, $id);
+    $this->assertTrue(preg_match('@checked="checked"@', $input), t('Checkbox %id is checked', array('%id' => $id)));
+  }
+
+  /**
+   * Assert that a checkbox identified by $id is not checked.
+   */
+  function assertIsNotChecked($html, $id) {
+    $input = $this->getTagById($html, $id);
+    if (!empty($input)) {
+      $this->assertFalse(preg_match('@checked@', $input), t('Checkbox %id is not checked', array('%id' => $id)));
+    }
+    else {
+      $this->fail(t('Checkbox %id is not found', array('%id' => $id)));
+    }
+  }
+
+  /**
+   * Return an <option> element by value from rendered HTML, or
+   * '' if it is not found. 
+   */
+  function getOptionByValue($html, $value) {
+    if (preg_match('@(<option[^>]*value="' . $value . '"[^>]*>[^<]*</option>)@i', $html, $m)) {
+      return $m[0];
+    }
+    return '';
+  }
+
+  /**
+   * Assert that an <option> for value $value is selected.
+   */
+  function assertIsSelected($html, $value) {
+    $input = $this->getOptionByValue($html, $value);
+    $this->assertTrue(preg_match('@selected="selected"@', $input), t('Option %value is selected', array('%value' => $value)));
+  }
+
+  /**
+   * Assert that an <option> for value $value is not selected.
+   */
+  function assertIsNotSelected($html, $value) {
+    $input = $this->getOptionByValue($html, $value);
+    if (!empty($input)) {
+      $this->assertFalse(preg_match('@selected@', $input), t('Option %value is not selected', array('%value' => $value)));
+    }
+    else {
+      $this->fail(t('Option %value is not found', array('%value' => $value)));
+    }
+  }
+
+  function testRadioButtons() {
+    $instance = array(
+      'field_name' => $this->card_1['field_name'],
+      'object_type' => 'test_entity',
+      'bundle' => FIELD_TEST_BUNDLE,
+      'widget' => array(
+        'type' => 'options_buttons',
+      ),
+    );
+    $instance = field_create_instance($instance);
+
+    $entity = field_test_create_stub_entity(0, 0, FIELD_TEST_BUNDLE);
+
+    // With no field data, no buttons are checked.
+    $form = drupal_get_form('field_test_entity_form', $entity);
+    $render = drupal_render($form);
+    $this->assertIsNotChecked($render, 'edit-card-1-zxx-value-1');
+    $this->assertIsNotChecked($render, 'edit-card-1-zxx-value-2');
+    $this->assertIsNotChecked($render, 'edit-card-1-zxx-value-3');
+
+    // With field data, the selected button is checked.
+    $entity->card_1[FIELD_LANGUAGE_NONE][0]['value'] = '2';
+    $form = drupal_get_form('field_test_entity_form', $entity);
+    $render = drupal_render($form);
+    $this->assertIsNotChecked($render, 'edit-card-1-zxx-value-1');
+    $this->assertIsChecked($render, 'edit-card-1-zxx-value-2');
+    $this->assertIsNotChecked($render, 'edit-card-1-zxx-value-3');
+  }
+
+  function testCheckBoxes() {
+    $instance = array(
+      'field_name' => $this->card_2['field_name'],
+      'object_type' => 'test_entity',
+      'bundle' => FIELD_TEST_BUNDLE,
+      'widget' => array(
+        'type' => 'options_buttons',
+      ),
+    );
+    $instance = field_create_instance($instance);
+
+    $entity = field_test_create_stub_entity(0, 0, FIELD_TEST_BUNDLE);
+
+    // With no field data, nothing is checked.
+    $form = drupal_get_form('field_test_entity_form', $entity);
+    $render = drupal_render($form);
+    $this->assertIsNotChecked($render, 'edit-card-2-zxx-value-1');
+    $this->assertIsNotChecked($render, 'edit-card-2-zxx-value-2');
+    $this->assertIsNotChecked($render, 'edit-card-2-zxx-value-3');
+
+    // With field data, the specified items are checked.
+    $entity->card_2[FIELD_LANGUAGE_NONE][0]['value'] = '2';
+    $entity->card_2[FIELD_LANGUAGE_NONE][1]['value'] = '3';
+    $form = drupal_get_form('field_test_entity_form', $entity);
+    $render = drupal_render($form);
+    $this->assertIsNotChecked($render, 'edit-card-2-zxx-value-1');
+    $this->assertIsChecked($render, 'edit-card-2-zxx-value-2');
+    $this->assertIsChecked($render, 'edit-card-2-zxx-value-3');
+  }
+
+  function testSelectList() {
+    $instance = array(
+      'field_name' => $this->card_2['field_name'],
+      'object_type' => 'test_entity',
+      'bundle' => FIELD_TEST_BUNDLE,
+      'widget' => array(
+        'type' => 'options_select',
+      ),
+    );
+    $instance = field_create_instance($instance);
+
+    $entity = field_test_create_stub_entity(0, 0, FIELD_TEST_BUNDLE);
+
+    // With no field data, no options are selected.
+    $form = drupal_get_form('field_test_entity_form', $entity);
+    $render = drupal_render($form);
+    $this->assertIsNotSelected($render, 1);
+    $this->assertIsNotSelected($render, 2);
+    $this->assertIsNotSelected($render, 3);
+
+    // With field data, the specified options are selected.
+    $entity->card_2[FIELD_LANGUAGE_NONE][0]['value'] = '2';
+    $entity->card_2[FIELD_LANGUAGE_NONE][1]['value'] = '1';
+    $form = drupal_get_form('field_test_entity_form', $entity);
+    $render = drupal_render($form);
+    $this->assertIsSelected($render, 1);
+    $this->assertIsSelected($render, 2);
+    $this->assertIsNotSelected($render, 3);
+  }
+
+  /**
+   * @todo: Test formatters.
+   */
+}
+
