diff --git a/src/formatters/json.js b/src/formatters/json.js new file mode 100644 index 00000000..72d926b2 --- /dev/null +++ b/src/formatters/json.js @@ -0,0 +1,52 @@ +/* globals JSON: true */ + +CSSLint.addFormatter({ + //format information + id: "json", + name: "JSON", + + /** + * Return content to be printed before all file results. + * @return {String} to prepend before all results + */ + startFormat: function() { + "use strict"; + this.json = []; + return ""; + }, + + /** + * Return content to be printed after all file results. + * @return {String} to append after all results + */ + endFormat: function() { + "use strict"; + var ret = ""; + if (this.json.length > 0) { + if (this.json.length === 1) { + ret = JSON.stringify(this.json[0]); + } else { + ret = JSON.stringify(this.json); + } + } + return ret; + }, + + /** + * Given CSS Lint results for a file, return output for this format. + * @param results {Object} with error and warning messages + * @param filename {String} relative file path (Unused) + * @return {String} output for results + */ + formatResults: function(results, filename, options) { + "use strict"; + if (results.messages.length > 0 || !options.quiet) { + this.json.push({ + filename: filename, + messages: results.messages, + stats: results.stats + }); + } + return ""; + } +}); diff --git a/tests/formatters/json.js b/tests/formatters/json.js new file mode 100644 index 00000000..21561902 --- /dev/null +++ b/tests/formatters/json.js @@ -0,0 +1,72 @@ +(function(){ + "use strict"; + var Assert = YUITest.Assert; + + YUITest.TestRunner.add(new YUITest.TestCase({ + + name: "JSON formatter", + + "File with no problems should say so": function() { + var result = { messages: [], stats: [] }; + var expected = "{\"filename\":\"path/to/FILE\",\"messages\":[],\"stats\":[]}"; + var formatter = CSSLint.getFormatter("json"); + var actual = formatter.startFormat() + + formatter.formatResults(result, "path/to/FILE", + {fullPath: "/absolute/path/to/FILE"}) + + formatter.endFormat(); + Assert.areEqual(expected, actual); + }, + + "Should have no output when quiet option is specified and no errors": function() { + var result = { messages: [], stats: [] }; + var formatter = CSSLint.getFormatter("json"); + var actual = formatter.startFormat() + + formatter.formatResults(result, "path/to/FILE", + {fullPath: "/absolute/path/to/FILE", quiet: "true"}) + + formatter.endFormat(); + Assert.areEqual("", actual); + }, + + "Should have output when quiet option is specified and there are errors": function() { + var result = { messages: [ + { type: "warning", line: 1, col: 1, message: "BOGUS", evidence: "ALSO BOGUS", rule: [] }], stats: [] }; + var expected = "{\"filename\":\"path/to/FILE\",\"messages\":[{\"type\":\"warning\",\"line\":1,\"col\":1,\"message\":\"BOGUS\",\"evidence\":\"ALSO BOGUS\",\"rule\":[]}],\"stats\":[]}"; + var formatter = CSSLint.getFormatter("json"); + var actual = formatter.startFormat() + + formatter.formatResults(result, "path/to/FILE", + {fullPath: "/absolute/path/to/FILE", quiet: "true"}) + + formatter.endFormat(); + Assert.areEqual(expected, actual); + }, + + "File with problems should list them": function() { + var result = { messages: [ + { type: "warning", line: 1, col: 1, message: "BOGUS", evidence: "ALSO BOGUS", rule: [] }, + { type: "error", line: 2, col: 1, message: "BOGUS", evidence: "ALSO BOGUS", rule: [] } + ], stats: [] }; + var expected = "{\"filename\":\"path/to/FILE\",\"messages\":[{\"type\":\"warning\",\"line\":1,\"col\":1,\"message\":\"BOGUS\",\"evidence\":\"ALSO BOGUS\",\"rule\":[]},{\"type\":\"error\",\"line\":2,\"col\":1,\"message\":\"BOGUS\",\"evidence\":\"ALSO BOGUS\",\"rule\":[]}],\"stats\":[]}"; + var formatter = CSSLint.getFormatter("json"); + var actual = formatter.startFormat() + + formatter.formatResults(result, "path/to/FILE", + {fullPath: "/absolute/path/to/FILE"}) + + formatter.endFormat(); + Assert.areEqual(expected, actual); + }, + + "Multiple files are handled properly": function () { + var result = { messages: [ + { type: "warning", line: 1, col: 1, message: "BOGUS", evidence: "ALSO BOGUS", rule: [] }], stats: [] }; + var expected = "[{\"filename\":\"path/to/FILE\",\"messages\":[{\"type\":\"warning\",\"line\":1,\"col\":1,\"message\":\"BOGUS\",\"evidence\":\"ALSO BOGUS\",\"rule\":[]}],\"stats\":[]},{\"filename\":\"path/to/FILE\",\"messages\":[{\"type\":\"warning\",\"line\":1,\"col\":1,\"message\":\"BOGUS\",\"evidence\":\"ALSO BOGUS\",\"rule\":[]}],\"stats\":[]}]"; + var formatter = CSSLint.getFormatter("json"); + var actual = formatter.startFormat() + + formatter.formatResults(result, "path/to/FILE", + {fullPath: "/absolute/path/to/FILE"}) + + formatter.formatResults(result, "path/to/FILE", + {fullPath: "/absolute/path/to/FILE"}) + + formatter.endFormat(); + Assert.areEqual(expected, actual); + } + + })); + +})();