diff --git a/conf/eslint.json b/conf/eslint.json index 570498df9885..21a5bd36ca9b 100644 --- a/conf/eslint.json +++ b/conf/eslint.json @@ -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, diff --git a/docs/Rules.md b/docs/Rules.md index 70072c23577c..c7ee92e37dc3 100644 --- a/docs/Rules.md +++ b/docs/Rules.md @@ -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 diff --git a/docs/no-dangle.md b/docs/no-dangle.md new file mode 100644 index 000000000000..8a3e9fe604b8 --- /dev/null +++ b/docs/no-dangle.md @@ -0,0 +1,46 @@ +# 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", +}; + +foo({ + bar: "baz", + qux: "quux", +}); +``` + +The following are okay and will not raise warnings: + +```js +var foo = { + bar: "baz", + qux: "quux" +}; + +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. diff --git a/lib/rules/no-dangle.js b/lib/rules/no-dangle.js new file mode 100644 index 000000000000..e8f05fad3616 --- /dev/null +++ b/lib/rules/no-dangle.js @@ -0,0 +1,23 @@ +/** + * @fileoverview Rule to flag trailing commas in object literals. + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = function(context) { + + return { + + "ObjectExpression": function(node) { + + // Regex looking for a comma followed by a closing curly. + if (context.getSource(node).match(/,(\s+)?}/)) { + context.report(node, "Found trailing comma in object literal."); + } + } + }; + +}; diff --git a/tests/lib/rules/no-dangle.js b/tests/lib/rules/no-dangle.js new file mode 100644 index 000000000000..4ee736a39c8f --- /dev/null +++ b/tests/lib/rules/no-dangle.js @@ -0,0 +1,75 @@ +/** + * @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); + } + } + +}).export(module);