app/lib/assertions/it.js
/**
* Assertion test framework
* @module
*/
/**
* Test
* @typedef {Object} test
* @property {routine} [after] - Routine to execute against test after run.
* @property {routine} [before] - Routine to execute against test before run.
* @property {function} [context] - Closure within which to run test as context
* @property {string} error - Error message to expect from test run.
* @property {Array} [params] - Params to apply against functional subject during test run.
* @property {*} [result] - Result to expect from test run.
* @property {(Object|function)} [subject] - Subject on which to apply test.
* @property {string} [subjectName] - Name of subject on which to apply test.
* @property {number} [timeout] - Total seconds to allow in execution of test before automatic timeout.
* @property {string} [when] - Description of when the assertion applies.
*/
/**
* Test assertion to apply during run.
* @typedef {function} assertion
* @param {test} test
* @param {callback} done
*/
/**
* Test routine
* @typedef {function} routine
* @param {test} test
* @param {callback} done
*/
/**
* Run tests against subject
* @typedef {function} it
* @param {string} subjectName - Name of subject on which to apply test
* @param {(Object|function)} subject - Subject on which to apply test.
* @param {test[]} tests - Tests to run against subject
*/
/**
* Return function for applying assertion function against subject and tests.
* @param {string} description - Description of assertion to run against subject (e.g. "returns result").
* @param {assertion} assertion - Assertion function to run against subject with each test provided.
* @returns {module:assertions/it~it}
*/
module.exports = function(description, assertion) {
/**
* Return description compiled with test data
* @param {string} description - Base description
* @param {test} test
*/
var compiledDescription = function(description, test) {
if (test.subjectName) {
description = test.subjectName + ' ' + description;
}
if (test.when) {
description += ' when ' + test.when;
}
return description;
};
return function(subjectName, subject, tests) {
if (!tests) {
tests = subject;
subject = subjectName;
subjectName = null;
}
tests.forEach(function(test) {
test.subjectName = subjectName;
test.subject = subject;
if (!test.params) {
test.params = [];
}
it(compiledDescription(description, test), function(done) {
if (test.timeout) {
this.timeout(test.timeout);
}
var after = done;
if (test.after) {
after = function(error) {
if (error) {
done(error);
} else {
test.after(done);
}
};
}
if (test.before) {
test.before(function(error) {
if (error) {
done(error);
} else {
assertion(test, after);
}
});
} else {
assertion(test, after);
}
});
});
};
};