From a7a883bd6ba4f140b60cbbb2be5b53d750f6c8db Mon Sep 17 00:00:00 2001 From: Angelo Annunziata Date: Fri, 17 Nov 2023 21:30:18 +0100 Subject: [PATCH] feat: for-direction rule add check for condition in reverse order (#17755) feat: add check to for-direction rule when the condition is in reverse order --- docs/src/rules/for-direction.md | 6 +++++ lib/rules/for-direction.js | 39 +++++++++++++++++++------------- tests/lib/rules/for-direction.js | 20 +++++++++++++++- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/docs/src/rules/for-direction.md b/docs/src/rules/for-direction.md index 45759eb48f9..aa09cb181e3 100644 --- a/docs/src/rules/for-direction.md +++ b/docs/src/rules/for-direction.md @@ -24,6 +24,9 @@ for (var i = 10; i >= 0; i++) { for (var i = 0; i > 10; i++) { } +for (var i = 0; 10 > i; i--) { +} + const n = -2; for (let i = 0; i < 10; i += n) { } @@ -40,6 +43,9 @@ Examples of **correct** code for this rule: for (var i = 0; i < 10; i++) { } +for (var i = 0; 10 > i; i++) { // with counter "i" on the right +} + for (let i = 10; i >= 0; i += this.step) { // direction unknown } diff --git a/lib/rules/for-direction.js b/lib/rules/for-direction.js index 3f2ad9df645..69198d11ad2 100644 --- a/lib/rules/for-direction.js +++ b/lib/rules/for-direction.js @@ -101,30 +101,37 @@ module.exports = { } return 0; } + return { ForStatement(node) { - if (node.test && node.test.type === "BinaryExpression" && node.test.left.type === "Identifier" && node.update) { - const counter = node.test.left.name; - const operator = node.test.operator; - const update = node.update; + if (node.test && node.test.type === "BinaryExpression" && node.update) { + for (const counterPosition of ["left", "right"]) { + if (node.test[counterPosition].type !== "Identifier") { + continue; + } - let wrongDirection; + const counter = node.test[counterPosition].name; + const operator = node.test.operator; + const update = node.update; - if (operator === "<" || operator === "<=") { - wrongDirection = -1; - } else if (operator === ">" || operator === ">=") { - wrongDirection = 1; - } else { - return; - } + let wrongDirection; + + if (operator === "<" || operator === "<=") { + wrongDirection = counterPosition === "left" ? -1 : 1; + } else if (operator === ">" || operator === ">=") { + wrongDirection = counterPosition === "left" ? 1 : -1; + } else { + return; + } - if (update.type === "UpdateExpression") { - if (getUpdateDirection(update, counter) === wrongDirection) { + if (update.type === "UpdateExpression") { + if (getUpdateDirection(update, counter) === wrongDirection) { + report(node); + } + } else if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) === wrongDirection) { report(node); } - } else if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) === wrongDirection) { - report(node); } } } diff --git a/tests/lib/rules/for-direction.js b/tests/lib/rules/for-direction.js index 6e59f6bacf4..630f89df54d 100644 --- a/tests/lib/rules/for-direction.js +++ b/tests/lib/rules/for-direction.js @@ -28,6 +28,12 @@ ruleTester.run("for-direction", rule, { "for(var i = 10; i > 0; i--){}", "for(var i = 10; i >= 0; i--){}", + // test if '++', '--' with counter 'i' on the right side of test condition + "for(var i = 0; 10 > i; i++){}", + "for(var i = 0; 10 >= i; i++){}", + "for(var i = 10; 0 < i; i--){}", + "for(var i = 10; 0 <= i; i--){}", + // test if '+=', '-=', "for(var i = 0; i < 10; i+=1){}", "for(var i = 0; i <= 10; i+=1){}", @@ -44,6 +50,9 @@ ruleTester.run("for-direction", rule, { "for(var i = 0; i < MAX; i -= ~2);", "for(var i = 0, n = -1; i < MAX; i += -n);", + // test if '+=', '-=' with counter 'i' on the right side of test condition + "for(var i = 0; 10 > i; i+=1){}", + // test if no update. "for(var i = 10; i > 0;){}", "for(var i = 10; i >= 0;){}", @@ -82,6 +91,12 @@ ruleTester.run("for-direction", rule, { { code: "for(var i = 10; i > 10; i++){}", errors: [incorrectDirection] }, { code: "for(var i = 10; i >= 0; i++){}", errors: [incorrectDirection] }, + // test if '++', '--' with counter 'i' on the right side of test condition + { code: "for(var i = 0; 10 > i; i--){}", errors: [incorrectDirection] }, + { code: "for(var i = 0; 10 >= i; i--){}", errors: [incorrectDirection] }, + { code: "for(var i = 10; 10 < i; i++){}", errors: [incorrectDirection] }, + { code: "for(var i = 10; 0 <= i; i++){}", errors: [incorrectDirection] }, + // test if '+=', '-=' { code: "for(var i = 0; i < 10; i-=1){}", errors: [incorrectDirection] }, { code: "for(var i = 0; i <= 10; i-=1){}", errors: [incorrectDirection] }, @@ -96,6 +111,9 @@ ruleTester.run("for-direction", rule, { { code: "for(var i = MIN; i <= MAX; i-=true){}", errors: [incorrectDirection] }, { code: "for(var i = 0; i < 10; i-=+5e-7){}", errors: [incorrectDirection] }, { code: "for(var i = 0; i < MAX; i += (2 - 3));", errors: [incorrectDirection] }, - { code: "var n = -2; for(var i = 0; i < 10; i += n);", errors: [incorrectDirection] } + { code: "var n = -2; for(var i = 0; i < 10; i += n);", errors: [incorrectDirection] }, + + // test if '+=', '-=' with counter 'i' on the right side of test condition + { code: "for(var i = 0; 10 > i; i-=1){}", errors: [incorrectDirection] } ] });