tad
Version:
JavaScript test suite
140 lines (131 loc) • 3.57 kB
JavaScript
/* eslint max-lines: "off" */
// Runs tests
"use strict";
var isError = require("es5-ext/error/is-error")
, isFunction = require("es5-ext/function/is-function")
, noop = require("es5-ext/function/noop")
, toArray = require("es5-ext/object/to-array")
, hforEach = require("es5-ext/object/for-each")
, isValue = require("es5-ext/object/is-value")
, isThenable = require("es5-ext/object/is-thenable")
, deferred = require("deferred")
, createLogger = require("./logger")
, createAssert = require("./assert");
var nextTick = process.nextTick
, pattern = /^\s*(?:async\s*)?(?:[^\s()]+\s*)?\(\s*([tad])(?:\s*,\s*([tad]))?\s*\)/
, run;
run = function self(testee, tests, assert, logger) {
if (isFunction(tests)) {
tests = { "": tests };
}
hforEach(tests, function (t) {
var conf, match;
if (isFunction(t)) {
conf = t.conf = { t: true, a: true, d: false };
if (t.length > 2) {
conf.d = true;
} else if ((match = t.toString().match(pattern))) {
conf.t = conf.a = false;
conf[match[1]] = true;
if (match[2]) {
conf[match[2]] = true;
}
}
}
});
return deferred.reduce(
toArray(tests),
// eslint-disable-next-line max-statements
function (ignore, data) {
var testResult, d, finish, done, name, testFunction;
name = data[0];
testFunction = data[1];
d = deferred();
finish = function () {
logger.out(true);
d.resolve();
};
logger.in(name, true);
if (isFunction(testFunction)) {
try {
if (testFunction.conf.d) {
done = function (asyncTestResult) {
if (asyncTestResult) {
if (isError(asyncTestResult)) {
assert.fail(asyncTestResult);
finish();
} else {
self(testee, asyncTestResult, assert, logger)(finish).done();
}
} else {
finish();
}
};
if (testFunction.conf.t) {
// eslint-disable-next-line max-depth
if (testFunction.conf.a) {
testFunction(testee, assert, done);
} else {
testFunction(testee, done);
}
} else if (testFunction.conf.a) {
testFunction(assert, done);
} else {
testFunction(done);
}
} else {
if (testFunction.conf.t) {
testResult = testFunction(testee, assert);
} else {
testResult = testFunction(assert);
}
if (isThenable(testResult)) {
testResult.then(
function (thenableTestResult) {
if (thenableTestResult) {
self(
testee, thenableTestResult, assert, logger
)(finish).done();
} else {
finish();
}
},
function (error) {
assert.fail(error);
finish();
}
);
} else if (testResult) {
self(testee, testResult, assert, logger)(finish).done();
} else {
finish();
}
}
} catch (e) {
logger.error(e);
finish();
}
} else if (isValue(testFunction)) {
self(testee, testFunction, assert, logger)(finish).done();
} else {
assert.fail(new Error("No tests found at '" + name + "' property"));
finish();
}
return d.promise;
},
null
)(noop);
};
module.exports = function (testee, test, assert, logger) {
var runResult;
logger = logger || createLogger();
assert = assert || createAssert(logger);
nextTick(function () {
runResult = run(testee, test, assert, logger);
if (logger.end) {
runResult = runResult(logger.end.bind(logger));
}
runResult.done();
});
return logger;
};