From accca0b7d21d96e33fe542b87bf79ac17d541f08 Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Wed, 26 Nov 2014 16:04:32 -0800 Subject: [PATCH] Update: Make rules work with arrow functions (fixes #1508, fixes #1509, fixes #1493) --- lib/eslint.js | 3 +- lib/rules/block-scoped-var.js | 3 + lib/rules/brace-style.js | 1 + lib/rules/comma-spacing.js | 3 + lib/rules/complexity.js | 2 + lib/rules/consistent-return.js | 13 ++++ lib/rules/func-style.js | 10 +++ lib/rules/handle-callback-err.js | 7 +- lib/rules/max-depth.js | 5 ++ lib/rules/max-nested-callbacks.js | 49 ++++++++---- lib/rules/max-params.js | 38 +++++----- lib/rules/max-statements.js | 5 +- lib/rules/no-constant-condition.js | 32 ++++---- lib/rules/no-empty.js | 3 +- lib/rules/no-extra-bind.js | 4 +- lib/rules/no-extra-parens.js | 1 + lib/rules/no-extra-strict.js | 10 ++- lib/rules/no-func-assign.js | 1 + lib/rules/no-inner-declarations.js | 1 + lib/rules/no-loop-func.js | 2 + lib/rules/no-shadow-restricted-names.js | 7 ++ lib/rules/no-shadow.js | 1 + lib/rules/no-unused-expressions.js | 6 +- lib/rules/no-use-before-define.js | 1 + lib/rules/no-wrap-func.js | 31 +++++--- lib/rules/one-var.js | 5 +- lib/rules/space-after-keywords.js | 1 + lib/rules/strict.js | 4 +- lib/rules/valid-jsdoc.js | 3 + lib/rules/vars-on-top.js | 11 ++- lib/rules/wrap-iife.js | 1 + tests/lib/eslint.js | 23 ++++++ tests/lib/rules/block-scoped-var.js | 2 + tests/lib/rules/brace-style.js | 4 +- tests/lib/rules/comma-spacing.js | 17 +++++ tests/lib/rules/complexity.js | 4 +- tests/lib/rules/consistent-return.js | 23 +++++- tests/lib/rules/func-names.js | 1 + tests/lib/rules/func-style.js | 17 +++++ tests/lib/rules/handle-callback-err.js | 3 + tests/lib/rules/max-depth.js | 4 + tests/lib/rules/max-nested-callbacks.js | 28 ++++++- tests/lib/rules/max-params.js | 3 + tests/lib/rules/max-statements.js | 3 + tests/lib/rules/no-constant-condition.js | 4 +- tests/lib/rules/no-empty.js | 2 + tests/lib/rules/no-extra-bind.js | 4 +- tests/lib/rules/no-extra-parens.js | 3 + tests/lib/rules/no-extra-strict.js | 42 ++++++++--- tests/lib/rules/no-func-assign.js | 2 + tests/lib/rules/no-inner-declarations.js | 4 +- tests/lib/rules/no-loop-func.js | 2 + tests/lib/rules/no-multi-spaces.js | 15 ++++ tests/lib/rules/no-shadow-restricted-names.js | 12 +++ tests/lib/rules/no-shadow.js | 1 + tests/lib/rules/no-unused-expressions.js | 7 +- tests/lib/rules/no-use-before-define.js | 1 + tests/lib/rules/no-wrap-func.js | 2 + tests/lib/rules/one-var.js | 74 +++++++++++++++---- tests/lib/rules/space-after-keywords.js | 1 + tests/lib/rules/strict.js | 5 ++ tests/lib/rules/valid-jsdoc.js | 15 ++++ tests/lib/rules/vars-on-top.js | 18 +++++ tests/lib/rules/wrap-iife.js | 1 + 64 files changed, 499 insertions(+), 112 deletions(-) diff --git a/lib/eslint.js b/lib/eslint.js index 6bf68bd7b97..b7d19a85521 100755 --- a/lib/eslint.js +++ b/lib/eslint.js @@ -823,10 +823,11 @@ module.exports = (function() { case "FunctionDeclaration": return findJSDocComment(node.leadingComments); + case "ArrowFunctionExpression": case "FunctionExpression": if (parent.type !== "CallExpression" || parent.callee !== node) { - while (parent && !parent.leadingComments && parent.type !== "FunctionExpression" && parent.type !== "FunctionDeclaration") { + while (parent && !parent.leadingComments && !/Function/.test(parent.type)) { parent = parent.parent; } diff --git a/lib/rules/block-scoped-var.js b/lib/rules/block-scoped-var.js index 6094579dd5c..bc04af1d262 100644 --- a/lib/rules/block-scoped-var.js +++ b/lib/rules/block-scoped-var.js @@ -141,6 +141,9 @@ module.exports = function(context) { "FunctionExpression": functionHandler, "FunctionExpression:exit": popScope, + "ArrowFunctionExpression": functionHandler, + "ArrowFunctionExpression:exit": popScope, + "ForStatement": function(node) { pushScope(); if (node.init && node.init.type === "VariableDeclaration") { diff --git a/lib/rules/brace-style.js b/lib/rules/brace-style.js index 529ed05d652..fc0eeb12b21 100644 --- a/lib/rules/brace-style.js +++ b/lib/rules/brace-style.js @@ -188,6 +188,7 @@ module.exports = function(context) { return { "FunctionDeclaration": checkBlock("body"), "FunctionExpression": checkBlock("body"), + "ArrowFunctionExpression": checkBlock("body"), "IfStatement": checkIfStatement, "TryStatement": checkTryStatement, "CatchClause": checkCatchClause, diff --git a/lib/rules/comma-spacing.js b/lib/rules/comma-spacing.js index f8506da4a28..2dd6d2cacfa 100644 --- a/lib/rules/comma-spacing.js +++ b/lib/rules/comma-spacing.js @@ -170,6 +170,9 @@ module.exports = function(context) { "SequenceExpression": function(node) { validateCommaSpacing(node, "expressions"); }, + "ArrowFunctionExpression": function(node) { + validateCommaSpacing(node, "params"); + }, "FunctionExpression": function(node) { validateCommaSpacing(node, "params"); }, diff --git a/lib/rules/complexity.js b/lib/rules/complexity.js index 7441813f112..7cbc1d026c2 100644 --- a/lib/rules/complexity.js +++ b/lib/rules/complexity.js @@ -64,8 +64,10 @@ module.exports = function(context) { return { "FunctionDeclaration": startFunction, "FunctionExpression": startFunction, + "ArrowFunctionExpression": startFunction, "FunctionDeclaration:exit": endFunction, "FunctionExpression:exit": endFunction, + "ArrowFunctionExpression:exit": endFunction, "CatchClause": increaseComplexity, "ConditionalExpression": increaseComplexity, diff --git a/lib/rules/consistent-return.js b/lib/rules/consistent-return.js index e1448ca641a..6904ece744e 100644 --- a/lib/rules/consistent-return.js +++ b/lib/rules/consistent-return.js @@ -16,10 +16,21 @@ module.exports = function(context) { // Helpers //-------------------------------------------------------------------------- + /** + * Marks entrance into a function by pushing a new object onto the functions + * stack. + * @returns {void} + * @private + */ function enterFunction() { functions.push({}); } + /** + * Marks exit of a function by popping off the functions stack. + * @returns {void} + * @private + */ function exitFunction() { functions.pop(); } @@ -33,8 +44,10 @@ module.exports = function(context) { "FunctionDeclaration": enterFunction, "FunctionExpression": enterFunction, + "ArrowFunctionExpression": enterFunction, "FunctionDeclaration:exit": exitFunction, "FunctionExpression:exit": exitFunction, + "ArrowFunctionExpression:exit": exitFunction, "ReturnStatement": function(node) { diff --git a/lib/rules/func-style.js b/lib/rules/func-style.js index 527a13b7d8a..f54350e7651 100644 --- a/lib/rules/func-style.js +++ b/lib/rules/func-style.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to enforce a particular function style * @author Nicholas C. Zakas + * @copyright 2013 Nicholas C. Zakas. All rights reserved. */ "use strict"; @@ -24,10 +25,19 @@ module.exports = function(context) { "FunctionExpression": function() { var parent = context.getAncestors().pop(); + if (enforceDeclarations && parent.type === "VariableDeclarator") { + context.report(parent, "Expected a function declaration."); + } + }, + + "ArrowFunctionExpression": function() { + var parent = context.getAncestors().pop(); + if (enforceDeclarations && parent.type === "VariableDeclarator") { context.report(parent, "Expected a function declaration."); } } + }; }; diff --git a/lib/rules/handle-callback-err.js b/lib/rules/handle-callback-err.js index aa711323230..f57e4d1752d 100644 --- a/lib/rules/handle-callback-err.js +++ b/lib/rules/handle-callback-err.js @@ -1,6 +1,7 @@ /** * @fileoverview Ensure handling of errors when we know they exist. * @author Jamund Ferguson + * @copyright 2014 Jamund Ferguson. All rights reserved. */ "use strict"; @@ -92,7 +93,7 @@ module.exports = function(context) { var isAboutError = node.name === callback.errorVariableName; // we don't consider these use cases as "handling" the error - var doNotCount = ["FunctionDeclaration", "FunctionExpression", "CatchClause"]; + var doNotCount = ["FunctionDeclaration", "ArrowFunctionExpression", "FunctionExpression", "CatchClause"]; // make sure this identifier isn't used as part of one of them var isHandled = doNotCount.indexOf(node.parent.type) === -1; @@ -107,9 +108,11 @@ module.exports = function(context) { return { "FunctionDeclaration": startFunction, "FunctionExpression": startFunction, + "ArrowFunctionExpression": startFunction, "Identifier": checkForError, "FunctionDeclaration:exit": endFunction, - "FunctionExpression:exit": endFunction + "FunctionExpression:exit": endFunction, + "ArrowFunctionExpression:exit": endFunction }; }; diff --git a/lib/rules/max-depth.js b/lib/rules/max-depth.js index e439b56584c..ec679f100f8 100644 --- a/lib/rules/max-depth.js +++ b/lib/rules/max-depth.js @@ -1,6 +1,7 @@ /** * @fileoverview A rule to set the maximum depth block can be nested in a function. * @author Ian Christian Myers + * @copyright 2013 Ian Christian Myers. All rights reserved. */ "use strict"; @@ -47,6 +48,7 @@ module.exports = function(context) { "Program": startFunction, "FunctionDeclaration": startFunction, "FunctionExpression": startFunction, + "ArrowFunctionExpression": startFunction, "IfStatement": pushBlock, "SwitchStatement": pushBlock, @@ -56,6 +58,7 @@ module.exports = function(context) { "WithStatement": pushBlock, "ForStatement": pushBlock, "ForInStatement": pushBlock, + "ForOfStatement": pushBlock, "IfStatement:exit": popBlock, "SwitchStatement:exit": popBlock, @@ -65,9 +68,11 @@ module.exports = function(context) { "WithStatement:exit": popBlock, "ForStatement:exit": popBlock, "ForInStatement:exit": popBlock, + "ForOfStatement:exit": popBlock, "FunctionDeclaration:exit": endFunction, "FunctionExpression:exit": endFunction, + "ArrowFunctionExpression:exit": endFunction, "Program:exit": endFunction }; diff --git a/lib/rules/max-nested-callbacks.js b/lib/rules/max-nested-callbacks.js index 122d2d352b6..590274ffd1c 100644 --- a/lib/rules/max-nested-callbacks.js +++ b/lib/rules/max-nested-callbacks.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to enforce a maximum number of nested callbacks. * @author Ian Christian Myers + * @copyright 2013 Ian Christian Myers. All rights reserved. */ "use strict"; @@ -18,31 +19,49 @@ module.exports = function(context) { var THRESHOLD = context.options[0]; //-------------------------------------------------------------------------- - // Public API + // Helpers //-------------------------------------------------------------------------- var callbackStack = []; - return { + /** + * Checks a given function node for too many callbacks. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function checkFunction(node) { + var parent = node.parent; - "FunctionExpression": function (node) { - var parent = context.getAncestors().pop(); + if (parent.type === "CallExpression") { + callbackStack.push(node); + } - if (parent.type === "CallExpression") { - callbackStack.push(node); - } + if (callbackStack.length > THRESHOLD) { + var opts = {num: callbackStack.length, max: THRESHOLD}; + context.report(node, "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}.", opts); + } + } - if (callbackStack.length > THRESHOLD) { - var opts = {num: callbackStack.length, max: THRESHOLD}; - context.report(node, "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}.", opts); - } - }, + /** + * Pops the call stack. + * @returns {void} + * @private + */ + function popStack() { + callbackStack.pop(); + } + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- - "FunctionExpression:exit": function() { - callbackStack.pop(); - } + return { + "ArrowFunctionExpression": checkFunction, + "ArrowFunctionExpression:exit": popStack, + "FunctionExpression": checkFunction, + "FunctionExpression:exit": popStack }; }; diff --git a/lib/rules/max-params.js b/lib/rules/max-params.js index 918c19fa4ca..931548932f5 100644 --- a/lib/rules/max-params.js +++ b/lib/rules/max-params.js @@ -1,6 +1,8 @@ /** * @fileoverview Rule to flag when a function has too many parameters * @author Ilya Volodin + * @copyright 2014 Nicholas C. Zakas. All rights reserved. + * @copyright 2013 Ilya Volodin. All rights reserved. */ "use strict"; @@ -13,25 +15,25 @@ module.exports = function(context) { var numParams = context.options[0] || 3; - return { - - "FunctionDeclaration": function(node) { - if (node.params.length > numParams) { - context.report(node, "This function has too many parameters ({{count}}). Maximum allowed is {{max}}.", { - count: node.params.length, - max: numParams - }); - } - }, - - "FunctionExpression": function(node) { - if (node.params.length > numParams) { - context.report(node, "This function has too many parameters ({{count}}). Maximum allowed is {{max}}.", { - count: node.params.length, - max: numParams - }); - } + /** + * Checks a function to see if it has too many parameters. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function checkFunction(node) { + if (node.params.length > numParams) { + context.report(node, "This function has too many parameters ({{count}}). Maximum allowed is {{max}}.", { + count: node.params.length, + max: numParams + }); } + } + + return { + "FunctionDeclaration": checkFunction, + "ArrowFunctionExpression": checkFunction, + "FunctionExpression": checkFunction }; }; diff --git a/lib/rules/max-statements.js b/lib/rules/max-statements.js index 05c8f1e94aa..9fe11bfd91d 100644 --- a/lib/rules/max-statements.js +++ b/lib/rules/max-statements.js @@ -1,6 +1,7 @@ /** * @fileoverview A rule to set the maximum number of statements in a function. * @author Ian Christian Myers + * @copyright 2013 Ian Christian Myers. All rights reserved. */ "use strict"; @@ -42,11 +43,13 @@ module.exports = function(context) { return { "FunctionDeclaration": startFunction, "FunctionExpression": startFunction, + "ArrowFunctionExpression": startFunction, "BlockStatement": countStatements, "FunctionDeclaration:exit": endFunction, - "FunctionExpression:exit": endFunction + "FunctionExpression:exit": endFunction, + "ArrowFunctionExpression:exit": endFunction }; }; diff --git a/lib/rules/no-constant-condition.js b/lib/rules/no-constant-condition.js index a8961757039..73610111369 100644 --- a/lib/rules/no-constant-condition.js +++ b/lib/rules/no-constant-condition.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to flag use constant conditions * @author Christian Schulz + * @copyright 2014 Christian Schulz. All rights reserved. */ "use strict"; @@ -23,21 +24,22 @@ module.exports = function(context) { */ function isConstant(node) { switch (node.type) { - case "Literal": - case "FunctionExpression": - case "ObjectExpression": - case "ArrayExpression": - return true; - case "UnaryExpression": - return isConstant(node.argument); - case "BinaryExpression": - case "LogicalExpression": - return isConstant(node.left) && isConstant(node.right); - case "AssignmentExpression": - return isConstant(node.right); - case "SequenceExpression": - return isConstant(node.expressions[node.expressions.length - 1]); - // no default + case "Literal": + case "ArrowFunctionExpression": + case "FunctionExpression": + case "ObjectExpression": + case "ArrayExpression": + return true; + case "UnaryExpression": + return isConstant(node.argument); + case "BinaryExpression": + case "LogicalExpression": + return isConstant(node.left) && isConstant(node.right); + case "AssignmentExpression": + return isConstant(node.right); + case "SequenceExpression": + return isConstant(node.expressions[node.expressions.length - 1]); + // no default } return false; } diff --git a/lib/rules/no-empty.js b/lib/rules/no-empty.js index 6673855714e..0b7ef5d950f 100644 --- a/lib/rules/no-empty.js +++ b/lib/rules/no-empty.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to flag use of an empty block statement * @author Nicholas C. Zakas + * @copyright Nicholas C. Zakas. All rights reserved. */ "use strict"; @@ -18,7 +19,7 @@ module.exports = function(context) { parentType = parent.type, isFinallyBlock = (parentType === "TryStatement") && (parent.finalizer === node); - if (/FunctionExpression|FunctionDeclaration|CatchClause/.test(parentType) || + if (/Function|CatchClause/.test(parentType) || (isFinallyBlock && !parent.handlers.length)) { return; } diff --git a/lib/rules/no-extra-bind.js b/lib/rules/no-extra-bind.js index bc2bf31ae2a..b585730633e 100644 --- a/lib/rules/no-extra-bind.js +++ b/lib/rules/no-extra-bind.js @@ -47,7 +47,7 @@ module.exports = function(context) { if (node.arguments.length === 1 && node.callee.type === "MemberExpression" && node.callee.property.name === "bind" && - node.callee.object.type === "FunctionExpression") { + /FunctionExpression$/.test(node.callee.object.type)) { scope.push({ call: node, depth: -1, @@ -62,6 +62,8 @@ module.exports = function(context) { scope.pop(); } }, + "ArrowFunctionExpression": incrementScopeDepth, + "ArrowFunctionExpression:exit": decrementScopeDepth, "FunctionExpression": incrementScopeDepth, "FunctionExpression:exit": decrementScopeDepth, "FunctionDeclaration": incrementScopeDepth, diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js index 776354deba8..7127a4aaff0 100644 --- a/lib/rules/no-extra-parens.js +++ b/lib/rules/no-extra-parens.js @@ -1,6 +1,7 @@ /** * @fileoverview Disallow parenthesesisng higher precedence subexpressions. * @author Michael Ficarra + * @copyright 2014 Michael Ficarra. All rights reserved. */ "use strict"; diff --git a/lib/rules/no-extra-strict.js b/lib/rules/no-extra-strict.js index 7a55d431704..cfda87953c8 100644 --- a/lib/rules/no-extra-strict.js +++ b/lib/rules/no-extra-strict.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to flag unnecessary strict directives. * @author Ian Christian Myers + * @copyright 2014 Ian Christian Myers. All rights reserved. */ "use strict"; @@ -34,8 +35,9 @@ module.exports = function(context) { } function checkForUnnecessaryUseStrict(node) { - var useStrictDirectives, scope, upper; - useStrictDirectives = directives(node).filter(isStrict); + var useStrictDirectives = directives(node).filter(isStrict), + scope, + upper; switch (useStrictDirectives.length) { case 0: @@ -63,6 +65,10 @@ module.exports = function(context) { "Program": checkForUnnecessaryUseStrict, + "ArrowFunctionExpression": function(node) { + checkForUnnecessaryUseStrict(node.body); + }, + "FunctionExpression": function(node) { checkForUnnecessaryUseStrict(node.body); }, diff --git a/lib/rules/no-func-assign.js b/lib/rules/no-func-assign.js index 63af97562ae..3ea39e726e8 100644 --- a/lib/rules/no-func-assign.js +++ b/lib/rules/no-func-assign.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to flag use of function declaration identifiers as variables. * @author Ian Christian Myers + * @copyright 2013 Ian Christian Myers. All rights reserved. */ "use strict"; diff --git a/lib/rules/no-inner-declarations.js b/lib/rules/no-inner-declarations.js index 9e64e965d85..31294ab54db 100644 --- a/lib/rules/no-inner-declarations.js +++ b/lib/rules/no-inner-declarations.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to enforce declarations in program or function body root. * @author Brandon Mills + * @copyright 2014 Brandon Mills. All rights reserved. */ "use strict"; diff --git a/lib/rules/no-loop-func.js b/lib/rules/no-loop-func.js index b4802b6dbe7..16c17ff95bb 100644 --- a/lib/rules/no-loop-func.js +++ b/lib/rules/no-loop-func.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to flag creation of function inside a loop * @author Ilya Volodin + * @copyright 2013 Ilya Volodin. All rights reserved. */ "use strict"; @@ -23,6 +24,7 @@ module.exports = function(context) { } return { + "ArrowFunctionExpression": checkForLoops, "FunctionExpression": checkForLoops, "FunctionDeclaration": checkForLoops }; diff --git a/lib/rules/no-shadow-restricted-names.js b/lib/rules/no-shadow-restricted-names.js index f9862a3c9f2..5b8dd14a47d 100644 --- a/lib/rules/no-shadow-restricted-names.js +++ b/lib/rules/no-shadow-restricted-names.js @@ -1,6 +1,7 @@ /** * @fileoverview Disallow shadowing of NaN, undefined, and Infinity (ES5 section 15.1.1) * @author Michael Ficarra + * @copyright 2013 Michael Ficarra. All rights reserved. */ "use strict"; @@ -22,6 +23,12 @@ module.exports = function(context) { "VariableDeclarator": function(node) { checkForViolation(node.id); }, + "ArrowFunctionExpression": function(node) { + if (node.id) { + checkForViolation(node.id); + } + [].map.call(node.params, checkForViolation); + }, "FunctionExpression": function(node) { if (node.id) { checkForViolation(node.id); diff --git a/lib/rules/no-shadow.js b/lib/rules/no-shadow.js index 50deb8cbe8d..959f1208606 100644 --- a/lib/rules/no-shadow.js +++ b/lib/rules/no-shadow.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to flag on declaring variables already declared in the outer scope * @author Ilya Volodin + * @copyright 2013 Ilya Volodin. All rights reserved. */ "use strict"; diff --git a/lib/rules/no-unused-expressions.js b/lib/rules/no-unused-expressions.js index bf14f0913e5..729d0d84b25 100644 --- a/lib/rules/no-unused-expressions.js +++ b/lib/rules/no-unused-expressions.js @@ -1,6 +1,7 @@ /** * @fileoverview Flag expressions in statement position that do not side effect * @author Michael Ficarra + * @copyright 2013 Michael Ficarra. All rights reserved. */ "use strict"; @@ -49,8 +50,9 @@ module.exports = function(context) { function isDirective(node, ancestors) { var parent = ancestors[ancestors.length - 1], grandparent = ancestors[ancestors.length - 2]; - return (parent.type === "Program" || parent.type === "BlockStatement" && (grandparent.type === "FunctionExpression" || grandparent.type === "FunctionDeclaration")) && - directives(parent).indexOf(node) >= 0; + return (parent.type === "Program" || parent.type === "BlockStatement" && + (/Function/.test(grandparent.type))) && + directives(parent).indexOf(node) >= 0; } return { diff --git a/lib/rules/no-use-before-define.js b/lib/rules/no-use-before-define.js index dfbb25fc5e8..eddf96a30ab 100644 --- a/lib/rules/no-use-before-define.js +++ b/lib/rules/no-use-before-define.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to flag use of variables before they are defined * @author Ilya Volodin + * @copyright 2013 Ilya Volodin. All rights reserved. */ "use strict"; diff --git a/lib/rules/no-wrap-func.js b/lib/rules/no-wrap-func.js index c2119913be7..51a03b87b60 100644 --- a/lib/rules/no-wrap-func.js +++ b/lib/rules/no-wrap-func.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to flag wrapping non-iife in parens * @author Ilya Volodin + * @copyright 2013 Ilya Volodin. All rights reserved. */ "use strict"; @@ -11,20 +12,28 @@ module.exports = function(context) { - return { - - "FunctionExpression": function(node) { - var ancestors = context.getAncestors(), - previousToken, nextToken; + /** + * Checks a function expression to see if its surrounded by parens. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function checkFunction(node) { + var ancestors = context.getAncestors(), + previousToken, nextToken; - if (!/CallExpression|NewExpression/.test(ancestors.pop().type)) { - previousToken = context.getTokenBefore(node); - nextToken = context.getTokenAfter(node); - if (previousToken.value === "(" && nextToken.value === ")") { - context.report(node, "Wrapping non-IIFE function literals in parens is unnecessary."); - } + if (!/CallExpression|NewExpression/.test(ancestors.pop().type)) { + previousToken = context.getTokenBefore(node); + nextToken = context.getTokenAfter(node); + if (previousToken.value === "(" && nextToken.value === ")") { + context.report(node, "Wrapping non-IIFE function literals in parens is unnecessary."); } } + } + + return { + "ArrowFunctionExpression": checkFunction, + "FunctionExpression": checkFunction }; }; diff --git a/lib/rules/one-var.js b/lib/rules/one-var.js index f8872488ccc..c30d676c620 100644 --- a/lib/rules/one-var.js +++ b/lib/rules/one-var.js @@ -1,6 +1,7 @@ /** * @fileoverview A rule to ensure the use of a single variable declaration. * @author Ian Christian Myers + * @copyright 2013 Ian Christian Myers. All rights reserved. */ "use strict"; @@ -41,12 +42,14 @@ module.exports = function(context) { "Program": startFunction, "FunctionDeclaration": startFunction, "FunctionExpression": startFunction, + "ArrowFunctionExpression": startFunction, "VariableDeclaration": checkDeclarations, "Program:exit": endFunction, "FunctionDeclaration:exit": endFunction, - "FunctionExpression:exit": endFunction + "FunctionExpression:exit": endFunction, + "ArrowFunctionExpression:exit": endFunction }; }; diff --git a/lib/rules/space-after-keywords.js b/lib/rules/space-after-keywords.js index 0447cd8d662..1fedbe08374 100644 --- a/lib/rules/space-after-keywords.js +++ b/lib/rules/space-after-keywords.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to enforce the number of spaces after certain keywords * @author Nick Fisher + * @copyright 2014 Nick Fisher. All rights reserved. */ "use strict"; diff --git a/lib/rules/strict.js b/lib/rules/strict.js index d461bfb097e..fa5deb0ffde 100644 --- a/lib/rules/strict.js +++ b/lib/rules/strict.js @@ -133,10 +133,12 @@ module.exports = function(context) { "Program": enterScope, "FunctionDeclaration": enterScope, "FunctionExpression": enterScope, + "ArrowFunctionExpression": enterScope, "Program:exit": exitScope, "FunctionDeclaration:exit": exitScope, - "FunctionExpression:exit": exitScope + "FunctionExpression:exit": exitScope, + "ArrowFunctionExpression:exit": exitScope }; //-------------------------------------------------------------------------- diff --git a/lib/rules/valid-jsdoc.js b/lib/rules/valid-jsdoc.js index f45a1c20a79..e0ee73a65aa 100644 --- a/lib/rules/valid-jsdoc.js +++ b/lib/rules/valid-jsdoc.js @@ -1,6 +1,7 @@ /** * @fileoverview Validates JSDoc comments are syntactically correct * @author Nicholas C. Zakas + * @copyright 2014 Nicholas C. Zakas. All rights reserved. */ "use strict"; @@ -174,8 +175,10 @@ module.exports = function(context) { //-------------------------------------------------------------------------- return { + "ArrowFunctionExpression": startFunction, "FunctionExpression": startFunction, "FunctionDeclaration": startFunction, + "ArrowFunctionExpression:exit": checkJSDoc, "FunctionExpression:exit": checkJSDoc, "FunctionDeclaration:exit": checkJSDoc, "ReturnStatement": addReturn diff --git a/lib/rules/vars-on-top.js b/lib/rules/vars-on-top.js index bd248a4aab2..782b6682fbb 100644 --- a/lib/rules/vars-on-top.js +++ b/lib/rules/vars-on-top.js @@ -23,8 +23,8 @@ module.exports = function (context) { * @returns {Boolean} whether the given node structurally represents a directive */ function looksLikeDirective(node) { - return node.type === "ExpressionStatement" && - node.expression.type === "Literal" && typeof node.expression.value === "string"; + return node.type === "ExpressionStatement" && + node.expression.type === "Literal" && typeof node.expression.value === "string"; } /** @@ -73,10 +73,9 @@ module.exports = function (context) { * @returns {void} */ function blockScopeVarCheck(node, parent, grandParent) { - if (!((grandParent.type === "FunctionDeclaration" - || grandParent.type === "FunctionExpression") - && parent.type === "BlockStatement" - && isVarOnTop(node, parent.body))) { + if (!(/Function/.test(grandParent.type) && + parent.type === "BlockStatement" && + isVarOnTop(node, parent.body))) { context.report(node, errorMessage); } } diff --git a/lib/rules/wrap-iife.js b/lib/rules/wrap-iife.js index c80f2247851..eb3c5d1dc3f 100644 --- a/lib/rules/wrap-iife.js +++ b/lib/rules/wrap-iife.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to flag when IIFE is not wrapped in parens * @author Ilya Volodin + * @copyright 2013 Ilya Volodin. All rights reserved. */ "use strict"; diff --git a/tests/lib/eslint.js b/tests/lib/eslint.js index 620c22d533a..6f7962a5fc8 100644 --- a/tests/lib/eslint.js +++ b/tests/lib/eslint.js @@ -368,6 +368,29 @@ describe("eslint", function() { assert.isTrue(spy.calledOnce, "Event handler should be called."); }); + it("should get JSDoc comment for node when the node is a ArrowFunctionExpression inside of an object literal", function() { + + var code = [ + "/** Code is good */", + "var o = {", + "/** Desc*/", + "foo: () => {}", + "};" + ].join("\n"); + + function assertJSDoc(node) { + var jsdoc = eslint.getJSDocComment(node); + assert.equal(jsdoc.type, "Block"); + assert.equal(jsdoc.value, "* Desc"); + } + + var spy = sandbox.spy(assertJSDoc); + + eslint.on("ArrowFunctionExpression", spy); + eslint.verify(code, { ecmaFeatures: { arrowFunctions: true }, rules: {}}, filename, true); + assert.isTrue(spy.calledOnce, "Event handler should be called."); + }); + it("should get JSDoc comment for node when the node is a FunctionExpression in an assignment", function() { var code = [ diff --git a/tests/lib/rules/block-scoped-var.js b/tests/lib/rules/block-scoped-var.js index e012fb5c122..102d39982ae 100644 --- a/tests/lib/rules/block-scoped-var.js +++ b/tests/lib/rules/block-scoped-var.js @@ -31,6 +31,7 @@ eslintTester.addRuleTest("lib/rules/block-scoped-var", { "function f() { var hasOwnProperty; { hasOwnProperty; } }", "function f(){ a; b; var a, b; }", "function f(){ g(); function g(){} }", + { code: "var f = () => { var g = f; }", ecmaFeatures: { arrowFunctions: true } }, { code: "new Date", globals: {Date: false} }, { code: "new Date", globals: {} }, { code: "var eslint = require('eslint');", globals: {require: false} }, @@ -49,6 +50,7 @@ eslintTester.addRuleTest("lib/rules/block-scoped-var", { "a:;" ], invalid: [ + { code: "var f = () => { x; }", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: "\"x\" used outside of binding context.", type: "Identifier" }] }, { code: "function f(){ x; }", errors: [{ message: "\"x\" used outside of binding context.", type: "Identifier" }] }, { code: "function f(){ x; { var x; } }", errors: [{ message: "\"x\" used outside of binding context.", type: "Identifier" }] }, { code: "function f(){ { var x; } x; }", errors: [{ message: "\"x\" used outside of binding context.", type: "Identifier" }] }, diff --git a/tests/lib/rules/brace-style.js b/tests/lib/rules/brace-style.js index 8c3819b7087..497f148db93 100644 --- a/tests/lib/rules/brace-style.js +++ b/tests/lib/rules/brace-style.js @@ -60,9 +60,11 @@ eslintTester.addRuleTest("lib/rules/brace-style", { { code: "if (a && b && c) { }", args: ["2", "1tbs", { allowSingleLine: true }] }, { code: "switch(0) {}", args: ["2", "1tbs", { allowSingleLine: true }] }, { code: "if (foo) {}\nelse {}", args: ["2", "stroustrup", { allowSingleLine: true }] }, - { code: "try { bar(); }\ncatch (e) { baz(); }", args: ["2", "stroustrup", { allowSingleLine: true }] } + { code: "try { bar(); }\ncatch (e) { baz(); }", args: ["2", "stroustrup", { allowSingleLine: true }] }, + { code: "var foo = () => { return; }", ecmaFeatures: { arrowFunctions: true }, args: ["2", "stroustrup", { allowSingleLine: true }] } ], invalid: [ + { code: "var foo = () => { return; }", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: BODY_MESSAGE, type: "ReturnStatement"}] }, { code: "function foo() { return; }", errors: [{ message: BODY_MESSAGE, type: "ReturnStatement"}] }, { code: "function foo() \n { \n return; }", errors: [{ message: OPEN_MESSAGE, type: "FunctionDeclaration"}] }, { code: "!function foo() \n { \n return; }", errors: [{ message: OPEN_MESSAGE, type: "FunctionExpression"}] }, diff --git a/tests/lib/rules/comma-spacing.js b/tests/lib/rules/comma-spacing.js index ae097dd94b3..9d2f5ec2b4c 100644 --- a/tests/lib/rules/comma-spacing.js +++ b/tests/lib/rules/comma-spacing.js @@ -28,6 +28,8 @@ eslintTester.addRuleTest("lib/rules/comma-spacing", { "var obj = {'foo':'bar', 'baz':\n'qur'};", "var obj = {'foo':\n'bar', 'baz':\n'qur'};", "function foo(a, b){}", + { code: "var foo = (a, b) => {}", ecmaFeatures: { arrowFunctions: true } }, + { code: "var foo = a => a + 2", ecmaFeatures: { arrowFunctions: true } }, "a, b", "var a = (1 + 2, 2);", "a(b, c)", @@ -264,6 +266,21 @@ eslintTester.addRuleTest("lib/rules/comma-spacing", { type: "Identifier" } ] + }, + { + code: "var foo = (a,b) => {}", + ecmaFeatures: { arrowFunctions: true }, + args: [2, {before: true, after: true}], + errors: [ + { + message: "A space is required before ','.", + type: "Identifier" + }, + { + message: "A space is required after ','.", + type: "Identifier" + } + ] } ] }); diff --git a/tests/lib/rules/complexity.js b/tests/lib/rules/complexity.js index e8d08bc4d53..48dc2ff5cab 100644 --- a/tests/lib/rules/complexity.js +++ b/tests/lib/rules/complexity.js @@ -37,11 +37,13 @@ eslintTester.addRuleTest("lib/rules/complexity", { { code: "function a(x) {switch(x){case 1: 1; break; case 2: 2; break; default: if(x == 'foo') {5;};}}", args: [1, 4] }, { code: "function a(x) {while(true) {'foo';}}", args: [1, 2] }, { code: "function a(x) {do {'foo';} while (true)}", args: [1, 2] }, - { code: "if (foo) { bar(); }", args: [1, 3] } + { code: "if (foo) { bar(); }", args: [1, 3] }, + { code: "var a = (x) => {do {'foo';} while (true)}", args: [1, 2], ecmaFeatures: { arrowFunctions: true } } ], invalid: [ { code: "function a(x) {}", args: [1, 0], errors: 1 }, + { code: "var a = (x) => {if (true) {return x;}}", args: [1, 1], settings: {ecmascript: 6 }, errors: 1 }, { code: "function a(x) {if (true) {return x;}}", args: [1, 1], errors: 1 }, { code: "function a(x) {if (true) {return x;} else {return x+1;}}", args: [1, 1], errors: 1 }, { code: "function a(x) {if (true) {return x;} else if (false) {return x+1;} else {return 4;}}", args: [1, 2], errors: 1 }, diff --git a/tests/lib/rules/consistent-return.js b/tests/lib/rules/consistent-return.js index 30cc3875a20..ec621ad139d 100644 --- a/tests/lib/rules/consistent-return.js +++ b/tests/lib/rules/consistent-return.js @@ -26,7 +26,8 @@ eslintTester.addRuleTest("lib/rules/consistent-return", { "f(function() { if (true) return; else return; })", "f(function() { if (true) return true; else return false; })", "function foo() { function bar() { return true; } return; }", - "function foo() { function bar() { return; } return false; }" + "function foo() { function bar() { return; } return false; }", + { code: "var x = () => { return {}; };", ecmaFeatures: { arrowFunctions: true } } ], invalid: [ @@ -39,6 +40,16 @@ eslintTester.addRuleTest("lib/rules/consistent-return", { } ] }, + { + code: "var foo = () => { if (true) return true; else return; }", + ecmaFeatures: { arrowFunctions: true }, + errors: [ + { + message: "Expected a return value.", + type: "ReturnStatement" + } + ] + }, { code: "function foo() { if (true) return; else return false; }", errors: [ @@ -65,6 +76,16 @@ eslintTester.addRuleTest("lib/rules/consistent-return", { type: "ReturnStatement" } ] + }, + { + code: "f(a => { if (true) return; else return false; })", + ecmaFeatures: { arrowFunctions: true }, + errors: [ + { + message: "Expected no return value.", + type: "ReturnStatement" + } + ] } ] }); diff --git a/tests/lib/rules/func-names.js b/tests/lib/rules/func-names.js index 65f23d8b759..864c66994e3 100644 --- a/tests/lib/rules/func-names.js +++ b/tests/lib/rules/func-names.js @@ -22,6 +22,7 @@ var eslintTester = new ESLintTester(eslint); eslintTester.addRuleTest("lib/rules/func-names", { valid: [ "Foo.prototype.bar = function bar(){};", + { code: "Foo.prototype.bar = () => {}", ecmaFeatures: { arrowFunctions: true }}, "function foo(){}", "function test(d, e, f) {}", "new function bar(){}", diff --git a/tests/lib/rules/func-style.js b/tests/lib/rules/func-style.js index 6c794823879..97f626519b2 100644 --- a/tests/lib/rules/func-style.js +++ b/tests/lib/rules/func-style.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for func-style rule. * @author Nicholas C. Zakas + * @copyright 2013 Nicholas C. Zakas. All rights reserved. */ "use strict"; @@ -50,6 +51,11 @@ eslintTester.addRuleTest("lib/rules/func-style", { { code: "var foo = function(){};\n var bar = function(){};", args: [1, "expression"] + }, + { + code: "var foo = () => {};\n var bar = () => {}", + args: [1, "expression"], + ecmaFeatures: { arrowFunctions: true } } ], @@ -64,6 +70,17 @@ eslintTester.addRuleTest("lib/rules/func-style", { } ] }, + { + code: "var foo = () => {};", + args: [1, "declaration"], + ecmaFeatures: { arrowFunctions: true }, + errors: [ + { + message: "Expected a function declaration.", + type: "VariableDeclarator" + } + ] + }, { code: "function foo(){}", args: [1, "expression"], diff --git a/tests/lib/rules/handle-callback-err.js b/tests/lib/rules/handle-callback-err.js index 2c2fb644790..a444e141338 100644 --- a/tests/lib/rules/handle-callback-err.js +++ b/tests/lib/rules/handle-callback-err.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for missing-err rule. * @author Jamund Ferguson + * @copyright 2014 Jamund Ferguson. All rights reserved. */ "use strict"; @@ -41,6 +42,7 @@ eslintTester.addRuleTest("lib/rules/handle-callback-err", { "function help() { function userHandler(err) {function tester() { err; process.nextTick(function() { err; }); } } }", "function help(done) { var err = new Error('error'); done(); }", { code: "var test = function(error) {if(error){/* do nothing */}};", args: [2, "error"] }, + { code: "var test = (error) => {if(error){/* do nothing */}};", args: [2, "error"], ecmaFeatures: { arrowFunctions: true } }, { code: "var test = function(error) {if(! error){doSomethingHere();}};", args: [2, "error"] }, { code: "var test = function(err) { console.log(err); };", args: [2, "^(err|error)$"] }, { code: "var test = function(error) { console.log(error); };", args: [2, "^(err|error)$"] }, @@ -54,6 +56,7 @@ eslintTester.addRuleTest("lib/rules/handle-callback-err", { { code: "function test(err) {errorLookingWord();}", errors: [expectedFunctionDeclarationError] }, { code: "function test(err) {try{} catch(err) {}}", errors: [expectedFunctionDeclarationError] }, { code: "function test(err, callback) { foo(function(err, callback) {}); }", errors: [expectedFunctionDeclarationError, expectedFunctionExpressionError]}, + { code: "var test = (err) => {};", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: expectedErrorMessage, type: "ArrowFunctionExpression" }] }, { code: "var test = function(err) {};", errors: [expectedFunctionExpressionError] }, { code: "var test = function test(err, data) {};", errors: [expectedFunctionExpressionError] }, { code: "var test = function test(err) {/* if(err){} */};", errors: [expectedFunctionExpressionError] }, diff --git a/tests/lib/rules/max-depth.js b/tests/lib/rules/max-depth.js index 0d8dd2a812f..cd546f7321f 100644 --- a/tests/lib/rules/max-depth.js +++ b/tests/lib/rules/max-depth.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for max-depth. * @author Ian Christian Myers + * @copyright 2013 Ian Christian Myers. All rights reserved. */ "use strict"; @@ -20,12 +21,15 @@ var eslintTester = new ESLintTester(eslint); eslintTester.addRuleTest("lib/rules/max-depth", { valid: [ { code: "function foo() { if (true) { if (false) { if (true) { } } } }", args: [1, 3] }, + { code: "var foo = () => { if (true) { if (false) { if (true) { } } } }", args: [1, 3], ecmaFeatures: { arrowFunctions: true } }, "function foo() { if (true) { if (false) { if (true) { } } } }" ], invalid: [ { code: "function foo() { if (true) { if (false) { if (true) { } } } }", args: [1, 2], errors: [{ message: "Blocks are nested too deeply (3).", type: "IfStatement"}] }, + { code: "var foo = () => { if (true) { if (false) { if (true) { } } } }", args: [1, 2], ecmaFeatures: { arrowFunctions: true }, errors: [{ message: "Blocks are nested too deeply (3).", type: "IfStatement"}] }, { code: "function foo() { if (true) {} else { for(;;) {} } }", args: [1, 1], errors: [{ message: "Blocks are nested too deeply (2).", type: "ForStatement"}] }, { code: "function foo() { while (true) { if (true) {} } }", args: [1, 1], errors: [{ message: "Blocks are nested too deeply (2).", type: "IfStatement"}] }, + { code: "function foo() { for (let x of foo) { if (true) {} } }", args: [1, 1], ecmaFeatures: { blockBindings: true, forOf: true }, errors: [{ message: "Blocks are nested too deeply (2).", type: "IfStatement"}] }, { code: "function foo() { while (true) { if (true) { if (false) { } } } }", args: [1, 1], errors: [{ message: "Blocks are nested too deeply (2).", type: "IfStatement"}, { message: "Blocks are nested too deeply (3).", type: "IfStatement"}] } ] }); diff --git a/tests/lib/rules/max-nested-callbacks.js b/tests/lib/rules/max-nested-callbacks.js index 3deaf390757..5066ad612c0 100644 --- a/tests/lib/rules/max-nested-callbacks.js +++ b/tests/lib/rules/max-nested-callbacks.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for max-nested-callbacks rule. * @author Ian Christian Myers + * @copyright 2013 Ian Christian Myers. All rights reserved. */ "use strict"; @@ -21,10 +22,31 @@ eslintTester.addRuleTest("lib/rules/max-nested-callbacks", { valid: [ { code: "foo(function () { bar(thing, function (data) {}); });", args: [1, 3] }, { code: "var foo = function () {}; bar(function(){ baz(function() { qux(foo); }) });", args: [1, 2] }, - { code: "fn(function(){}, function(){}, function(){});", args: [1, 2] } + { code: "fn(function(){}, function(){}, function(){});", args: [1, 2] }, + { code: "fn(() => {}, function(){}, function(){});", args: [1, 2], ecmaFeatures: { arrowFunctions: true } } ], invalid: [ - { code: "foo(function () { bar(thing, function (data) { baz(function () {}); }); });", args: [1, 2], errors: [{ message: "Too many nested callbacks (3). Maximum allowed is 2.", type: "FunctionExpression"}] }, - { code: "foo(function () { if (isTrue) { bar(function (data) { baz(function () {}); }); } });", args: [1, 2], errors: [{ message: "Too many nested callbacks (3). Maximum allowed is 2.", type: "FunctionExpression"}] } + { + code: "foo(function () { bar(thing, function (data) { baz(function () {}); }); });", + args: [1, 2], + errors: [{ message: "Too many nested callbacks (3). Maximum allowed is 2.", type: "FunctionExpression"}] + }, + { + code: "foo(function () { bar(thing, (data) => { baz(function () {}); }); });", + args: [1, 2], + ecmaFeatures: { arrowFunctions: true }, + errors: [{ message: "Too many nested callbacks (3). Maximum allowed is 2.", type: "FunctionExpression"}] + }, + { + code: "foo(() => { bar(thing, (data) => { baz( () => {}); }); });", + args: [1, 2], + ecmaFeatures: { arrowFunctions: true }, + errors: [{ message: "Too many nested callbacks (3). Maximum allowed is 2.", type: "ArrowFunctionExpression"}] + }, + { + code: "foo(function () { if (isTrue) { bar(function (data) { baz(function () {}); }); } });", + args: [1, 2], + errors: [{ message: "Too many nested callbacks (3). Maximum allowed is 2.", type: "FunctionExpression"}] + } ] }); diff --git a/tests/lib/rules/max-params.js b/tests/lib/rules/max-params.js index 1ab7cdf28b1..b49fdb74ee7 100644 --- a/tests/lib/rules/max-params.js +++ b/tests/lib/rules/max-params.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for max-params rule. * @author Ilya Volodin + * @copyright 2013 Ilya Volodin. All rights reserved. */ "use strict"; @@ -21,12 +22,14 @@ eslintTester.addRuleTest("lib/rules/max-params", { valid: [ "function test(d, e, f) {}", { code: "var test = function(a, b, c) {};", args: [1, 3] }, + { code: "var test = (a, b, c) => {};", args: [1, 3], ecmaFeatures: { arrowFunctions: true } }, { code: "var test = function test(a, b, c) {};", args: [1, 3] } ], invalid: [ { code: "function test(a, b, c) {}", args: [1, 2], errors: [{ message: "This function has too many parameters (3). Maximum allowed is 2.", type: "FunctionDeclaration"}] }, { code: "function test(a, b, c, d) {}", errors: [{ message: "This function has too many parameters (4). Maximum allowed is 3.", type: "FunctionDeclaration"}] }, { code: "var test = function(a, b, c, d) {};", args: [1, 3], errors: [{ message: "This function has too many parameters (4). Maximum allowed is 3.", type: "FunctionExpression"}] }, + { code: "var test = (a, b, c, d) => {};", args: [1, 3], ecmaFeatures: { arrowFunctions: true }, errors: [{ message: "This function has too many parameters (4). Maximum allowed is 3.", type: "ArrowFunctionExpression"}] }, { code: "(function(a, b, c, d) {});", args: [1, 3], errors: [{ message: "This function has too many parameters (4). Maximum allowed is 3.", type: "FunctionExpression"}] }, { code: "var test = function test(a, b, c) {};", args: [1, 1], errors: [{ message: "This function has too many parameters (3). Maximum allowed is 1.", type: "FunctionExpression"}] } ] diff --git a/tests/lib/rules/max-statements.js b/tests/lib/rules/max-statements.js index 727785d4ce9..6d5cf7b4c5f 100644 --- a/tests/lib/rules/max-statements.js +++ b/tests/lib/rules/max-statements.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for max-statements rule. * @author Ian Christian Myers + * @copyright 2013 Ian Christian Myers. All rights reserved. */ "use strict"; @@ -20,6 +21,7 @@ var eslintTester = new ESLintTester(eslint); eslintTester.addRuleTest("lib/rules/max-statements", { valid: [ { code: "var foo = { thing: function() { var bar = 1; var baz = 2; } }", args: [1, 2] }, + { code: "var foo = { thing: () => { var bar = 1; var baz = 2; } }", args: [1, 2], ecmaFeatures: { arrowFunctions: true } }, { code: "function foo() { var bar = 1; function qux () { var noCount = 2; } return 3; }", args: [1, 3] }, { code: "function foo() { var bar = 1; if (true) { for (;;) { var qux = null; } } else { quxx(); } return 3; }", args: [1, 6]}, { code: "function foo() { var x = 5; function bar() { var y = 6; } bar(); z = 10; baz(); }", args: [1, 5]}, @@ -27,6 +29,7 @@ eslintTester.addRuleTest("lib/rules/max-statements", { ], invalid: [ { code: "function foo() { var bar = 1; var baz = 2; var qux = 3; }", args: [1, 2], errors: [{ message: "This function has too many statements (3). Maximum allowed is 2."}] }, + { code: "var foo = () => { var bar = 1; var baz = 2; var qux = 3; };", args: [1, 2], ecmaFeatures: { arrowFunctions: true }, errors: [{ message: "This function has too many statements (3). Maximum allowed is 2."}] }, { code: "var foo = function() { var bar = 1; var baz = 2; var qux = 3; };", args: [1, 2], errors: [{ message: "This function has too many statements (3). Maximum allowed is 2."}] }, { code: "function foo() { var bar = 1; if (true) { while (false) { var qux = null; } } return 3; }", args: [1, 4], errors: [{ message: "This function has too many statements (5). Maximum allowed is 4."}] }, { code: "function foo() { var bar = 1; if (true) { for (;;) { var qux = null; } } return 3; }", args: [1, 4], errors: [{ message: "This function has too many statements (5). Maximum allowed is 4."}] }, diff --git a/tests/lib/rules/no-constant-condition.js b/tests/lib/rules/no-constant-condition.js index cb160b9b3f4..d5ab7678476 100644 --- a/tests/lib/rules/no-constant-condition.js +++ b/tests/lib/rules/no-constant-condition.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for no-constant-condition rule. * @author Christian Schulz + * @copyright 2014 Christian Schulz. All rights reserved. */ "use strict"; @@ -46,6 +47,7 @@ eslintTester.addRuleTest("lib/rules/no-constant-condition", { { code: "while([]);", errors: [{ message: "Unexpected constant condition.", type: "WhileStatement"}] }, { code: "while(~!0);", errors: [{ message: "Unexpected constant condition.", type: "WhileStatement"}] }, { code: "while(x = 1);", errors: [{ message: "Unexpected constant condition.", type: "WhileStatement"}] }, - { code: "while(function(){});", errors: [{ message: "Unexpected constant condition.", type: "WhileStatement"}] } + { code: "while(function(){});", errors: [{ message: "Unexpected constant condition.", type: "WhileStatement"}] }, + { code: "while(() => {});", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: "Unexpected constant condition.", type: "WhileStatement"}] } ] }); diff --git a/tests/lib/rules/no-empty.js b/tests/lib/rules/no-empty.js index 43a305d99b3..c0a611295b9 100644 --- a/tests/lib/rules/no-empty.js +++ b/tests/lib/rules/no-empty.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for no-empty rule. * @author Nicholas C. Zakas + * @copyright Nicholas C. Zakas. All rights reserved. */ "use strict"; @@ -25,6 +26,7 @@ eslintTester.addRuleTest("lib/rules/no-empty", { "try { foo() } catch (ex) { foo() }", "switch(foo) {case 'foo': break;}", "(function() { }())", + { code: "var foo = () => {};", ecmaFeatures: { arrowFunctions: true } }, "function foo() { }", "try { foo() } catch (ex) {}", "try { foo() } finally {}" diff --git a/tests/lib/rules/no-extra-bind.js b/tests/lib/rules/no-extra-bind.js index be59e0afd15..a4d2d8ab8a5 100644 --- a/tests/lib/rules/no-extra-bind.js +++ b/tests/lib/rules/no-extra-bind.js @@ -23,10 +23,12 @@ eslintTester.addRuleTest("lib/rules/no-extra-bind", { "var a = function() { this.b }()", "var a = function() { this.b }.foo()", "var a = f.bind(a)", - "var a = function() { return this.b }.bind(c)" + "var a = function() { return this.b }.bind(c)", + { code: "var a = (() => { return b }).bind(c, d)", ecmaFeatures: { arrowFunctions: true } } ], invalid: [ { code: "var a = function() { return 1; }.bind(b)", errors: [{ message: "The function binding is unnecessary.", type: "CallExpression"}] }, + { code: "var a = (() => { return 1; }).bind(b)", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: "The function binding is unnecessary.", type: "CallExpression"}] }, { code: "var a = function() { (function(){ this.c }) }.bind(b)", errors: [{ message: "The function binding is unnecessary.", type: "CallExpression"}] }, { code: "var a = function() { function c(){ this.d } }.bind(b)", errors: [{ message: "The function binding is unnecessary.", type: "CallExpression"}] } ] diff --git a/tests/lib/rules/no-extra-parens.js b/tests/lib/rules/no-extra-parens.js index 2727dfc2600..b60356578f4 100644 --- a/tests/lib/rules/no-extra-parens.js +++ b/tests/lib/rules/no-extra-parens.js @@ -1,6 +1,7 @@ /** * @fileoverview Disallow parenthesesisng higher precedence subexpressions. * @author Michael Ficarra + * @copyright 2014 Michael Ficarra. All rights reserved. */ "use strict"; @@ -88,6 +89,7 @@ eslintTester.addRuleTest("lib/rules/no-extra-parens", { "with(a){}", "switch(a){ case 0: break; }", "function a(){ return b; }", + { code: "var a = () => { return b; }", ecmaFeatures: { arrowFunctions: true } }, "throw a;", "while(a);", "do; while(a);", @@ -112,6 +114,7 @@ eslintTester.addRuleTest("lib/rules/no-extra-parens", { "function a(){ return (/^a$/).test('a'); }", // IIFE is allowed to have parens in any position (#655) + { code: "var foo = (function() { return bar(); }())", ecmaFeatures: { arrowFunctions: true } }, "var foo = (function() { return bar(); }())", "var o = { foo: (function() { return bar(); }()) };", "o.foo = (function(){ return bar(); }());", diff --git a/tests/lib/rules/no-extra-strict.js b/tests/lib/rules/no-extra-strict.js index 1b2d95766a7..34d3696bbc0 100644 --- a/tests/lib/rules/no-extra-strict.js +++ b/tests/lib/rules/no-extra-strict.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests no-extra-strict. * @author Ian Christian Myers + * @copyright 2014 Ian Christian Myers. All rights reserved. */ "use strict"; @@ -22,23 +23,42 @@ eslintTester.addRuleTest("lib/rules/no-extra-strict", { "function foo() { 'use strict'; f('use strict'); }", "function foo() { 'use strict'; { 'use strict'; } }", "a = function () { 'use strict'; return true; }", + { code: "a = () => { 'use strict'; return true; }", ecmaFeatures: { arrowFunctions: true } }, "a = function foo() { 'use strict'; return true; }", "this.a = function b() { 'use strict'; return 1; };" ], invalid: [ - { code: "\"use strict\"; function foo() { \"use strict\"; var bar = true; }", - errors: [{ message: "Unnecessary 'use strict'.", type: "Literal"}] }, - { code: "'use strict'; function foo() { 'use strict'; var bar = true; }", - errors: [{ message: "Unnecessary 'use strict'.", type: "Literal"}] }, - { code: "\"use strict\"; (function foo() { function bar () { \"use strict\"; } }());", - errors: [{ message: "Unnecessary 'use strict'.", type: "Literal"}] }, - { code: "'use strict'; (function foo() { function bar () { 'use strict'; } }());", - errors: [{ message: "Unnecessary 'use strict'.", type: "Literal"}] }, - { code: "(function foo() { 'use strict'; 'use strict'; }());", - errors: [{ message: "Multiple 'use strict' directives.", type: "Literal"}] }, - { code: "'use strict'; a = function foo() { 'use strict'; return true; }", + { + code: "\"use strict\"; function foo() { \"use strict\"; var bar = true; }", + errors: [{ message: "Unnecessary 'use strict'.", type: "Literal"}] + }, + { + code: "'use strict'; function foo() { 'use strict'; var bar = true; }", + errors: [{ message: "Unnecessary 'use strict'.", type: "Literal"}] + }, + { + code: "\"use strict\"; (function foo() { function bar () { \"use strict\"; } }());", + errors: [{ message: "Unnecessary 'use strict'.", type: "Literal"}] + }, + { + code: "'use strict'; (function foo() { function bar () { 'use strict'; } }());", + errors: [{ message: "Unnecessary 'use strict'.", type: "Literal"}] + }, + { + code: "(function foo() { 'use strict'; 'use strict'; }());", + errors: [{ message: "Multiple 'use strict' directives.", type: "Literal"}] + }, + { + code: "'use strict'; a = function foo() { 'use strict'; return true; }", errors: [{ message: "Unnecessary 'use strict'.", type: "Literal"}] } + // TODO: When escope supports ES6, uncomment this + // { + // code: "'use strict'; a = () => { 'use strict'; return true; };", + // ecmaFeatures: { arrowFunctions: true }, + // errors: [{ message: "Unnecessary 'use strict'.", type: "Literal"}] + // } + ] }); diff --git a/tests/lib/rules/no-func-assign.js b/tests/lib/rules/no-func-assign.js index bb946399fed..503c8f734d8 100644 --- a/tests/lib/rules/no-func-assign.js +++ b/tests/lib/rules/no-func-assign.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for no-func-assign. * @author Ian Christian Myers + * @copyright 2013 Ian Christian Myers. All rights reserved. */ "use strict"; @@ -22,6 +23,7 @@ eslintTester.addRuleTest("lib/rules/no-func-assign", { "function foo() { var foo = bar; }", "function foo(foo) { foo = bar; }", "function foo() { var foo; foo = bar; }", + { code: "var foo = () => {}; foo = bar;", ecmaFeatures: { arrowFunctions: true } }, "var foo = function() {}; foo = bar;", "var foo = function() { foo = bar; };" ], diff --git a/tests/lib/rules/no-inner-declarations.js b/tests/lib/rules/no-inner-declarations.js index aa360c45f21..3e489b8dbfa 100644 --- a/tests/lib/rules/no-inner-declarations.js +++ b/tests/lib/rules/no-inner-declarations.js @@ -1,6 +1,7 @@ /** - * @fileoverview Tests for declaration-position rule. + * @fileoverview Tests for no-inner-declarations rule. * @author Brandon Mills + * @copyright 2014 Brandon Mills. All rights reserved. */ "use strict"; @@ -27,6 +28,7 @@ eslintTester.addRuleTest("lib/rules/no-inner-declarations", { "if (test) { var fn = function expr() { }; }", "function decl() { var fn = function expr() { }; }", "function decl(arg) { var fn; if (arg) { fn = function() { }; } }", + { code: "function decl(arg) { var fn; if (arg) { fn = function expr() { }; } }", ecmaFeatures: { arrowFunctions: true } }, "function decl(arg) { var fn; if (arg) { fn = function expr() { }; } }", "if (test) { var foo; }", "function doSomething() { while (test) { var foo; } }", diff --git a/tests/lib/rules/no-loop-func.js b/tests/lib/rules/no-loop-func.js index a94b7902593..27a5be1a567 100644 --- a/tests/lib/rules/no-loop-func.js +++ b/tests/lib/rules/no-loop-func.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for no-loop-func rule. * @author Ilya Volodin + * @copyright 2013 Ilya Volodin. All rights reserved. */ "use strict"; @@ -25,6 +26,7 @@ eslintTester.addRuleTest("lib/rules/no-loop-func", { invalid: [ { code: "for (var i=0; i {}) }", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: "Don't make functions within a loop", type: "ArrowFunctionExpression"}] }, { code: "for (var i=0; i {}", + ecmaFeatures: { arrowFunctions: true }, + errors: [{ + message: "Multiple spaces found before 'b'.", + type: "Identifier" + }] + }, { code: "var a = 1", errors: [{ diff --git a/tests/lib/rules/no-shadow-restricted-names.js b/tests/lib/rules/no-shadow-restricted-names.js index d84c2994f5c..1f1b7173f0b 100644 --- a/tests/lib/rules/no-shadow-restricted-names.js +++ b/tests/lib/rules/no-shadow-restricted-names.js @@ -1,6 +1,7 @@ /** * @fileoverview Disallow shadowing of NaN, undefined, and Infinity (ES5 section 15.1.1) * @author Michael Ficarra + * @copyright 2013 Michael Ficarra. All rights reserved. */ "use strict"; @@ -70,6 +71,17 @@ eslintTester.addRuleTest("lib/rules/no-shadow-restricted-names", { { message: "Shadowing of global property \"eval\".", type: "Identifier"}, { message: "Shadowing of global property \"eval\".", type: "Identifier"} ] + }, + { code: "var eval = (eval) => { var eval; !function eval(eval) { try {} catch(eval) {} }; }", + ecmaFeatures: { arrowFunctions: true }, + errors: [ + { message: "Shadowing of global property \"eval\".", type: "Identifier"}, + { message: "Shadowing of global property \"eval\".", type: "Identifier"}, + { message: "Shadowing of global property \"eval\".", type: "Identifier"}, + { message: "Shadowing of global property \"eval\".", type: "Identifier"}, + { message: "Shadowing of global property \"eval\".", type: "Identifier"}, + { message: "Shadowing of global property \"eval\".", type: "Identifier"} + ] } ] }); diff --git a/tests/lib/rules/no-shadow.js b/tests/lib/rules/no-shadow.js index fdcf5a6cc63..1ee955cfdc2 100644 --- a/tests/lib/rules/no-shadow.js +++ b/tests/lib/rules/no-shadow.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for no-shadow rule. * @author Ilya Volodin + * @copyright 2013 Ilya Volodin. All rights reserved. */ "use strict"; diff --git a/tests/lib/rules/no-unused-expressions.js b/tests/lib/rules/no-unused-expressions.js index 5dc4ae0c84c..ddc33d43a76 100644 --- a/tests/lib/rules/no-unused-expressions.js +++ b/tests/lib/rules/no-unused-expressions.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for no-unused-expressions rule. - * @author Nicholas C. Zakas + * @author Michael Ficarra + * @copyright 2013 Michael Ficarra. All rights reserved. */ "use strict"; @@ -30,6 +31,7 @@ eslintTester.addRuleTest("lib/rules/no-unused-expressions", { "\"use strict\";", "\"directive one\"; \"directive two\"; f();", "function foo() {\"use strict\"; return true; }", + { code: "var foo = () => {\"use strict\"; return true; }", ecmaFeatures: { arrowFunctions: true } }, "function foo() {\"directive one\"; \"directive two\"; f(); }", "function foo() { var foo = \"use strict\"; return true; }", { @@ -50,6 +52,7 @@ eslintTester.addRuleTest("lib/rules/no-unused-expressions", { { code: "\"directive one\"; f(); \"directive two\";", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] }, { code: "function foo() {\"directive one\"; f(); \"directive two\"; }", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] }, { code: "if (0) { \"not a directive\"; f(); }", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] }, - { code: "function foo() { var foo = true; \"use strict\"; }", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] } + { code: "function foo() { var foo = true; \"use strict\"; }", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] }, + { code: "var foo = () => { var foo = true; \"use strict\"; }", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] } ] }); diff --git a/tests/lib/rules/no-use-before-define.js b/tests/lib/rules/no-use-before-define.js index b4f53af5e09..34ad8a72d67 100644 --- a/tests/lib/rules/no-use-before-define.js +++ b/tests/lib/rules/no-use-before-define.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for no-use-before-define rule. * @author Ilya Volodin + * @copyright 2013 Ilya Volodin. All rights reserved. */ "use strict"; diff --git a/tests/lib/rules/no-wrap-func.js b/tests/lib/rules/no-wrap-func.js index 002cc210294..ac81ae7f2d8 100644 --- a/tests/lib/rules/no-wrap-func.js +++ b/tests/lib/rules/no-wrap-func.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for no-wrap-func rule. * @author Ilya Volodin + * @copyright 2013 Ilya Volodin. All rights reserved. */ "use strict"; @@ -24,6 +25,7 @@ eslintTester.addRuleTest("lib/rules/no-wrap-func", { "new Object(function() {})" ], invalid: [ + { code: "(() => {});", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: "Wrapping non-IIFE function literals in parens is unnecessary.", type: "ArrowFunctionExpression"}] }, { code: "(function() {});", errors: [{ message: "Wrapping non-IIFE function literals in parens is unnecessary.", type: "FunctionExpression"}] }, { code: "var a = (function() {});", errors: [{ message: "Wrapping non-IIFE function literals in parens is unnecessary.", type: "FunctionExpression"}] } ] diff --git a/tests/lib/rules/one-var.js b/tests/lib/rules/one-var.js index 6409d9a61b4..ead1bb20425 100644 --- a/tests/lib/rules/one-var.js +++ b/tests/lib/rules/one-var.js @@ -1,6 +1,8 @@ /** * @fileoverview Tests for one-var. * @author Ian Christian Myers and Michael Paulukonis + * @copyright 2013 Ian Christian Myers. All rights reserved. + * @copyright 2013 Michael Paulukonis. All rights reserved. */ "use strict"; @@ -20,18 +22,64 @@ eslintTester.addRuleTest("lib/rules/one-var", { "var foo = function () { var bar = true; baz(); }" ], invalid: [ - { code: "function foo() { var bar = true; var baz = false; }", - errors: [{ message: "Combine this with the previous 'var' statement.", type: "VariableDeclaration"}] }, - { code: "function foo() { var bar = true; if (qux) { var baz = false; } else { var quxx = 42; } }", - errors: [ - { message: "Combine this with the previous 'var' statement.", type: "VariableDeclaration"}, - { message: "Combine this with the previous 'var' statement.", type: "VariableDeclaration"} - ] }, - { code: "var foo = function () { var bar = true; var baz = false; }", - errors: [{ message: "Combine this with the previous 'var' statement.", type: "VariableDeclaration"}] }, - { code: "var foo = function () { var bar = true; if (qux) { var baz = false; } }", - errors: [{ message: "Combine this with the previous 'var' statement.", type: "VariableDeclaration"}] }, - { code: "var foo; var bar;", - errors: [{ message: "Combine this with the previous 'var' statement.", type: "VariableDeclaration"}] } + { + code: "function foo() { var bar = true; var baz = false; }", + errors: [ + { + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration" + } + ] + }, + { + code: "function foo() { var bar = true; if (qux) { var baz = false; } else { var quxx = 42; } }", + errors: [ + { + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration" + }, + { + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration" + } + ] + }, + { + code: "var foo = function () { var bar = true; var baz = false; }", + errors: [ + { + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration" + } + ] + }, + { + code: "var foo = () => { var bar = true; var baz = false; }", + ecmaFeatures: { arrowFunctions: true }, + errors: [ + { + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration" + } + ] + }, + { + code: "var foo = function () { var bar = true; if (qux) { var baz = false; } }", + errors: [ + { + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration" + } + ] + }, + { + code: "var foo; var bar;", + errors: [ + { + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration" + } + ] + } ] }); diff --git a/tests/lib/rules/space-after-keywords.js b/tests/lib/rules/space-after-keywords.js index c354c50f444..f8763dceaae 100644 --- a/tests/lib/rules/space-after-keywords.js +++ b/tests/lib/rules/space-after-keywords.js @@ -1,6 +1,7 @@ /** * @fileoverview Rule to enforce the number of spaces after certain keywords * @author Nick Fisher + * @copyright 2014 Nick Fisher. All rights reserved. */ "use strict"; diff --git a/tests/lib/rules/strict.js b/tests/lib/rules/strict.js index 6d3dab0cd99..dbe451cd6f7 100644 --- a/tests/lib/rules/strict.js +++ b/tests/lib/rules/strict.js @@ -221,6 +221,11 @@ eslintTester.addRuleTest("lib/rules/strict", { { message: "Unnecessary \"use strict\" directive.", type: "ExpressionStatement" }, { message: "Multiple \"use strict\" directives.", type: "ExpressionStatement" } ] + }, + { + code: "var foo = () => { return; };", + ecmaFeatures: { arrowFunctions: true }, + errors: [{ message: "Missing \"use strict\" statement.", type: "ArrowFunctionExpression"}] } ] diff --git a/tests/lib/rules/valid-jsdoc.js b/tests/lib/rules/valid-jsdoc.js index bf4df7ac005..317dd123b58 100644 --- a/tests/lib/rules/valid-jsdoc.js +++ b/tests/lib/rules/valid-jsdoc.js @@ -1,6 +1,7 @@ /** * @fileoverview Validates JSDoc comments are syntactically correct * @author Nicholas C. Zakas + * @copyright 2014 Nicholas C. Zakas. All rights reserved. */ "use strict"; @@ -35,6 +36,11 @@ eslintTester.addRuleTest("lib/rules/valid-jsdoc", { code: "/**\n* Description\n* @return {void} */\nfunction foo(){}", args: [1, {}] }, + { + code: "/**\n* Description\n* @param {string} p bar\n*/\nFoo.bar = (p) => {};", + args: [1, {requireReturn: false}], + ecmaFeatures: { arrowFunctions: true } + }, { code: "/**\n* Description\n* @param {string} p bar\n*/\nFoo.bar = function(p){};", args: [1, {requireReturn: false}] @@ -99,6 +105,15 @@ eslintTester.addRuleTest("lib/rules/valid-jsdoc", { type: "Block" }] }, + { + code: "/** Foo \n@return {void} Foo\n */\nfoo.bar = () => {}", + args: [1, { prefer: { "return": "returns" }}], + ecmaFeatures: { arrowFunctions: true }, + errors: [{ + message: "Use @returns instead.", + type: "Block" + }] + }, { code: "/** Foo \n@param {void Foo\n */\nfunction foo(){}", errors: [{ diff --git a/tests/lib/rules/vars-on-top.js b/tests/lib/rules/vars-on-top.js index 5d81f4b5efb..415d9b057e6 100644 --- a/tests/lib/rules/vars-on-top.js +++ b/tests/lib/rules/vars-on-top.js @@ -356,6 +356,24 @@ eslintTester.addRuleTest("lib/rules/vars-on-top", { } ] }, + { + code: [ + "var foo = () => {", + " var first = [1,2,3];", + " var item;", + " for (item in first) {", + " var hello = item;", + " }", + "}" + ].join("\n"), + ecmaFeatures: { arrowFunctions: true }, + errors: [ + { + message: "All \"var\" declarations must be at the top of the function scope.", + type: "VariableDeclaration" + } + ] + }, { code: "'use strict'; 0; var x; f();", errors: [{message: "All \"var\" declarations must be at the top of the function scope.", type: "VariableDeclaration"}] diff --git a/tests/lib/rules/wrap-iife.js b/tests/lib/rules/wrap-iife.js index da264f116d3..cfbc0394f69 100644 --- a/tests/lib/rules/wrap-iife.js +++ b/tests/lib/rules/wrap-iife.js @@ -1,6 +1,7 @@ /** * @fileoverview Tests for wrap-iife rule. * @author Ilya Volodin + * @copyright 2013 Ilya Volodin. All rights reserved. */ "use strict";