Skip to content

Commit

Permalink
Created no-dangle rule.
Browse files Browse the repository at this point in the history
Created the no-dangle rule, which warns when it encounters a trailing comma in an object literal. The following will raise warnings:

var foo = {
  bar: "baz",
}

Fixes issue eslint#13
  • Loading branch information
iancmyers committed Jul 19, 2013
1 parent ce7b49d commit 8262223
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 0 deletions.
1 change: 1 addition & 0 deletions conf/eslint.json
Expand Up @@ -5,6 +5,7 @@
"no-caller": 1,
"no-bitwise": 0,
"no-console": 1,
"no-dangle": 1,
"no-debugger": 1,
"no-empty": 1,
"no-eval": 1,
Expand Down
1 change: 1 addition & 0 deletions docs/Rules.md
Expand Up @@ -7,6 +7,7 @@ Rules in ESLint are divided into several categories to help you better understan
The following rules point out areas where you might have made mistakes.

* [no-console](no-console.md) - disallow use of `console`
* [no-dangle](no-dangle.md) - disallow trailing commas in object literals
* [no-debugger](No-debugger.md) - disallow use of `debugger`
* [no-empty](No-empty.md) - disallow empty statements
* [no-unreachable](No-unreachable.md) - disallow unreachable statements after a return, throw, continue, or break statement
Expand Down
50 changes: 50 additions & 0 deletions docs/no-dangle.md
@@ -0,0 +1,50 @@
# no dangle

Trailing commas in object literals are valid according to the ECMAScript 5 (and ECMAScript 3!) spec, however IE8 (when not in IE8 document mode) and below will throw an error when it encounters trailing commas in JavaScript.

```js
var foo = {
bar: "baz",
qux: "quux",
};
```

## Rule Details

This rule is aimed at detecting trailing commas in object literals. As such, it will warn whenever it encounters a trailing comma in an object literal.

The following are considered warnings:

```js
var foo = {
bar: "baz",
qux: "quux",
};

var arr = [1,2,];

foo({
bar: "baz",
qux: "quux",
});
```

The following are okay and will not raise warnings:

```js
var foo = {
bar: "baz",
qux: "quux"
};

var arr = [1,2];

foo({
bar: "baz",
qux: "quux"
});
```

## When Not To Use It

If your code will not be run in IE8 or below (a NodeJS application, for example) and you'd prefer to allow trailing commas, turn this rule off.
36 changes: 36 additions & 0 deletions lib/rules/no-dangle.js
@@ -0,0 +1,36 @@
/**
* @fileoverview Rule to flag trailing commas in object literals.
* @author Ian Christian Myers
*/

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function(context) {

//-------------------------------------------------------------------------
// Helpers
//-------------------------------------------------------------------------

function checkForTrailingComma(node) {
var tokens = context.getTokens(node),
secondToLastToken = tokens[tokens.length - 2];

// The last token in an object/array literal will always be a closing
// curly, so we check the second to last token for a comma.
if (secondToLastToken.value === ",") {
context.report(node, "Found trailing comma in object literal.");
}
}

//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------

return {
"ObjectExpression": checkForTrailingComma,
"ArrayExpression": checkForTrailingComma
};

};
106 changes: 106 additions & 0 deletions tests/lib/rules/no-dangle.js
@@ -0,0 +1,106 @@
/**
* @fileoverview Tests for no-dangle rule.
* @author Ian Christian Myers
*/

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

var vows = require("vows"),
assert = require("assert"),
eslint = require("../../../lib/eslint");

//------------------------------------------------------------------------------
// Constants
//------------------------------------------------------------------------------

var RULE_ID = "no-dangle";

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

vows.describe(RULE_ID).addBatch({

"when evaluating object literal with a dangling comma": {

topic: "var foo = { bar: \"baz\", }",

"should report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 1);
assert.equal(messages[0].ruleId, RULE_ID);
assert.equal(messages[0].message, "Found trailing comma in object literal.");
assert.include(messages[0].node.type, "ObjectExpression");
}
},

"when evaluating object literal passed to a function with a dangling comma": {

topic: "foo({ bar: \"baz\", qux: \"quux\", });",

"should report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 1);
assert.equal(messages[0].ruleId, RULE_ID);
assert.equal(messages[0].message, "Found trailing comma in object literal.");
assert.include(messages[0].node.type, "ObjectExpression");
}
},


"when evaluating object literal without a dangling comma": {

topic: "var foo = { bar: \"baz\" }",

"should not report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 0);
}
},

"when evaluating array literal with a dangling comma": {

topic: "var foo = [ \"baz\", ]",

"should report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 1);
assert.equal(messages[0].ruleId, RULE_ID);
assert.equal(messages[0].message, "Found trailing comma in object literal.");
assert.include(messages[0].node.type, "ArrayExpression");
}
},

"when evaluating array literal without a dangling comma": {

topic: "var foo = [ \"baz\" ]",

"should not report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 0);
}
}

}).export(module);

0 comments on commit 8262223

Please sign in to comment.