Bug 784717 - Asynchronous directory walk tests. r=froydnj
authorDavid Rajchenbach-Teller <dteller@mozilla.com>
Wed, 26 Sep 2012 21:37:23 -0400
changeset 108341 8332dd98c1cb2019a1b16b858baede06ec134e93
parent 108340 90b62202f9e380005f190d9cff1c6e7d8127d45e
child 108342 dabd0af858d73d173194f9dcb29abcb1b365291b
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersfroydnj
bugs784717
milestone18.0a1
Bug 784717 - Asynchronous directory walk tests. r=froydnj
toolkit/components/osfile/tests/mochi/main_test_osfile_async.js
--- a/toolkit/components/osfile/tests/mochi/main_test_osfile_async.js
+++ b/toolkit/components/osfile/tests/mochi/main_test_osfile_async.js
@@ -154,17 +154,18 @@ let reference_compare_files = function r
   });
   return promise;
 };
 
 let test = maketest("Main",
   function main(test) {
     SimpleTest.waitForExplicitFinish();
     let tests = [test_constants, test_path, test_open, test_stat,
-                 test_read_write, test_position, test_copy];
+                 test_read_write, test_position, test_copy,
+                 test_iter];
     let current = 0;
     let aux = function aux() {
       if (current >= tests.length) {
         info("Test is over");
         SimpleTest.finish();
         return null;
       }
       let test = tests[current++];
@@ -668,9 +669,142 @@ let test_mkdir = maketest("mkdir",
       },
       function(error) {
         ok(error instanceof OS.File.Error && error.becauseNoSuchFile,
            "Directory was effectively removed");
       }
     );
 
     return promise;
-  });
\ No newline at end of file
+  });
+
+let test_iter = maketest("iter",
+  function iter(test) {
+    let path;
+    let promise = OS.File.getCurrentDirectory();
+    let temporary_file_name;
+    let iterator;
+
+    // Trivial walks through the directory
+    promise = promise.then(
+      function obtained_current_directory(aPath) {
+        test.info("Preparing iteration");
+        path = aPath;
+        iterator = new OS.File.DirectoryIterator(aPath);
+        temporary_file_name = OS.Path.join(path, "empty-temporary-file.tmp");
+        return OS.File.remove(temporary_file_name);
+      }
+    );
+
+    // Ignore errors removing file
+    promise = promise.then(null, function() {});
+
+    promise = promise.then(
+      function removed_temporary_file() {
+        return iterator.nextBatch();
+      }
+    );
+
+    let allfiles1;
+    promise = promise.then(
+      function obtained_allfiles1(aAllFiles) {
+        test.info("Obtained all files through nextBatch");
+        allfiles1 = aAllFiles;
+        test.isnot(allfiles1.length, 0, "There is at least one file");
+        test.isnot(allfiles1[0].path, null, "Files have a path");
+        return iterator.close();
+      });
+
+    let allfiles2 = [];
+    let i = 0;
+    promise = promise.then(
+      function closed_iterator() {
+        test.info("Closed iterator");
+        iterator = new OS.File.DirectoryIterator(path);
+        return iterator.forEach(function(entry, index) {
+          is(i++, index, "Getting the correct index");
+          allfiles2.push(entry);
+        });
+      }
+    );
+
+    promise = promise.then(
+      function obtained_allfiles2() {
+        test.info("Obtained all files through forEach");
+        is(allfiles1.length, allfiles2.length, "Both runs returned the same number of files");
+        for (let i = 0; i < allfiles1.length; ++i) {
+          if (allfiles1[i].path != allfiles2[i].path) {
+            test.is(allfiles1[i].path, allfiles2[i].path, "Both runs return the same files");
+            break;
+          }
+        }
+      }
+    );
+
+    // Testing batch iteration + whether an iteration can be stopped early
+    let BATCH_LENGTH = 10;
+    promise = promise.then(
+      function compared_allfiles() {
+        test.info("Getting some files through nextBatch");
+        iterator.close();
+        iterator = new OS.File.DirectoryIterator(path);
+        return iterator.nextBatch(BATCH_LENGTH);
+      }
+    );
+    let somefiles1;
+    promise = promise.then(
+      function obtained_somefiles1(aFiles) {
+        somefiles1 = aFiles;
+        return iterator.nextBatch(BATCH_LENGTH);
+      }
+    );
+    let somefiles2;
+    promise = promise.then(
+      function obtained_somefiles2(aFiles) {
+        somefiles2 = aFiles;
+        iterator.close();
+        iterator = new OS.File.DirectoryIterator(path);
+        return iterator.forEach(
+          function cb(entry, index, iterator) {
+            if (index < BATCH_LENGTH) {
+              test.is(entry.path, somefiles1[index].path, "Both runs return the same files (part 1)");
+            } else if (index < 2*BATCH_LENGTH) {
+              test.is(entry.path, somefiles2[index - BATCH_LENGTH].path, "Both runs return the same files (part 2)");
+            } else if (index == 2 * BATCH_LENGTH) {
+              test.info("Attempting to stop asynchronous forEach");
+              return iterator.close();
+            } else {
+              test.fail("Can we stop an asynchronous forEach? " + index);
+            }
+            return null;
+          });
+      }
+    );
+
+    // Ensuring that we find new files if they appear
+    promise = promise.then(
+      function create_temporary_file() {
+        return OS.File.open(temporary_file_name, { write: true } );
+      }
+    );
+    promise = promise.then(
+      function with_temporary_file(file) {
+        file.close();
+        iterator = new OS.File.DirectoryIterator(path);
+        return iterator.nextBatch();
+      }
+    );
+    promise = promise.then(
+      function with_new_list(aFiles) {
+        is(aFiles.length, allfiles1.length + 1, "The directory iterator has noticed the new file");
+      }
+    );
+
+    promise = always(promise,
+      function cleanup() {
+        if (iterator) {
+          iterator.close();
+        }
+      }
+    );
+
+    return promise;
+});
\ No newline at end of file