Create feeds_dev_0.patch

Patch to update from public release alpha8 to devdiff -rupN feeds_old/feeds.info feeds_new/feeds.info
--- feeds_old/feeds.info	2013-04-22 19:05:11.000000000 -0400
+++ feeds_new/feeds.info	2013-09-30 17:57:56.000000000 -0400
@@ -56,9 +56,9 @@ files[] = views/feeds_views_handler_fiel
 files[] = views/feeds_views_handler_field_source.inc
 files[] = views/feeds_views_handler_filter_severity.inc
 
-; Information added by drupal.org packaging script on 2013-04-22
-version = "7.x-2.0-alpha8"
+; Information added by drupal.org packaging script on 2013-09-30
+version = "7.x-2.0-alpha8+8-dev"
 core = "7.x"
 project = "feeds"
-datestamp = "1366671911"
+datestamp = "1380578276"
 
diff -rupN feeds_old/feeds.module feeds_new/feeds.module
--- feeds_old/feeds.module	2013-04-22 18:57:07.000000000 -0400
+++ feeds_new/feeds.module	2013-09-19 19:09:04.000000000 -0400
@@ -1039,7 +1039,9 @@ function feeds_library_exists($file, $li
  * Checks whether simplepie exists.
  */
 function feeds_simplepie_exists() {
-  return (feeds_library_exists('simplepie.compiled.php', 'simplepie') ||
+  return (
+    feeds_library_exists('autoloader.php', 'simplepie') ||
+    feeds_library_exists('simplepie.compiled.php', 'simplepie') ||
     feeds_library_exists('simplepie.mini.php', 'simplepie') ||
     feeds_library_exists('simplepie.inc', 'simplepie')
   );
@@ -1049,13 +1051,19 @@ function feeds_simplepie_exists() {
  * Includes the simplepie library.
  */
 function feeds_include_simplepie() {
-  $files = array('simplepie.mini.php', 'simplepie.compiled.php', 'simplepie.inc');
+  $files = array(
+    'autoloader.php',
+    'simplepie.mini.php',
+    'simplepie.compiled.php',
+    'simplepie.inc',
+  );
 
   foreach ($files as $file) {
     if (feeds_include_library($file, 'simplepie')) {
       return TRUE;
     }
   }
+
   return FALSE;
 }
 
diff -rupN feeds_old/feeds_import/feeds_import.info feeds_new/feeds_import/feeds_import.info
--- feeds_old/feeds_import/feeds_import.info	2013-04-22 19:05:11.000000000 -0400
+++ feeds_new/feeds_import/feeds_import.info	2013-09-30 17:57:56.000000000 -0400
@@ -9,9 +9,9 @@ name = "Feeds Import"
 package = "Feeds"
 php = "5.2.4"
 
-; Information added by drupal.org packaging script on 2013-04-22
-version = "7.x-2.0-alpha8"
+; Information added by drupal.org packaging script on 2013-09-30
+version = "7.x-2.0-alpha8+8-dev"
 core = "7.x"
 project = "feeds"
-datestamp = "1366671911"
+datestamp = "1380578276"
 
diff -rupN feeds_old/feeds_news/feeds_news.info feeds_new/feeds_news/feeds_news.info
--- feeds_old/feeds_news/feeds_news.info	2013-04-22 19:05:11.000000000 -0400
+++ feeds_new/feeds_news/feeds_news.info	2013-09-30 17:57:56.000000000 -0400
@@ -17,9 +17,9 @@ name = "Feeds News"
 package = "Feeds"
 php = "5.2.4"
 
-; Information added by drupal.org packaging script on 2013-04-22
-version = "7.x-2.0-alpha8"
+; Information added by drupal.org packaging script on 2013-09-30
+version = "7.x-2.0-alpha8+8-dev"
 core = "7.x"
 project = "feeds"
-datestamp = "1366671911"
+datestamp = "1380578276"
 
diff -rupN feeds_old/feeds_ui/feeds_ui.admin.inc feeds_new/feeds_ui/feeds_ui.admin.inc
--- feeds_old/feeds_ui/feeds_ui.admin.inc	2013-04-22 18:57:07.000000000 -0400
+++ feeds_new/feeds_ui/feeds_ui.admin.inc	2013-09-19 19:09:04.000000000 -0400
@@ -718,7 +718,7 @@ function feeds_ui_mapping_settings_form_
  * Validation handler for feeds_ui_mapping_form().
  */
 function feeds_ui_mapping_form_validate($form, &$form_state) {
-  if (empty($form_state['values']['source']) xor empty($form_state['values']['target'])) {
+  if (!strlen($form_state['values']['source']) xor !strlen($form_state['values']['target'])) {
 
     // Check triggering_element here so we can react differently for ajax
     // submissions.
@@ -726,7 +726,7 @@ function feeds_ui_mapping_form_validate(
 
       // Regular form submission.
       case 'op':
-        if (empty($form_state['values']['source'])) {
+        if (!strlen($form_state['values']['source'])) {
           form_error($form['source'], t('You must select a mapping source.'));
         }
         else {
@@ -790,7 +790,7 @@ function feeds_ui_mapping_form_submit($f
 
   $processor->addConfig(array('mappings' => $mappings));
 
-  if (!empty($form_state['values']['source']) && !empty($form_state['values']['target'])) {
+  if (strlen($form_state['values']['source']) && strlen($form_state['values']['target'])) {
     try {
       $mappings = $processor->getMappings();
       $mappings[] = array(
@@ -1148,9 +1148,17 @@ function feeds_ui_importer_import_valida
       '%api_version' => feeds_api_version())));
   }
 
-  $existing = feeds_importer($feeds_importer->id);
-  if ($existing && !$form_state['values']['id_override'] && $existing->export_type != EXPORT_IN_CODE) {
-    return form_error($form['id'], t('Feeds importer already exists with that id.'));
+  // Change to user-supplied id.
+  if ($form_state['values']['id']) {
+    $feeds_importer->id = $form_state['values']['id'];
+  }
+
+  $exists = feeds_ui_importer_machine_name_exists($feeds_importer->id);
+
+  if ($exists && !$form_state['values']['id_override']) {
+    if (feeds_importer($feeds_importer->id)->export_type != EXPORT_IN_CODE) {
+      return form_error($form['id'], t('Feeds importer already exists with that id.'));
+    }
   }
 
   if (!$form_state['values']['bypass_validation']) {
@@ -1172,12 +1180,14 @@ function feeds_ui_importer_import_valida
  */
 function feeds_ui_importer_import_submit($form, &$form_state) {
   $importer = $form_state['importer'];
-  $importer = feeds_importer($importer->id);
-  $importer->setConfig($importer->config);
+
+  // Create a copy of the importer to preserve config.
+  $save = feeds_importer($importer->id);
+  $save->setConfig($importer->config);
   foreach (array('fetcher', 'parser', 'processor') as $type) {
-    $importer->$type->setConfig($importer->config[$type]['config']);
+    $save->$type->setConfig($importer->config[$type]['config']);
   }
-  $importer->save();
+  $save->save();
 
   drupal_set_message(t('Successfully imported the %id feeds importer.', array('%id' => $importer->id)));
   $form_state['redirect'] = 'admin/structure/feeds';
diff -rupN feeds_old/feeds_ui/feeds_ui.info feeds_new/feeds_ui/feeds_ui.info
--- feeds_old/feeds_ui/feeds_ui.info	2013-04-22 19:05:11.000000000 -0400
+++ feeds_new/feeds_ui/feeds_ui.info	2013-09-30 17:57:56.000000000 -0400
@@ -7,9 +7,9 @@ configure = admin/structure/feeds
 
 files[] = feeds_ui.test
 
-; Information added by drupal.org packaging script on 2013-04-22
-version = "7.x-2.0-alpha8"
+; Information added by drupal.org packaging script on 2013-09-30
+version = "7.x-2.0-alpha8+8-dev"
 core = "7.x"
 project = "feeds"
-datestamp = "1366671911"
+datestamp = "1380578276"
 
diff -rupN feeds_old/libraries/http_request.inc feeds_new/libraries/http_request.inc
--- feeds_old/libraries/http_request.inc	2013-04-22 18:57:07.000000000 -0400
+++ feeds_new/libraries/http_request.inc	2013-09-19 19:09:04.000000000 -0400
@@ -178,6 +178,22 @@ function http_request_get($url, $usernam
       curl_setopt($download, CURLOPT_RETURNTRANSFER, TRUE);
       curl_setopt($download, CURLOPT_ENCODING, '');
       curl_setopt($download, CURLOPT_TIMEOUT, $request_timeout);
+
+      $proxy_server = variable_get('proxy_server');
+
+      if ($proxy_server && _drupal_http_use_proxy($uri['host'])) {
+        curl_setopt($download, CURLOPT_PROXY, $proxy_server);
+        curl_setopt($download, CURLOPT_PROXYPORT, variable_get('proxy_port', 8080));
+
+        // Proxy user/password.
+        if ($proxy_username = variable_get('proxy_username')) {
+          $username_password = $proxy_username . ':' . variable_get('proxy_password', '');
+
+          curl_setopt($download, CURLOPT_PROXYUSERPWD, $username_password);
+          curl_setopt($download, CURLOPT_PROXYAUTH, variable_get('proxy_auth_method', CURLAUTH_BASIC));
+        }
+      }
+
       if ($accept_invalid_cert) {
         curl_setopt($download, CURLOPT_SSL_VERIFYPEER, 0);
       }
@@ -193,6 +209,18 @@ function http_request_get($url, $usernam
         );
       }
 
+      // When using a proxy, remove extra data from the header which is not
+      // considered by CURLINFO_HEADER_SIZE (possibly cURL bug).
+      // This data is only added when to HTTP header when working with a proxy.
+      // Example string added: <HTTP/1.0 200 Connection established\r\n\r\n>
+      if ($proxy_server && _drupal_http_use_proxy($uri['host'])) {
+        $http_header_break = "\r\n\r\n";
+        $response = explode($http_header_break, $data);
+        if (count($response) > 2) {
+          $data = substr($data, strlen($response[0] . $http_header_break), strlen($data));
+        }
+      }
+
       $header_size = curl_getinfo($download, CURLINFO_HEADER_SIZE);
       $header = substr($data, 0, $header_size - 1);
       $result->data = substr($data, $header_size);
diff -rupN feeds_old/mappers/date.inc feeds_new/mappers/date.inc
--- feeds_old/mappers/date.inc	2013-04-22 18:57:07.000000000 -0400
+++ feeds_new/mappers/date.inc	2013-09-19 19:09:04.000000000 -0400
@@ -46,23 +46,28 @@ function date_feeds_processor_targets_al
  */
 function date_feeds_set_target($source, $entity, $target, $feed_element) {
   list($field_name, $sub_field) = explode(':', $target, 2);
-  if (!($feed_element instanceof FeedsDateTimeElement)) {
-    if (!is_array($feed_element)) {
-      $feed_element = array($feed_element);
-    }
-    $delta = 0;
-    foreach ($feed_element as $f) {
-      if (empty($f) || !is_numeric($f) && !date_create($f)) {
-        $array_element = new FeedsDateTimeElement(NULL, NULL);
+
+  if (!is_array($feed_element)) {
+    $feed_element = array($feed_element);
+  }
+
+  $delta = 0;
+  foreach ($feed_element as $f) {
+
+    if (!($feed_element instanceof FeedsDateTimeElement)) {
+
+      if (empty($f) || !is_numeric($f) && is_string($f) && !date_create($f)) {
+        $f = new FeedsDateTimeElement(NULL, NULL);
       }
       elseif ($sub_field == 'end') {
-        $array_element = new FeedsDateTimeElement(NULL, $f);
+        $f = new FeedsDateTimeElement(NULL, $f);
       }
       else {
-        $array_element = new FeedsDateTimeElement($f, NULL);
+        $f = new FeedsDateTimeElement($f, NULL);
       }
-      $array_element->buildDateField($entity, $field_name, $delta);
-      $delta++;
     }
+
+    $f->buildDateField($entity, $field_name, $delta);
+    $delta++;
   }
 }
diff -rupN feeds_old/mappers/file.inc feeds_new/mappers/file.inc
--- feeds_old/mappers/file.inc	2013-04-22 18:57:07.000000000 -0400
+++ feeds_new/mappers/file.inc	2013-09-19 19:09:04.000000000 -0400
@@ -4,27 +4,39 @@
  * @file
  * On behalf implementation of Feeds mapping API for file.module and
  * image.module.
- *
- * Does actually not include mappers for field types defined in fields module
- * (because there aren't any) but mappers for all fields that contain their
- * value simply in $entity->fieldname['und'][$i]['value'].
  */
 
 /**
  * Implements hook_feeds_processor_targets_alter().
  *
- * @see FeedsNodeProcessor::getMappingTargets().
+ * @see FeedsNodeProcessor::getMappingTargets()
  */
 function file_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
   foreach (field_info_instances($entity_type, $bundle_name) as $name => $instance) {
     $info = field_info_field($name);
 
     if (in_array($info['type'], array('file', 'image'))) {
-      $targets[$name] = array(
-        'name' => check_plain($instance['label']),
+      $targets[$name . ':uri'] = array(
+        'name' => t('@label: URI', array('@label' => $instance['label'])),
         'callback' => 'file_feeds_set_target',
-        'description' => t('The @label field of the node.', array('@label' => $instance['label'])),
+        'description' => t('The URI of the @label field.', array('@label' => $instance['label'])),
+        'real_target' => $name,
       );
+
+      if ($info['type'] == 'image') {
+        $targets[$name . ':alt'] = array(
+          'name' => t('@label: Alt', array('@label' => $instance['label'])),
+          'callback' => 'file_feeds_set_target',
+          'description' => t('The alt tag of the @label field.', array('@label' => $instance['label'])),
+          'real_target' => $name,
+        );
+        $targets[$name . ':title'] = array(
+          'name' => t('@label: Title', array('@label' => $instance['label'])),
+          'callback' => 'file_feeds_set_target',
+          'description' => t('The title of the @label field.', array('@label' => $instance['label'])),
+          'real_target' => $name,
+        );
+      }
     }
   }
 }
@@ -40,56 +52,82 @@ function file_feeds_set_target($source, 
   if (empty($value)) {
     return;
   }
-  module_load_include('inc', 'file');
 
   // Make sure $value is an array of objects of type FeedsEnclosure.
   if (!is_array($value)) {
     $value = array($value);
   }
-  foreach ($value as $k => $v) {
-    if (!($v instanceof FeedsEnclosure)) {
-      if (is_string($v)) {
-        $value[$k] = new FeedsEnclosure($v, file_get_mimetype($v));
-      }
-      else {
-        unset($value[$k]);
+
+  // Add default of uri for backwards compatibility.
+  list($field_name, $sub_field) = explode(':', $target . ':uri');
+  $info = field_info_field($field_name);
+
+  if ($sub_field == 'uri') {
+
+    foreach ($value as $k => $v) {
+      if (!($v instanceof FeedsEnclosure)) {
+        if (is_string($v)) {
+          $value[$k] = new FeedsEnclosure($v, file_get_mimetype($v));
+        }
+        else {
+          unset($value[$k]);
+        }
       }
     }
-  }
-  if (empty($value)) {
-    return;
-  }
-
-  $entity_type = $source->importer->processor->entityType();
+    if (empty($value)) {
+      return;
+    }
 
-  // Determine file destination.
-  // @todo This needs review and debugging.
-  $instance_info = field_info_instance($entity_type, $target, $source->importer->processor->bundle());
-  $info = field_info_field($target);
-  $data = array();
-  if (!empty($entity->uid)) {
-    $data[$entity_type] = $entity;
+    static $destination;
+    if (!$destination) {
+      $entity_type = $source->importer->processor->entityType();
+      $bundle = $source->importer->processor->bundle();
+
+      $instance_info = field_info_instance($entity_type, $field_name, $bundle);
+
+      // Determine file destination.
+      // @todo This needs review and debugging.
+      $data = array();
+      if (!empty($entity->uid)) {
+        $data[$entity_type] = $entity;
+      }
+      $destination = file_field_widget_uri($info, $instance_info, $data);
+    }
   }
-  $destination = file_field_widget_uri($info, $instance_info, $data);
 
   // Populate entity.
-  $i = 0;
-  $field = isset($entity->$target) ? $entity->$target : array();
+  $field = isset($entity->$field_name) ? $entity->$field_name : array(LANGUAGE_NONE => array());
+  $delta = 0;
   foreach ($value as $v) {
-    try {
-      $file = $v->getFile($destination);
+    if ($info['cardinality'] == $delta) {
+      break;
     }
-    catch (Exception $e) {
-      watchdog_exception('Feeds', $e, nl2br(check_plain($e)));
+
+    if (!isset($field[LANGUAGE_NONE][$delta])) {
+      $field[LANGUAGE_NONE][$delta] = array();
     }
-    if ($file) {
-      $field['und'][$i] = (array)$file;
-      $field['und'][$i]['display'] = 1; // @todo: Figure out how to properly populate this field.
-      if ($info['cardinality'] == 1) {
+
+    switch ($sub_field) {
+      case 'alt':
+      case 'title':
+        $field[LANGUAGE_NONE][$delta][$sub_field] = $v;
+        break;
+
+      case 'uri':
+        try {
+          $file = $v->getFile($destination);
+          $field[LANGUAGE_NONE][$delta] += (array) $file;
+          // @todo: Figure out how to properly populate this field.
+          $field[LANGUAGE_NONE][$delta]['display'] = 1;
+        }
+        catch (Exception $e) {
+          watchdog_exception('Feeds', $e, nl2br(check_plain($e)));
+        }
         break;
-      }
-      $i++;
     }
+
+    $delta++;
   }
-  $entity->{$target} = $field;
+
+  $entity->$field_name = $field;
 }
diff -rupN feeds_old/tests/feeds/feeds-tests-files.tpl.php feeds_new/tests/feeds/feeds-tests-files.tpl.php
--- feeds_old/tests/feeds/feeds-tests-files.tpl.php	2013-04-22 18:57:07.000000000 -0400
+++ feeds_new/tests/feeds/feeds-tests-files.tpl.php	2013-09-19 19:09:04.000000000 -0400
@@ -1,6 +1,6 @@
-Title,published,file,GUID
-"Tubing is awesome",205200720,<?php print $files[0]; ?>,0
-"Jeff vs Tom",428112720,<?php print $files[1]; ?>,1
-"Attersee",1151766000,<?php print $files[2]; ?>,2
-"H Street NE",1256326995,<?php print $files[3]; ?>,3
-"La Fayette Park",1256326995,<?php print $files[4]; ?>,4
+Title,published,file,GUID,alt,title2
+"Tubing is awesome",205200720,<?php print $files[0]; ?>,0,Alt text 0,Title text 0
+"Jeff vs Tom",428112720,<?php print $files[1]; ?>,1,Alt text 1,Title text 1
+"Attersee",1151766000,<?php print $files[2]; ?>,2,Alt text 2,Title text 2
+"H Street NE",1256326995,<?php print $files[3]; ?>,3,Alt text 3,Title text 3
+"La Fayette Park",1256326995,<?php print $files[4]; ?>,4,Alt text 4,Title text 4
diff -rupN feeds_old/tests/feeds.test feeds_new/tests/feeds.test
--- feeds_old/tests/feeds.test	2013-04-22 18:57:07.000000000 -0400
+++ feeds_new/tests/feeds.test	2013-09-19 19:09:04.000000000 -0400
@@ -18,11 +18,11 @@ class FeedsWebTestCase extends DrupalWeb
     // array of module names to setUp().
     if (isset($args[0])) {
       if (is_array($args[0])) {
-      $modules = $args[0];
-    }
+        $modules = $args[0];
+      }
       else {
-      $modules = $args;
-    }
+        $modules = $args;
+      }
     }
     else {
       $modules = array();
diff -rupN feeds_old/tests/feeds_mapper.test feeds_new/tests/feeds_mapper.test
--- feeds_old/tests/feeds_mapper.test	2013-04-22 18:57:07.000000000 -0400
+++ feeds_new/tests/feeds_mapper.test	2013-09-19 19:09:04.000000000 -0400
@@ -19,8 +19,8 @@ class FeedsMapperTestCase extends FeedsW
     'email' => 'email_textfield',
     'emimage' => 'emimage_textfields',
     'emaudio' => 'emaudio_textfields',
-    'filefield' => 'filefield_widget',
-    'image' => 'imagefield_widget',
+    'file' => 'file_generic',
+    'image' => 'image_image',
     'link_field' => 'link_field',
     'number_float' => 'number',
     'number_integer' => 'number',
diff -rupN feeds_old/tests/feeds_mapper_file.test feeds_new/tests/feeds_mapper_file.test
--- feeds_old/tests/feeds_mapper_file.test	2013-04-22 18:57:07.000000000 -0400
+++ feeds_new/tests/feeds_mapper_file.test	2013-09-19 19:09:04.000000000 -0400
@@ -7,10 +7,6 @@
 
 /**
  * Class for testing Feeds file mapper.
- *
- * @todo Add a test for enclosures using a local file that is
- *   a) in place and that
- *   b) needs to be copied from one location to another.
  */
 class FeedsMapperFileTestCase extends FeedsMapperTestCase {
   public static function getInfo() {
@@ -25,12 +21,12 @@ class FeedsMapperFileTestCase extends Fe
    * Basic test loading a single entry CSV file.
    */
   public function test() {
-    // If this is unset (or FALSE) http_request.inc will use curl, and will generate a 404
-    // for this feel url provided by feeds_tests. However, if feeds_tests was enabled in your
-    // site before running the test, it will work fine. Since it is truly screwy, lets just
-    // force it to use drupal_http_request for this test case.
+    // If this is unset (or FALSE) http_request.inc will use curl, and will
+    // generate a 404 for this feel url provided by feeds_tests. However, if
+    // feeds_tests was enabled in your site before running the test, it will
+    // work fine. Since it is truly screwy, lets just force it to use
+    // drupal_http_request for this test case.
     variable_set('feeds_never_use_curl', TRUE);
-    variable_set('clean_url', TRUE);
 
     // Only download simplepie if the plugin doesn't already exist somewhere.
     // People running tests locally might have it.
@@ -51,21 +47,21 @@ class FeedsMapperFileTestCase extends Fe
     $this->addMappings('syndication', array(
       0 => array(
         'source' => 'title',
-        'target' => 'title'
+        'target' => 'title',
       ),
       1 => array(
         'source' => 'timestamp',
-        'target' => 'created'
+        'target' => 'created',
       ),
       2 => array(
         'source' => 'enclosures',
-        'target' => 'field_files'
+        'target' => 'field_files:uri',
       ),
     ));
     $nid = $this->createFeedNode('syndication', $GLOBALS['base_url'] . '/testing/feeds/flickr.xml');
     $this->assertText('Created 5 nodes');
 
-    $files = $this->_testFiles();
+    $files = $this->listTestFiles();
     $entities = db_select('feeds_item')
       ->fields('feeds_item', array('entity_id'))
       ->condition('id', 'syndication')
@@ -95,27 +91,28 @@ class FeedsMapperFileTestCase extends Fe
     $this->addMappings('node', array(
       0 => array(
         'source' => 'title',
-        'target' => 'title'
+        'target' => 'title',
       ),
       1 => array(
         'source' => 'file',
-        'target' => 'field_files'
+        'target' => 'field_files:uri',
       ),
     ));
 
     // Import.
     $edit = array(
-      'feeds[FeedsHTTPFetcher][source]' => $GLOBALS['base_url'] . '/testing/feeds/files.csv',
+      'feeds[FeedsHTTPFetcher][source]' => url('testing/feeds/files.csv', array('absolute' => TRUE)),
     );
     $this->drupalPost('import/node', $edit, 'Import');
     $this->assertText('Created 5 nodes');
 
     // Assert: files should be in resources/.
-    $files = $this->_testFiles();
+    $files = $this->listTestFiles();
     $entities = db_select('feeds_item')
       ->fields('feeds_item', array('entity_id'))
       ->condition('id', 'node')
       ->execute();
+
     foreach ($entities as $entity) {
       $this->drupalGet('node/' . $entity->entity_id . '/edit');
       $f = new FeedsEnclosure(array_shift($files), NULL);
@@ -137,11 +134,12 @@ class FeedsMapperFileTestCase extends Fe
     $this->assertText('Created 5 nodes');
 
     // Assert: files should be in images/ now.
-    $files = $this->_testFiles();
+    $files = $this->listTestFiles();
     $entities = db_select('feeds_item')
       ->fields('feeds_item', array('entity_id'))
       ->condition('id', 'node')
       ->execute();
+
     foreach ($entities as $entity) {
       $this->drupalGet('node/' . $entity->entity_id . '/edit');
       $f = new FeedsEnclosure(array_shift($files), NULL);
@@ -149,29 +147,85 @@ class FeedsMapperFileTestCase extends Fe
     }
 
     // Deleting all imported items will delete the files from the images/ dir.
-    // @todo: for some reason the first file does not get deleted.
-//    $this->drupalPost('import/node/delete-items', array(), 'Delete');
-//    foreach ($this->_testFiles() as $file) {
-//      $this->assertFalse(is_file("public://images/$file"));
-//    }
+    $this->drupalPost('import/node/delete-items', array(), 'Delete');
+    foreach ($this->listTestFiles() as $file) {
+      $this->assertFalse(is_file("public://images/$file"));
+    }
   }
 
   /**
-   * Lists test files.
+   * Tests mapping to an image field.
    */
-  public function _testFiles() {
-    return array('tubing.jpeg', 'foosball.jpeg', 'attersee.jpeg', 'hstreet.jpeg', 'la fayette.jpeg');
+  public function testImages() {
+    variable_set('feeds_never_use_curl', TRUE);
+
+    $typename = $this->createContentType(array(), array('images' => 'image'));
+
+    // Enable title and alt mapping.
+    $edit = array(
+      'instance[settings][alt_field]' => 1,
+      'instance[settings][title_field]' => 1,
+    );
+    $this->drupalPost("admin/structure/types/manage/$typename/fields/field_images", $edit, t('Save settings'));
+
+    // Create a CSV importer configuration.
+    $this->createImporterConfiguration('Node import from CSV', 'image_test');
+    $this->setPlugin('image_test', 'FeedsCSVParser');
+    $this->setSettings('image_test', 'FeedsNodeProcessor', array('bundle' => $typename));
+    $this->setSettings('image_test', NULL, array('content_type' => ''));
+    $this->addMappings('image_test', array(
+      0 => array(
+        'source' => 'title',
+        'target' => 'title',
+      ),
+      1 => array(
+        'source' => 'file',
+        'target' => 'field_images:uri',
+      ),
+      2 => array(
+        'source' => 'title2',
+        'target' => 'field_images:title',
+      ),
+      3 => array(
+        'source' => 'alt',
+        'target' => 'field_images:alt',
+      ),
+    ));
+
+    // Import.
+    $edit = array(
+      'feeds[FeedsHTTPFetcher][source]' => url('testing/feeds/files-remote.csv', array('absolute' => TRUE)),
+    );
+    $this->drupalPost('import/image_test', $edit, 'Import');
+    $this->assertText('Created 5 nodes');
+
+    // Assert files exist.
+    $files = $this->listTestFiles();
+    $entities = db_select('feeds_item')
+      ->fields('feeds_item', array('entity_id'))
+      ->condition('id', 'image_test')
+      ->execute();
+
+    foreach ($entities as $i => $entity) {
+      $this->drupalGet('node/' . $entity->entity_id . '/edit');
+      $f = new FeedsEnclosure(array_shift($files), NULL);
+      $this->assertRaw($f->getUrlEncodedValue());
+      $this->assertRaw("Alt text $i");
+      $this->assertRaw("Title text $i");
+    }
   }
 
   /**
-   * Handle file field widgets.
+   * Lists test files.
    */
-  public function selectFieldWidget($fied_name, $field_type) {
-    if ($field_type == 'file') {
-      return 'file_generic';
-    }
-    else {
-      return parent::selectFieldWidget($fied_name, $field_type);
-    }
+  protected function listTestFiles() {
+    return array(
+      'tubing.jpeg',
+      'foosball.jpeg',
+      'attersee.jpeg',
+      'hstreet.jpeg',
+      'la fayette.jpeg',
+    );
   }
+
 }
diff -rupN feeds_old/tests/feeds_tests.info feeds_new/tests/feeds_tests.info
--- feeds_old/tests/feeds_tests.info	2013-04-22 19:05:11.000000000 -0400
+++ feeds_new/tests/feeds_tests.info	2013-09-30 17:57:56.000000000 -0400
@@ -6,9 +6,9 @@ core = 7.x
 files[] = feeds_test.module
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2013-04-22
-version = "7.x-2.0-alpha8"
+; Information added by drupal.org packaging script on 2013-09-30
+version = "7.x-2.0-alpha8+8-dev"
 core = "7.x"
 project = "feeds"
-datestamp = "1366671911"
+datestamp = "1380578276"
 
diff -rupN feeds_old/tests/feeds_tests.module feeds_new/tests/feeds_tests.module
--- feeds_old/tests/feeds_tests.module	2013-04-22 18:57:07.000000000 -0400
+++ feeds_new/tests/feeds_tests.module	2013-09-19 19:09:04.000000000 -0400
@@ -19,6 +19,11 @@ function feeds_tests_menu() {
     'access arguments' => array('access content'),
     'type' => MENU_CALLBACK,
   );
+  $items['testing/feeds/files-remote.csv'] = array(
+    'page callback' => 'feeds_tests_files_remote',
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+  );
   return $items;
 }
 
@@ -53,7 +58,7 @@ function feeds_tests_flickr() {
   );
   $path = drupal_get_path('module', 'feeds_tests') . '/feeds/assets';
   foreach ($images as &$image) {
-    $image = url("$path/$image", array('absolute' => TRUE));
+    $image = file_create_url("$path/$image");
   }
   drupal_add_http_header('Content-Type', 'application/rss+xml; charset=utf-8');
   print theme('feeds_tests_flickr', array('image_urls' => $images));
@@ -78,7 +83,26 @@ function feeds_tests_files() {
 }
 
 /**
- * Implements hook_feeds_processor_targets_alter()
+ * Outputs a CSV file pointing to files to download.
+ */
+function feeds_tests_files_remote() {
+  $images = array(
+    0 => 'tubing.jpeg',
+    1 => 'foosball.jpeg',
+    2 => 'attersee.jpeg',
+    3 => 'hstreet.jpeg',
+    4 => 'la fayette.jpeg',
+  );
+  $path = drupal_get_path('module', 'feeds_tests') . '/feeds/assets';
+  foreach ($images as &$image) {
+    $image = file_create_url("$path/$image");
+  }
+  drupal_add_http_header('Content-Type', 'text/plain; charset=utf-8');
+  print theme('feeds_tests_files', array('files' => $images));
+}
+
+/**
+ * Implements hook_feeds_processor_targets_alter().
  */
 function feeds_tests_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
   $targets['test_target'] = array(
@@ -96,7 +120,7 @@ function feeds_tests_feeds_processor_tar
  * @see my_module_set_target()
  */
 function feeds_tests_mapper_set_target($source, $entity, $target, $value, $mapping) {
-  $entity->body['und'][0]['value'] = serialize($mapping); 
+  $entity->body['und'][0]['value'] = serialize($mapping);
 }
 
 /**
@@ -106,10 +130,10 @@ function feeds_tests_mapper_set_target($
  */
 function feeds_tests_mapper_summary($mapping, $target, $form, $form_state) {
   $options = array(
-    'option1' => t('Option 1'), 
+    'option1' => t('Option 1'),
     'option2' => t('Another Option'),
-    'option3' => t('Option for select'), 
-    'option4' => t('Another One')
+    'option3' => t('Option for select'),
+    'option4' => t('Another One'),
   );
 
   $items = array();
@@ -139,7 +163,7 @@ function feeds_tests_mapper_summary($map
   return drupal_render($list);
 }
 
-/*
+/**
  * Provides the form with mapper settings.
  */
 function feeds_tests_mapper_form($mapping, $target, $form, $form_state) {
@@ -181,4 +205,3 @@ function feeds_tests_mapper_form($mappin
     ),
   );
 }
-