summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/general/parsingTestHelpers.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/general/parsingTestHelpers.jsm')
-rw-r--r--browser/base/content/test/general/parsingTestHelpers.jsm131
1 files changed, 131 insertions, 0 deletions
diff --git a/browser/base/content/test/general/parsingTestHelpers.jsm b/browser/base/content/test/general/parsingTestHelpers.jsm
new file mode 100644
index 000000000..69c764483
--- /dev/null
+++ b/browser/base/content/test/general/parsingTestHelpers.jsm
@@ -0,0 +1,131 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["generateURIsFromDirTree"];
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+/* Shorthand constructors to construct an nsI(Local)File and zip reader: */
+const LocalFile = new Components.Constructor("@mozilla.org/file/local;1", Ci.nsIFile, "initWithPath");
+const ZipReader = new Components.Constructor("@mozilla.org/libjar/zip-reader;1", "nsIZipReader", "open");
+
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/osfile.jsm");
+Cu.import("resource://gre/modules/Task.jsm");
+
+
+/**
+ * Returns a promise that is resolved with a list of files that have one of the
+ * extensions passed, represented by their nsIURI objects, which exist inside
+ * the directory passed.
+ *
+ * @param dir the directory which to scan for files (nsIFile)
+ * @param extensions the extensions of files we're interested in (Array).
+ */
+function generateURIsFromDirTree(dir, extensions) {
+ if (!Array.isArray(extensions)) {
+ extensions = [extensions];
+ }
+ let dirQueue = [dir.path];
+ return Task.spawn(function*() {
+ let rv = [];
+ while (dirQueue.length) {
+ let nextDir = dirQueue.shift();
+ let {subdirs, files} = yield iterateOverPath(nextDir, extensions);
+ dirQueue.push(...subdirs);
+ rv.push(...files);
+ }
+ return rv;
+ });
+}
+
+/**
+ * Uses OS.File.DirectoryIterator to asynchronously iterate over a directory.
+ * It returns a promise that is resolved with an object with two properties:
+ * - files: an array of nsIURIs corresponding to files that match the extensions passed
+ * - subdirs: an array of paths for subdirectories we need to recurse into
+ * (handled by generateURIsFromDirTree above)
+ *
+ * @param path the path to check (string)
+ * @param extensions the file extensions we're interested in.
+ */
+function iterateOverPath(path, extensions) {
+ let iterator = new OS.File.DirectoryIterator(path);
+ let parentDir = new LocalFile(path);
+ let subdirs = [];
+ let files = [];
+
+ let pathEntryIterator = (entry) => {
+ if (entry.isDir) {
+ subdirs.push(entry.path);
+ } else if (extensions.some((extension) => entry.name.endsWith(extension))) {
+ let file = parentDir.clone();
+ file.append(entry.name);
+ // the build system might leave dead symlinks hanging around, which are
+ // returned as part of the directory iterator, but don't actually exist:
+ if (file.exists()) {
+ let uriSpec = getURLForFile(file);
+ files.push(Services.io.newURI(uriSpec, null, null));
+ }
+ } else if (entry.name.endsWith(".ja") || entry.name.endsWith(".jar") ||
+ entry.name.endsWith(".zip") || entry.name.endsWith(".xpi")) {
+ let file = parentDir.clone();
+ file.append(entry.name);
+ for (let extension of extensions) {
+ let jarEntryIterator = generateEntriesFromJarFile(file, extension);
+ files.push(...jarEntryIterator);
+ }
+ }
+ };
+
+ return new Promise((resolve, reject) => {
+ Task.spawn(function* () {
+ try {
+ // Iterate through the directory
+ yield iterator.forEach(pathEntryIterator);
+ resolve({files: files, subdirs: subdirs});
+ } catch (ex) {
+ reject(ex);
+ } finally {
+ iterator.close();
+ }
+ });
+ });
+}
+
+/* Helper function to generate a URI spec (NB: not an nsIURI yet!)
+ * given an nsIFile object */
+function getURLForFile(file) {
+ let fileHandler = Services.io.getProtocolHandler("file");
+ fileHandler = fileHandler.QueryInterface(Ci.nsIFileProtocolHandler);
+ return fileHandler.getURLSpecFromActualFile(file);
+}
+
+/**
+ * A generator that generates nsIURIs for particular files found in jar files
+ * like omni.ja.
+ *
+ * @param jarFile an nsIFile object for the jar file that needs checking.
+ * @param extension the extension we're interested in.
+ */
+function* generateEntriesFromJarFile(jarFile, extension) {
+ let zr = new ZipReader(jarFile);
+ let entryEnumerator = zr.findEntries("*" + extension + "$");
+
+ const kURIStart = getURLForFile(jarFile);
+ while (entryEnumerator.hasMore()) {
+ let entry = entryEnumerator.getNext();
+ // Ignore the JS cache which is stored in omni.ja
+ if (entry.startsWith("jsloader") || entry.startsWith("jssubloader")) {
+ continue;
+ }
+ let entryURISpec = "jar:" + kURIStart + "!/" + entry;
+ yield Services.io.newURI(entryURISpec, null, null);
+ }
+ zr.close();
+}
+
+