Skip to content

Commit

Permalink
New: Add no-whitespace-before-property rule (fixes eslint#1086)
Browse files Browse the repository at this point in the history
  • Loading branch information
kaicataldo committed Dec 28, 2015
1 parent 8974fd6 commit fb34aa3
Show file tree
Hide file tree
Showing 5 changed files with 359 additions and 0 deletions.
1 change: 1 addition & 0 deletions conf/eslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"no-sequences": 0,
"no-shadow": 0,
"no-shadow-restricted-names": 0,
"no-whitespace-before-property": 0,
"no-spaced-func": 0,
"no-sparse-arrays": 2,
"no-sync": 0,
Expand Down
1 change: 1 addition & 0 deletions docs/rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ These rules are purely matters of style and are quite subjective.
* [no-new-object](no-new-object.md) - disallow the use of the `Object` constructor
* [no-plusplus](no-plusplus.md) - disallow use of unary operators, `++` and `--`
* [no-restricted-syntax](no-restricted-syntax.md) - disallow use of certain syntax in code
* [no-whitespace-before-property](no-whitespace-before-property.md) - disallow whitespace before properties
* [no-spaced-func](no-spaced-func.md) - disallow space between function identifier and application (fixable)
* [no-ternary](no-ternary.md) - disallow the use of ternary operators
* [no-trailing-spaces](no-trailing-spaces.md) - disallow trailing whitespace at the end of lines (fixable)
Expand Down
70 changes: 70 additions & 0 deletions docs/rules/no-whitespace-before-property.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Disallow whitespace before properties (no-whitespace-before-property)

JavaScript allows whitespace between objects and their properties. However, inconsistent spacing can make code harder to read and can lead to errors.

```js
foo. bar

foo . bar

foo [bar]
```

## Rule Details

This rule disallows whitespace around dot or brackets before properties of objects if they are on the same line. It does not alert for whitespace when the object and property are on separate lines, as it is common to add newlines to longer chains of properties to improve readability:

```js
foo
.bar()
.baz()
.qux()
```

The following patterns are considered problems when this rule is turned on:

```js
/*eslint no-whitespace-before-property: 2*/

foo [bar]

foo. bar

foo .bar

foo. bar. baz

foo. bar()
.baz()

foo
.bar(). baz()
```

And the following patterns are not considered problems:

```js
/*eslint no-whitespace-before-property: 2*/

foo.bar

foo[bar]

foo.bar.baz

foo
.bar().baz()

foo
.bar()
.baz()

foo.
bar().
baz()
```

## When Not To Use It

Turn this rule off if you do not care about allowing whitespace around dot or brackets before properties of objects if they are on the same line.

43 changes: 43 additions & 0 deletions lib/rules/no-whitespace-before-property.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @fileoverview Rule to disallow whitespace before properties
* @author Kai Cataldo
* @copyright 2015 Kai Cataldo. All rights reserved.
* See LICENSE file in root directory for full license.
*/
"use strict";

var astUtils = require("../ast-utils");

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

module.exports = function(context) {
var sourceCode = context.getSourceCode();

//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------

return {
MemberExpression: function(node) {
var obj = node.object;
var prop = node.property;

if (astUtils.isTokenOnSameLine(obj, prop)) {
if (sourceCode.isSpaceBetweenTokens(obj, prop)) {
context.report({
node: node,
message: "Unexpected whitespace before property \"{{ propName }}\".",
data: {
propName: prop.name
}
});
}
}
}
};
};

module.exports.schema = [];

244 changes: 244 additions & 0 deletions tests/lib/rules/no-whitespace-before-property.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
/**
* @fileoverview Rule to disallow whitespace before properties
* @author Kai Cataldo
* @copyright 2015 Kai Cataldo. All rights reserved.
* See LICENSE file in root directory for full license.
*/
"use strict";

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

var rule = require("../../../lib/rules/no-whitespace-before-property"),
RuleTester = require("../../../lib/testers/rule-tester");

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

var ruleTester = new RuleTester();

ruleTester.run("no-whitespace-before-property", rule, {

valid: [
"foo.bar",
"foo.bar()",
"foo[bar]",
"foo\n.bar",
"foo.\nbar",
"foo\n.bar()",
"foo.\nbar()",
"foo\n[bar]",
"foo.\n bar",
"foo\n. bar",
"foo.\n bar()",
"foo\n. bar()",
"foo\n [bar]",
"foo.\n\tbar",
"foo\n.\tbar",
"foo.\n\tbar()",
"foo\n.\tbar()",
"foo\n\t[bar]",
"foo.bar.baz",
"foo\n.bar\n.baz",
"foo.\nbar.\nbaz",
"foo.bar().baz()",
"foo\n.bar()\n.baz()",
"foo.\nbar().\nbaz()",
"foo\n.bar\n[baz]",
"foo\n .bar\n .baz",
"foo.\n bar.\n baz",
"foo\n .bar()\n .baz()",
"foo.\n bar().\n baz()",
"foo\n .bar\n [baz]",
"foo\n\t.bar\n\t.baz",
"foo.\n\tbar.\n\tbaz",
"foo\n\t.bar()\n\t.baz()",
"foo.\n\tbar().\n\tbaz()",
"foo\n\t.bar\n\t[baz]"
],

invalid: [
{
code: "foo. bar",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo .bar",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo [bar]",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo. bar. baz",
errors: ["Unexpected whitespace before property \"baz\".", "Unexpected whitespace before property \"bar\"."]
},
{
code: "foo .bar. baz",
errors: ["Unexpected whitespace before property \"baz\".", "Unexpected whitespace before property \"bar\"."]
},
{
code: "foo [bar] [baz]",
errors: ["Unexpected whitespace before property \"baz\".", "Unexpected whitespace before property \"bar\"."]
},
{
code: "foo [bar][baz]",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo[bar] [baz]",
errors: ["Unexpected whitespace before property \"baz\"."]
},
{
code: "foo.bar [baz]",
errors: ["Unexpected whitespace before property \"baz\"."]
},
{
code: "foo. bar[baz]",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo[bar]. baz",
errors: ["Unexpected whitespace before property \"baz\"."]
},

// tabs
{
code: "foo\t.bar",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo.\tbar",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo\t.bar()",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo.\tbar()",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo\t[bar]",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo.\tbar.\tbaz",
errors: ["Unexpected whitespace before property \"baz\".", "Unexpected whitespace before property \"bar\"."]
},
{
code: "foo\t.bar.\tbaz",
errors: ["Unexpected whitespace before property \"baz\".", "Unexpected whitespace before property \"bar\"."]
},
{
code: "foo.\tbar().\tbaz()",
errors: ["Unexpected whitespace before property \"baz\".", "Unexpected whitespace before property \"bar\"."]
},
{
code: "foo\t.bar().\tbaz()",
errors: ["Unexpected whitespace before property \"baz\".", "Unexpected whitespace before property \"bar\"."]
},
{
code: "foo\t[bar]\t[baz]",
errors: ["Unexpected whitespace before property \"baz\".", "Unexpected whitespace before property \"bar\"."]
},
{
code: "foo\t[bar][baz]",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo[bar]\t[baz]",
errors: ["Unexpected whitespace before property \"baz\"."]
},
{
code: "foo.bar\t[baz]",
errors: ["Unexpected whitespace before property \"baz\"."]
},
{
code: "foo.\tbar[baz]",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo[bar].\tbaz",
errors: ["Unexpected whitespace before property \"baz\"."]
},

// newlines
{
code: "foo [bar]\n .baz",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo. bar\n .baz",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo .bar\n.baz",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo.\n bar. baz",
errors: ["Unexpected whitespace before property \"baz\"."]
},
{
code: "foo.\nbar . baz",
errors: ["Unexpected whitespace before property \"baz\"."]
},
{
code: "foo. bar()\n .baz()",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo .bar()\n.baz()",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo.\n bar(). baz()",
errors: ["Unexpected whitespace before property \"baz\"."]
},
{
code: "foo.\nbar() . baz()",
errors: ["Unexpected whitespace before property \"baz\"."]
},
{
code: "foo\t[bar]\n\t.baz",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo.\tbar\n\t.baz",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo\t.bar\n.baz",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo.\n\tbar.\tbaz",
errors: ["Unexpected whitespace before property \"baz\"."]
},
{
code: "foo.\nbar\t.\tbaz",
errors: ["Unexpected whitespace before property \"baz\"."]
},
{
code: "foo.\tbar()\n\t.baz()",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo\t.bar()\n.baz()",
errors: ["Unexpected whitespace before property \"bar\"."]
},
{
code: "foo.\n\tbar().\tbaz()",
errors: ["Unexpected whitespace before property \"baz\"."]
},
{
code: "foo.\nbar()\t.\tbaz()",
errors: ["Unexpected whitespace before property \"baz\"."]
}
]
});

0 comments on commit fb34aa3

Please sign in to comment.