Index: potx.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/potx/Attic/potx.inc,v
retrieving revision 1.1.2.17.2.7.2.19.4.6
diff -u -p -r1.1.2.17.2.7.2.19.4.6 potx.inc
--- potx.inc	25 Aug 2009 15:36:14 -0000	1.1.2.17.2.7.2.19.4.6
+++ potx.inc	20 Oct 2009 15:37:23 -0000
@@ -1476,6 +1476,16 @@ function _potx_save_string($value = NULL
   global $_potx_strings, $_potx_install;
 
   if (isset($value)) {
+    
+    // Value set but empty. Mark error on empty translatable string. Only trim
+    // for empty string checking, since we should store leading/trailing
+    // whitespace as it appears in the string otherwise.
+    $check_empty = trim($value);
+    if (empty($check_empty)) {
+      potx_status('error', t('Empty string attempted to be localized. Please do not leave test code for localization in your source.'), $file, $line);
+      return;
+    }
+    
     switch ($string_mode) {
       case POTX_STRING_BOTH:
         // Mark installer strings as duplicates of runtime strings if
Index: tests/potx.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/potx/tests/Attic/potx.test,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 potx.test
--- tests/potx.test	8 Sep 2009 15:06:11 -0000	1.1.2.1
+++ tests/potx.test	20 Oct 2009 15:37:23 -0000
@@ -21,6 +21,8 @@ class PotxTestCase extends DrupalWebTest
     parent::setUp('locale', 'potx');
     // Add potx.inc which we test for its functionality.
     include_once(drupal_get_path('module', 'potx') .'/potx.inc');
+    // Store empty error message for reuse in multiple cases.
+    $this->empty_error = t('Empty string attempted to be localized. Please do not leave test code for localization in your source.');
   }
 
   /**
@@ -57,6 +59,11 @@ class PotxTestCase extends DrupalWebTest
     $this->assertMsgID('Dynamic callback test string');
     $this->assertNoMsgID('1 test string');
     $this->assertNoMsgID('This is a test string.');
+    
+    $this->assert(count($this->potx_status) == 3, t('3 error messages found'));
+    $this->assert($this->potx_status[0][0] == $this->empty_error, t('First empty error found.'));
+    $this->assert($this->potx_status[1][0] == $this->empty_error, t('Second empty error found.'));
+    $this->assert($this->potx_status[2][0] == $this->empty_error, t('Third empty error found.'));
   }
 
   /**
@@ -92,6 +99,11 @@ class PotxTestCase extends DrupalWebTest
     $this->assertMsgID('Dynamic callback test string');
     $this->assertNoMsgID('1 test string');
     $this->assertNoMsgID('This is a test string.');
+
+    $this->assert(count($this->potx_status) == 3, t('3 error messages found'));
+    $this->assert($this->potx_status[0][0] == $this->empty_error, t('First empty error found.'));
+    $this->assert($this->potx_status[1][0] == $this->empty_error, t('Second empty error found.'));
+    $this->assert($this->potx_status[2][0] == $this->empty_error, t('Third empty error found.'));
   }
   
   /**
@@ -132,6 +144,10 @@ class PotxTestCase extends DrupalWebTest
     $this->assertMsgID('Dynamic callback test string');
     $this->assertNoMsgID('1 test string');
     $this->assertNoMsgID('This is a test string.');
+
+    $this->assert(count($this->potx_status) == 2, t('2 error messages found'));
+    $this->assert($this->potx_status[0][0] == $this->empty_error, t('First empty error found.'));
+    $this->assert($this->potx_status[1][0] == $this->empty_error, t('Second empty error found.'));
   }
 
   /**
@@ -162,6 +178,9 @@ class PotxTestCase extends DrupalWebTest
     $this->assertPluralID('@count test strings in JS');
     $this->assertMsgID('Another test string in JS');
     $this->assertMsgID('Embedded test string in JS');
+
+    $this->assert(count($this->potx_status) == 1, t('1 error message found'));
+    $this->assert($this->potx_status[0][0] == $this->empty_error, t('Empty error found.'));
   }
 
   /**
@@ -171,6 +190,7 @@ class PotxTestCase extends DrupalWebTest
     global $_potx_store, $_potx_strings, $_potx_install;
     $_potx_store = $_potx_strings = $_potx_install = array();
     
+    potx_status('set', POTX_STATUS_STRUCTURED);
     _potx_process_file($filename, 0, '_potx_save_string', '_potx_save_version', $api_version);
     _potx_build_files($string_mode, POTX_BUILD_SINGLE, 'general', '_potx_save_string', '_potx_save_version', '_potx_get_header', NULL, NULL, $api_version);
 
@@ -178,8 +198,10 @@ class PotxTestCase extends DrupalWebTest
     ob_start();
     _potx_write_files('potx-test.po');
     $this->potx_output = ob_get_clean();
-    $this->pass(var_export($this->potx_output, TRUE));
-  }
+    // $this->pass(var_export($this->potx_output, TRUE));
+    $this->potx_status = potx_status('get', TRUE);
+    // $this->pass(var_export($this->potx_status, TRUE));
+}
   
   /**
    * Helper function to assert an msgid construct in the .po file.
@@ -231,4 +253,18 @@ class PotxTestCase extends DrupalWebTest
     $this->assert(strpos($this->potx_output, 'msgid_plural "'. _potx_format_quoted_string('"'. $string . '"') .'"') !== FALSE, $message, $group);
   }
 
+  /**
+   * Debug functionality until simpletest built-in debugging is backported.
+   */
+  private function outputScreenContents($description = 'output', $basename = 'output') {
+    // This is a hack to get a directory that won't be cleaned up by simpletest
+    $file_dir = file_directory_path() .'/../simpletest_output_pages';
+    if (!is_dir($file_dir)) {
+      mkdir($file_dir, 0777, TRUE);
+    }
+    $output_path = "$file_dir/$basename.". $this->randomName(10) .'.html';
+    $rv = file_put_contents($output_path, $this->drupalGetContent());
+    $this->pass("$description: ". l('Contents of result page', $output_path));
+  }
+
 }
Index: tests/potx_test.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/potx/tests/Attic/potx_test.js,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 potx_test.js
--- tests/potx_test.js	8 Sep 2009 15:06:11 -0000	1.1.2.1
+++ tests/potx_test.js	20 Oct 2009 15:37:23 -0000
@@ -7,3 +7,4 @@
 Drupal.t('Test string in JS');
 Drupal.formatPlural(count, '1 test string in JS', '@count test strings in JS');
 Drupal.t('Another test string in JS', {'test': Drupal.t('Embedded test string in JS')});
+Drupal.t('');
Index: tests/potx_test_5.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/potx/tests/Attic/potx_test_5.module,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 potx_test_5.module
--- tests/potx_test_5.module	8 Sep 2009 15:06:11 -0000	1.1.2.1
+++ tests/potx_test_5.module	20 Oct 2009 15:37:23 -0000
@@ -19,6 +19,10 @@ function potx_test_5_menu($may_cache) {
       'access' => user_access('access content'),
       'callback' => 'potx_test_5_page',
     );
+    $items[] = array('path' =>
+      'test-empty-t',
+      'title' => t(''),
+    );
   }
   return $items;
 }
@@ -32,10 +36,11 @@ function potx_test_5_page() {
   $t('Dynamic callback test string');
   
   t('Test string in context', array(), array('context' => 'Test context'));
+  t('');
 }
 
 function potx_test_5_perm() {
-  return array('test potx permission', 'one more test potx permission');
+  return array('test potx permission', 'one more test potx permission', '');
 }
 
 function potx_test_5_permission() {
Index: tests/potx_test_6.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/potx/tests/Attic/potx_test_6.module,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 potx_test_6.module
--- tests/potx_test_6.module	8 Sep 2009 15:06:11 -0000	1.1.2.1
+++ tests/potx_test_6.module	20 Oct 2009 15:37:23 -0000
@@ -16,6 +16,9 @@ function potx_test_6_menu() {
     'description' => 'This is a test menu item',
     'page callback' => 'potx_test_6_page',
   );
+  $items['translate/test-empty'] = array(
+    'title' => '',
+  );
   return $items;
 }
 
@@ -28,10 +31,11 @@ function potx_test_6_page() {
   $t('Dynamic callback test string');
   
   t('Test string in context', array(), array('context' => 'Test context'));
+  t('');
 }
 
 function potx_test_6_perm() {
-  return array('test potx permission', 'one more test potx permission');
+  return array('test potx permission', 'one more test potx permission', '');
 }
 
 function potx_test_6_permission() {
Index: tests/potx_test_7.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/potx/tests/Attic/potx_test_7.module,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 potx_test_7.module
--- tests/potx_test_7.module	8 Sep 2009 15:06:11 -0000	1.1.2.1
+++ tests/potx_test_7.module	20 Oct 2009 15:37:23 -0000
@@ -16,6 +16,9 @@ function potx_test_7_menu() {
     'description' => 'This is a test menu item',
     'page callback' => 'potx_test_7_page',
   );
+  $items['translate/test-empty'] = array(
+    'title' => '',
+  );
   return $items;
 }
 
@@ -28,10 +31,11 @@ function potx_test_7_page() {
   $t('Dynamic callback test string');
   
   t('Test string in context', array(), array('context' => 'Test context'));
+  t('');
 }
 
 function potx_test_7_perm() {
-  return array('test potx permission', 'one more test potx permission');
+  return array('test potx permission', 'one more test potx permission', '');
 }
 
 function potx_test_7_permission() {
