michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: module.metadata = { michael@0: "stability": "deprecated" michael@0: }; michael@0: michael@0: const file = require("../io/file"); michael@0: const memory = require('./memory'); michael@0: const suites = require('@test/options').allTestModules; michael@0: const { Loader } = require("sdk/test/loader"); michael@0: const cuddlefish = require("sdk/loader/cuddlefish"); michael@0: michael@0: let loader = Loader(module); michael@0: const NOT_TESTS = ['setup', 'teardown']; michael@0: michael@0: var TestFinder = exports.TestFinder = function TestFinder(options) { michael@0: memory.track(this); michael@0: this.filter = options.filter; michael@0: this.testInProcess = options.testInProcess === false ? false : true; michael@0: this.testOutOfProcess = options.testOutOfProcess === true ? true : false; michael@0: }; michael@0: michael@0: TestFinder.prototype = { michael@0: findTests: function findTests(cb) { michael@0: var self = this; michael@0: var tests = []; michael@0: var filter; michael@0: // A filter string is {fileNameRegex}[:{testNameRegex}] - ie, a colon michael@0: // optionally separates a regex for the test fileName from a regex for the michael@0: // testName. michael@0: if (this.filter) { michael@0: var colonPos = this.filter.indexOf(':'); michael@0: var filterFileRegex, filterNameRegex; michael@0: if (colonPos === -1) { michael@0: filterFileRegex = new RegExp(self.filter); michael@0: } else { michael@0: filterFileRegex = new RegExp(self.filter.substr(0, colonPos)); michael@0: filterNameRegex = new RegExp(self.filter.substr(colonPos + 1)); michael@0: } michael@0: // This function will first be called with just the filename; if michael@0: // it returns true the module will be loaded then the function michael@0: // called again with both the filename and the testname. michael@0: filter = function(filename, testname) { michael@0: return filterFileRegex.test(filename) && michael@0: ((testname && filterNameRegex) ? filterNameRegex.test(testname) michael@0: : true); michael@0: }; michael@0: } else michael@0: filter = function() {return true}; michael@0: michael@0: suites.forEach(function(suite) { michael@0: // Load each test file as a main module in its own loader instance michael@0: // `suite` is defined by cuddlefish/manifest.py:ManifestBuilder.build michael@0: michael@0: let suiteModule; michael@0: michael@0: try { michael@0: suiteModule = cuddlefish.main(loader, suite); michael@0: } michael@0: catch (e) { michael@0: if (!/^Unsupported Application/.test(e.message)) michael@0: throw e; michael@0: // If `Unsupported Application` error thrown during test, michael@0: // skip the test suite michael@0: suiteModule = { michael@0: 'test suite skipped': assert => assert.pass(e.message) michael@0: }; michael@0: } michael@0: michael@0: if (self.testInProcess) michael@0: for each (let name in Object.keys(suiteModule).sort()) { michael@0: if(NOT_TESTS.indexOf(name) === -1 && filter(suite, name)) { michael@0: tests.push({ michael@0: setup: suiteModule.setup, michael@0: teardown: suiteModule.teardown, michael@0: testFunction: suiteModule[name], michael@0: name: suite + "." + name michael@0: }); michael@0: } michael@0: } michael@0: }); michael@0: michael@0: cb(tests); michael@0: } michael@0: };