Skip to content

Commit

Permalink
Fix: one-var allows uninitialized vars in ForIn/ForOf (fixes #5744) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
kaicataldo authored and nzakas committed Jun 5, 2016
1 parent 6cbee31 commit 316a507
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 0 deletions.
12 changes: 12 additions & 0 deletions docs/rules/one-var.md
Expand Up @@ -203,6 +203,8 @@ function foo() {

When configured with an object as the first option, you can individually control how `var`, `let`, and `const` are handled, or alternatively how `uninitialized` and `initialized` variables are handled (which if used will override `var`, `let`, and `const`).

**Note:** A variable declared in a for-in or for-of loop will not be flagged with the option `{ uninitialized: "always" }`, as this value is determined by the loop.

The following patterns are not considered problems:

```js
Expand Down Expand Up @@ -234,6 +236,16 @@ function foo() {
var foo = true;
var bar = false;
}

let x, y;
for (let z of foo) {
doSomething(z);
}

let x, y, z;
for (z of foo) {
doSomething(z);
}
```

If you are configuring the rule with an object, by default, if you didn't specify declaration type it will not be checked. So the following pattern is not considered a warning when options are set to: `{ var: "always", let: "always" }`
Expand Down
3 changes: 3 additions & 0 deletions lib/rules/one-var.js
Expand Up @@ -286,6 +286,9 @@ module.exports = {
context.report(node, "Combine this with the previous '" + type + "' statement with initialized variables.");
}
if (options[type].uninitialized === MODE_ALWAYS) {
if (node.parent.left === node && (node.parent.type === "ForInStatement" || node.parent.type === "ForOfStatement")) {
return;
}
context.report(node, "Combine this with the previous '" + type + "' statement with uninitialized variables.");
}
}
Expand Down
116 changes: 116 additions & 0 deletions tests/lib/rules/one-var.js
Expand Up @@ -188,6 +188,56 @@ ruleTester.run("one-var", rule, {
code: "for (let x in foo) {}; for (let y in foo) {}",
parserOptions: { ecmaVersion: 6 },
options: [{ uninitialized: "always" }]
},
{
code: "var x; for (var y in foo) {}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }]
},
{
code: "var x, y; for (y in foo) {}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }]
},
{
code: "var x, y; for (var z in foo) {}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }]
},
{
code: "var x; for (var y in foo) {var bar = y; for (var z in bar) {}}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }]
},
{
code: "var a = 1; var b = 2; var x, y; for (var z in foo) {var baz = z; for (var d in baz) {}}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }]
},
{
code: "var x; for (var y of foo) {}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }]
},
{
code: "var x, y; for (y of foo) {}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }]
},
{
code: "var x, y; for (var z of foo) {}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }]
},
{
code: "var x; for (var y of foo) {var bar = y; for (var z of bar) {}}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }]
},
{
code: "var a = 1; var b = 2; var x, y; for (var z of foo) {var baz = z; for (var d of baz) {}}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }]
}
],
invalid: [
Expand Down Expand Up @@ -482,6 +532,72 @@ ruleTester.run("one-var", rule, {
line: 1,
column: 10
} ]
},
{
code: "var x = 1, y = 2; for (var z in foo) {}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }],
errors: [{
message: "Split initialized 'var' declarations into multiple statements.",
type: "VariableDeclaration",
line: 1,
column: 1
}]
},
{
code: "var x = 1, y = 2; for (var z of foo) {}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }],
errors: [{
message: "Split initialized 'var' declarations into multiple statements.",
type: "VariableDeclaration",
line: 1,
column: 1
}]
},
{
code: "var x; var y; for (var z in foo) {}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }],
errors: [{
message: "Combine this with the previous 'var' statement with uninitialized variables.",
type: "VariableDeclaration",
line: 1,
column: 8
}]
},
{
code: "var x; var y; for (var z of foo) {}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }],
errors: [{
message: "Combine this with the previous 'var' statement with uninitialized variables.",
type: "VariableDeclaration",
line: 1,
column: 8
}]
},
{
code: "var x; for (var y in foo) {var bar = y; var a; for (var z of bar) {}}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }],
errors: [{
message: "Combine this with the previous 'var' statement with uninitialized variables.",
type: "VariableDeclaration",
line: 1,
column: 41
}]
},
{
code: "var a = 1; var b = 2; var x, y; for (var z of foo) {var c = 3, baz = z; for (var d in baz) {}}",
parserOptions: { ecmaVersion: 6 },
options: [{ initialized: "never", uninitialized: "always" }],
errors: [{
message: "Split initialized 'var' declarations into multiple statements.",
type: "VariableDeclaration",
line: 1,
column: 53
}]
}
]
});

0 comments on commit 316a507

Please sign in to comment.