Index: modules/field/field.test =================================================================== RCS file: /cvs/drupal/drupal/modules/field/field.test,v retrieving revision 1.43 diff -u -r1.43 field.test --- modules/field/field.test 25 Aug 2009 21:53:47 -0000 1.43 +++ modules/field/field.test 25 Aug 2009 22:58:23 -0000 @@ -7,20 +7,29 @@ */ /** - * Unit test class for field_attach_* functions. - * - * All field_attach_* test work with all field_storage plugins and - * all hook_field_attach_pre_{load,insert,update}() hooks. + * Parent class for Field API tests. */ -class FieldAttachTestCase extends DrupalWebTestCase { - public static function getInfo() { - return array( - 'name' => 'Field attach tests', - 'description' => 'Test Field Attach API functions.', - 'group' => 'Field', - ); +class FieldTestCase extends DrupalWebTestCase { + + /** + * Generate random values for a field_test field. + * + * @param $cardinality + * Number of values to generate. + * @return + * An array of random values, in the format expected for field values. + */ + function _generateTestFieldValues($cardinality) { + $values = array(); + for ($i = 0; $i < $cardinality; $i++) { + // field_test fields treat 0 as 'empty value'. + $values[$i]['value'] = mt_rand(1, 127); + } + return $values; } +} +class FieldAttachTestCase extends FieldTestCase { function setUp() { parent::setUp('field_test'); @@ -47,6 +56,22 @@ ); field_create_instance($this->instance); } +} + +/** + * Unit test class for storage-related field_attach_* functions. + * + * All field_attach_* test work with all field_storage plugins and + * all hook_field_attach_pre_{load,insert,update}() hooks. + */ +class FieldAttachStorageTestCase extends FieldAttachTestCase { + public static function getInfo() { + return array( + 'name' => 'Field attach tests (storage-related)', + 'description' => 'Test storage-related Field Attach API functions.', + 'group' => 'Field', + ); + } /** * Check field values insert, update and load. @@ -276,6 +301,162 @@ } /** + * Test field_attach_delete(). + */ + function testFieldAttachDelete() { + $entity_type = 'test_entity'; + $langcode = FIELD_LANGUAGE_NONE; + $rev[0] = field_test_create_stub_entity(0, 0, $this->instance['bundle']); + + // Create revision 0 + $values = $this->_generateTestFieldValues($this->field['cardinality']); + $rev[0]->{$this->field_name}[$langcode] = $values; + field_attach_insert($entity_type, $rev[0]); + + // Create revision 1 + $rev[1] = field_test_create_stub_entity(0, 1, $this->instance['bundle']); + $rev[1]->{$this->field_name}[$langcode] = $values; + field_attach_update($entity_type, $rev[1]); + + // Create revision 2 + $rev[2] = field_test_create_stub_entity(0, 2, $this->instance['bundle']); + $rev[2]->{$this->field_name}[$langcode] = $values; + field_attach_update($entity_type, $rev[2]); + + // Confirm each revision loads + foreach (array_keys($rev) as $vid) { + $read = field_test_create_stub_entity(0, $vid, $this->instance['bundle']); + field_attach_load_revision($entity_type, array(0 => $read)); + $this->assertEqual(count($read->{$this->field_name}[$langcode]), $this->field['cardinality'], "The test object revision $vid has {$this->field['cardinality']} values."); + } + + // Delete revision 1, confirm the other two still load. + field_attach_delete_revision($entity_type, $rev[1]); + foreach (array(0, 2) as $vid) { + $read = field_test_create_stub_entity(0, $vid, $this->instance['bundle']); + field_attach_load_revision($entity_type, array(0 => $read)); + $this->assertEqual(count($read->{$this->field_name}[$langcode]), $this->field['cardinality'], "The test object revision $vid has {$this->field['cardinality']} values."); + } + + // Confirm the current revision still loads + $read = field_test_create_stub_entity(0, 2, $this->instance['bundle']); + field_attach_load($entity_type, array(0 => $read)); + $this->assertEqual(count($read->{$this->field_name}[$langcode]), $this->field['cardinality'], "The test object current revision has {$this->field['cardinality']} values."); + + // Delete all field data, confirm nothing loads + field_attach_delete($entity_type, $rev[2]); + foreach (array(0, 1, 2) as $vid) { + $read = field_test_create_stub_entity(0, $vid, $this->instance['bundle']); + field_attach_load_revision($entity_type, array(0 => $read)); + $this->assertIdentical($read->{$this->field_name}, array(), "The test object revision $vid is deleted."); + } + $read = field_test_create_stub_entity(0, 2, $this->instance['bundle']); + field_attach_load($entity_type, array(0 => $read)); + $this->assertIdentical($read->{$this->field_name}, array(), t('The test object current revision is deleted.')); + } + + /** + * Test field_attach_create_bundle() and field_attach_rename_bundle(). + */ + function testFieldAttachCreateRenameBundle() { + // Create a new bundle. This has to be initiated by the module so that its + // hook_entity_info() is consistent. + $new_bundle = 'test_bundle_' . drupal_strtolower($this->randomName()); + field_test_create_bundle($new_bundle); + + // Add an instance to that bundle. + $this->instance['bundle'] = $new_bundle; + field_create_instance($this->instance); + + // Save an object with data in the field. + $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); + $langcode = FIELD_LANGUAGE_NONE; + $values = $this->_generateTestFieldValues($this->field['cardinality']); + $entity->{$this->field_name}[$langcode] = $values; + $entity_type = 'test_entity'; + field_attach_insert($entity_type, $entity); + + // Verify the field data is present on load. + $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); + field_attach_load($entity_type, array(0 => $entity)); + $this->assertEqual(count($entity->{$this->field_name}[$langcode]), $this->field['cardinality'], "Data is retrieved for the new bundle"); + + // Rename the bundle. This has to be initiated by the module so that its + // hook_entity_info() is consistent. + $new_bundle = 'test_bundle_' . drupal_strtolower($this->randomName()); + field_test_rename_bundle($this->instance['bundle'], $new_bundle); + + // Check that the instance definition has been updated. + $this->instance = field_info_instance($this->field_name, $new_bundle); + $this->assertIdentical($this->instance['bundle'], $new_bundle, "Bundle name has been updated in the instance."); + + // Verify the field data is present on load. + $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); + field_attach_load($entity_type, array(0 => $entity)); + $this->assertEqual(count($entity->{$this->field_name}[$langcode]), $this->field['cardinality'], "Bundle name has been updated in the field storage"); + } + + /** + * Test field_attach_delete_bundle(). + */ + function testFieldAttachDeleteBundle() { + // Create a new bundle. This has to be initiated by the module so that its + // hook_entity_info() is consistent. + $new_bundle = 'test_bundle_' . drupal_strtolower($this->randomName()); + field_test_create_bundle($new_bundle); + + // Add an instance to that bundle. + $this->instance['bundle'] = $new_bundle; + field_create_instance($this->instance); + + // Create a second field for the test bundle + $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', + 'weight' => mt_rand(0, 127), + // test_field has no instance settings + 'widget' => array( + 'type' => 'test_field_widget', + 'settings' => array( + 'size' => mt_rand(0, 255)))); + field_create_instance($instance); + + // Save an object with data for both fields + $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); + $langcode = FIELD_LANGUAGE_NONE; + $values = $this->_generateTestFieldValues($this->field['cardinality']); + $entity->{$this->field_name}[$langcode] = $values; + $entity->{$field_name}[$langcode] = $this->_generateTestFieldValues(1); + $entity_type = 'test_entity'; + field_attach_insert($entity_type, $entity); + + // Verify the fields are present on load + $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); + field_attach_load($entity_type, array(0 => $entity)); + $this->assertEqual(count($entity->{$this->field_name}[$langcode]), 4, 'First field got loaded'); + $this->assertEqual(count($entity->{$field_name}[$langcode]), 1, 'Second field got loaded'); + + // Delete the bundle. This has to be initiated by the module so that its + // hook_entity_info() is consistent. + field_test_delete_bundle($this->instance['bundle']); + + // Verify no data gets loaded + $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); + field_attach_load($entity_type, array(0 => $entity)); + $this->assertFalse(isset($entity->{$this->field_name}[$langcode]), 'No data for first field'); + $this->assertFalse(isset($entity->{$field_name}[$langcode]), 'No data for second field'); + + // Verify that the instances are gone + $this->assertFalse(field_read_instance($this->field_name, $this->instance['bundle']), "First field is deleted"); + $this->assertFalse(field_read_instance($field_name, $instance['bundle']), "Second field is deleted"); + } + + /** * Test field_attach_query(). */ function testFieldAttachQuery() { @@ -454,7 +635,23 @@ ); $this->assertEqual($result, $expected, t('FIELD_QUERY_RETURN_IDS result format returns the expect result')); } +} +/** + * Unit test class for non-storage related field_attach_* functions. + */ +class FieldAttachOtherTestCase extends FieldAttachTestCase { + public static function getInfo() { + return array( + 'name' => 'Field attach tests (other)', + 'description' => 'Test other Field Attach API functions.', + 'group' => 'Field', + ); + } + + /** + * Test field_attach_views() and field_attach_preprocess(). + */ function testFieldAttachViewAndPreprocess() { $entity_type = 'test_entity'; $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); @@ -546,153 +743,6 @@ $this->assertTrue($result, t('Variable $@field_name correctly populated.', array('@field_name' => $this->field_name))); } - function testFieldAttachDelete() { - $entity_type = 'test_entity'; - $langcode = FIELD_LANGUAGE_NONE; - $rev[0] = field_test_create_stub_entity(0, 0, $this->instance['bundle']); - - // Create revision 0 - $values = $this->_generateTestFieldValues($this->field['cardinality']); - $rev[0]->{$this->field_name}[$langcode] = $values; - field_attach_insert($entity_type, $rev[0]); - - // Create revision 1 - $rev[1] = field_test_create_stub_entity(0, 1, $this->instance['bundle']); - $rev[1]->{$this->field_name}[$langcode] = $values; - field_attach_update($entity_type, $rev[1]); - - // Create revision 2 - $rev[2] = field_test_create_stub_entity(0, 2, $this->instance['bundle']); - $rev[2]->{$this->field_name}[$langcode] = $values; - field_attach_update($entity_type, $rev[2]); - - // Confirm each revision loads - foreach (array_keys($rev) as $vid) { - $read = field_test_create_stub_entity(0, $vid, $this->instance['bundle']); - field_attach_load_revision($entity_type, array(0 => $read)); - $this->assertEqual(count($read->{$this->field_name}[$langcode]), $this->field['cardinality'], "The test object revision $vid has {$this->field['cardinality']} values."); - } - - // Delete revision 1, confirm the other two still load. - field_attach_delete_revision($entity_type, $rev[1]); - foreach (array(0, 2) as $vid) { - $read = field_test_create_stub_entity(0, $vid, $this->instance['bundle']); - field_attach_load_revision($entity_type, array(0 => $read)); - $this->assertEqual(count($read->{$this->field_name}[$langcode]), $this->field['cardinality'], "The test object revision $vid has {$this->field['cardinality']} values."); - } - - // Confirm the current revision still loads - $read = field_test_create_stub_entity(0, 2, $this->instance['bundle']); - field_attach_load($entity_type, array(0 => $read)); - $this->assertEqual(count($read->{$this->field_name}[$langcode]), $this->field['cardinality'], "The test object current revision has {$this->field['cardinality']} values."); - - // Delete all field data, confirm nothing loads - field_attach_delete($entity_type, $rev[2]); - foreach (array(0, 1, 2) as $vid) { - $read = field_test_create_stub_entity(0, $vid, $this->instance['bundle']); - field_attach_load_revision($entity_type, array(0 => $read)); - $this->assertIdentical($read->{$this->field_name}, array(), "The test object revision $vid is deleted."); - } - $read = field_test_create_stub_entity(0, 2, $this->instance['bundle']); - field_attach_load($entity_type, array(0 => $read)); - $this->assertIdentical($read->{$this->field_name}, array(), t('The test object current revision is deleted.')); - } - - function testFieldAttachCreateRenameBundle() { - // Create a new bundle. This has to be initiated by the module so that its - // hook_entity_info() is consistent. - $new_bundle = 'test_bundle_' . drupal_strtolower($this->randomName()); - field_test_create_bundle($new_bundle); - - // Add an instance to that bundle. - $this->instance['bundle'] = $new_bundle; - field_create_instance($this->instance); - - // Save an object with data in the field. - $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); - $langcode = FIELD_LANGUAGE_NONE; - $values = $this->_generateTestFieldValues($this->field['cardinality']); - $entity->{$this->field_name}[$langcode] = $values; - $entity_type = 'test_entity'; - field_attach_insert($entity_type, $entity); - - // Verify the field data is present on load. - $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); - field_attach_load($entity_type, array(0 => $entity)); - $this->assertEqual(count($entity->{$this->field_name}[$langcode]), $this->field['cardinality'], "Data is retrieved for the new bundle"); - - // Rename the bundle. This has to be initiated by the module so that its - // hook_entity_info() is consistent. - $new_bundle = 'test_bundle_' . drupal_strtolower($this->randomName()); - field_test_rename_bundle($this->instance['bundle'], $new_bundle); - - // Check that the instance definition has been updated. - $this->instance = field_info_instance($this->field_name, $new_bundle); - $this->assertIdentical($this->instance['bundle'], $new_bundle, "Bundle name has been updated in the instance."); - - // Verify the field data is present on load. - $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); - field_attach_load($entity_type, array(0 => $entity)); - $this->assertEqual(count($entity->{$this->field_name}[$langcode]), $this->field['cardinality'], "Bundle name has been updated in the field storage"); - } - - function testFieldAttachDeleteBundle() { - // Create a new bundle. This has to be initiated by the module so that its - // hook_entity_info() is consistent. - $new_bundle = 'test_bundle_' . drupal_strtolower($this->randomName()); - field_test_create_bundle($new_bundle); - - // Add an instance to that bundle. - $this->instance['bundle'] = $new_bundle; - field_create_instance($this->instance); - - // Create a second field for the test bundle - $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', - 'weight' => mt_rand(0, 127), - // test_field has no instance settings - 'widget' => array( - 'type' => 'test_field_widget', - 'settings' => array( - 'size' => mt_rand(0, 255)))); - field_create_instance($instance); - - // Save an object with data for both fields - $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); - $langcode = FIELD_LANGUAGE_NONE; - $values = $this->_generateTestFieldValues($this->field['cardinality']); - $entity->{$this->field_name}[$langcode] = $values; - $entity->{$field_name}[$langcode] = $this->_generateTestFieldValues(1); - $entity_type = 'test_entity'; - field_attach_insert($entity_type, $entity); - - // Verify the fields are present on load - $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); - field_attach_load($entity_type, array(0 => $entity)); - $this->assertEqual(count($entity->{$this->field_name}[$langcode]), 4, 'First field got loaded'); - $this->assertEqual(count($entity->{$field_name}[$langcode]), 1, 'Second field got loaded'); - - // Delete the bundle. This has to be initiated by the module so that its - // hook_entity_info() is consistent. - field_test_delete_bundle($this->instance['bundle']); - - // Verify no data gets loaded - $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); - field_attach_load($entity_type, array(0 => $entity)); - $this->assertFalse(isset($entity->{$this->field_name}[$langcode]), 'No data for first field'); - $this->assertFalse(isset($entity->{$field_name}[$langcode]), 'No data for second field'); - - // Verify that the instances are gone - $this->assertFalse(field_read_instance($this->field_name, $this->instance['bundle']), "First field is deleted"); - $this->assertFalse(field_read_instance($field_name, $instance['bundle']), "Second field is deleted"); - } - /** * Test field cache. */ @@ -781,8 +831,12 @@ $this->assertFalse(cache_get($cid, 'cache_field'), t('Cached: no cache entry after delete')); } - // Verify that field_attach_validate() invokes the correct - // hook_field_validate. + /** + * Test field_attach_validate(). + * + * Verify that field_attach_validate() invokes the correct + * hook_field_validate. + */ function testFieldAttachValidate() { $entity_type = 'test_entity'; $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); @@ -818,8 +872,12 @@ $this->assertEqual(count($errors[$this->field_name][$langcode]), 0, 'No extraneous errors set'); } - // Validate that FAPI elements are generated. This could be much - // more thorough, but it does verify that the correct widgets show up. + /** + * Test field_attach_form(). + * + * This could be much more thorough, but it does verify that the correct + * widgets show up. + */ function testFieldAttachForm() { $entity_type = 'test_entity'; $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); @@ -835,6 +893,9 @@ } } + /** + * Test field_attach_submit(). + */ function testFieldAttachSubmit() { $entity_type = 'test_entity'; $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']); @@ -871,26 +932,51 @@ } $this->assertIdentical($entity->{$this->field_name}[$langcode], $expected_values, 'Submit filters empty values'); } +} - /** - * Generate random values for a field_test field. - * - * @param $cardinality - * Number of values to generate. - * @return - * An array of random values, in the format expected for field values. - */ - function _generateTestFieldValues($cardinality) { - $values = array(); - for ($i = 0; $i < $cardinality; $i++) { - // field_test fields treat 0 as 'empty value'. - $values[$i]['value'] = mt_rand(1, 127); - } - return $values; +/** + * Unit test class for storage-related field_attach_* functions. + * + * All field_attach_* test work with all field_storage plugins and + * all hook_field_attach_pre_{load,insert,update}() hooks. + */ +class FieldAttachStorageTestCase extends FieldTestCase { + public static function getInfo() { + return array( + 'name' => 'Field attach tests (storage-related)', + 'description' => 'Test storage-related Field Attach API functions.', + 'group' => 'Field', + ); } -} -class FieldInfoTestCase extends DrupalWebTestCase { + function setUp() { + parent::setUp('field_test'); + + $this->field_name = drupal_strtolower($this->randomName() . '_field_name'); + $this->field = array('field_name' => $this->field_name, 'type' => 'test_field', 'cardinality' => 4); + $this->field = field_create_field($this->field); + $this->field_id = $this->field['id']; + $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); + } + +class FieldInfoTestCase extends FieldTestCase { public static function getInfo() { return array( @@ -1085,7 +1171,7 @@ } } -class FieldFormTestCase extends DrupalWebTestCase { +class FieldFormTestCase extends FieldTestCase { public static function getInfo() { return array( 'name' => 'Field form tests', @@ -1385,7 +1471,7 @@ } } -class FieldCrudTestCase extends DrupalWebTestCase { +class FieldCrudTestCase extends FieldTestCase { public static function getInfo() { return array( 'name' => 'Field CRUD tests', @@ -1645,7 +1731,7 @@ } } -class FieldInstanceCrudTestCase extends DrupalWebTestCase { +class FieldInstanceCrudTestCase extends FieldTestCase { protected $field; public static function getInfo() { @@ -1837,7 +1923,7 @@ * that only the correct values are returned by * field_multilingual_available_languages(). */ -class FieldTranslationsTestCase extends DrupalWebTestCase { +class FieldTranslationsTestCase extends FieldTestCase { public static function getInfo() { return array( 'name' => 'Field translations tests', @@ -2040,7 +2126,7 @@ $object = field_test_create_stub_entity($eid, $evid, $this->instance['bundle']); $field_translations = array(); foreach (field_multilingual_available_languages($obj_type, $this->field) as $langcode) { - $field_translations[$langcode] = FieldAttachTestCase::_generateTestFieldValues($this->field['cardinality']); + $field_translations[$langcode] = _generateTestFieldValues($this->field['cardinality']); } // Save and reload the field translations. @@ -2063,7 +2149,7 @@ /** * Unit test class for field bulk delete and batch purge functionality. */ -class FieldBulkDeleteTestCase extends DrupalWebTestCase { +class FieldBulkDeleteTestCase extends FieldTestCase { protected $field; public static function getInfo() { @@ -2075,23 +2161,6 @@ } /** - * Generate random values for a field_test field. - * - * @param $cardinality - * Number of values to generate. - * @return - * An array of random values, in the format expected for field values. - */ - function _generateTestFieldValues($cardinality) { - $values = array(); - for ($i = 0; $i < $cardinality; $i++) { - // field_test fields treat 0 as 'empty value'. - $values[$i]['value'] = mt_rand(1, 127); - } - return $values; - } - - /** * Convenience function for Field API tests. * * Given an array of potentially fully-populated objects and an