diff --git a/lib/rules/no-extra-boolean-cast.js b/lib/rules/no-extra-boolean-cast.js index d5ed4620ee8..4f911bf0168 100644 --- a/lib/rules/no-extra-boolean-cast.js +++ b/lib/rules/no-extra-boolean-cast.js @@ -35,6 +35,11 @@ module.exports = { enforceForLogicalOperands: { type: "boolean", default: false + }, + + enforceForInnerOperands: { + type: "boolean", + default: false } }, additionalProperties: false @@ -49,6 +54,9 @@ module.exports = { create(context) { const sourceCode = context.sourceCode; + const enforceForLogicalOperands = context.options[0]?.enforceForLogicalOperands === true; + const enforceForInnerOperands = context.options[0]?.enforceForInnerOperands === true; + // Node types which have a test which will coerce values to booleans. const BOOLEAN_NODE_TYPES = new Set([ @@ -79,9 +87,7 @@ module.exports = { */ function isLogicalContext(node) { return node.type === "LogicalExpression" && - (node.operator === "||" || node.operator === "&&") && - (context.options.length && context.options[0].enforceForLogicalOperands === true); - + (node.operator === "||" || node.operator === "&&"); } @@ -115,29 +121,48 @@ module.exports = { return isInFlaggedContext(node.parent); } - if (node.parent.type === "ConditionalExpression" && (node.parent.consequent === node || node.parent.alternate === node)) { - return isInFlaggedContext(node.parent); - } - /* - * Check last expression only in a sequence, i.e. if ((1, 2, Boolean(3))) {}, since - * the others don't affect the result of the expression. + * legacy behavior - enforceForLogicalOperands will only recurse on + * logical expressions, not on other contexts. + * enforceForInnerOperands will recurse on the rest. */ - if (node.parent.type === "SequenceExpression" && node.parent.expressions.at(-1) === node) { - return isInFlaggedContext(node.parent); - } - // Check the right hand side of a `??` operator. - if (node.parent.type === "LogicalExpression" && node.parent.operator === "??" && node.parent.right === node) { - return isInFlaggedContext(node.parent); + if (enforceForLogicalOperands || enforceForInnerOperands) { + if (isLogicalContext(node.parent)) { + return isInFlaggedContext(node.parent); + } + } - return isInBooleanContext(node) || - (isLogicalContext(node.parent) && + if (enforceForInnerOperands) { + if ( + node.parent.type === "ConditionalExpression" && + (node.parent.consequent === node || node.parent.alternate === node) + ) { + return isInFlaggedContext(node.parent); + } - // For nested logical statements - isInFlaggedContext(node.parent) - ); + /* + * Check last expression only in a sequence, i.e. if ((1, 2, Boolean(3))) {}, since + * the others don't affect the result of the expression. + */ + if ( + node.parent.type === "SequenceExpression" && + node.parent.expressions.at(-1) === node + ) { + return isInFlaggedContext(node.parent); + } + + // Check the right hand side of a `??` operator. + if ( + node.parent.type === "LogicalExpression" && node.parent.operator === "??" && + node.parent.right === node + ) { + return isInFlaggedContext(node.parent); + } + } + + return isInBooleanContext(node); } diff --git a/tests/lib/rules/no-extra-boolean-cast.js b/tests/lib/rules/no-extra-boolean-cast.js index c79e4e74bfd..d4b325b8005 100644 --- a/tests/lib/rules/no-extra-boolean-cast.js +++ b/tests/lib/rules/no-extra-boolean-cast.js @@ -112,7 +112,101 @@ ruleTester.run("no-extra-boolean-cast", rule, { code: "if (!!foo ?? bar) {}", options: [{ enforceForLogicalOperands: true }], languageOptions: { ecmaVersion: 2020 } - } + }, + { + code: "var foo = bar || !!baz", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "var foo = bar && !!baz", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "var foo = bar || (baz && !!bat)", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "function foo() { return (!!bar || baz); }", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "var foo = bar() ? (!!baz && bat) : (!!bat && qux)", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "for(!!(foo && bar);;) {}", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "for(;; !!(foo || bar)) {}", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "var foo = Boolean(bar) || baz;", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "var foo = bar || Boolean(baz);", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "var foo = Boolean(bar) || Boolean(baz);", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "function foo() { return (Boolean(bar) || baz); }", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "var foo = bar() ? Boolean(baz) || bat : Boolean(bat)", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "for(Boolean(foo) || bar;;) {}", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "for(;; Boolean(foo) || bar) {}", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "if (new Boolean(foo) || bar) {}", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "if (!!foo || bar) {}", + options: [{ enforceForInnerOperands: false }] + }, + { + code: "if ((!!foo || bar) === baz) {}", + options: [{ enforceForInnerOperands: true }] + }, + { + code: "if (!!foo ?? bar) {}", + options: [{ enforceForInnerOperands: true }], + languageOptions: { ecmaVersion: 2020 } + }, + + /* + * additional expressions should not be checked with option + * configurations other than `enforceForInnerOperands: true`. + */ + ...[ + "Boolean((1, 2, Boolean(3)))", + "Boolean(foo ? Boolean(bar) : Boolean(baz))", + "Boolean(foo ?? Boolean(bar))" + ].flatMap(code => + [ + { code }, + { + code, + options: [{ enforceForLogicalOperands: true }] + }, + { + code, + options: [{ enforceForLogicalOperands: false }] + } + ]) ], invalid: [ @@ -1381,112 +1475,786 @@ ruleTester.run("no-extra-boolean-cast", rule, { }] }, - // test parentheses in autofix - { - code: "Boolean(!!(a, b))", - output: "Boolean((a, b))", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] - }, + // In Logical context { - code: "Boolean(Boolean((a, b)))", - output: "Boolean((a, b))", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (!!foo || bar) {}", + output: "if (foo || bar) {}", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression", + column: 5, + endColumn: 10 + }] }, { - code: "Boolean((!!(a, b)))", - output: "Boolean((a, b))", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (!!foo && bar) {}", + output: "if (foo && bar) {}", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression", + column: 5, + endColumn: 10 + }] }, + { - code: "Boolean((Boolean((a, b))))", - output: "Boolean((a, b))", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if ((!!foo || bar) && bat) {}", + output: "if ((foo || bar) && bat) {}", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression", + column: 6, + endColumn: 11 + }] }, { - code: "Boolean(!(!(a, b)))", - output: "Boolean((a, b))", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (foo && !!bar) {}", + output: "if (foo && bar) {}", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression", + column: 12, + endColumn: 17 + }] }, { - code: "Boolean((!(!(a, b))))", - output: "Boolean((a, b))", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "do {} while (!!foo || bar)", + output: "do {} while (foo || bar)", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression", + column: 14 + }] }, { - code: "Boolean(!!(a = b))", - output: "Boolean(a = b)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "while (!!foo || bar) {}", + output: "while (foo || bar) {}", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression", + column: 8 + }] }, { - code: "Boolean((!!(a = b)))", - output: "Boolean((a = b))", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "!!foo && bat ? bar : baz", + output: "foo && bat ? bar : baz", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression", + column: 1 + }] }, { - code: "Boolean(Boolean(a = b))", - output: "Boolean(a = b)", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "for (; !!foo || bar;) {}", + output: "for (; foo || bar;) {}", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression", + column: 8 + }] }, { - code: "Boolean(Boolean((a += b)))", - output: "Boolean(a += b)", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "!!!foo || bar", + output: "!foo || bar", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression", + column: 2 + }] }, { - code: "Boolean(!!(a === b))", - output: "Boolean(a === b)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "Boolean(!!foo || bar)", + output: "Boolean(foo || bar)", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression", + column: 9 + }] }, { - code: "Boolean(!!((a !== b)))", - output: "Boolean(a !== b)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "new Boolean(!!foo || bar)", + output: "new Boolean(foo || bar)", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression", + column: 13 + }] }, { - code: "Boolean(!!a.b)", - output: "Boolean(a.b)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (Boolean(foo) || bar) {}", + output: "if (foo || bar) {}", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] }, { - code: "Boolean(Boolean((a)))", - output: "Boolean(a)", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "do {} while (Boolean(foo) || bar)", + output: "do {} while (foo || bar)", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] }, { - code: "Boolean((!!(a)))", - output: "Boolean((a))", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "while (Boolean(foo) || bar) {}", + output: "while (foo || bar) {}", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] }, - { - code: "new Boolean(!!(a, b))", - output: "new Boolean((a, b))", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "Boolean(foo) || bat ? bar : baz", + output: "foo || bat ? bar : baz", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] }, { - code: "new Boolean(Boolean((a, b)))", - output: "new Boolean((a, b))", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "for (; Boolean(foo) || bar;) {}", + output: "for (; foo || bar;) {}", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] }, { - code: "new Boolean((!!(a, b)))", - output: "new Boolean((a, b))", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "!Boolean(foo) || bar", + output: "!foo || bar", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] }, { - code: "new Boolean((Boolean((a, b))))", - output: "new Boolean((a, b))", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "!Boolean(foo && bar) || bat", + output: "!(foo && bar) || bat", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] }, { - code: "new Boolean(!(!(a, b)))", - output: "new Boolean((a, b))", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "!Boolean(foo + bar) || bat", + output: "!(foo + bar) || bat", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] }, { - code: "new Boolean((!(!(a, b))))", - output: "new Boolean((a, b))", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "!Boolean(+foo) || bar", + output: "!+foo || bar", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!Boolean(foo()) || bar", + output: "!foo() || bar", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!Boolean(foo() || bar)", + output: "!(foo() || bar)", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!Boolean(foo = bar) || bat", + output: "!(foo = bar) || bat", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!Boolean(...foo) || bar;", + output: null, + options: [{ enforceForInnerOperands: true }], + languageOptions: { ecmaVersion: 2015 }, + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!Boolean(foo, bar()) || bar;", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!Boolean((foo, bar()) || bat);", + output: "!((foo, bar()) || bat);", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!Boolean() || bar;", + output: "true || bar;", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!(Boolean()) || bar;", + output: "true || bar;", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "if (!Boolean() || bar) { foo() }", + output: "if (true || bar) { foo() }", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "while (!Boolean() || bar) { foo() }", + output: "while (true || bar) { foo() }", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "var foo = Boolean() || bar ? bar() : baz()", + output: "var foo = false || bar ? bar() : baz()", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "if (Boolean() || bar) { foo() }", + output: "if (false || bar) { foo() }", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "while (Boolean() || bar) { foo() }", + output: "while (false || bar) { foo() }", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + + + // Adjacent tokens tests + { + code: "function *foo() { yield(!!a || d) ? b : c }", + output: "function *foo() { yield(a || d) ? b : c }", + options: [{ enforceForInnerOperands: true }], + languageOptions: { ecmaVersion: 2015 }, + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression" + }] + }, + { + code: "function *foo() { yield(!! a || d) ? b : c }", + output: "function *foo() { yield(a || d) ? b : c }", + options: [{ enforceForInnerOperands: true }], + languageOptions: { ecmaVersion: 2015 }, + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression" + }] + }, + { + code: "function *foo() { yield(! !a || d) ? b : c }", + output: "function *foo() { yield(a || d) ? b : c }", + options: [{ enforceForInnerOperands: true }], + languageOptions: { ecmaVersion: 2015 }, + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression" + }] + }, + { + code: "function *foo() { yield (!!a || d) ? b : c }", + output: "function *foo() { yield (a || d) ? b : c }", + options: [{ enforceForInnerOperands: true }], + languageOptions: { ecmaVersion: 2015 }, + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression" + }] + }, + { + code: "function *foo() { yield/**/(!!a || d) ? b : c }", + output: "function *foo() { yield/**/(a || d) ? b : c }", + options: [{ enforceForInnerOperands: true }], + languageOptions: { ecmaVersion: 2015 }, + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression" + }] + }, + { + code: "x=!!a || d ? b : c ", + output: "x=a || d ? b : c ", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression" + }] + }, + { + code: "void(!Boolean() || bar)", + output: "void(true || bar)", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "void(! Boolean() || bar)", + output: "void(true || bar)", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "typeof(!Boolean() || bar)", + output: "typeof(true || bar)", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "(!Boolean() || bar)", + output: "(true || bar)", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "void/**/(!Boolean() || bar)", + output: "void/**/(true || bar)", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + + // Comments tests + { + code: "!/**/(!!foo || bar)", + output: "!/**/(foo || bar)", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression" + }] + }, + { + code: "!!/**/!foo || bar", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression" + }] + }, + { + code: "!!!/**/foo || bar", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression" + }] + }, + { + code: "!(!!foo || bar)/**/", + output: "!(foo || bar)/**/", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression" + }] + }, + { + code: "if(!/**/!foo || bar);", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression" + }] + }, + { + code: "(!!/**/foo || bar ? 1 : 2)", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression" + }] + }, + { + code: "!/**/(Boolean(foo) || bar)", + output: "!/**/(foo || bar)", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!Boolean/**/(foo) || bar", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!Boolean(/**/foo) || bar", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!Boolean(foo/**/) || bar", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!(Boolean(foo)|| bar)/**/", + output: "!(foo|| bar)/**/", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "if(Boolean/**/(foo) || bar);", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "(Boolean(foo/**/)|| bar ? 1 : 2)", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "/**/!Boolean()|| bar", + output: "/**/true|| bar", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!/**/Boolean()|| bar", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!Boolean/**/()|| bar", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "!Boolean(/**/)|| bar", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "(!Boolean()|| bar)/**/", + output: "(true|| bar)/**/", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "if(!/**/Boolean()|| bar);", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "(!Boolean(/**/) || bar ? 1 : 2)", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "if(/**/Boolean()|| bar);", + output: "if(/**/false|| bar);", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "if(Boolean/**/()|| bar);", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "if(Boolean(/**/)|| bar);", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "if(Boolean()|| bar/**/);", + output: "if(false|| bar/**/);", + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "(Boolean/**/()|| bar ? 1 : 2)", + output: null, + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedCall", + type: "CallExpression" + }] + }, + { + code: "if (a && !!(b ? c : d)){}", + output: "if (a && (b ? c : d)){}", + + options: [{ enforceForInnerOperands: true }], + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression", + column: 10, + endColumn: 23 + }] + }, + { + code: "function *foo() { yield!!a || d ? b : c }", + output: "function *foo() { yield a || d ? b : c }", + options: [{ enforceForInnerOperands: true }], + languageOptions: { ecmaVersion: 6 }, + errors: [{ + messageId: "unexpectedNegation", + type: "UnaryExpression", + column: 24, + endColumn: 27 + }] + }, + + // test parentheses in autofix + { + code: "Boolean(!!(a, b))", + output: "Boolean((a, b))", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean(Boolean((a, b)))", + output: "Boolean((a, b))", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "Boolean((!!(a, b)))", + output: "Boolean((a, b))", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean((Boolean((a, b))))", + output: "Boolean((a, b))", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "Boolean(!(!(a, b)))", + output: "Boolean((a, b))", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean((!(!(a, b))))", + output: "Boolean((a, b))", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean(!!(a = b))", + output: "Boolean(a = b)", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean((!!(a = b)))", + output: "Boolean((a = b))", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean(Boolean(a = b))", + output: "Boolean(a = b)", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "Boolean(Boolean((a += b)))", + output: "Boolean(a += b)", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "Boolean(!!(a === b))", + output: "Boolean(a === b)", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean(!!((a !== b)))", + output: "Boolean(a !== b)", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean(!!a.b)", + output: "Boolean(a.b)", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean(Boolean((a)))", + output: "Boolean(a)", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "Boolean((!!(a)))", + output: "Boolean((a))", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + + { + code: "new Boolean(!!(a, b))", + output: "new Boolean((a, b))", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "new Boolean(Boolean((a, b)))", + output: "new Boolean((a, b))", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "new Boolean((!!(a, b)))", + output: "new Boolean((a, b))", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "new Boolean((Boolean((a, b))))", + output: "new Boolean((a, b))", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "new Boolean(!(!(a, b)))", + output: "new Boolean((a, b))", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "new Boolean((!(!(a, b))))", + output: "new Boolean((a, b))", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] }, { code: "new Boolean(!!(a = b))", @@ -1844,289 +2612,621 @@ ruleTester.run("no-extra-boolean-cast", rule, { errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] }, { - code: "!!(a ? b : c) ? d : e", - output: "(a ? b : c) ? d : e", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "!!(a ? b : c) ? d : e", + output: "(a ? b : c) ? d : e", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean(a ? b : c) ? d : e", + output: "(a ? b : c) ? d : e", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!!(a || b) ? c : d", + output: "a || b ? c : d", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean(a && b) ? c : d", + output: "a && b ? c : d", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!!(a === b) ? c : d", + output: "a === b ? c : d", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean(a < b) ? c : d", + output: "a < b ? c : d", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!!((a !== b)) ? c : d", + output: "a !== b ? c : d", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean((a >= b)) ? c : d", + output: "a >= b ? c : d", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!!+a ? b : c", + output: "+a ? b : c", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "!!+(a) ? b : c", + output: "+(a) ? b : c", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean(!a) ? b : c", + output: "!a ? b : c", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!!f(a) ? b : c", + output: "f(a) ? b : c", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "(!!f(a)) ? b : c", + output: "(f(a)) ? b : c", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean(a.b) ? c : d", + output: "a.b ? c : d", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!!a ? b : c", + output: "a ? b : c", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "Boolean(a) ? b : c", + output: "a ? b : c", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!!!(a, b)", + output: "!(a, b)", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "!Boolean((a, b))", + output: "!(a, b)", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!!!(a = b)", + output: "!(a = b)", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "!!(!(a += b))", + output: "!(a += b)", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "!(!!(a += b))", + output: "!(a += b)", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "!Boolean(a -= b)", + output: "!(a -= b)", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!Boolean((a -= b))", + output: "!(a -= b)", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!(Boolean(a -= b))", + output: "!(a -= b)", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!!!(a || b)", + output: "!(a || b)", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "!Boolean(a || b)", + output: "!(a || b)", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!!!(a && b)", + output: "!(a && b)", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "!Boolean(a && b)", + output: "!(a && b)", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!!!(a != b)", + output: "!(a != b)", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "!!!(a === b)", + output: "!(a === b)", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "var x = !Boolean(a > b)", + output: "var x = !(a > b)", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!!!(a - b)", + output: "!(a - b)", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "!!!(a ** b)", + output: "!(a ** b)", + languageOptions: { ecmaVersion: 2016 }, + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "!Boolean(a ** b)", + output: "!(a ** b)", + languageOptions: { ecmaVersion: 2016 }, + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "async function f() { !!!(await a) }", + output: "async function f() { !await a }", + languageOptions: { ecmaVersion: 2017 }, + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + }, + { + code: "async function f() { !Boolean(await a) }", + output: "async function f() { !await a }", + languageOptions: { ecmaVersion: 2017 }, + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!!!!a", + output: "!!a", // Reports 2 errors. After the first fix, the second error will disappear. + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] + }, + { + code: "!!(!(!a))", + output: "!!a", // Reports 2 errors. After the first fix, the second error will disappear. + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] + }, + { + code: "!Boolean(!a)", + output: "!!a", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!Boolean((!a))", + output: "!!a", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + }, + { + code: "!Boolean(!(a))", + output: "!!(a)", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] }, { - code: "Boolean(a ? b : c) ? d : e", - output: "(a ? b : c) ? d : e", + code: "!(Boolean(!a))", + output: "!(!a)", errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] }, { - code: "!!(a || b) ? c : d", - output: "a || b ? c : d", + code: "!!!+a", + output: "!+a", errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] }, { - code: "Boolean(a && b) ? c : d", - output: "a && b ? c : d", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] - }, - { - code: "!!(a === b) ? c : d", - output: "a === b ? c : d", + code: "!!!(+a)", + output: "!+a", errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] }, { - code: "Boolean(a < b) ? c : d", - output: "a < b ? c : d", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "!!(!+a)", + output: "!+a", + errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] }, { - code: "!!((a !== b)) ? c : d", - output: "a !== b ? c : d", + code: "!(!!+a)", + output: "!(+a)", errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] }, { - code: "Boolean((a >= b)) ? c : d", - output: "a >= b ? c : d", + code: "!Boolean((-a))", + output: "!-a", errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] }, { - code: "!!+a ? b : c", - output: "+a ? b : c", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "!Boolean(-(a))", + output: "!-(a)", + errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] }, { - code: "!!+(a) ? b : c", - output: "+(a) ? b : c", + code: "!!!(--a)", + output: "!--a", errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] }, { - code: "Boolean(!a) ? b : c", - output: "!a ? b : c", + code: "!Boolean(a++)", + output: "!a++", errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] }, { - code: "!!f(a) ? b : c", - output: "f(a) ? b : c", + code: "!!!f(a)", + output: "!f(a)", errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] }, { - code: "(!!f(a)) ? b : c", - output: "(f(a)) ? b : c", + code: "!!!(f(a))", + output: "!f(a)", errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] }, { - code: "Boolean(a.b) ? c : d", - output: "a.b ? c : d", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] - }, - { - code: "!!a ? b : c", - output: "a ? b : c", + code: "!!!a", + output: "!a", errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] }, { - code: "Boolean(a) ? b : c", - output: "a ? b : c", + code: "!Boolean(a)", + output: "!a", errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] }, { - code: "!!!(a, b)", - output: "!(a, b)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (!!(a, b) || !!(c, d)) {}", + output: "if ((a, b) || (c, d)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!Boolean((a, b))", - output: "!(a, b)", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (Boolean((a, b)) || Boolean((c, d))) {}", + output: "if ((a, b) || (c, d)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedCall", type: "CallExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } + ] }, { - code: "!!!(a = b)", - output: "!(a = b)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if ((!!((a, b))) || (!!((c, d)))) {}", + output: "if ((a, b) || (c, d)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!!(!(a += b))", - output: "!(a += b)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (!!(a, b) && !!(c, d)) {}", + output: "if ((a, b) && (c, d)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!(!!(a += b))", - output: "!(a += b)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (Boolean((a, b)) && Boolean((c, d))) {}", + output: "if ((a, b) && (c, d)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedCall", type: "CallExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } + ] }, { - code: "!Boolean(a -= b)", - output: "!(a -= b)", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if ((!!((a, b))) && (!!((c, d)))) {}", + output: "if ((a, b) && (c, d)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!Boolean((a -= b))", - output: "!(a -= b)", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (!!(a = b) || !!(c = d)) {}", + output: "if ((a = b) || (c = d)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!(Boolean(a -= b))", - output: "!(a -= b)", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (Boolean(a /= b) || Boolean(c /= d)) {}", + output: "if ((a /= b) || (c /= d)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedCall", type: "CallExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } + ] }, { - code: "!!!(a || b)", - output: "!(a || b)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (!!(a >>= b) && !!(c >>= d)) {}", + output: "if ((a >>= b) && (c >>= d)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!Boolean(a || b)", - output: "!(a || b)", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (Boolean(a **= b) && Boolean(c **= d)) {}", + output: "if ((a **= b) && (c **= d)) {}", + options: [{ enforceForLogicalOperands: true }], + languageOptions: { ecmaVersion: 2016 }, + errors: [ + { messageId: "unexpectedCall", type: "CallExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } + ] }, { - code: "!!!(a && b)", - output: "!(a && b)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (!!(a ? b : c) || !!(d ? e : f)) {}", + output: "if ((a ? b : c) || (d ? e : f)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!Boolean(a && b)", - output: "!(a && b)", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (Boolean(a ? b : c) || Boolean(d ? e : f)) {}", + output: "if ((a ? b : c) || (d ? e : f)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedCall", type: "CallExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } + ] }, { - code: "!!!(a != b)", - output: "!(a != b)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (!!(a ? b : c) && !!(d ? e : f)) {}", + output: "if ((a ? b : c) && (d ? e : f)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!!!(a === b)", - output: "!(a === b)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (Boolean(a ? b : c) && Boolean(d ? e : f)) {}", + output: "if ((a ? b : c) && (d ? e : f)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedCall", type: "CallExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } + ] }, { - code: "var x = !Boolean(a > b)", - output: "var x = !(a > b)", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (!!(a || b) || !!(c || d)) {}", + output: "if (a || b || (c || d)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!!!(a - b)", - output: "!(a - b)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (Boolean(a || b) || Boolean(c || d)) {}", + output: "if (a || b || (c || d)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedCall", type: "CallExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } + ] }, { - code: "!!!(a ** b)", - output: "!(a ** b)", - languageOptions: { ecmaVersion: 2016 }, - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (!!(a || b) && !!(c || d)) {}", + output: "if ((a || b) && (c || d)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!Boolean(a ** b)", - output: "!(a ** b)", - languageOptions: { ecmaVersion: 2016 }, - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (Boolean(a || b) && Boolean(c || d)) {}", + output: "if ((a || b) && (c || d)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedCall", type: "CallExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } + ] }, { - code: "async function f() { !!!(await a) }", - output: "async function f() { !await a }", - languageOptions: { ecmaVersion: 2017 }, - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (!!(a && b) || !!(c && d)) {}", + output: "if (a && b || c && d) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "async function f() { !Boolean(await a) }", - output: "async function f() { !await a }", - languageOptions: { ecmaVersion: 2017 }, - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (Boolean(a && b) || Boolean(c && d)) {}", + output: "if (a && b || c && d) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedCall", type: "CallExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } + ] }, { - code: "!!!!a", - output: "!!a", // Reports 2 errors. After the first fix, the second error will disappear. + code: "if (!!(a && b) && !!(c && d)) {}", + output: "if (a && b && (c && d)) {}", + options: [{ enforceForLogicalOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } ] }, { - code: "!!(!(!a))", - output: "!!a", // Reports 2 errors. After the first fix, the second error will disappear. + code: "if (Boolean(a && b) && Boolean(c && d)) {}", + output: "if (a && b && (c && d)) {}", + options: [{ enforceForLogicalOperands: true }], errors: [ - { messageId: "unexpectedNegation", type: "UnaryExpression" }, - { messageId: "unexpectedNegation", type: "UnaryExpression" } + { messageId: "unexpectedCall", type: "CallExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } ] }, { - code: "!Boolean(!a)", - output: "!!a", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (!!(a !== b) || !!(c !== d)) {}", + output: "if (a !== b || c !== d) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!Boolean((!a))", - output: "!!a", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (Boolean(a != b) || Boolean(c != d)) {}", + output: "if (a != b || c != d) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedCall", type: "CallExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } + ] }, { - code: "!Boolean(!(a))", - output: "!!(a)", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (!!(a === b) && !!(c === d)) {}", + output: "if (a === b && c === d) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!(Boolean(!a))", - output: "!(!a)", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (!!(a > b) || !!(c < d)) {}", + output: "if (a > b || c < d) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!!!+a", - output: "!+a", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (Boolean(!a) || Boolean(+b)) {}", + output: "if (!a || +b) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedCall", type: "CallExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } + ] }, { - code: "!!!(+a)", - output: "!+a", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (!!f(a) && !!b.c) {}", + output: "if (f(a) && b.c) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!!(!+a)", - output: "!+a", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (Boolean(a) || !!b) {}", + output: "if (a || b) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedCall", type: "CallExpression" }, + { messageId: "unexpectedNegation", type: "UnaryExpression" } + ] }, { - code: "!(!!+a)", - output: "!(+a)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (!!a && Boolean(b)) {}", + output: "if (a && b) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } + ] }, { - code: "!Boolean((-a))", - output: "!-a", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if ((!!a) || (Boolean(b))) {}", + output: "if ((a) || (b)) {}", + options: [{ enforceForLogicalOperands: true }], + errors: [ + { messageId: "unexpectedNegation", type: "UnaryExpression" }, + { messageId: "unexpectedCall", type: "CallExpression" } + ] }, + { - code: "!Boolean(-(a))", - output: "!-(a)", + code: "if (Boolean(a ?? b) || c) {}", + output: "if ((a ?? b) || c) {}", + options: [{ enforceForLogicalOperands: true }], + languageOptions: { ecmaVersion: 2020 }, errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] }, + + // Optional chaining { - code: "!!!(--a)", - output: "!--a", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (Boolean?.(foo)) {};", + output: "if (foo) {};", + languageOptions: { ecmaVersion: 2020 }, + errors: [{ messageId: "unexpectedCall" }] }, { - code: "!Boolean(a++)", - output: "!a++", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if (Boolean?.(a ?? b) || c) {}", + output: "if ((a ?? b) || c) {}", + options: [{ enforceForLogicalOperands: true }], + languageOptions: { ecmaVersion: 2020 }, + errors: [{ messageId: "unexpectedCall" }] }, + + // https://github.com/eslint/eslint/issues/17173 { - code: "!!!f(a)", - output: "!f(a)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (!Boolean(a as any)) { }", + output: "if (!(a as any)) { }", + languageOptions: { + parser: require(parser("typescript-parsers/boolean-cast-with-assertion")), + ecmaVersion: 2020 + }, + errors: [{ messageId: "unexpectedCall" }] }, { - code: "!!!(f(a))", - output: "!f(a)", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if ((1, 2, Boolean(3))) {}", + output: "if ((1, 2, 3)) {}", + options: [{ enforceForInnerOperands: true }], + errors: [{ messageId: "unexpectedCall" }] }, { - code: "!!!a", - output: "!a", - errors: [{ messageId: "unexpectedNegation", type: "UnaryExpression" }] + code: "if (a ?? Boolean(b)) {}", + output: "if (a ?? b) {}", + options: [{ enforceForInnerOperands: true }], + errors: [{ messageId: "unexpectedCall" }] }, { - code: "!Boolean(a)", - output: "!a", - errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] + code: "if ((a, b, c ?? (d, e, f ?? Boolean(g)))) {}", + output: "if ((a, b, c ?? (d, e, f ?? g))) {}", + options: [{ enforceForInnerOperands: true }], + errors: [{ messageId: "unexpectedCall" }] }, { code: "if (!!(a, b) || !!(c, d)) {}", output: "if ((a, b) || (c, d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2135,7 +3235,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean((a, b)) || Boolean((c, d))) {}", output: "if ((a, b) || (c, d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedCall", type: "CallExpression" }, { messageId: "unexpectedCall", type: "CallExpression" } @@ -2144,7 +3244,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if ((!!((a, b))) || (!!((c, d)))) {}", output: "if ((a, b) || (c, d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2153,7 +3253,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!(a, b) && !!(c, d)) {}", output: "if ((a, b) && (c, d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2162,7 +3262,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean((a, b)) && Boolean((c, d))) {}", output: "if ((a, b) && (c, d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedCall", type: "CallExpression" }, { messageId: "unexpectedCall", type: "CallExpression" } @@ -2171,7 +3271,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if ((!!((a, b))) && (!!((c, d)))) {}", output: "if ((a, b) && (c, d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2180,7 +3280,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!(a = b) || !!(c = d)) {}", output: "if ((a = b) || (c = d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2189,7 +3289,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean(a /= b) || Boolean(c /= d)) {}", output: "if ((a /= b) || (c /= d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedCall", type: "CallExpression" }, { messageId: "unexpectedCall", type: "CallExpression" } @@ -2198,7 +3298,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!(a >>= b) && !!(c >>= d)) {}", output: "if ((a >>= b) && (c >>= d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2207,7 +3307,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean(a **= b) && Boolean(c **= d)) {}", output: "if ((a **= b) && (c **= d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], languageOptions: { ecmaVersion: 2016 }, errors: [ { messageId: "unexpectedCall", type: "CallExpression" }, @@ -2217,7 +3317,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!(a ? b : c) || !!(d ? e : f)) {}", output: "if ((a ? b : c) || (d ? e : f)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2226,7 +3326,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean(a ? b : c) || Boolean(d ? e : f)) {}", output: "if ((a ? b : c) || (d ? e : f)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedCall", type: "CallExpression" }, { messageId: "unexpectedCall", type: "CallExpression" } @@ -2235,7 +3335,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!(a ? b : c) && !!(d ? e : f)) {}", output: "if ((a ? b : c) && (d ? e : f)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2244,7 +3344,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean(a ? b : c) && Boolean(d ? e : f)) {}", output: "if ((a ? b : c) && (d ? e : f)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedCall", type: "CallExpression" }, { messageId: "unexpectedCall", type: "CallExpression" } @@ -2253,7 +3353,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!(a || b) || !!(c || d)) {}", output: "if (a || b || (c || d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2262,7 +3362,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean(a || b) || Boolean(c || d)) {}", output: "if (a || b || (c || d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedCall", type: "CallExpression" }, { messageId: "unexpectedCall", type: "CallExpression" } @@ -2271,7 +3371,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!(a || b) && !!(c || d)) {}", output: "if ((a || b) && (c || d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2280,7 +3380,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean(a || b) && Boolean(c || d)) {}", output: "if ((a || b) && (c || d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedCall", type: "CallExpression" }, { messageId: "unexpectedCall", type: "CallExpression" } @@ -2289,7 +3389,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!(a && b) || !!(c && d)) {}", output: "if (a && b || c && d) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2298,7 +3398,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean(a && b) || Boolean(c && d)) {}", output: "if (a && b || c && d) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedCall", type: "CallExpression" }, { messageId: "unexpectedCall", type: "CallExpression" } @@ -2307,7 +3407,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!(a && b) && !!(c && d)) {}", output: "if (a && b && (c && d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2316,7 +3416,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean(a && b) && Boolean(c && d)) {}", output: "if (a && b && (c && d)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedCall", type: "CallExpression" }, { messageId: "unexpectedCall", type: "CallExpression" } @@ -2325,7 +3425,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!(a !== b) || !!(c !== d)) {}", output: "if (a !== b || c !== d) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2334,7 +3434,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean(a != b) || Boolean(c != d)) {}", output: "if (a != b || c != d) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedCall", type: "CallExpression" }, { messageId: "unexpectedCall", type: "CallExpression" } @@ -2343,7 +3443,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!(a === b) && !!(c === d)) {}", output: "if (a === b && c === d) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2352,7 +3452,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!(a > b) || !!(c < d)) {}", output: "if (a > b || c < d) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2361,7 +3461,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean(!a) || Boolean(+b)) {}", output: "if (!a || +b) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedCall", type: "CallExpression" }, { messageId: "unexpectedCall", type: "CallExpression" } @@ -2370,7 +3470,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!f(a) && !!b.c) {}", output: "if (f(a) && b.c) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2379,7 +3479,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean(a) || !!b) {}", output: "if (a || b) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedCall", type: "CallExpression" }, { messageId: "unexpectedNegation", type: "UnaryExpression" } @@ -2388,7 +3488,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (!!a && Boolean(b)) {}", output: "if (a && b) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedCall", type: "CallExpression" } @@ -2397,7 +3497,7 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if ((!!a) || (Boolean(b))) {}", output: "if ((a) || (b)) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], errors: [ { messageId: "unexpectedNegation", type: "UnaryExpression" }, { messageId: "unexpectedCall", type: "CallExpression" } @@ -2407,88 +3507,45 @@ ruleTester.run("no-extra-boolean-cast", rule, { { code: "if (Boolean(a ?? b) || c) {}", output: "if ((a ?? b) || c) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], languageOptions: { ecmaVersion: 2020 }, errors: [{ messageId: "unexpectedCall", type: "CallExpression" }] }, - - // Optional chaining - { - code: "if (Boolean?.(foo)) ;", - output: "if (foo) ;", - languageOptions: { ecmaVersion: 2020 }, - errors: [{ messageId: "unexpectedCall" }] - }, { code: "if (Boolean?.(a ?? b) || c) {}", output: "if ((a ?? b) || c) {}", - options: [{ enforceForLogicalOperands: true }], + options: [{ enforceForInnerOperands: true }], languageOptions: { ecmaVersion: 2020 }, errors: [{ messageId: "unexpectedCall" }] }, - - // https://github.com/eslint/eslint/issues/17173 - { - code: "if (!Boolean(a as any)) { }", - output: "if (!(a as any)) { }", - languageOptions: { - parser: require(parser("typescript-parsers/boolean-cast-with-assertion")), - ecmaVersion: 2020 - }, - errors: [{ messageId: "unexpectedCall" }] - }, - { - code: "if ((1, 2, Boolean(3))) {}", - output: "if ((1, 2, 3)) {}", - errors: [{ messageId: "unexpectedCall" }] - }, - { - code: "if (a ?? Boolean(b)) {}", - output: "if (a ?? b) {}", - options: [{ enforceForLogicalOperands: true }], - errors: [{ messageId: "unexpectedCall" }] - }, - { - code: "if (a ?? Boolean(b)) {}", - output: "if (a ?? b) {}", - options: [{ enforceForLogicalOperands: false }], - errors: [{ messageId: "unexpectedCall" }] - }, - { - code: "if ((a, b, c ?? (d, e, f ?? Boolean(g)))) {}", - output: "if ((a, b, c ?? (d, e, f ?? g))) {}", - options: [{ enforceForLogicalOperands: false }], - errors: [{ messageId: "unexpectedCall" }] - }, - { - code: "if ((a, b, c ?? (d, e, f ?? Boolean(g)))) {}", - output: "if ((a, b, c ?? (d, e, f ?? g))) {}", - options: [{ enforceForLogicalOperands: true }], - errors: [{ messageId: "unexpectedCall" }] - }, { code: "if (a ? Boolean(b) : c) {}", output: "if (a ? b : c) {}", + options: [{ enforceForInnerOperands: true }], errors: [{ messageId: "unexpectedCall" }] }, { code: "if (a ? b : Boolean(c)) {}", output: "if (a ? b : c) {}", + options: [{ enforceForInnerOperands: true }], errors: [{ messageId: "unexpectedCall" }] }, { code: "if (a ? b : Boolean(c ? d : e)) {}", output: "if (a ? b : c ? d : e) {}", + options: [{ enforceForInnerOperands: true }], errors: [{ messageId: "unexpectedCall" }] }, { code: "const ternary = Boolean(bar ? !!baz : bat);", output: "const ternary = Boolean(bar ? baz : bat);", + options: [{ enforceForInnerOperands: true }], errors: [{ messageId: "unexpectedNegation" }] }, { code: "const commaOperator = Boolean((bar, baz, !!bat));", output: "const commaOperator = Boolean((bar, baz, bat));", + options: [{ enforceForInnerOperands: true }], errors: [{ messageId: "unexpectedNegation" }] }, { @@ -2500,16 +3557,19 @@ for (let i = 0; (console.log(i), Boolean(i < 10)); i++) { for (let i = 0; (console.log(i), i < 10); i++) { // ... }`, + options: [{ enforceForInnerOperands: true }], errors: [{ messageId: "unexpectedCall" }] }, { code: "const nullishCoalescingOperator = Boolean(bar ?? Boolean(baz));", output: "const nullishCoalescingOperator = Boolean(bar ?? baz);", + options: [{ enforceForInnerOperands: true }], errors: [{ messageId: "unexpectedCall" }] }, { code: "if (a ? Boolean(b = c) : Boolean(d = e));", output: "if (a ? b = c : d = e);", + options: [{ enforceForInnerOperands: true }], errors: [{ messageId: "unexpectedCall" }, { messageId: "unexpectedCall" }] } ]