diff --git a/docs/rules/no-constant-condition.md b/docs/rules/no-constant-condition.md index 036bbb786b9..8de5e69f3f8 100644 --- a/docs/rules/no-constant-condition.md +++ b/docs/rules/no-constant-condition.md @@ -32,6 +32,14 @@ if (x &&= false) { doSomethingNever(); } +if (class {}) { + doSomethingAlways(); +} + +if (new Boolean(x)) { + doSomethingAlways(); +} + if (x ||= true) { doSomethingAlways(); } diff --git a/lib/rules/no-constant-condition.js b/lib/rules/no-constant-condition.js index 2c57d9fb3ab..0bcb31931e4 100644 --- a/lib/rules/no-constant-condition.js +++ b/lib/rules/no-constant-condition.js @@ -139,6 +139,7 @@ module.exports = { case "ArrowFunctionExpression": case "FunctionExpression": case "ObjectExpression": + case "ClassExpression": return true; case "TemplateLiteral": return (inBooleanPosition && node.quasis.some(quasi => quasi.value.cooked.length)) || @@ -180,7 +181,8 @@ module.exports = { isLeftShortCircuit || isRightShortCircuit; } - + case "NewExpression": + return inBooleanPosition; case "AssignmentExpression": if (node.operator === "=") { return isConstant(node.right, inBooleanPosition); diff --git a/tests/lib/rules/no-constant-condition.js b/tests/lib/rules/no-constant-condition.js index ecb6de53426..0b5f3c5a1dc 100644 --- a/tests/lib/rules/no-constant-condition.js +++ b/tests/lib/rules/no-constant-condition.js @@ -174,7 +174,8 @@ ruleTester.run("no-constant-condition", rule, { "function* foo() {for (; ; yield) {}}", "function* foo() {while (true) {function* foo() {yield;}yield;}}", "function* foo() { for (let x = yield; x < 10; x++) {yield;}yield;}", - "function* foo() { for (let x = yield; ; x++) { yield; }}" + "function* foo() { for (let x = yield; ; x++) { yield; }}", + "if (new Number(x) + 1 === 2) {}" ], invalid: [ { code: "for(;true;);", errors: [{ messageId: "unexpected", type: "Literal" }] }, @@ -387,6 +388,16 @@ ruleTester.run("no-constant-condition", rule, { { code: "if(0b1n);", parserOptions: { ecmaVersion: 11 }, errors: [{ messageId: "unexpected", type: "Literal" }] }, { code: "if(0o1n);", parserOptions: { ecmaVersion: 11 }, errors: [{ messageId: "unexpected", type: "Literal" }] }, { code: "if(0x1n);", parserOptions: { ecmaVersion: 11 }, errors: [{ messageId: "unexpected", type: "Literal" }] }, - { code: "if(0x1n || foo);", parserOptions: { ecmaVersion: 11 }, errors: [{ messageId: "unexpected", type: "LogicalExpression" }] } + { code: "if(0x1n || foo);", parserOptions: { ecmaVersion: 11 }, errors: [{ messageId: "unexpected", type: "LogicalExpression" }] }, + + // Classes and instances are always truthy + { code: "if(class {}) {}", errors: [{ messageId: "unexpected" }] }, + { code: "if(new Foo()) {}", errors: [{ messageId: "unexpected" }] }, + + // Boxed primitives are always truthy + { code: "if(new Boolean(foo)) {}", errors: [{ messageId: "unexpected" }] }, + { code: "if(new String(foo)) {}", errors: [{ messageId: "unexpected" }] }, + { code: "if(new Number(foo)) {}", errors: [{ messageId: "unexpected" }] } + ] });