Skip to content

Commit

Permalink
Added a multi-file junit reporter. Need to write more tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
allanmboyd committed Mar 27, 2012
1 parent 79b15c0 commit 4d18a30
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 25 deletions.
29 changes: 19 additions & 10 deletions lib/reporters/ConsoleReporter.js
Expand Up @@ -34,7 +34,20 @@ var bold = function (str) {

var ConsoleReporter = new Reporter();
ConsoleReporter.prototype.constructor = ConsoleReporter;
ConsoleReporter.prototype.suitesEnd = function(testCount, successCount, failedCount, errorCount) {

exports.createReporter = function () {
var reporter = new ConsoleReporter();
reporter.suitesEnd = suitesEnd;
reporter.suiteStart = suiteStart;
reporter.topicStart = topicStart;
reporter.testSuccess= testSuccess;
reporter.testFailure = testFailure;
reporter.testError = testError;

return reporter;
};

var suitesEnd = function(testCount, successCount, failedCount, errorCount) {

var summary = "\nTests: " + testCount + ", Passed: " + successCount +
", Failed: " + failedCount + ", Errors: " + errorCount;
Expand All @@ -46,15 +59,15 @@ ConsoleReporter.prototype.suitesEnd = function(testCount, successCount, failedCo
}
};

ConsoleReporter.prototype.suiteStart = function(suiteName, suiteDescription) {
var suiteStart = function(suiteName, suiteDescription) {
var output = "\n" + suiteName;
if (suiteDescription) {
output += " - " + suiteDescription;
}
console.log(bold(output));
};

ConsoleReporter.prototype.topicStart = function(topicName, topicDescription, testCount, successCount, failedCount, errorCount, suiteTime) {
var topicStart = function(topicName, topicDescription, testCount, successCount, failedCount, errorCount, suiteTime) {
this.topicTestCount = testCount;
this.topicSuccessCount = successCount;
this.topicFailedCount = failedCount;
Expand All @@ -77,23 +90,19 @@ ConsoleReporter.prototype.topicStart = function(topicName, topicDescription, tes
}
};

ConsoleReporter.prototype.testSuccess = function(testName) {
var testSuccess = function(testName) {
console.log(' ✔ ' + testName);
};

ConsoleReporter.prototype.testFailure = function(testName, error, testTime, testFile) {
var testFailure = function(testName, error, testTime, testFile) {
failTheme.stackFilters = [testFile];
var failError = formatErrors.highlightError(error, failTheme);
console.log(' ✖ ' + testName);
console.log(failError.stack);
};

ConsoleReporter.prototype.testError = function(testName, error) {
var testError = function(testName, error) {
var formattedError = formatErrors.highlightError(error, errorTheme);
console.log(" \u274e " + testName + '\n');
console.log(formattedError.stack);
};

module.exports = function () {
return ConsoleReporter;
};
32 changes: 21 additions & 11 deletions lib/reporters/JUnitReporter.js
Expand Up @@ -7,21 +7,35 @@ var failTheme = new formatErrors.StackTheme();

var JUnitReporter = new Reporter();
JUnitReporter.prototype.constructor = JUnitReporter;
JUnitReporter.prototype.suitesStart = function() {

exports.createReporter = function () {
var reporter = new JUnitReporter();
reporter.suitesStart = suitesStart;
reporter.suitesEnd = suitesEnd;
reporter.suiteStart = suiteStart;
reporter.topicStart = topicStart;
reporter.testStart = testStart;
reporter.testFailure = testFailure;
reporter.testError = testError;

return reporter;
};

var suitesStart = function() {
this.nowString = new Date().toISOString();
this.dom = new xmlDom.DOMParser();
this.doc = this.dom.parseFromString(""); // create an empty doc
this.testsuitesElement = this.doc.createElement("testsuites");
this.doc.appendChild(this.testsuitesElement);
};

JUnitReporter.prototype.suitesEnd = function() {
var suitesEnd = function() {
var serializer = new xmlDom.XMLSerializer();
var docAsString = serializer.serializeToString(this.doc);
console.log(docAsString);
};

JUnitReporter.prototype.suiteStart = function(suiteName, suiteDescription, testCount, successCount, failedCount, errorCount, suiteTime) {
var suiteStart = function(suiteName, suiteDescription, testCount, successCount, failedCount, errorCount, suiteTime) {
var nowString = new Date().toISOString();
this.testsuiteElement = this.doc.createElement("testsuite");
this.testsuitesElement.appendChild(this.testsuiteElement);
Expand All @@ -33,22 +47,21 @@ JUnitReporter.prototype.suiteStart = function(suiteName, suiteDescription, testC
this.testsuiteElement.setAttribute("failures", "" + failedCount);
this.testsuiteElement.setAttribute("errors", "" + errorCount);
this.testsuiteElement.setAttribute("time", "" + suiteTime);

};

JUnitReporter.prototype.topicStart = function(topicName, topicDescription) {
var topicStart = function(topicName, topicDescription) {
this.topicName = topicName + (topicDescription ? " - " + topicDescription : "");
};

JUnitReporter.prototype.testStart = function(testName, testTime) {
var testStart = function(testName, testTime) {
this.testcaseElement = this.doc.createElement("testcase");
this.testcaseElement.setAttribute("name", testName);
this.testcaseElement.setAttribute("classname", this.topicName);
this.testcaseElement.setAttribute("time", "" + testTime);
this.testsuiteElement.appendChild(this.testcaseElement);
};

JUnitReporter.prototype.testFailure = function(testName, error, testFile) {
var testFailure = function(testName, error, testFile) {
failTheme.stackFilters = [testFile];
var failError = formatErrors.highlightError(error, failTheme);
var failureElement = this.doc.createElement("failure");
Expand All @@ -57,13 +70,10 @@ JUnitReporter.prototype.testFailure = function(testName, error, testFile) {
this.testcaseElement.appendChild(failureElement);
};

JUnitReporter.prototype.testError = function(testName, error) {
var testError = function(testName, error) {
var errorElement = this.doc.createElement("error");
errorElement.setAttribute("name", error.name);
errorElement.setAttribute("message", error.stack);
this.testcaseElement.appendChild(errorElement);
};

module.exports = function () {
return JUnitReporter;
};
98 changes: 98 additions & 0 deletions lib/reporters/MultiFileJUnitReporter.js
@@ -0,0 +1,98 @@
var formatErrors = require("formaterrors");
var fs = require("fs");
var logly = require("logly");
var os = require("os");
var path = require("path");
var Reporter = require("../Reporter");
var xmlDom = require("xmldom");

var failTheme = new formatErrors.StackTheme();

var MultiFileJUnitReporter = new Reporter();
MultiFileJUnitReporter.prototype.constructor = MultiFileJUnitReporter;

exports.createReporter = function(options) {
var reporter = new MultiFileJUnitReporter();
reporter.outputDir = options.outputDir || ".";

reporter.suiteStart = suiteStart;
reporter.suiteEnd = suiteEnd;
reporter.topicStart = topicStart;
reporter.testStart = testStart;
reporter.testFailure = testFailure;
reporter.testError = testError;

return reporter;
};

var suiteStart = function(suiteName, suiteDescription, testCount, successCount, failedCount, errorCount, suiteTime) {
this.suiteName = suiteName;
this.dom = new xmlDom.DOMParser();
this.doc = this.dom.parseFromString(""); // create an empty doc
var nowString = new Date().toISOString();
this.testsuiteElement = this.doc.createElement("testsuite");
this.doc.appendChild(this.testsuiteElement);
var nameAttr = suiteName + (suiteDescription ? " - " + suiteDescription : "");
this.testsuiteElement.setAttribute("name", nameAttr);
this.testsuiteElement.setAttribute("timestamp", nowString);
this.testsuiteElement.setAttribute("hostname", os.hostname());
this.testsuiteElement.setAttribute("tests", "" + testCount);
this.testsuiteElement.setAttribute("failures", "" + failedCount);
this.testsuiteElement.setAttribute("errors", "" + errorCount);
this.testsuiteElement.setAttribute("time", "" + suiteTime);
};

var suiteEnd = function() {
checkTargetDir(this.outputDir);

var serializer = new xmlDom.XMLSerializer();
var docAsString = serializer.serializeToString(this.doc);
var target = this.outputDir + "/" + fixFilename(this.suiteName) + ".xml";

fs.writeFile(target, docAsString, "utf8", function (error) {
if (error) {
logly.warn("Failed to write file '" + target + "'");
logly.error(error.stack);
}
});
};

var topicStart = function(topicName, topicDescription) {
this.topicName = topicName + (topicDescription ? " - " + topicDescription : "");
};

var testStart = function(testName, testTime) {
this.testcaseElement = this.doc.createElement("testcase");
this.testcaseElement.setAttribute("name", testName);
this.testcaseElement.setAttribute("classname", this.topicName);
this.testcaseElement.setAttribute("time", "" + testTime);
this.testsuiteElement.appendChild(this.testcaseElement);
};

var testFailure = function(testName, error, testFile) {
failTheme.stackFilters = [testFile];
var failError = formatErrors.highlightError(error, failTheme);
var failureElement = this.doc.createElement("failure");
failureElement.setAttribute("name", failError.name);
failureElement.setAttribute("message", failError.stack);
this.testcaseElement.appendChild(failureElement);
};

var testError = function(testName, error) {
var errorElement = this.doc.createElement("error");
errorElement.setAttribute("name", error.name);
errorElement.setAttribute("message", error.stack);
this.testcaseElement.appendChild(errorElement);
};

function checkTargetDir(targetDir) {
if (!path.existsSync(targetDir)) {
fs.mkdirSync(targetDir, "0755");
}
}

function fixFilename(filename) {
filename = filename.replace("http://","");
filename = filename.replace(/\//g, "-");
return filename;
}
2 changes: 1 addition & 1 deletion lib/suiteManager.js
Expand Up @@ -223,7 +223,7 @@ var runSuiteTest = function (testDetails) {
exports.runSuiteTest = runSuiteTest;

exports.generateReport = function (reporter) {
reporter = reporter || new (require("./reporters/ConsoleReporter")())();
reporter = reporter || require("./reporters/ConsoleReporter").createReporter();
walkSuites(reporter);
};

Expand Down
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -23,12 +23,13 @@
}
],
"scripts": {
"test": "./node_modules/jshint/bin/hint lib/errors.js lib/Reporter.js lib/spider.js lib/spiderOptions.js lib/spiderTest.js lib/suiteManager.js lib/reporters/ConsoleReporter.js lib/reporters/JUnitReporter.js test/testSpider.js test/testSuiteManager.js test/testSpiderTest.js && ./node_modules/nodeunit/bin/nodeunit test/testSpider.js test/testSuiteManager.js test/testSpiderTest.js"
"test": "./node_modules/jshint/bin/hint lib/errors.js lib/Reporter.js lib/spider.js lib/spiderOptions.js lib/spiderTest.js lib/suiteManager.js lib/reporters/ConsoleReporter.js lib/reporters/JUnitReporter.js lib/reporters/MultiFileJunitReporter.js test/testSpider.js test/testSuiteManager.js test/testSpiderTest.js && ./node_modules/nodeunit/bin/nodeunit test/testSpider.js test/testSuiteManager.js test/testSpiderTest.js"
},
"dependencies" : {
"cheerio": ">= 0.3.2",
"exceptions" : "0.1.1",
"formaterrors" : "0.1.1",
"logly": "1.1.1",
"request" : ">= 2.2.9",
"routes" : ">= 0.1.0",
"xmldom": ">= 0.1.1"
Expand Down
4 changes: 2 additions & 2 deletions test/testSpiderTest.js
Expand Up @@ -77,10 +77,10 @@ exports.testRunTestsWithProvidedReporter = function (test) {
// For some reason "process" is not available inside modules that are tested by nodeunit
// this is why process is used here to establish the test directory
// Use a jnuit reporter
var junitReporter = new (require("../lib/reporters/JUnitReporter")())();
var junitReporter = require("../lib/reporters/JUnitReporter").createReporter();
spiderTest.runTests("http://localhost:" + serverPort + "/testIndex.html",
process.cwd() + "/" + "test/resources/spiderTests", function() {
server.close();
test.done();
}, null, junitReporter);
};
};

0 comments on commit 4d18a30

Please sign in to comment.