Skip to content

Commit

Permalink
Merge pull request #208 from iancmyers/formatter-jslint-xml
Browse files Browse the repository at this point in the history
Formatter: JSLint XML (fixes #15)
  • Loading branch information
nzakas committed Aug 6, 2013
2 parents 5b33dbc + b1938c2 commit 15ecd64
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/eslint.js
Expand Up @@ -287,7 +287,8 @@ module.exports = (function() {
node: node,
message: message,
line: node.loc.start.line,
column: node.loc.start.column
column: node.loc.start.column,
source: api.getSource(node)
});
};

Expand Down
71 changes: 71 additions & 0 deletions lib/formatters/jslint-xml.js
@@ -0,0 +1,71 @@
/**
* @fileoverview JSLint XML reporter
* @author Ian Christian Myers
*/

//------------------------------------------------------------------------------
// Helper Functions
//------------------------------------------------------------------------------

/**
* Replace special characters before write to output.
*
* Rules:
* - single quotes is the escape sequence for double-quotes
* - &lt; is the escape sequence for <
* - &gt; is the escape sequence for >
* - &quot; is the escape sequence for "
* - &apos; is the escape sequence for '
* - &amp; is the escape sequence for &
*
* @param {String} message to escape
* @return escaped message as {String}
*/
function escapeSpecialCharacters(str) {

str = str || "";
var pairs = {
"&": "&amp;",
"\"": "&quot;",
"'": "&apos;",
"<": "&lt;",
">": "&gt;"
};

return str.replace(/[&"'<>]/g, function(c) {
return pairs[c];
});

}

//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------

module.exports = function(results) {

var output = "";

output += "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
output += "<jslint>";

results.forEach(function(result) {
var messages = result.messages;

output += "<file name=\"" + result.filePath + "\">";

messages.forEach(function(message) {
output += "<issue line=\"" + message.line + "\" " +
"char=\"" + message.column + "\" " +
"evidence=\"" + escapeSpecialCharacters(message.source) + "\" " +
"reason=\"" + escapeSpecialCharacters(message.message) + "\" />";
});

output += "</file>";

});

output += "</jslint>";

return output;
};
126 changes: 126 additions & 0 deletions tests/lib/formatters/jslint-xml.js
@@ -0,0 +1,126 @@
/**
* @fileoverview Tests for JSLint XML reporter.
* @author Ian Christian Myers
*/

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

var vows = require("vows"),
assert = require("assert"),
formatter = require("../../../lib/formatters/jslint-xml");

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

vows.describe("formatter:jslint-xml").addBatch({

"when passed a single message": {

topic: [{
filePath: "foo.js",
messages: [{
message: "Unexpected foo.",
line: 5,
column: 10,
ruleId: "foo",
source: "foo"
}]
}],

"should return a string in JSLint XML format with 1 issue in 1 file": function(topic) {
var config = {
rules: { foo: 2 }
};

var result = formatter(topic, config);
assert.equal("<?xml version=\"1.0\" encoding=\"utf-8\"?><jslint><file name=\"foo.js\"><issue line=\"5\" char=\"10\" evidence=\"foo\" reason=\"Unexpected foo.\" /></file></jslint>", result);
}

},

"when passed a fatal error message": {

topic: [{
filePath: "foo.js",
messages: [{
fatal: true,
message: "Unexpected foo.",
line: 5,
column: 10,
ruleId: "foo",
source: "foo"
}]
}],

"should return a string in JSLint XML format with 1 issue in 1 file": function(topic) {
var config = {}; // doesn't matter what's in the config for this test

var result = formatter(topic, config);
assert.equal("<?xml version=\"1.0\" encoding=\"utf-8\"?><jslint><file name=\"foo.js\"><issue line=\"5\" char=\"10\" evidence=\"foo\" reason=\"Unexpected foo.\" /></file></jslint>", result);
}
},

"when passed multiple messages": {
topic: [{
filePath: "foo.js",
messages: [{
message: "Unexpected foo.",
line: 5,
column: 10,
ruleId: "foo",
source: "foo"
}, {
message: "Unexpected bar.",
line: 6,
column: 11,
ruleId: "bar",
source: "bar"
}]
}],

"should return a string in JSLint XML format with 2 issues in 1 file": function(topic) {
var config = {
rules: { foo: 2, bar: 1 }
};

var result = formatter(topic, config);
assert.equal("<?xml version=\"1.0\" encoding=\"utf-8\"?><jslint><file name=\"foo.js\"><issue line=\"5\" char=\"10\" evidence=\"foo\" reason=\"Unexpected foo.\" /><issue line=\"6\" char=\"11\" evidence=\"bar\" reason=\"Unexpected bar.\" /></file></jslint>", result);
}

},

"when passed multiple files with 1 message each": {
topic: [{
filePath: "foo.js",
messages: [{
message: "Unexpected foo.",
line: 5,
column: 10,
ruleId: "foo",
source: "foo"
}]
}, {
filePath: "bar.js",
messages: [{
message: "Unexpected bar.",
line: 6,
column: 11,
ruleId: "bar",
source: "bar"
}]
}],

"should return a string in JSLint XML format with 2 issues in 2 files": function(topic) {
var config = {
rules: { foo: 2, bar: 1 }
};

var result = formatter(topic, config);
assert.equal("<?xml version=\"1.0\" encoding=\"utf-8\"?><jslint><file name=\"foo.js\"><issue line=\"5\" char=\"10\" evidence=\"foo\" reason=\"Unexpected foo.\" /></file><file name=\"bar.js\"><issue line=\"6\" char=\"11\" evidence=\"bar\" reason=\"Unexpected bar.\" /></file></jslint>", result);
}
}

}).export(module);

0 comments on commit 15ecd64

Please sign in to comment.