Index: modules/field/field.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.test,v
retrieving revision 1.10
diff -u -p -r1.10 field.test
--- modules/field/field.test	13 Apr 2009 05:18:17 -0000	1.10
+++ modules/field/field.test	16 Apr 2009 22:40:29 -0000
@@ -1,7 +1,10 @@
 <?php
 // $Id: field.test,v 1.10 2009/04/13 05:18:17 webchick Exp $
 
-// TODO : use drupalCreateField() / drupalCreateFieldInstance() all over ?
+/**
+ * @file
+ * The unit test file for fields in core.
+ */
 
 class FieldAttachTestCase extends DrupalWebTestCase {
   public static function getInfo() {
@@ -13,18 +16,15 @@ class FieldAttachTestCase extends Drupal
   }
 
   function setUp() {
-    parent::setUp('field_sql_storage', 'field', 'field_test');
-
-    $this->field_name = drupal_strtolower($this->randomName(). '_field_name');
-    $this->table = _field_sql_storage_tablename($this->field_name);
-    $this->revision_table = _field_sql_storage_revision_tablename($this->field_name);
+    parent::setUp(variable_get('field_storage_module', 'field_sql_storage'), 'field', 'field_test');
+    $this->field_name = drupal_strtolower($this->randomName() . '_field_name');
     $this->field = array('field_name' => $this->field_name, 'type' => 'test_field', 'cardinality' => 4);
     field_create_field($this->field);
     $this->instance = array(
       'field_name' => $this->field_name,
       'bundle' => 'test_bundle',
-      'label' => $this->randomName(). '_label',
-      'description' => $this->randomName(). '_description',
+      'label' => $this->randomName() . '_label',
+      'description' => $this->randomName() . '_description',
       'weight' => mt_rand(0, 127),
       'settings' => array(
         'test_instance_setting' => $this->randomName(),
@@ -40,60 +40,6 @@ class FieldAttachTestCase extends Drupal
     field_create_instance($this->instance);
   }
 
-  function testFieldAttachLoad() {
-    $entity_type = 'test_entity';
-    $eid = 0;
-
-    $etid = _field_sql_storage_etid($entity_type);
-    $columns = array('etid', 'entity_id', 'revision_id', 'delta', $this->field_name . '_value');
-
-    // Insert data for four revisions to the field revisions table
-    $query = db_insert($this->revision_table)->fields($columns);
-    for ($evid = 0; $evid < 4; ++$evid) {
-      $values[$evid] = array();
-      // Note: we insert one extra value ('<=' instead of '<').
-      for ($delta = 0; $delta <= $this->field['cardinality']; $delta++) {
-        $value = mt_rand(1, 127);
-        $values[$evid][] = $value;
-        $query->values(array($etid, $eid, $evid, $delta, $value));
-      }
-    }
-    $query->execute();
-
-    // Insert data for the "most current revision" into the field table
-    $query = db_insert($this->table)->fields($columns);
-    foreach ($values[0] as $delta => $value) {
-      $query->values(array($etid, $eid, 0, $delta, $value));
-    }
-    $query->execute();
-
-    // Load the "most current revision"
-    $entity = field_test_create_stub_entity($eid, 0, $this->instance['bundle']);
-    field_attach_load($entity_type, array($eid => $entity));
-    foreach ($values[0] as $delta => $value) {
-      if ($delta < $this->field['cardinality']) {
-        $this->assertEqual($entity->{$this->field_name}[$delta]['value'], $value, "Value $delta is loaded correctly for current revision");
-      }
-      else {
-        $this->assertFalse(array_key_exists($delta, $entity->{$this->field_name}), "No extraneous value gets loaded for current revision.");
-      }
-    }
-
-    // Load every revision
-    for ($evid = 0; $evid < 4; ++$evid) {
-      $entity = field_test_create_stub_entity($eid, $evid, $this->instance['bundle']);
-      field_attach_load_revision($entity_type, array($eid => $entity));
-      foreach ($values[$evid] as $delta => $value) {
-        if ($delta < $this->field['cardinality']) {
-          $this->assertEqual($entity->{$this->field_name}[$delta]['value'], $value, "Value $delta for revision $evid is loaded correctly");
-        }
-        else {
-          $this->assertFalse(array_key_exists($delta, $entity->{$this->field_name}), "No extraneous value gets loaded for revision $evid.");
-        }
-      }
-    }
-  }
-
 //  function testFieldAttachLoadMultiple() {
     // TODO : test the 'multiple' aspect of load:
     // define 2 bundles, 3 fields
@@ -102,120 +48,129 @@ class FieldAttachTestCase extends Drupal
     // load 2 entities (one for each bundle) in a single load
     // check that everything gets loaded ok.
 //  }
-
-  function testFieldAttachInsertAndUpdate() {
+  function testFieldAttachLoadAndInsertAndUpdate() {
     $entity_type = 'test_entity';
-    $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
-
-    // Test insert.
     $values = array();
-    // Note: we try to insert one extra value ('<=' instead of '<').
-    // TODO : test empty values filtering and "compression" (store consecutive deltas).
+    // Note: we insert one extra value ('<=' instead of '<').
     for ($delta = 0; $delta <= $this->field['cardinality']; $delta++) {
       $values[$delta]['value'] = mt_rand(1, 127);
     }
-    $entity->{$this->field_name} = $rev_values[0] = $values;
-    field_attach_insert($entity_type, $entity);
+    for ($rev_index =0; $rev_index < 3; $rev_index++) {
+      $rev[$rev_index] = field_test_create_stub_entity(0, $rev_index, $this->instance['bundle']);
 
-    $rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', PDO::FETCH_ASSOC);
-    foreach ($values as $delta => $value) {
-      if ($delta < $this->field['cardinality']) {
-        $this->assertEqual($rows[$delta][$this->field_name . '_value'], $value['value'], t("Value $delta is inserted correctly"));
+      // Create initial content revision 0 
+      if (!$rev_index) {
+        $rev[$rev_index]->{$this->field_name} = $values;
+        field_attach_insert($entity_type, $rev[$rev_index]);
       }
       else {
-        $this->assertFalse(array_key_exists($delta, $rows), "No extraneous value gets inserted.");
-      }
-    }
-
-    // Test update.
-    $entity = field_test_create_stub_entity(0, 1, $this->instance['bundle']);
-    $values = array();
-    // Note: we try to update one extra value ('<=' instead of '<').
-    for ($delta = 0; $delta <= $this->field['cardinality']; $delta++) {
-      $values[$delta]['value'] = mt_rand(1, 127);
-    }
-    $entity->{$this->field_name} = $rev_values[1] = $values;
-    field_attach_update($entity_type, $entity);
-    $rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', PDO::FETCH_ASSOC);
-    foreach ($values as $delta => $value) {
-      if ($delta < $this->field['cardinality']) {
-        $this->assertEqual($rows[$delta][$this->field_name . '_value'], $value['value'], t("Value $delta is updated correctly"));
-      }
-      else {
-        $this->assertFalse(array_key_exists($delta, $rows), "No extraneous value gets updated.");
+        // create revisions
+        $rev[$rev_index] = field_test_create_stub_entity(0, $rev_index, $this->instance['bundle']);    
+        try {
+          $rev[$rev_index]->{$this->field_name} = $values;
+          field_attach_update($entity_type, $rev[$rev_index]);
+          $this->pass("created revision $rev_index");
+        }
+        catch (PDOException $e) {
+          $this->fail($e->getMessage());
+        }
       }
     }
-
-    // Check that data for both revisions are in the revision table.
-    // We make sure each value is stored correctly, then unset it.
-    // When an entire revision's values are unset (remembering that we
-    // put one extra value in $values per revision), unset the entire
-    // revision. Then, if $rev_values is empty at the end, all
-    // revision data was found.
-    $results = db_select($this->revision_table, 't')->fields('t')->execute();
-    foreach ($results as $row) {
-      $this->assertEqual($row->{$this->field_name . '_value'}, $rev_values[$row->revision_id][$row->delta]['value'], "Value {$row->delta} for revision {$row->revision_id} stored correctly");
-      unset($rev_values[$row->revision_id][$row->delta]);
-      if (count($rev_values[$row->revision_id]) == 1) {
-        unset($rev_values[$row->revision_id]);
-      }
+    // Confirm current revision loads
+    $load = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
+    field_attach_load($entity_type, array(0 => $load));
+    $this->assertEqual(count($load->{$this->field_name}), $this->field['cardinality'], "The test object revision currrent has {$this->field['cardinality']} values.");
+    for ($delta = 0; $delta < $this->field['cardinality']; $delta++) {
+      $this->assertEqual($load->{$this->field_name}[$delta]['value'] , $values[$delta]['value'], "current revision  field $delta ok");
     }
-    $this->assertTrue(empty($rev_values), "All values for all revisions are stored in revision table {$this->revision_table}");
 
-    // Check that update leaves the field data untouched if $object has no
-    // $field_name key.
-    unset($entity->{$this->field_name});
-    field_attach_update($entity_type, $entity);
-    $rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', PDO::FETCH_ASSOC);
-    foreach ($values as $delta => $value) {
-      if ($delta < $this->field['cardinality']) {
-        $this->assertEqual($rows[$delta][$this->field_name . '_value'], $value['value'], t("Update with no field_name entry leaves value $delta untouched"));
+    // Confirm each revision loads
+    foreach (array_keys($rev) as $vid) {
+      $load = field_test_create_stub_entity(0, $vid, $this->instance['bundle']);
+      field_attach_load_revision($entity_type, array(0 => $load));
+      $this->assertEqual(count($load->{$this->field_name}), $this->field['cardinality'], "The test object revision $vid has {$this->field['cardinality']} values.");
+      for ($delta = 0; $delta < $this->field['cardinality']; $delta++) {
+        $this->assertEqual($load->{$this->field_name}[$delta]['value'], $values[$delta]['value'], "The test object revision $vid field $delta ok.");
       }
+      $this->assertTrue(FALSE);
     }
-
-    // Check that update with an empty $object->$field_name empties the field.
-    $entity->{$this->field_name} = NULL;
-    field_attach_update($entity_type, $entity);
-    $rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', PDO::FETCH_ASSOC);
-    $this->assertEqual(count($rows), 0, t("Update with an empty field_name entry empties the field."));
-  }
+  } 
 
   // Test insert and update with missing or invalid fields. For the
   // most part, these tests pass by not crashing or causing exceptions.
   function testFieldAttachSaveMissingData() {
+    $test_data = 5;
     $entity_type = 'test_entity';
     $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
 
     // Insert: Field is missing
     field_attach_insert($entity_type, $entity);
-    $count = db_result(db_query("SELECT COUNT(*) FROM {{$this->table}}"));
-    $this->assertEqual($count, 0, 'Missing field results in no inserts');
-
+    $this->assertTrue(TRUE, 'Missing field in insert ok');
+    $entity->{$this->field_name} = NULL;
+      
     // Insert: Field is NULL
     $entity->{$this->field_name} = NULL;
-    field_attach_insert($entity_type, $entity);
-    $count = db_result(db_query("SELECT COUNT(*) FROM {{$this->table}}"));
-    $this->assertEqual($count, 0, 'NULL field results in no inserts');
+    field_attach_insert($entity_type, $entity);    
+    $this->assertTrue(TRUE, 'NULL field in insert ok');
+    field_attach_load($entity_type, array(0 => $entity));
+    $this->assertTrue($entity->{$this->field_name} == NULL, 'NULL field in insert ok');
 
     // Add some real data
-    $entity->{$this->field_name} = array(0 => array('value' => 1));
+    $entity->{$this->field_name} = array(0 => array('value' => $test_data));
     field_attach_insert($entity_type, $entity);
-    $count = db_result(db_query("SELECT COUNT(*) FROM {{$this->table}}"));
-    $this->assertEqual($count, 1, 'Field data saved');
+    $this->assertTrue(TRUE, 'with data insert ok');
+    $entity->{$this->field_name} = NULL;
+    field_attach_load($entity_type, array(0 => $entity));
+    $this->assertTrue($entity->{$this->field_name}[0]['value'] == $test_data, 'with data ok');
+    $values = array(array());
+    // Note: we insert one extra value ('<=' instead of '<').    
+    for ($delta = 0;$delta <= $this->field['cardinality'];$delta++) {
+      $values[$delta]['value'] = mt_rand(1, 127); ;
+    }
+    $entity->{$this->field_name} = $values;
+    try {
+      field_attach_update($entity_type, $entity);
+      $this->assertTrue(TRUE, 'with data insert ok');
+      $entity->{$this->field_name} = NULL;
+      field_attach_load($entity_type, array(0 => $entity));
+      for ($delta = 0;$delta < $this->field['cardinality'] ;$delta++) {
+        $this->assertEqual($entity->{$this->field_name}[$delta]['value'], $values[$delta]['value'], 'with data ok');
+      };
+    } 
+    catch (PDOException $e) {
+      $this->fail($e->getMessage());
+    }
 
     // Update: Field is missing. Data should survive.
     unset($entity->{$this->field_name});
-    field_attach_update($entity_type, $entity);
-    $count = db_result(db_query("SELECT COUNT(*) FROM {{$this->table}}"));
-    $this->assertEqual($count, 1, 'Missing field leaves data in table');
+    try {
+      field_attach_update($entity_type, $entity);
+      $this->assertTrue(TRUE, 'Missing field update');
+      $entity->{$this->field_name} = NULL;
+      field_attach_load($entity_type, array(0 => $entity));
+      for ($delta = 0;$delta < $this->field['cardinality'] ;$delta++) {
+        $this->assertEqual($entity->{$this->field_name}[$delta]['value'], $values[$delta]['value'], 'with data ok');
+      };
+  //    $this->assertTrue($entity->{$this->field_name}[0]['value'] == $values[0]['value'], 'Missing field update');
+    }
+    catch (PDOException $e) {
+      $this->fail($e->getMessage());    
+    }
 
     // Update: Field is NULL. Data should be wiped.
     $entity->{$this->field_name} = NULL;
-    field_attach_update($entity_type, $entity);
-    $count = db_result(db_query("SELECT COUNT(*) FROM {{$this->table}}"));
-    $this->assertEqual($count, 0, 'NULL field leaves no data in table');
+    try {
+      field_attach_update($entity_type, $entity);
+      $this->pass('NULL field update');
+      //todo is this correct
+      field_attach_load($entity_type, array(0 => $entity));
+      $this->assertTrue($entity->{$this->field_name} == NULL, 'NULL field update');
+    }
+    catch (PDOException $e) {
+      $this->fail($e->getMessage());
+    }
   }
-
+  
   function testFieldAttachViewAndPreprocess() {
     $entity_type = 'test_entity';
     $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
@@ -381,7 +336,8 @@ class FieldAttachTestCase extends Drupal
     // Save an object with data in the field.
     $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
     $values = array();
-    for ($delta = 0; $delta < $this->field['cardinality']; $delta++) {
+    // Note: we insert one extra value ('<=' instead of '<').    
+    for ($delta = 0; $delta <= $this->field['cardinality']; $delta++) {
       $values[$delta]['value'] = mt_rand(1, 127);
     }
     $entity->{$this->field_name} = $values;
@@ -419,16 +375,14 @@ class FieldAttachTestCase extends Drupal
     field_create_instance($this->instance);
 
     // Create a second field for the test bundle
-    $field_name = drupal_strtolower($this->randomName(). '_field_name');
-    $table = _field_sql_storage_tablename($field_name);
-    $revision_table = _field_sql_storage_revision_tablename($field_name);
+    $field_name = drupal_strtolower($this->randomName() . '_field_name');
     $field = array('field_name' => $field_name, 'type' => 'test_field', 'cardinality' => 1);
     field_create_field($field);
     $instance = array(
       'field_name' => $field_name,
       'bundle' => $this->instance['bundle'],
-      'label' => $this->randomName(). '_label',
-      'description' => $this->randomName(). '_description',
+      'label' => $this->randomName() . '_label',
+      'description' => $this->randomName() . '_description',
       'weight' => mt_rand(0, 127),
       // test_field has no instance settings
       'widget' => array(
@@ -726,14 +680,14 @@ class FieldFormTestCase extends DrupalWe
     $web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content'));
     $this->drupalLogin($web_user);
 
-    $this->field_single = array('field_name' => drupal_strtolower($this->randomName(). '_field_name'), 'type' => 'test_field');
-    $this->field_multiple = array('field_name' => drupal_strtolower($this->randomName(). '_field_name'), 'type' => 'test_field', 'cardinality' => 4);
-    $this->field_unlimited = array('field_name' => drupal_strtolower($this->randomName(). '_field_name'), 'type' => 'test_field', 'cardinality' => FIELD_CARDINALITY_UNLIMITED);
+    $this->field_single = array('field_name' => drupal_strtolower($this->randomName() . '_field_name'), 'type' => 'test_field');
+    $this->field_multiple = array('field_name' => drupal_strtolower($this->randomName() . '_field_name'), 'type' => 'test_field', 'cardinality' => 4);
+    $this->field_unlimited = array('field_name' => drupal_strtolower($this->randomName() . '_field_name'), 'type' => 'test_field', 'cardinality' => FIELD_CARDINALITY_UNLIMITED);
 
     $this->instance = array(
       'bundle' => 'test_bundle',
-      'label' => $this->randomName(). '_label',
-      'description' => $this->randomName(). '_description',
+      'label' => $this->randomName() . '_label',
+      'description' => $this->randomName() . '_description',
       'weight' => mt_rand(0, 127),
       'settings' => array(
         'test_instance_setting' => $this->randomName(),
@@ -892,7 +846,7 @@ class FieldFormTestCase extends DrupalWe
     $this->assertPattern("|$pattern|s", 'Widgets are displayed in the correct order');
     $this->assertFieldByName("$this->field_name[$delta][value]", '', "New widget is displayed");
     $this->assertFieldByName("$this->field_name[$delta][_weight]", $delta, "New widget has the right weight");
-    $this->assertNoField("$this->field_name[". ($delta + 1) . '][value]', 'No extraneous widget is displayed');
+    $this->assertNoField("$this->field_name[" . ($delta + 1) . '][value]', 'No extraneous widget is displayed');
 
     // Submit the form and create the entity.
     $this->drupalPost(NULL, $edit, t('Save'));
@@ -946,7 +900,8 @@ class FieldTestCase extends DrupalWebTes
       );
       field_create_field($field_definition);
       $this->fail(t('Cannot create a field with no type.'));
-    } catch (FieldException $e) {
+    } 
+    catch (FieldException $e) {
       $this->pass(t('Cannot create a field with no type.'));
     }
 
@@ -955,7 +910,8 @@ class FieldTestCase extends DrupalWebTes
       $field_definition = array('type' => 'test_field');
       field_create_field($field_definition);
       $this->fail(t('Cannot create an unnamed field.'));
-    } catch (FieldException $e) {
+    } 
+    catch (FieldException $e) {
       $this->pass(t('Cannot create an unnamed field.'));
     }
 
@@ -979,14 +935,12 @@ class FieldTestCase extends DrupalWebTes
     $settings = $info['settings'];
     $this->assertIdentical($settings, $field['settings'] , t('Default field settings have been written.'));
 
-    // Check that a table has been created for the field.
-    $this->assertTrue(db_table_exists('field_data_' . $field_definition['field_name']), t('A table has been created for the field.'));
-
     // Guarantee that the name is unique.
     try {
       field_create_field($field_definition);
       $this->fail(t('Cannot create two fields with the same name.'));
-    } catch (FieldException $e) {
+    } 
+    catch (FieldException $e) {
       $this->pass(t('Cannot create two fields with the same name.'));
     }
 
@@ -995,7 +949,8 @@ class FieldTestCase extends DrupalWebTes
     try {
       field_create_field($field_definition);
       $this->fail(t('Cannot create a field with an invalid name.'));
-    } catch (FieldException $e) {
+    } 
+    catch (FieldException $e) {
       $this->pass(t('Cannot create a field with an invalid name.'));
     }
 
Index: modules/field/modules/text/text.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/text/text.test,v
retrieving revision 1.4
diff -u -p -r1.4 text.test
--- modules/field/modules/text/text.test	12 Apr 2009 02:18:51 -0000	1.4
+++ modules/field/modules/text/text.test	16 Apr 2009 22:37:40 -0000
@@ -1,12 +1,17 @@
 <?php
 // $Id: text.test,v 1.4 2009/04/12 02:18:51 webchick Exp $
 
+/**
+  * @file
+  *  The unit test file for text fields in core.
+  */
+
 class TextFieldTestCase extends DrupalWebTestCase {
   protected $instance;
 
   public static function getInfo() {
     return array(
-      'name'  => t('Text Field'),
+      'name'  => t('Field'),
       'description'  => t("Test the creation of text fields."),
       'group' => t('Field')
     );
@@ -65,8 +70,7 @@ class TextFieldTestCase extends DrupalWe
       'field_name' => $this->field_name,
       'bundle' => FIELD_TEST_BUNDLE,
       'label' => $this->randomName() . '_label',
-      'settings' => array(
-        'text_processing' => TRUE,
+      'settings' => array('text_processing' => TRUE,
       ),
       'widget' => array(
         'type' => $widget_type,
Index: modules/field/modules/field_sql_storage/field_sql_storage.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/field_sql_storage/field_sql_storage.test,v
retrieving revision 1.2
diff -u -p -r1.2 field_sql_storage.test
--- modules/field/modules/field_sql_storage/field_sql_storage.test	31 Mar 2009 01:49:51 -0000	1.2
+++ modules/field/modules/field_sql_storage/field_sql_storage.test	16 Apr 2009 22:37:40 -0000
@@ -12,6 +12,29 @@ class FieldSqlStorageTestCase extends Dr
 
   function setUp() {
     parent::setUp('field_sql_storage', 'field', 'field_test');
+    $this->field_name = drupal_strtolower($this->randomName() . '_field_name');
+    $this->table = _field_sql_storage_tablename($this->field_name);
+    $this->revision_table = _field_sql_storage_revision_tablename($this->field_name);
+    $this->field = array('field_name' => $this->field_name, 'type' => 'test_field', 'cardinality' => 4);
+    field_create_field($this->field);
+    $this->instance = array(
+      'field_name' => $this->field_name,
+      'bundle' => 'test_bundle',
+      'label' => $this->randomName() . '_label',
+      'description' => $this->randomName() . '_description',
+      'weight' => mt_rand(0, 127),
+      'settings' => array(
+        'test_instance_setting' => $this->randomName(),
+      ),
+      'widget' => array(
+        'type' => 'test_field_widget',
+        'label' => 'Test Field',
+        'settings' => array(
+          'test_widget_setting' => $this->randomName(),
+        )
+      )
+    );
+    field_create_instance($this->instance);
   }
 
   function testEntityTypeId() {
@@ -26,4 +49,169 @@ class FieldSqlStorageTestCase extends Dr
     $this->assertEqual($t1, _field_sql_storage_etid('t1'), '_field_sql_storage_etid returns the same value for the first entity type');
     $this->assertEqual($t2, _field_sql_storage_etid('t2'), '_field_sql_storage_etid returns the same value for the second entity type');
   }
+  function testFieldAttachLoad() {
+    $entity_type = 'test_entity';
+    $eid = 0;
+
+    $etid = _field_sql_storage_etid($entity_type);
+    $columns = array('etid', 'entity_id', 'revision_id', 'delta', $this->field_name . '_value');
+
+    // Insert data for four revisions to the field revisions table
+    $query = db_insert($this->revision_table)->fields($columns);
+    for ($evid = 0; $evid < 4; ++$evid) {
+      $values[$evid] = array();
+      // Note: we insert one extra value ('<=' instead of '<').
+      for ($delta = 0; $delta <= $this->field['cardinality']; $delta++) {
+        $value = mt_rand(1, 127);
+        $values[$evid][] = $value;
+        $query->values(array($etid, $eid, $evid, $delta, $value));
+      }
+    }
+    $query->execute();
+
+    // Insert data for the "most current revision" into the field table
+    $query = db_insert($this->table)->fields($columns);
+    foreach ($values[0] as $delta => $value) {
+      $query->values(array($etid, $eid, 0, $delta, $value));
+    }
+    $query->execute();
+
+    // Load the "most current revision"
+    $entity = field_test_create_stub_entity($eid, 0, $this->instance['bundle']);
+    field_attach_load($entity_type, array($eid => $entity));
+    foreach ($values[0] as $delta => $value) {
+      if ($delta < $this->field['cardinality']) {
+        $this->assertEqual($entity->{$this->field_name}[$delta]['value'], $value, "Value $delta is loaded correctly for current revision");
+      }
+      else {
+        $this->assertFalse(array_key_exists($delta, $entity->{$this->field_name}), "No extraneous value gets loaded for current revision.");
+      }
+    }
+
+    // Load every revision
+    for ($evid = 0; $evid < 4; ++$evid) {
+      $entity = field_test_create_stub_entity($eid, $evid, $this->instance['bundle']);
+      field_attach_load_revision($entity_type, array($eid => $entity));
+      foreach ($values[$evid] as $delta => $value) {
+        if ($delta < $this->field['cardinality']) {
+          $this->assertEqual($entity->{$this->field_name}[$delta]['value'], $value, "Value $delta for revision $evid is loaded correctly");
+        }
+        else {
+          $this->assertFalse(array_key_exists($delta, $entity->{$this->field_name}), "No extraneous value gets loaded for revision $evid.");
+        }
+      }
+    }
+  }
+  function testFieldAttachInsertAndUpdate() {
+    $entity_type = 'test_entity';
+    $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
+
+    // Test insert.
+    $values = array();
+    // Note: we try to insert one extra value ('<=' instead of '<').
+    // TODO : test empty values filtering and "compression" (store consecutive deltas).
+    for ($delta = 0; $delta <= $this->field['cardinality']; $delta++) {
+      $values[$delta]['value'] = mt_rand(1, 127);
+    }
+    $entity->{$this->field_name} = $rev_values[0] = $values;
+    field_attach_insert($entity_type, $entity);
+
+    $rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', PDO::FETCH_ASSOC);
+    foreach ($values as $delta => $value) {
+      if ($delta < $this->field['cardinality']) {
+        $this->assertEqual($rows[$delta][$this->field_name . '_value'], $value['value'], t("Value $delta is inserted correctly"));
+      }
+      else {
+        $this->assertFalse(array_key_exists($delta, $rows), "No extraneous value gets inserted.");
+      }
+    }
+
+    // Test update.
+    $entity = field_test_create_stub_entity(0, 1, $this->instance['bundle']);
+    $values = array();
+    // Note: we try to update one extra value ('<=' instead of '<').
+    for ($delta = 0; $delta <= $this->field['cardinality']; $delta++) {
+      $values[$delta]['value'] = mt_rand(1, 127);
+    }
+    $entity->{$this->field_name} = $rev_values[1] = $values;
+    field_attach_update($entity_type, $entity);
+    $rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', PDO::FETCH_ASSOC);
+    foreach ($values as $delta => $value) {
+      if ($delta < $this->field['cardinality']) {
+        $this->assertEqual($rows[$delta][$this->field_name . '_value'], $value['value'], t("Value $delta is updated correctly"));
+      }
+      else {
+        $this->assertFalse(array_key_exists($delta, $rows), "No extraneous value gets updated.");
+      }
+    }
+
+    // Check that data for both revisions are in the revision table.
+    // We make sure each value is stored correctly, then unset it.
+    // When an entire revision's values are unset (remembering that we
+    // put one extra value in $values per revision), unset the entire
+    // revision. Then, if $rev_values is empty at the end, all
+    // revision data was found.
+    $results = db_select($this->revision_table, 't')->fields('t')->execute();
+    foreach ($results as $row) {
+      $this->assertEqual($row->{$this->field_name . '_value'}, $rev_values[$row->revision_id][$row->delta]['value'], "Value {$row->delta} for revision {$row->revision_id} stored correctly");
+      unset($rev_values[$row->revision_id][$row->delta]);
+      if (count($rev_values[$row->revision_id]) == 1) {
+        unset($rev_values[$row->revision_id]);
+      }
+    }
+    $this->assertTrue(empty($rev_values), "All values for all revisions are stored in revision table {$this->revision_table}");
+
+    // Check that update leaves the field data untouched if $object has no
+    // $field_name key.
+    unset($entity->{$this->field_name});
+    field_attach_update($entity_type, $entity);
+    $rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', PDO::FETCH_ASSOC);
+    foreach ($values as $delta => $value) {
+      if ($delta < $this->field['cardinality']) {
+        $this->assertEqual($rows[$delta][$this->field_name . '_value'], $value['value'], t("Update with no field_name entry leaves value $delta untouched"));
+      }
+    }
+
+    // Check that update with an empty $object->$field_name empties the field.
+    $entity->{$this->field_name} = NULL;
+    field_attach_update($entity_type, $entity);
+    $rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', PDO::FETCH_ASSOC);
+    $this->assertEqual(count($rows), 0, t("Update with an empty field_name entry empties the field."));
+  }
+
+  // Test insert and update with missing or invalid fields. For the
+  // most part, these tests pass by not crashing or causing exceptions.
+  function testFieldAttachSaveMissingData() {
+    $entity_type = 'test_entity';
+    $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
+
+    // Insert: Field is missing
+    field_attach_insert($entity_type, $entity);
+    $count = db_result(db_query("SELECT COUNT(*) FROM {{$this->table}}"));
+    $this->assertEqual($count, 0, 'Missing field results in no inserts');
+
+    // Insert: Field is NULL
+    $entity->{$this->field_name} = NULL;
+    field_attach_insert($entity_type, $entity);
+    $count = db_result(db_query("SELECT COUNT(*) FROM {{$this->table}}"));
+    $this->assertEqual($count, 0, 'NULL field results in no inserts');
+
+    // Add some real data
+    $entity->{$this->field_name} = array(0 => array('value' => 1));
+    field_attach_insert($entity_type, $entity);
+    $count = db_result(db_query("SELECT COUNT(*) FROM {{$this->table}}"));
+    $this->assertEqual($count, 1, 'Field data saved');
+
+    // Update: Field is missing. Data should survive.
+    unset($entity->{$this->field_name});
+    field_attach_update($entity_type, $entity);
+    $count = db_result(db_query("SELECT COUNT(*) FROM {{$this->table}}"));
+    $this->assertEqual($count, 1, 'Missing field leaves data in table');
+
+    // Update: Field is NULL. Data should be wiped.
+    $entity->{$this->field_name} = NULL;
+    field_attach_update($entity_type, $entity);
+    $count = db_result(db_query("SELECT COUNT(*) FROM {{$this->table}}"));
+    $this->assertEqual($count, 0, 'NULL field leaves no data in table');
+  }
 }
