| /* |
| * 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. |
| * |
| */ |
| |
| var path = require('path') |
| , fs = require('fs') |
| , exec = require('child_process').exec |
| , 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 |
| var t = new jake.TestTask('bij-js', function () { |
| this.testName = 'testSpecial'; |
| this.testFiles.include('test/**'); |
| }); |
| |
| */ |
| var TestTask = function (name, definition) { |
| var self = this; |
| |
| /** |
| @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; |
| |
| if (typeof definition == 'function') { |
| definition.call(this); |
| } |
| |
| if (this.showDescription) { |
| desc('Run the tests for ' + name); |
| } |
| task(this.testName, function () { |
| var t = jake.Task[self.testName + ':run']; |
| t.invoke.apply(t, arguments); |
| }, {async: true}); |
| |
| namespace(self.testName, function () { |
| |
| task('run', function (pat) { |
| var p = pat || '.*' |
| , re |
| , 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); |
| testFiles = self.testFiles.toArray().filter(function (f) { |
| return (re).test(f); |
| }); |
| |
| // 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 |
| var prereqs = [] |
| // Continuation to pass to the async tests, wrapping `continune` |
| , next = function () { |
| complete(); |
| } |
| // Create the task for this test-function |
| , createTask = function (name, action) { |
| // If the test-function is defined with a continuation |
| // param, flag the task as async |
| isAsync = !!action.length; |
| |
| // Define the actual namespaced task with the name, the |
| // wrapped action, and the correc async-flag |
| task(name, createAction(name, action), { |
| async: isAsync |
| }); |
| } |
| // Used as the action for the defined task for each test. |
| , createAction = function (n, a) { |
| // A wrapped function that passes in the `next` function |
| // for any tasks that run asynchronously |
| return function () { |
| var cb |
| , msg; |
| if (a.length) { |
| cb = next; |
| } |
| if (!(n == 'before' || n == 'after')) { |
| if (n.toLowerCase().indexOf('test') === 0) { |
| msg = n; |
| } |
| else { |
| msg = '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 |
| , 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) { |
| var exp = require(path.join(currDir, file)) |
| , name |
| , action |
| , banner |
| , isAsync; |
| |
| // Create a namespace for each filename, so test-name collisions |
| // won't be a problem |
| namespace(file, function () { |
| |
| // For displaying file banner |
| banner = '*** Running ' + file + ' ***'; |
| prereqs.push(self.testName + 'Exec:' + file + ':' + banner); |
| // Create the task |
| createTask(banner, function () {}); |
| |
| if (typeof exp.before == 'function') { |
| prereqs.push(self.testName + 'Exec:' + file + ':before'); |
| // Create the task |
| createTask('before', exp.before); |
| } |
| |
| // Walk each exported function, and create a task for each |
| for (var p in exp) { |
| if (p == 'before' || p == 'after') { |
| continue; |
| } |
| // Add the namespace:name of this test to the list of prereqs |
| // for the dummy top-level task |
| prereqs.push(self.testName + 'Exec:' + file + ':' + p); |
| // Create the task |
| createTask(p, exp[p]); |
| } |
| |
| if (typeof exp.after == 'function') { |
| prereqs.push(self.testName + 'Exec:' + file + ':after'); |
| // Create the task |
| createTask('after', exp.after); |
| } |
| |
| }); |
| }); |
| |
| // 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.addListener('complete', function () { |
| jake.logger.log('All tests ran successfully'); |
| complete(); |
| }); |
| |
| topLevel.invoke(); // Do the thing! |
| }); |
| |
| |
| }, {async: true}); |
| }); |
| |
| |
| }; |
| |
| jake.TestTask = TestTask; |
| exports.TestTask = TestTask; |
| |