Skip to content

Commit

Permalink
Add Stylish formatter and make it default. Fixes eslint#517
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Jan 16, 2014
1 parent 3c8e833 commit 5f89734
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 3 deletions.
2 changes: 1 addition & 1 deletion docs/command-line-interface/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Options:
-h, --help Show help.
-c, --config Load configuration data from this file.
--rulesdir Load additional rules from this directory.
-f, --format Use a specific output format. [default: "compact"]
-f, --format Use a specific output format. [default: "stylish"]
-v, --version Outputs the version number.
```

Expand Down
75 changes: 75 additions & 0 deletions lib/formatters/stylish.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
* @fileoverview Stylish reporter
* @author Sindre Sorhus
*/
"use strict";

var chalk = require("chalk"),
table = require("text-table");

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

function getMessageType(message, rules) {
if (message.fatal) {
return chalk.red("error");
}

var severity = rules[message.ruleId][0] || rules[message.ruleId];

if (severity === 2) {
return chalk.red("error");
}

return chalk.yellow("warning");
}

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

module.exports = function(results, config) {

var output = "\n",
total = 0,
rules = config.rules || {};

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) {
return [
"",
message.line || 0,
message.column || 0,
getMessageType(message, rules),
chalk.blue(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";
});

output += chalk.red.bold("\u2716 " + total + " problem" + (total === 1 ? "" : "s") + "\n");

return total > 0 ? output : "";
};
2 changes: 1 addition & 1 deletion lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ optimist.describe("rulesdir", "Load additional rules from this directory.");

// Format
optimist.alias("f", "format");
optimist.default("f", "compact");
optimist.default("f", "stylish");
optimist.describe("f", "Use a specific output format.");

// Version
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
"estraverse": "~1.3.0",
"esprima": "*",
"escope": "1.0.0",
"glob": "~3.2.7"
"glob": "~3.2.7",
"text-table": "~0.2.0",
"chalk": "~0.4.0"
},
"devDependencies": {
"sinon": "*",
Expand Down
166 changes: 166 additions & 0 deletions tests/lib/formatters/stylish.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/**
* @fileoverview Tests for options.
* @author Sindre Sorhus
*/

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

var assert = require("chai").assert,
formatter = require("../../../lib/formatters/stylish");

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

describe("formatter:stylish", function() {
describe("when passed no messages", function() {
var code = [{
filePath: "foo.js",
messages: []
}];

it("should return message", function() {
var config = {
rules: { foo: 2 }
};

var result = formatter(code, config);
assert.equal("", result);
});
});

describe("when passed a single message", function() {
var code = [{
filePath: "foo.js",
messages: [{
message: "Unexpected foo.",
line: 5,
column: 10,
ruleId: "foo"
}]
}];

it("should return a string in the correct format for errors", function() {
var config = {
rules: { foo: 2 }
};

var result = formatter(code, config);
assert.equal("\nfoo.js\n 5:10 error Unexpected foo foo\n\n\u2716 1 problem\n", result);
});

it("should return a string in the correct format for warnings", function() {
var config = {
rules: { foo: 1 }
};

var result = formatter(code, config);
assert.equal("\nfoo.js\n 5:10 warning Unexpected foo foo\n\n\u2716 1 problem\n", result);
});

it("should return a string in the correct format for errors with options config", function() {
var config = {
rules: { foo: [2, "option"] }
};

var result = formatter(code, config);
assert.equal("\nfoo.js\n 5:10 error Unexpected foo foo\n\n\u2716 1 problem\n", result);
});
});

describe("when passed a fatal error message", function() {
var code = [{
filePath: "foo.js",
messages: [{
fatal: true,
message: "Unexpected foo.",
line: 5,
column: 10,
ruleId: "foo"
}]
}];

it("should return a string in the correct format", function() {
var config = {}; // doesn't matter what's in the config for this test

var result = formatter(code, config);
assert.equal("\nfoo.js\n 5:10 error Unexpected foo foo\n\n\u2716 1 problem\n", result);
});
});

describe("when passed multiple messages", function() {
var code = [{
filePath: "foo.js",
messages: [{
message: "Unexpected foo.",
line: 5,
column: 10,
ruleId: "foo"
}, {
message: "Unexpected bar.",
line: 6,
column: 11,
ruleId: "bar"
}]
}];

it("should return a string with multiple entries", function() {
var config = {
rules: { foo: 2, bar: 1 }
};

var result = formatter(code, config);
assert.equal("\nfoo.js\n 5:10 error Unexpected foo foo\n 6:11 warning Unexpected bar bar\n\n\u2716 2 problems\n", result);
});
});

describe("when passed multiple files with 1 message each", function() {
var code = [{
filePath: "foo.js",
messages: [{
message: "Unexpected foo.",
line: 5,
column: 10,
ruleId: "foo"
}]
}, {
filePath: "bar.js",
messages: [{
message: "Unexpected bar.",
line: 6,
column: 11,
ruleId: "bar"
}]
}];

it("should return a string with multiple entries", function() {
var config = {
rules: { foo: 2, bar: 1 }
};

var result = formatter(code, config);
assert.equal("\nfoo.js\n 5:10 error Unexpected foo foo\n\nbar.js\n 6:11 warning Unexpected bar bar\n\n\u2716 2 problems\n", result);
});
});

describe("when passed one file not found message", function() {
var code = [{
filePath: "foo.js",
messages: [{
fatal: true,
message: "Couldn't find foo.js."
}]
}];

it("should return a string without line and column", function() {
var config = {
rules: { foo: 2, bar: 1 }
};

var result = formatter(code, config);
assert.equal("\nfoo.js\n 0:0 error Couldn't find foo.js\n\n\u2716 1 problem\n", result);
});
});
});

0 comments on commit 5f89734

Please sign in to comment.