Skip to content
This repository has been archived by the owner on Feb 26, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1521 from erikvold/1024791
Browse files Browse the repository at this point in the history
Bug 1024791 - Scan the add-on for tests r=@jsantell
  • Loading branch information
erikvold committed Jun 21, 2014
2 parents ae38002 + 1059f2c commit f6bc931
Show file tree
Hide file tree
Showing 16 changed files with 244 additions and 254 deletions.
1 change: 0 additions & 1 deletion app-extension/bootstrap.js
Expand Up @@ -233,7 +233,6 @@ function startup(data, reasonCode) {
// Arguments related to test runner.
modules: {
'@test/options': {
allTestModules: options.allTestModules,
iterations: options.iterations,
filter: options.filter,
profileMemory: options.profileMemory,
Expand Down
4 changes: 2 additions & 2 deletions lib/sdk/addon/installer.js
Expand Up @@ -54,7 +54,6 @@ exports.install = function install(xpiPath) {
setTimeout(resolve, 0, aAddon.id);
},
onInstallFailed: function (aInstall) {
console.log("failed");
aInstall.removeListener(listener);
reject(aInstall.error);
},
Expand Down Expand Up @@ -114,8 +113,9 @@ exports.isActive = function isActive(addonId) {
return getAddon(addonId).then(addon => addon.isActive && !addon.appDisabled);
};

function getAddon (id) {
const getAddon = function getAddon (id) {
let { promise, resolve, reject } = defer();
AddonManager.getAddonByID(id, addon => addon ? resolve(addon) : reject());
return promise;
}
exports.getAddon = getAddon;
2 changes: 0 additions & 2 deletions lib/sdk/addon/window.js
Expand Up @@ -56,8 +56,6 @@ eventTarget.addEventListener("DOMContentLoaded", function handler(event) {
resolve();
}, false);



exports.ready = promise;
exports.window = window;

Expand Down
164 changes: 120 additions & 44 deletions lib/sdk/deprecated/unit-test-finder.js
@@ -1,7 +1,6 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

module.metadata = {
Expand All @@ -10,9 +9,109 @@ module.metadata = {

const file = require("../io/file");
const memory = require('./memory');
const suites = require('@test/options').allTestModules;
const { Loader } = require("sdk/test/loader");
const cuddlefish = require("sdk/loader/cuddlefish");
const { Loader } = require("../test/loader");
const cuddlefish = require("../loader/cuddlefish");
const { defer, resolve } = require("../core/promise");
const { getAddon } = require("../addon/installer");
const { id } = require("sdk/self");
const { newURI } = require('sdk/url/utils');
const { getZipReader } = require("../zip/utils");

const { Cc, Ci, Cu } = require("chrome");
const { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
var ios = Cc['@mozilla.org/network/io-service;1']
.getService(Ci.nsIIOService);

const TEST_REGEX = /(([^\/]+\/)(?:lib\/)?)(tests?\/test-[^\.\/]+)\.js$/;

const { mapcat, map, filter, fromEnumerator } = require("sdk/util/sequence");

const toFile = x => x.QueryInterface(Ci.nsIFile);
const isTestFile = ({leafName}) => leafName.substr(0, 5) == "test-" && leafName.substr(-3, 3) == ".js";
const getFileURI = x => ios.newFileURI(x).spec;

const getDirectoryEntries = file => map(toFile, fromEnumerator(_ => file.directoryEntries));
const getTestFiles = directory => filter(isTestFile, getDirectoryEntries(directory));
const getTestURIs = directory => map(getFileURI, getTestFiles(directory));

const isDirectory = x => x.isDirectory();
const getTestEntries = directory => mapcat(entry =>
/^tests?$/.test(entry.leafName) ? getTestURIs(entry) : getTestEntries(entry),
filter(isDirectory, getDirectoryEntries(directory)));

const removeDups = (array) => array.reduce((result, value) => {
if (value != result[result.length - 1]) {
result.push(value);
}
return result;
}, []);

const getSuites = function getSuites({ id }) {
return getAddon(id).then(addon => {
let fileURI = addon.getResourceURI("tests/");
let isPacked = fileURI.scheme == "jar";
let xpiURI = addon.getResourceURI();
let file = xpiURI.QueryInterface(Ci.nsIFileURL).file;
let suites = [];
let addEntry = (entry) => {
if (TEST_REGEX.test(entry)) {
let suite = RegExp.$2 + RegExp.$3;
suites.push(suite);
}
}

if (isPacked) {
return getZipReader(file).then(zip => {
let entries = zip.findEntries(null);
while (entries.hasMore()) {
let entry = entries.getNext();
addEntry(entry);
}
zip.close();

// sort and remove dups
suites = removeDups(suites.sort());
return suites;
})
} else {
let tests = getTestEntries(file);
[...tests].forEach(addEntry);
}

// sort and remove dups
suites = removeDups(suites.sort());
return suites;
});
}
exports.getSuites = getSuites;

const makeFilter = function makeFilter(options) {
// A filter string is {fileNameRegex}[:{testNameRegex}] - ie, a colon
// optionally separates a regex for the test fileName from a regex for the
// testName.
if (options.filter) {
let colonPos = options.filter.indexOf(':');
let filterFileRegex, filterNameRegex;

if (colonPos === -1) {
filterFileRegex = new RegExp(options.filter);
} else {
filterFileRegex = new RegExp(options.filter.substr(0, colonPos));
filterNameRegex = new RegExp(options.filter.substr(colonPos + 1));
}
// This function will first be called with just the filename; if
// it returns true the module will be loaded then the function
// called again with both the filename and the testname.
return (filename, testname) => {
return filterFileRegex.test(filename) &&
((testname && filterNameRegex) ? filterNameRegex.test(testname)
: true);
};
}

return () => true;
}
exports.makeFilter = makeFilter;

let loader = Loader(module);
const NOT_TESTS = ['setup', 'teardown'];
Expand All @@ -25,65 +124,42 @@ var TestFinder = exports.TestFinder = function TestFinder(options) {
};

TestFinder.prototype = {
findTests: function findTests(cb) {
var self = this;
var tests = [];
var filter;
// A filter string is {fileNameRegex}[:{testNameRegex}] - ie, a colon
// optionally separates a regex for the test fileName from a regex for the
// testName.
if (this.filter) {
var colonPos = this.filter.indexOf(':');
var filterFileRegex, filterNameRegex;
if (colonPos === -1) {
filterFileRegex = new RegExp(self.filter);
} else {
filterFileRegex = new RegExp(self.filter.substr(0, colonPos));
filterNameRegex = new RegExp(self.filter.substr(colonPos + 1));
}
// This function will first be called with just the filename; if
// it returns true the module will be loaded then the function
// called again with both the filename and the testname.
filter = function(filename, testname) {
return filterFileRegex.test(filename) &&
((testname && filterNameRegex) ? filterNameRegex.test(testname)
: true);
};
} else
filter = function() {return true};

suites.forEach(function(suite) {
findTests: function findTests() {
return getSuites({ id: id }).then(suites => {
let filter = makeFilter({ filter: this.filter });
let tests = [];

suites.forEach(suite => {
// Load each test file as a main module in its own loader instance
// `suite` is defined by cuddlefish/manifest.py:ManifestBuilder.build

let suiteModule;

try {
suiteModule = cuddlefish.main(loader, suite);
}
catch (e) {
if (!/^Unsupported Application/.test(e.message))
throw e;
// If `Unsupported Application` error thrown during test,
// skip the test suite
suiteModule = {
'test suite skipped': assert => assert.pass(e.message)
};
}

if (self.testInProcess)
if (this.testInProcess) {
for each (let name in Object.keys(suiteModule).sort()) {
if(NOT_TESTS.indexOf(name) === -1 && filter(suite, name)) {
if (NOT_TESTS.indexOf(name) === -1 && filter(suite, name)) {
tests.push({
setup: suiteModule.setup,
teardown: suiteModule.teardown,
testFunction: suiteModule[name],
name: suite + "." + name
});
setup: suiteModule.setup,
teardown: suiteModule.teardown,
testFunction: suiteModule[name],
name: suite + "." + name
});
}
}
});
}
})

cb(tests);
return tests;
});
}
};

0 comments on commit f6bc931

Please sign in to comment.