mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1004418 - create a mochitest to verify all JS we ship parses, r=ttaubert
--HG-- extra : rebase_source : 94af2c3b26c3fca0f3c697b56c5e7b7d6488fce6
This commit is contained in:
parent
7a6a4c6b03
commit
bd0172679e
@ -64,6 +64,7 @@ support-files =
|
||||
offlineQuotaNotification.cacheManifest
|
||||
offlineQuotaNotification.html
|
||||
page_style_sample.html
|
||||
parsingTestHelpers.jsm
|
||||
print_postdata.sjs
|
||||
redirect_bug623155.sjs
|
||||
searchSuggestionEngine.sjs
|
||||
@ -342,6 +343,7 @@ skip-if = buildapp == 'mulet' || e10s # Bug 866413 - PageInfo doesn't work in e1
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content
|
||||
|
||||
[browser_parsable_css.js]
|
||||
[browser_parsable_script.js]
|
||||
|
||||
[browser_pinnedTabs.js]
|
||||
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
|
||||
|
@ -17,6 +17,9 @@ const kWhitelist = [
|
||||
{sourceName: /loop\/.*sdk-content\/.*\.css$/i /* TokBox SDK assets, see bug 1032469 */}
|
||||
];
|
||||
|
||||
let moduleLocation = gTestPath.replace(/\/[^\/]*$/i, "/parsingTestHelpers.jsm");
|
||||
let {generateURIsFromDirTree} = Cu.import(moduleLocation, {});
|
||||
|
||||
/**
|
||||
* Check if an error should be ignored due to matching one of the whitelist
|
||||
* objects defined in kWhitelist
|
||||
@ -40,113 +43,12 @@ function ignoredError(aErrorObject) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a promise that is resolved with a list of CSS files to check,
|
||||
* represented by their nsIURI objects.
|
||||
*
|
||||
* @param appDir the application directory to scan for CSS files (nsIFile)
|
||||
*/
|
||||
function generateURIsFromDirTree(appDir) {
|
||||
let rv = [];
|
||||
let dirQueue = [appDir.path];
|
||||
return Task.spawn(function*() {
|
||||
while (dirQueue.length) {
|
||||
let nextDir = dirQueue.shift();
|
||||
let {subdirs, cssfiles} = yield iterateOverPath(nextDir);
|
||||
dirQueue = dirQueue.concat(subdirs);
|
||||
rv = rv.concat(cssfiles);
|
||||
}
|
||||
return rv;
|
||||
});
|
||||
}
|
||||
|
||||
/* Shorthand constructor to construct an nsI(Local)File */
|
||||
let LocalFile = Components.Constructor("@mozilla.org/file/local;1", Ci.nsIFile, "initWithPath");
|
||||
|
||||
/**
|
||||
* Uses OS.File.DirectoryIterator to asynchronously iterate over a directory.
|
||||
* It returns a promise that is resolved with an object with two properties:
|
||||
* - cssfiles: an array of nsIURIs corresponding to CSS that needs checking
|
||||
* - subdirs: an array of paths for subdirectories we need to recurse into
|
||||
* (handled by generateURIsFromDirTree above)
|
||||
*
|
||||
* @param path the path to check (string)
|
||||
*/
|
||||
function iterateOverPath(path) {
|
||||
let iterator = new OS.File.DirectoryIterator(path);
|
||||
let parentDir = new LocalFile(path);
|
||||
let subdirs = [];
|
||||
let cssfiles = [];
|
||||
// Iterate through the directory
|
||||
let promise = iterator.forEach(
|
||||
function onEntry(entry) {
|
||||
if (entry.isDir) {
|
||||
let subdir = parentDir.clone();
|
||||
subdir.append(entry.name);
|
||||
subdirs.push(subdir.path);
|
||||
} else if (entry.name.endsWith(".css")) {
|
||||
let file = parentDir.clone();
|
||||
file.append(entry.name);
|
||||
let uriSpec = getURLForFile(file);
|
||||
cssfiles.push(Services.io.newURI(uriSpec, null, null));
|
||||
} else if (entry.name.endsWith(".ja")) {
|
||||
let file = parentDir.clone();
|
||||
file.append(entry.name);
|
||||
let subentries = [uri for (uri of generateEntriesFromJarFile(file))];
|
||||
cssfiles = cssfiles.concat(subentries);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
let outerPromise = Promise.defer();
|
||||
promise.then(function() {
|
||||
outerPromise.resolve({cssfiles: cssfiles, subdirs: subdirs});
|
||||
iterator.close();
|
||||
}, function(e) {
|
||||
outerPromise.reject(e);
|
||||
iterator.close();
|
||||
});
|
||||
return outerPromise.promise;
|
||||
}
|
||||
|
||||
/* 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.getURLSpecFromFile(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* A generator that generates nsIURIs for CSS files found in jar files
|
||||
* like omni.ja.
|
||||
*
|
||||
* @param jarFile an nsIFile object for the jar file that needs checking.
|
||||
*/
|
||||
function* generateEntriesFromJarFile(jarFile) {
|
||||
const ZipReader = new Components.Constructor("@mozilla.org/libjar/zip-reader;1", "nsIZipReader", "open");
|
||||
let zr = new ZipReader(jarFile);
|
||||
let entryEnumerator = zr.findEntries("*.css$");
|
||||
|
||||
const kURIStart = getURLForFile(jarFile);
|
||||
while (entryEnumerator.hasMore()) {
|
||||
let entry = entryEnumerator.getNext();
|
||||
let entryURISpec = "jar:" + kURIStart + "!/" + entry;
|
||||
yield Services.io.newURI(entryURISpec, null, null);
|
||||
}
|
||||
zr.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual test.
|
||||
*/
|
||||
add_task(function checkAllTheCSS() {
|
||||
let appDir = Services.dirsvc.get("XCurProcD", Ci.nsIFile);
|
||||
// This asynchronously produces a list of URLs (sadly, mostly sync on our
|
||||
// test infrastructure because it runs against jarfiles there, and
|
||||
// our zipreader APIs are all sync)
|
||||
let uris = yield generateURIsFromDirTree(appDir);
|
||||
let uris = yield generateURIsFromDirTree(appDir, ".css");
|
||||
|
||||
// Create a clean iframe to load all the files into:
|
||||
let hiddenWin = Services.appShell.hiddenDOMWindow;
|
||||
|
83
browser/base/content/test/general/browser_parsable_script.js
Normal file
83
browser/base/content/test/general/browser_parsable_script.js
Normal file
@ -0,0 +1,83 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* This list allows pre-existing or 'unfixable' JS issues to remain, while we
|
||||
* detect newly occurring issues in shipping JS. It is a list of regexes
|
||||
* matching files which have errors:
|
||||
*/
|
||||
const kWhitelist = new Set([
|
||||
/defaults\/profile\/prefs.js$/,
|
||||
]);
|
||||
|
||||
|
||||
let moduleLocation = gTestPath.replace(/\/[^\/]*$/i, "/parsingTestHelpers.jsm");
|
||||
let {generateURIsFromDirTree} = Cu.import(moduleLocation, {});
|
||||
let {Reflect} = Cu.import("resource://gre/modules/reflect.jsm", {});
|
||||
|
||||
/**
|
||||
* Check if an error should be ignored due to matching one of the whitelist
|
||||
* objects defined in kWhitelist
|
||||
*
|
||||
* @param uri the uri to check against the whitelist
|
||||
* @return true if the uri should be skipped, false otherwise.
|
||||
*/
|
||||
function uriIsWhiteListed(uri) {
|
||||
for (let whitelistItem of kWhitelist) {
|
||||
if (whitelistItem.test(uri.spec)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function parsePromise(uri) {
|
||||
let promise = new Promise((resolve, reject) => {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", uri, true);
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == this.DONE) {
|
||||
let scriptText = this.responseText;
|
||||
let ast;
|
||||
try {
|
||||
info("Checking " + uri);
|
||||
ast = Reflect.parse(scriptText);
|
||||
resolve(true);
|
||||
} catch (ex) {
|
||||
let errorMsg = "Script error reading " + uri + ": " + ex;
|
||||
ok(false, errorMsg);
|
||||
resolve(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.onerror = (error) => {
|
||||
ok(false, "XHR error reading " + uri + ": " + error);
|
||||
resolve(false);
|
||||
};
|
||||
xhr.overrideMimeType("application/javascript");
|
||||
xhr.send(null);
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
add_task(function* checkAllTheJS() {
|
||||
let appDir = Services.dirsvc.get("XCurProcD", Ci.nsIFile);
|
||||
// This asynchronously produces a list of URLs (sadly, mostly sync on our
|
||||
// test infrastructure because it runs against jarfiles there, and
|
||||
// our zipreader APIs are all sync)
|
||||
let uris = yield generateURIsFromDirTree(appDir, [".js", ".jsm"]);
|
||||
|
||||
// We create an array of promises so we can parallelize all our parsing
|
||||
// and file loading activity:
|
||||
let allPromises = [];
|
||||
for (let uri of uris) {
|
||||
if (uriIsWhiteListed(uri)) {
|
||||
info("Not checking " + uri.spec);
|
||||
continue;
|
||||
}
|
||||
allPromises.push(parsePromise(uri.spec));
|
||||
}
|
||||
|
||||
let promiseResults = yield Promise.all(allPromises);
|
||||
is(promiseResults.filter((x) => !x).length, 0, "There should be 0 parsing errors");
|
||||
});
|
||||
|
126
browser/base/content/test/general/parsingTestHelpers.jsm
Normal file
126
browser/base/content/test/general/parsingTestHelpers.jsm
Normal file
@ -0,0 +1,126 @@
|
||||
/* 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);
|
||||
let uriSpec = getURLForFile(file);
|
||||
files.push(Services.io.newURI(uriSpec, null, null));
|
||||
} else if (entry.name.endsWith(".ja") || entry.name.endsWith(".jar")) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user