diff --git a/lib/formatters/junit.js b/lib/formatters/junit.js new file mode 100644 index 000000000000..08fc45e8fdbe --- /dev/null +++ b/lib/formatters/junit.js @@ -0,0 +1,95 @@ +/** + * @fileoverview jUnit Reporter + * @author Jamund Ferguson + */ + +/*jshint node:true*/ + +//------------------------------------------------------------------------------ +// Helper Functions +//------------------------------------------------------------------------------ + +function getMessageType(message, rules) { + + if (message.fatal || rules[message.ruleId] === 2) { + return "Error"; + } else { + return "Warning"; + } + +} + +/** + * Replace special characters before write to output. + * + * Rules: + * - single quotes is the escape sequence for double-quotes + * - < is the escape sequence for < + * - > is the escape sequence for > + * - " is the escape sequence for " + * - ' is the escape sequence for ' + * - & is the escape sequence for & + * + * @param {String} message to escape + * @return escaped message as {String} + */ +function escapeSpecialCharacters(str) { + + str = str || ""; + var pairs = { + "&": "&", + "\"": """, + "'": "'", + "<": "<", + ">": ">" + }; + for (var r in pairs) { + str = str.replace(new RegExp(r, "g"), pairs[r]); + } + return str || ""; + +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results, config) { + + var output = "", + rules = config.rules || {}; + + output += "\n"; + output += "\n"; + + results.forEach(function(result) { + + var messages = result.messages; + + if (messages.length) { + output += "\n"; + } + + messages.forEach(function(message) { + var type = message.fatal ? "error" : "failure"; + output += ""; + output += "<" + type + " message=\"" + escapeSpecialCharacters(message.message) + "\">"; + output += ""; + output += ""; + output += "\n"; + }); + + if (messages.length) { + output += "\n"; + } + + }); + + output += "\n"; + + return output; +}; \ No newline at end of file diff --git a/tests/lib/formatters/junit.js b/tests/lib/formatters/junit.js new file mode 100644 index 000000000000..e0102b874f7f --- /dev/null +++ b/tests/lib/formatters/junit.js @@ -0,0 +1,136 @@ +/** + * @fileoverview Tests for jUnit Formatter. + * @author Jamund Ferguson + */ + +/*jshint node:true*/ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +var vows = require("vows"), + assert = require("assert"), + sinon = require("sinon"), + formatter = require("../../../lib/formatters/junit"); + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +vows.describe("formatter:junit").addBatch({ + + "when there are no problems": { + + topic: [], + + "should not complain about anything": function(topic) { + var config = {}; // not needed for this test + var result = formatter(topic, config); + assert.equal('', result.replace(/\n/g, "")); + } + }, + + "when passed a single message": { + + topic: [{ + filePath: "foo.js", + messages: [{ + message: "Unexpected foo.", + line: 5, + column: 10, + ruleId: "foo" + }] + }], + + "should return a single with a message and the line and col number in the body (error)": function(topic) { + var config = { + rules: { foo: 2 } + }; + + var result = formatter(topic, config); + assert.equal('', result.replace(/\n/g, "")); + }, + + "should return a single with a message and the line and col number in the body (warning)": function(topic) { + var config = { + rules: { foo: 1 } + }; + + var result = formatter(topic, config); + assert.equal('', result.replace(/\n/g, "")); + } + + }, + + "when passed a fatal error message": { + + topic: [{ + filePath: "foo.js", + messages: [{ + fatal: true, + message: "Unexpected foo.", + line: 5, + column: 10, + ruleId: "foo" + }] + }], + + "should return a single and an ": function(topic) { + var config = {}; + var result = formatter(topic, config); + assert.equal('', result.replace(/\n/g, "")); + } + }, + + "when passed multiple messages": { + + topic: [{ + filePath: "foo.js", + messages: [{ + message: "Unexpected foo.", + line: 5, + column: 10, + ruleId: "foo" + }, { + message: "Unexpected bar.", + line: 6, + column: 11, + ruleId: "bar" + }] + }], + + "should return a multiple 's": function(topic) { + var config = { + rules: { foo: 2, bar: 1 } + }; + + var result = formatter(topic, config); + assert.equal('', result.replace(/\n/g, "")); + } + + }, + + "when passed special characters": { + + topic: [{ + filePath: "foo.js", + messages: [{ + message: "Unexpected .", + line: 5, + column: 10, + ruleId: "foo" + }] + }], + + "should make them go away": function(topic) { + var config = { + rules: { foo: 1 } + }; + + var result = formatter(topic, config); + assert.equal('', result.replace(/\n/g, "")); + + } + }, +}).export(module);