diff options
Diffstat (limited to 'tools/eslint/lib/formatters')
-rw-r--r-- | tools/eslint/lib/formatters/checkstyle.js | 68 | ||||
-rw-r--r-- | tools/eslint/lib/formatters/compact.js | 53 | ||||
-rw-r--r-- | tools/eslint/lib/formatters/jslint-xml.js | 40 | ||||
-rw-r--r-- | tools/eslint/lib/formatters/junit.js | 63 | ||||
-rw-r--r-- | tools/eslint/lib/formatters/stylish.js | 90 | ||||
-rw-r--r-- | tools/eslint/lib/formatters/tap.js | 90 |
6 files changed, 404 insertions, 0 deletions
diff --git a/tools/eslint/lib/formatters/checkstyle.js b/tools/eslint/lib/formatters/checkstyle.js new file mode 100644 index 0000000000..5e98c8b131 --- /dev/null +++ b/tools/eslint/lib/formatters/checkstyle.js @@ -0,0 +1,68 @@ +/** + * @fileoverview CheckStyle XML reporter + * @author Ian Christian Myers + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Helper Functions +//------------------------------------------------------------------------------ + +function getMessageType(message) { + if (message.fatal || message.severity === 2) { + return "error"; + } else { + return "warning"; + } +} + +function xmlEscape(s) { + return ("" + s).replace(/[<>&"']/g, function(c) { + switch (c) { + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "\"": + return """; + case "'": + return "'"; + // no default + } + }); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + + var output = ""; + + output += "<?xml version=\"1.0\" encoding=\"utf-8\"?>"; + output += "<checkstyle version=\"4.3\">"; + + results.forEach(function(result) { + var messages = result.messages; + + output += "<file name=\"" + xmlEscape(result.filePath) + "\">"; + + messages.forEach(function(message) { + output += "<error line=\"" + xmlEscape(message.line) + "\" " + + "column=\"" + xmlEscape(message.column) + "\" " + + "severity=\"" + xmlEscape(getMessageType(message)) + "\" " + + "message=\"" + xmlEscape(message.message) + + (message.ruleId ? " (" + message.ruleId + ")" : "") + "\" />"; + }); + + output += "</file>"; + + }); + + output += "</checkstyle>"; + + return output; +}; diff --git a/tools/eslint/lib/formatters/compact.js b/tools/eslint/lib/formatters/compact.js new file mode 100644 index 0000000000..b7c2fc7e25 --- /dev/null +++ b/tools/eslint/lib/formatters/compact.js @@ -0,0 +1,53 @@ +/** + * @fileoverview Compact reporter + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Helper Functions +//------------------------------------------------------------------------------ + +function getMessageType(message) { + if (message.fatal || message.severity === 2) { + return "Error"; + } else { + return "Warning"; + } +} + + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + + var output = "", + total = 0; + + results.forEach(function(result) { + + var messages = result.messages; + total += messages.length; + + messages.forEach(function(message) { + + output += result.filePath + ": "; + output += "line " + (message.line || 0); + output += ", col " + (message.column || 0); + output += ", " + getMessageType(message); + output += " - " + message.message; + output += message.ruleId ? " (" + message.ruleId + ")" : ""; + output += "\n"; + + }); + + }); + + if (total > 0) { + output += "\n" + total + " problem" + (total !== 1 ? "s" : ""); + } + + return output; +}; diff --git a/tools/eslint/lib/formatters/jslint-xml.js b/tools/eslint/lib/formatters/jslint-xml.js new file mode 100644 index 0000000000..26aa2de0b5 --- /dev/null +++ b/tools/eslint/lib/formatters/jslint-xml.js @@ -0,0 +1,40 @@ +/** + * @fileoverview JSLint XML reporter + * @author Ian Christian Myers + */ +"use strict"; + +var xmlescape = require("xml-escape"); + +//------------------------------------------------------------------------------ +// 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=\"" + xmlescape(message.source || "") + "\" " + + "reason=\"" + xmlescape(message.message || "") + + (message.ruleId ? " (" + message.ruleId + ")" : "") + "\" />"; + }); + + output += "</file>"; + + }); + + output += "</jslint>"; + + return output; +}; diff --git a/tools/eslint/lib/formatters/junit.js b/tools/eslint/lib/formatters/junit.js new file mode 100644 index 0000000000..7ee94135f6 --- /dev/null +++ b/tools/eslint/lib/formatters/junit.js @@ -0,0 +1,63 @@ +/** + * @fileoverview jUnit Reporter + * @author Jamund Ferguson + */ +"use strict"; + +var xmlescape = require("xml-escape"); + +//------------------------------------------------------------------------------ +// Helper Functions +//------------------------------------------------------------------------------ + +function getMessageType(message) { + if (message.fatal || message.severity === 2) { + return "Error"; + } else { + return "Warning"; + } +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + + var output = ""; + + output += "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; + output += "<testsuites>\n"; + + results.forEach(function(result) { + + var messages = result.messages; + + if (messages.length) { + output += "<testsuite package=\"org.eslint\" time=\"0\" tests=\"" + messages.length + "\" errors=\"" + messages.length + "\" name=\"" + result.filePath + "\">\n"; + } + + messages.forEach(function(message) { + var type = message.fatal ? "error" : "failure"; + output += "<testcase time=\"0\" name=\"org.eslint." + (message.ruleId || "unknown") + "\">"; + output += "<" + type + " message=\"" + xmlescape(message.message || "") + "\">"; + output += "<![CDATA["; + output += "line " + (message.line || 0) + ", col "; + output += (message.column || 0) + ", " + getMessageType(message); + output += " - " + xmlescape(message.message || ""); + output += (message.ruleId ? " (" + message.ruleId + ")" : ""); + output += "]]>"; + output += "</" + type + ">"; + output += "</testcase>\n"; + }); + + if (messages.length) { + output += "</testsuite>\n"; + } + + }); + + output += "</testsuites>\n"; + + return output; +}; diff --git a/tools/eslint/lib/formatters/stylish.js b/tools/eslint/lib/formatters/stylish.js new file mode 100644 index 0000000000..59e01d0b3e --- /dev/null +++ b/tools/eslint/lib/formatters/stylish.js @@ -0,0 +1,90 @@ +/** + * @fileoverview Stylish reporter + * @author Sindre Sorhus + */ +"use strict"; + +var chalk = require("chalk"), + table = require("text-table"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Given a word and a count, append an s if count is not one. + * @param {string} word A word in its singular form. + * @param {int} count A number controlling whether word should be pluralized. + * @returns {string} The original word with an s on the end if count is not one. + */ +function pluralize(word, count) { + return (count === 1 ? word : word + "s"); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + + var output = "\n", + total = 0, + errors = 0, + warnings = 0, + summaryColor = "yellow"; + + results.forEach(function(result) { + var messages = result.messages; + + if (messages.length === 0) { + return; + } + + total += messages.length; + output += chalk.underline(result.filePath) + "\n"; + + output += table( + messages.map(function(message) { + var messageType; + + if (message.fatal || message.severity === 2) { + messageType = chalk.red("error"); + summaryColor = "red"; + errors++; + } else { + messageType = chalk.yellow("warning"); + warnings++; + } + + return [ + "", + message.line || 0, + message.column || 0, + messageType, + message.message.replace(/\.$/, ""), + chalk.gray(message.ruleId || "") + ]; + }), + { + align: ["", "r", "l"], + stringLength: function(str) { + return chalk.stripColor(str).length; + } + } + ).split("\n").map(function(el) { + return el.replace(/(\d+)\s+(\d+)/, function(m, p1, p2) { + return chalk.gray(p1 + ":" + p2); + }); + }).join("\n") + "\n\n"; + }); + + if (total > 0) { + output += chalk[summaryColor].bold([ + "\u2716 ", total, pluralize(" problem", total), + " (", errors, pluralize(" error", errors), ", ", + warnings, pluralize(" warning", warnings), ")\n" + ].join("")); + } + + return total > 0 ? output : ""; +}; diff --git a/tools/eslint/lib/formatters/tap.js b/tools/eslint/lib/formatters/tap.js new file mode 100644 index 0000000000..b9f4cd66b9 --- /dev/null +++ b/tools/eslint/lib/formatters/tap.js @@ -0,0 +1,90 @@ +/** + * @fileoverview TAP reporter + * @author Jonathan Kingston + */ +"use strict"; + +var yaml = require("js-yaml"); + +//------------------------------------------------------------------------------ +// Helper Functions +//------------------------------------------------------------------------------ + +/** + * Returns a canonical error level string based upon the error message passed in. + * @param {object} message Individual error message provided by eslint + * @returns {String} Error level string + */ +function getMessageType(message) { + if (message.fatal || message.severity === 2) { + return "error"; + } else { + return "warning"; + } +} + +/** + * Takes in a JavaScript object and outputs a TAP diagnostics string + * @param {object} diagnostic JavaScript object to be embedded as YAML into output. + * @returns {string} diagnostics string with YAML embedded - TAP version 13 compliant + */ +function outputDiagnostics(diagnostic) { + var prefix = " "; + var output = prefix + "---\n"; + output += prefix + yaml.safeDump(diagnostic).split("\n").join("\n" + prefix); + output += "...\n"; + return output; +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + var output = "TAP version 13\n1.." + results.length + "\n"; + + results.forEach(function(result, id) { + var messages = result.messages; + var testResult = "ok"; + var diagnostics = {}; + + if (messages.length > 0) { + testResult = "not ok"; + + messages.forEach(function(message) { + var diagnostic = { + message: message.message, + severity: getMessageType(message), + data: { + line: message.line || 0, + column: message.column || 0, + ruleId: message.ruleId || "" + } + }; + + // If we have multiple messages place them under a messages key + // The first error will be logged as message key + // This is to adhere to TAP 13 loosely defined specification of having a message key + if ("message" in diagnostics) { + if ("messages" in diagnostics) { + diagnostics.messages.push(diagnostic); + } else { + diagnostics.messages = [diagnostic]; + } + } else { + diagnostics = diagnostic; + } + }); + } + + output += testResult + " " + (id + 1) + " - " + result.filePath + "\n"; + + // If we have an error include diagnostics + if (messages.length > 0) { + output += outputDiagnostics(diagnostics); + } + + }); + + return output; +}; |