Permalink
Browse files

Fix: Avoid magic numbers in rule options (fixes #4182)

  • Loading branch information...
bsbeeks committed Feb 20, 2016
1 parent 44ee913 commit 6bc99325e8458214a98e98b813950204e82a95be
View
@@ -48,6 +48,18 @@ function a(x) {
}
```
Optionally, you may specify a `maximum` object property:
```json
"complexity": [2, 2]
```
is equivalent to
```json
"complexity": [2, {"maximum": 2}]
```
## When Not To Use It
If you can't determine an appropriate complexity limit for your code, then it's best to disable this rule.
View
@@ -24,6 +24,10 @@ The default depth above which this rule will warn is `4`. You can configure the
```json
"max-depth": [2, 10]
// or you can use an object property
"max-depth": [2, {"maximum": 10}]
```
The following patterns are considered problems:
@@ -24,6 +24,10 @@ The default max depth for this rule is 10. You can define the depth as an option
```json
"max-nested-callbacks": [2, 3]
// or you can use an object property
"max-nested-callbacks": [2, {"maximum": 3}]
```
The following patterns are considered problems:
View
@@ -32,6 +32,19 @@ function foo (bar, baz, qux) {
}
```
Optionally, you may specify a `maximum` object property:
```json
"max-params": [2, 2]
```
is equivalent to
```json
"max-params": [2, {"maximum": 2}]
```
## Related Rules
* [complexity](complexity.md)
@@ -20,6 +20,10 @@ There is an additional optional argument to ignore top level functions.
```json
"max-statements": [2, 10, {"ignoreTopLevelFunctions": true}]
// or you can use an object property to set the maximum
"max-statements": [2, {"maximum": 10}, {"ignoreTopLevelFunctions": true}]
```
The following patterns are considered problems:
View
@@ -11,8 +11,15 @@
//------------------------------------------------------------------------------
module.exports = function(context) {
var option = context.options[0],
THRESHOLD = 20;
var THRESHOLD = (typeof context.options[0] !== "undefined") ? context.options[0] : 20;
if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") {
THRESHOLD = option.maximum;
}
if (typeof option === "number") {
THRESHOLD = option;
}
//--------------------------------------------------------------------------
// Helpers
@@ -116,7 +123,21 @@ module.exports = function(context) {
module.exports.schema = [
{
"type": "integer",
"minimum": 0
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"maximum": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
}
]
}
];
View
@@ -17,7 +17,15 @@ module.exports = function(context) {
//--------------------------------------------------------------------------
var functionStack = [],
maxDepth = context.options[0] || 4;
option = context.options[0],
maxDepth = 4;
if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") {
maxDepth = option.maximum;
}
if (typeof option === "number") {
maxDepth = option;
}
/**
* When parsing a new function, store it in our function stack
@@ -105,7 +113,21 @@ module.exports = function(context) {
module.exports.schema = [
{
"type": "integer",
"minimum": 0
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"maximum": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
}
]
}
];
@@ -15,8 +15,15 @@ module.exports = function(context) {
//--------------------------------------------------------------------------
// Constants
//--------------------------------------------------------------------------
var option = context.options[0],
THRESHOLD = 10;
var THRESHOLD = context.options[0] || 10;
if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") {
THRESHOLD = option.maximum;
}
if (typeof option === "number") {
THRESHOLD = option;
}
//--------------------------------------------------------------------------
// Helpers
@@ -68,7 +75,21 @@ module.exports = function(context) {
module.exports.schema = [
{
"type": "integer",
"minimum": 0
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"maximum": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
}
]
}
];
View
@@ -13,7 +13,15 @@
module.exports = function(context) {
var numParams = context.options[0] || 3;
var option = context.options[0],
numParams = 3;
if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") {
numParams = option.maximum;
}
if (typeof option === "number") {
numParams = option;
}
/**
* Checks a function to see if it has too many parameters.
@@ -40,7 +48,21 @@ module.exports = function(context) {
module.exports.schema = [
{
"type": "integer",
"minimum": 0
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"maximum": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
}
]
}
];
@@ -17,10 +17,18 @@ module.exports = function(context) {
//--------------------------------------------------------------------------
var functionStack = [],
maxStatements = context.options[0] || 10,
option = context.options[0],
maxStatements = 10,
ignoreTopLevelFunctions = context.options[1] && context.options[1].ignoreTopLevelFunctions || false,
topLevelFunctions = [];
if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") {
maxStatements = option.maximum;
}
if (typeof option === "number") {
maxStatements = option;
}
/**
* Reports a node if it has too many statements
* @param {ASTNode} node node to evaluate
@@ -104,8 +112,22 @@ module.exports = function(context) {
module.exports.schema = [
{
"type": "integer",
"minimum": 0
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"maximum": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
}
]
},
{
"type": "object",
@@ -56,7 +56,10 @@ ruleTester.run("complexity", rule, {
{ code: "function a(x) {while(true) {'foo';}}", options: [2] },
{ code: "function a(x) {do {'foo';} while (true)}", options: [2] },
{ code: "if (foo) { bar(); }", options: [3] },
{ code: "var a = (x) => {do {'foo';} while (true)}", options: [2], parserOptions: { ecmaVersion: 6 } }
{ code: "var a = (x) => {do {'foo';} while (true)}", options: [2], parserOptions: { ecmaVersion: 6 } },
// object property options
{ code: "function b(x) {}", options: [{ "maximum": 1 }] }
],
invalid: [
{ code: "function a(x) {}", options: [0], errors: [{ message: "Function 'a' has a complexity of 1."}] },
@@ -86,6 +89,9 @@ ruleTester.run("complexity", rule, {
{
code: createComplexity(21),
errors: [{ message: "Function 'test' has a complexity of 21." }]
}
},
// object property options
{ code: "function a(x) {}", options: [{ "maximum": 0 }], errors: [{ message: "Function 'a' has a complexity of 1."}] }
]
});
@@ -23,7 +23,10 @@ ruleTester.run("max-depth", rule, {
{ code: "function foo() { if (true) { if (false) { if (true) { } } } }", options: [3] },
{ code: "function foo() { if (true) { } else if (false) { } else if (true) { } else if (false) {} }", options: [3] },
{ code: "var foo = () => { if (true) { if (false) { if (true) { } } } }", options: [3], parserOptions: { ecmaVersion: 6 } },
{ code: "function foo() { if (true) { if (false) { if (true) { } } } }" }
{ code: "function foo() { if (true) { if (false) { if (true) { } } } }" },
// object property options
{ code: "function foo() { if (true) { if (false) { if (true) { } } } }", options: [{ "maximum": 3 }] }
],
invalid: [
{ code: "function foo() { if (true) { if (false) { if (true) { } } } }", options: [2], errors: [{ message: "Blocks are nested too deeply (3).", type: "IfStatement"}] },
@@ -32,6 +35,9 @@ ruleTester.run("max-depth", rule, {
{ code: "function foo() { while (true) { if (true) {} } }", options: [1], errors: [{ message: "Blocks are nested too deeply (2).", type: "IfStatement"}] },
{ code: "function foo() { for (let x of foo) { if (true) {} } }", options: [1], parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Blocks are nested too deeply (2).", type: "IfStatement"}] },
{ code: "function foo() { while (true) { if (true) { if (false) { } } } }", options: [1], errors: [{ message: "Blocks are nested too deeply (2).", type: "IfStatement"}, { message: "Blocks are nested too deeply (3).", type: "IfStatement"}] },
{ code: "function foo() { if (true) { if (false) { if (true) { if (false) { if (true) { } } } } } }", errors: [{ message: "Blocks are nested too deeply (5).", type: "IfStatement"}] }
{ code: "function foo() { if (true) { if (false) { if (true) { if (false) { if (true) { } } } } } }", errors: [{ message: "Blocks are nested too deeply (5).", type: "IfStatement"}] },
// object property options
{ code: "function foo() { if (true) { if (false) { if (true) { } } } }", options: [{ "maximum": 2 }], errors: [{ message: "Blocks are nested too deeply (3).", type: "IfStatement"}] }
]
});
@@ -41,8 +41,10 @@ ruleTester.run("max-nested-callbacks", rule, {
{ code: "var foo = function() {}; bar(function(){ baz(function() { qux(foo); }) });", options: [2] },
{ code: "fn(function(){}, function(){}, function(){});", options: [2] },
{ code: "fn(() => {}, function(){}, function(){});", options: [2], parserOptions: { ecmaVersion: 6 } },
{ code: nestFunctions(10)}
{ code: nestFunctions(10)},
// object property options
{ code: "foo(function() { bar(thing, function(data) {}); });", options: [{ "maximum": 3 }] }
],
invalid: [
{
@@ -70,6 +72,13 @@ ruleTester.run("max-nested-callbacks", rule, {
{
code: nestFunctions(11),
errors: [{ message: "Too many nested callbacks (11). Maximum allowed is 10.", type: "FunctionExpression"}]
},
// object property options
{
code: "foo(function() { bar(thing, function(data) { baz(function() {}); }); });",
options: [{ "maximum": 2 }],
errors: [{ message: "Too many nested callbacks (3). Maximum allowed is 2.", type: "FunctionExpression"}]
}
]
});
@@ -23,14 +23,20 @@ ruleTester.run("max-params", rule, {
{ code: "function test(d, e, f) {}" },
{ code: "var test = function(a, b, c) {};", options: [3] },
{ code: "var test = (a, b, c) => {};", options: [3], parserOptions: { ecmaVersion: 6 } },
{ code: "var test = function test(a, b, c) {};", options: [3] }
{ code: "var test = function test(a, b, c) {};", options: [3] },
// object property options
{ code: "var test = function(a, b, c) {};", options: [{ "maximum": 3 }] }
],
invalid: [
{ code: "function test(a, b, c) {}", options: [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) {};", options: [3], errors: [{ message: "This function has too many parameters (4). Maximum allowed is 3.", type: "FunctionExpression"}] },
{ code: "var test = (a, b, c, d) => {};", options: [3], parserOptions: { ecmaVersion: 6 }, errors: [{ message: "This function has too many parameters (4). Maximum allowed is 3.", type: "ArrowFunctionExpression"}] },
{ code: "(function(a, b, c, d) {});", options: [3], errors: [{ message: "This function has too many parameters (4). Maximum allowed is 3.", type: "FunctionExpression"}] },
{ code: "var test = function test(a, b, c) {};", options: [1], errors: [{ message: "This function has too many parameters (3). Maximum allowed is 1.", type: "FunctionExpression"}] }
{ code: "var test = function test(a, b, c) {};", options: [1], errors: [{ message: "This function has too many parameters (3). Maximum allowed is 1.", type: "FunctionExpression"}] },
// object property options
{ code: "function test(a, b, c) {}", options: [{ "maximum": 2 }], errors: [{ message: "This function has too many parameters (3). Maximum allowed is 2.", type: "FunctionDeclaration"}] }
]
});
@@ -28,7 +28,10 @@ ruleTester.run("max-statements", rule, {
{ code: "function foo() { var a; var b; var c; var x; var y; var z; bar(); baz(); qux(); quxx(); }" },
{ code: "(function() { var bar = 1; return function () { return 42; }; })()", options: [1, {ignoreTopLevelFunctions: true}] },
{ code: "function foo() { var bar = 1; var baz = 2; }", options: [1, {ignoreTopLevelFunctions: true}] },
{ code: "define(['foo', 'qux'], function(foo, qux) { var bar = 1; var baz = 2; })", options: [1, {ignoreTopLevelFunctions: true}] }
{ code: "define(['foo', 'qux'], function(foo, qux) { var bar = 1; var baz = 2; })", options: [1, {ignoreTopLevelFunctions: true}] },
// object property options
{ code: "var foo = { thing: function() { var bar = 1; var baz = 2; } }", options: [{ "maximum": 2 }] }
],
invalid: [
{ code: "function foo() { var bar = 1; var baz = 2; var qux = 3; }", options: [2], errors: [{ message: "This function has too many statements (3). Maximum allowed is 2."}] },
@@ -42,6 +45,9 @@ ruleTester.run("max-statements", rule, {
{ code: ";(function() { var bar = 1; return function () { var z; return 42; }; })()", options: [1, {ignoreTopLevelFunctions: true}], errors: [{ message: "This function has too many statements (2). Maximum allowed is 1."}] },
{ code: ";(function() { var bar = 1; var baz = 2; })(); (function() { var bar = 1; var baz = 2; })()", options: [1, {ignoreTopLevelFunctions: true}], errors: [{ message: "This function has too many statements (2). Maximum allowed is 1."}, { message: "This function has too many statements (2). Maximum allowed is 1."}] },
{ code: "define(['foo', 'qux'], function(foo, qux) { var bar = 1; var baz = 2; return function () { var z; return 42; }; })", options: [1, {ignoreTopLevelFunctions: true}], errors: [{ message: "This function has too many statements (2). Maximum allowed is 1."}] },
{ code: "function foo() { var a; var b; var c; var x; var y; var z; bar(); baz(); qux(); quxx(); foo(); }", errors: [{ message: "This function has too many statements (11). Maximum allowed is 10."}] }
{ code: "function foo() { var a; var b; var c; var x; var y; var z; bar(); baz(); qux(); quxx(); foo(); }", errors: [{ message: "This function has too many statements (11). Maximum allowed is 10."}] },
// object property options
{ code: "function foo() { var bar = 1; var baz = 2; var qux = 3; }", options: [{ "maximum": 2 }], errors: [{ message: "This function has too many statements (3). Maximum allowed is 2."}] }
]
});

0 comments on commit 6bc9932

Please sign in to comment.