From 3a94acf27ea1eff8bd1125450f07c0c366332e80 Mon Sep 17 00:00:00 2001 From: Minteck Date: Sun, 17 Oct 2021 20:08:04 +0200 Subject: Initial commit --- node_modules/jake/lib/test_task.js | 270 +++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 node_modules/jake/lib/test_task.js (limited to 'node_modules/jake/lib/test_task.js') diff --git a/node_modules/jake/lib/test_task.js b/node_modules/jake/lib/test_task.js new file mode 100644 index 0000000..6482bf1 --- /dev/null +++ b/node_modules/jake/lib/test_task.js @@ -0,0 +1,270 @@ +/* + * Jake JavaScript build tool + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +let path = require('path'); +let currDir = process.cwd(); + +/** + @name jake + @namespace jake +*/ +/** + @name jake.TestTask + @constructor + @description Instantiating a TestTask creates a number of Jake + Tasks that make running tests for your software easy. + + @param {String} name The name of the project + @param {Function} definition Defines the list of files containing the tests, + and the name of the namespace/task for running them. Will be executed on the + instantiated TestTask (i.e., 'this', will be the TestTask instance), to set + the various instance-propertiess. + + @example + let t = new jake.TestTask('bij-js', function () { + this.testName = 'testSpecial'; + this.testFiles.include('test/**'); + }); + + */ +let TestTask = function () { + let self = this; + let args = Array.prototype.slice.call(arguments); + let name = args.shift(); + let definition = args.pop(); + let prereqs = args.pop() || []; + + /** + @name jake.TestTask#testNam + @public + @type {String} + @description The name of the namespace to place the tests in, and + the top-level task for running tests. Defaults to "test" + */ + this.testName = 'test'; + + /** + @name jake.TestTask#testFiles + @public + @type {jake.FileList} + @description The list of files containing tests to load + */ + this.testFiles = new jake.FileList(); + + /** + @name jake.TestTask#showDescription + @public + @type {Boolean} + @description Show the created task when doing Jake -T + */ + this.showDescription = true; + + /* + @name jake.TestTask#totalTests + @public + @type {Number} + @description The total number of tests to run + */ + this.totalTests = 0; + + /* + @name jake.TestTask#executedTests + @public + @type {Number} + @description The number of tests successfully run + */ + this.executedTests = 0; + + if (typeof definition == 'function') { + definition.call(this); + } + + if (this.showDescription) { + desc('Run the tests for ' + name); + } + + task(this.testName, prereqs, {async: true}, function () { + let t = jake.Task[this.fullName + ':run']; + t.on('complete', function () { + complete(); + }); + // Pass args to the namespaced test + t.invoke.apply(t, arguments); + }); + + namespace(self.testName, function () { + + let runTask = task('run', {async: true}, function (pat) { + let re; + let testFiles; + + // Don't nest; make a top-level namespace. Don't want + // re-calling from inside to nest infinitely + jake.currentNamespace = jake.defaultNamespace; + + re = new RegExp(pat); + // Get test files that match the passed-in pattern + testFiles = self.testFiles.toArray() + .filter(function (f) { + return (re).test(f); + }) // Don't load the same file multiple times -- should this be in FileList? + .reduce(function (p, c) { + if (p.indexOf(c) < 0) { + p.push(c); + } + return p; + }, []); + + // Create a namespace for all the testing tasks to live in + namespace(self.testName + 'Exec', function () { + // Each test will be a prereq for the dummy top-level task + let prereqs = []; + // Continuation to pass to the async tests, wrapping `continune` + let next = function () { + complete(); + }; + // Create the task for this test-function + let createTask = function (name, action) { + // If the test-function is defined with a continuation + // param, flag the task as async + let t; + let isAsync = !!action.length; + + // Define the actual namespaced task with the name, the + // wrapped action, and the correc async-flag + t = task(name, createAction(name, action), { + async: isAsync + }); + t.once('complete', function () { + self.executedTests++; + }); + t._internal = true; + return t; + }; + // Used as the action for the defined task for each test. + let createAction = function (n, a) { + // A wrapped function that passes in the `next` function + // for any tasks that run asynchronously + return function () { + let cb; + if (a.length) { + cb = next; + } + if (!(n == 'before' || n == 'after' || + /_beforeEach$/.test(n) || /_afterEach$/.test(n))) { + jake.logger.log(n); + } + // 'this' will be the task when action is run + return a.call(this, cb); + }; + }; + // Dummy top-level task for everything to be prereqs for + let topLevel; + + // Pull in each test-file, and iterate over any exported + // test-functions. Register each test-function as a prereq task + testFiles.forEach(function (file) { + let exp = require(path.join(currDir, file)); + + // Create a namespace for each filename, so test-name collisions + // won't be a problem + namespace(file, function () { + let testPrefix = self.testName + 'Exec:' + file + ':'; + let testName; + // Dummy task for displaying file banner + testName = '*** Running ' + file + ' ***'; + prereqs.push(testPrefix + testName); + createTask(testName, function () {}); + + // 'before' setup + if (typeof exp.before == 'function') { + prereqs.push(testPrefix + 'before'); + // Create the task + createTask('before', exp.before); + } + + // Walk each exported function, and create a task for each + for (let p in exp) { + if (p == 'before' || p == 'after' || + p == 'beforeEach' || p == 'afterEach') { + continue; + } + + if (typeof exp.beforeEach == 'function') { + prereqs.push(testPrefix + p + '_beforeEach'); + // Create the task + createTask(p + '_beforeEach', exp.beforeEach); + } + + // Add the namespace:name of this test to the list of prereqs + // for the dummy top-level task + prereqs.push(testPrefix + p); + // Create the task + createTask(p, exp[p]); + + if (typeof exp.afterEach == 'function') { + prereqs.push(testPrefix + p + '_afterEach'); + // Create the task + createTask(p + '_afterEach', exp.afterEach); + } + } + + // 'after' teardown + if (typeof exp.after == 'function') { + prereqs.push(testPrefix + 'after'); + // Create the task + let afterTask = createTask('after', exp.after); + afterTask._internal = true; + } + + }); + }); + + self.totalTests = prereqs.length; + process.on('exit', function () { + // Throw in the case where the process exits without + // finishing tests, but no error was thrown + if (!jake.errorCode && (self.totalTests > self.executedTests)) { + throw new Error('Process exited without all tests completing.'); + } + }); + + // Create the dummy top-level task. When calling a task internally + // with `invoke` that is async (or has async prereqs), have to listen + // for the 'complete' event to know when it's done + topLevel = task('__top__', prereqs); + topLevel._internal = true; + topLevel.addListener('complete', function () { + jake.logger.log('All tests ran successfully'); + complete(); + }); + + topLevel.invoke(); // Do the thing! + }); + + }); + runTask._internal = true; + + }); + + +}; + +jake.TestTask = TestTask; +exports.TestTask = TestTask; + -- cgit