Skip to content

Commit

Permalink
added support for nodeunit tests groups. added more error logging
Browse files Browse the repository at this point in the history
  • Loading branch information
urigolani committed Oct 6, 2011
1 parent f900da7 commit e1c2289
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 25 deletions.
93 changes: 78 additions & 15 deletions lib/nodeunitWrapper.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,42 @@

var testRunner = require('./singleTestReporter');

//
// This method runs a test *testName* from *testModule* and calls the callback on the
// test result. The callback on the test result upon completion.
// testModule {object}: The test module. All function in this object must be nodeunit tests.
// testName {string}: The name of the test
// testModule {object}: The test module. All functions in this object must be nodeunit tests, or a group of tests
// testName {string}: The name of the test. must be a name generated by enumTests method
// context {object}: Test context. Attached to each nodeunit test's 'test' parameter
// callback {function}: A call back function called upon test completion and receiving the test
// reasult as it's first argument
exports.runTest = function(testModule, testName, callback) {
var test = testModule[testName];
if(test && typeof test === 'function'){
testRunner.run(testName, test, callback);
}
exports.runTest = function(testModule, testName, callback, context) {
var testObject = testModule[testName],
testMethod,
previousTestMethod,
testNamePieces,
group,
test;

testMethod = getTest(testModule, testName);

if(testMethod){
if(context){
previousTestMethod = testMethod;
testMethod = function(test){
test.context = context;
previousTestMethod(test);
}
}
}
// surround the run with try catch, in case there was any error with running the test method
try {
testRunner.run(testName, testMethod, callback);
}
catch(e)
{
console.log(e.toString());
callback('ERROR - failed to run test "' + testName +'"');
}
}

//
Expand All @@ -20,15 +45,53 @@ exports.runTest = function(testModule, testName, callback) {
// testSuite {object}: The test suite;
// callback {function}: A callback receiving the test enumaration (array) as its first argument
exports.enumTests = function(testSuite, callback){
var tests = [];
var tests = enumarateGroup(testSuite);
callback(null, tests);
}

//
// private methods:

//
// enumarates a group of tests by recursivly flatenning the tree like structure nodeunit tests have
// returns a flat array of tests names. names are prefixed by their containing group followed by an underscore
var enumarateGroup = function(group, namePrefix){
var tests = [],
testName;

for(var test in testSuite){
// allow functions only assuming all functions in testSuite are tests

if(typeof testSuite[test] === 'function')
tests.push(test);
for(var key in group){
//if(group.hasOwnProperty(key))
if(typeof group[key] === 'function'){
testName = namePrefix ? namePrefix + key : key;
tests.push(testName);
}
// else key is a group of tests
else{
enumarateGroup(group[key], (namePrefix ? (namePrefix + key + '_') : (key + '_'))).forEach(function(testName) {
tests.push(testName);
});
}
}

callback(tests);

return tests;
}

//
// get the a test from a testModule, recursively searching for the containing group of the test by parsing the testName
// by underscore.
var getTest = function(testModule, testName){
var testNamePieces = testName.split('_'),
testMethod,
group = testModule;

// dive into the tests tree until reaching the group containing the testMethod
for(var i = 0; i < testNamePieces.length - 1; i++){
group = group[testNamePieces[i]];
}

// extract the test from the containing group
testMethod = group[testNamePieces[testNamePieces.length - 1]];
return testMethod;
}


2 changes: 1 addition & 1 deletion lib/singleTestReporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,6 @@ exports.run = function (testName, testMethod, testEnd) {
}
},
function(){
testEnd(testResult);
testEnd(null, testResult);
}); // callback function to be called when the test is done.
};
35 changes: 26 additions & 9 deletions lib/testService.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ var testRunner = require('./nodeUnitWrapper'),
}

// the exported class
var testService = function(){
this.init();
var testService = function(context){
this.init();
};

module.exports = testService;
Expand All @@ -33,6 +33,8 @@ testService.prototype = {
init: function() {
// The web service
this.webService = express.createServer();
// add a body parser
this.webService.use(express.bodyParser());
// The test modules loaded
this.testModules = [];
// The formatted tests the test service supports
Expand All @@ -48,20 +50,35 @@ testService.prototype = {
}
else{
res.send('test not found', 404);
console.error('get request to tests' + testModule+ '/' + testName + ' has failed');
}
});

this.webService.post('/tests/:testModule/:testName', function(req, res){
if(req.params.testModule &&
// pull the context from the request
var context = req.body && req.body.context ? req.body.context : null;

if(req.params.testModule &&
req.params.testName &&
self.tests[req.params.testModule + '_' + req.params.testName]){
testRunner.runTest(self.testModules[req.params.testModule], req.params.testName, function(testResult){
res.json(testResult);

});
testRunner.runTest(
self.testModules[req.params.testModule],
req.params.testName,
function(err, testResult){
if(err)
{
res.send(err, 500);
}
else{
res.json(testResult);
}
},
context
);
}
else{
res.send('test not found', 404);
console.error('post request to tests' + testModule+ '/' + testName + ' has failed');
}
});

Expand Down Expand Up @@ -98,8 +115,8 @@ testService.prototype = {
self.testModules[testModule.name] = testModule.module;

// enumarate the tests in test model and format accordingly. adding tests and access points mappings.
testRunner.enumTests(self.testModules[testModule.name], function(moduleTests){
formatTests(moduleTests, testModule.name).forEach(function(test){
testRunner.enumTests(self.testModules[testModule.name], function(err, moduleTests){
formatTests(moduleTests, testModule.name).forEach(function(test){
self.tests[testModule.name + '_' + test.name] = test;
});
});
Expand Down

0 comments on commit e1c2289

Please sign in to comment.