diff --git a/lib/rules/no-lone-blocks.js b/lib/rules/no-lone-blocks.js index 48296bf79c8..95a5b334c60 100644 --- a/lib/rules/no-lone-blocks.js +++ b/lib/rules/no-lone-blocks.js @@ -32,26 +32,22 @@ module.exports = { * @returns {void} */ function report(node) { - const parent = context.getAncestors().pop(); + const message = node.parent.type === "BlockStatement" ? "Nested block is redundant." : "Block is redundant."; - context.report({ node, message: parent.type === "Program" - ? "Block is redundant." - : "Nested block is redundant." - }); + context.report({ node, message }); } /** - * Checks for any ocurrence of BlockStatement > BlockStatement or Program > BlockStatement - * @returns {boolean} True if the current node is a lone block. + * Checks for any ocurrence of a BlockStatement in a place where lists of statements can appear + * @param {ASTNode} node The node to check + * @returns {boolean} True if the node is a lone block. */ - function isLoneBlock() { - const parent = context.getAncestors().pop(); - - /* - * Note: astUtils.STATEMENT_LIST_PARENTS is not used here because blocks in SwitchCases are not checked. - * https://github.com/eslint/eslint/issues/8047 - */ - return parent.type === "BlockStatement" || parent.type === "Program"; + function isLoneBlock(node) { + return node.parent.type === "BlockStatement" || + node.parent.type === "Program" || + + // Don't report blocks in switch cases if the block is the only statement of the case. + node.parent.type === "SwitchCase" && !(node.parent.consequent[0] === node && node.parent.consequent.length === 1); } /** diff --git a/tests/lib/rules/no-lone-blocks.js b/tests/lib/rules/no-lone-blocks.js index a3a0a4ab1e2..8205ba7d4d1 100644 --- a/tests/lib/rules/no-lone-blocks.js +++ b/tests/lib/rules/no-lone-blocks.js @@ -31,7 +31,32 @@ ruleTester.run("no-lone-blocks", rule, { { code: "{ function bar() {} }", parserOptions: { ecmaVersion: 6, ecmaFeatures: { impliedStrict: true } } }, { code: "{ class Bar {} }", parserOptions: { ecmaVersion: 6 } }, - { code: "{ {let y = 1;} let x = 1; }", parserOptions: { ecmaVersion: 6 } } + { code: "{ {let y = 1;} let x = 1; }", parserOptions: { ecmaVersion: 6 } }, + ` + switch (foo) { + case bar: { + baz; + } + } + `, + ` + switch (foo) { + case bar: { + baz; + } + case qux: { + boop; + } + } + `, + ` + switch (foo) { + case bar: + { + baz; + } + } + ` ], invalid: [ { code: "{}", errors: [{ message: "Block is redundant.", type: "BlockStatement" }] }, @@ -69,6 +94,30 @@ ruleTester.run("no-lone-blocks", rule, { { message: "Nested block is redundant.", type: "BlockStatement", line: 2 }, { message: "Block is redundant.", type: "BlockStatement", line: 4 } ] + }, + { + code: ` + switch (foo) { + case 1: + foo(); + { + bar; + } + } + `, + errors: [{ message: "Block is redundant.", type: "BlockStatement", line: 5 }] + }, + { + code: ` + switch (foo) { + case 1: + { + bar; + } + foo(); + } + `, + errors: [{ message: "Block is redundant.", type: "BlockStatement", line: 4 }] } ] });