# Copyright (c) 2021 Andreas Finkler # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html # For details: https://github.com/PyCQA/pylint/blob/master/LICENSE """Tests for the pylint checker in :mod:`pylint.extensions.confusing_elif """ import astroid from pylint.extensions.confusing_elif import ConfusingConsecutiveElifChecker from pylint.testutils import CheckerTestCase, Message MSG_ID_CONFUSING_CONSECUTIVE_ELIF = "confusing-consecutive-elif" class TestConfusingConsecutiveElifChecker(CheckerTestCase): """Tests for pylint.extensions.confusing_elif.ConfusingConsecutiveElifChecker""" CHECKER_CLASS = ConfusingConsecutiveElifChecker def test_triggered_if_if_block_ends_with_elif(self): """ Given an if-elif construct When the body of the if ends with an elif Then the message confusing-consecutive-elif must be triggered. """ example_code = """ def foo(a, b, c): if a > b: #@ if a > 0: return a elif a < 0: return 0 elif a > c: #@ return c """ if_node_to_test, elif_node = astroid.extract_node(example_code) with self.assertAddsMessages( Message(msg_id=MSG_ID_CONFUSING_CONSECUTIVE_ELIF, node=elif_node) ): self.checker.visit_if(if_node_to_test) def test_triggered_if_elif_block_ends_with_elif(self): """ Given an if-elif-elif construct When the body of the first elif ends with an elif Then the message confusing-consecutive-elif must be triggered. """ example_code = """ def foo(a, b, c): if a < b: return b elif a > b: #@ if a > 0: return a elif a < 0: return 0 elif a > c: #@ return c """ if_node_to_test, elif_node = astroid.extract_node(example_code) with self.assertAddsMessages( Message(msg_id=MSG_ID_CONFUSING_CONSECUTIVE_ELIF, node=elif_node) ): self.checker.visit_if(if_node_to_test) def test_triggered_if_block_ends_with_if(self): """ Given an if-elif construct When the body of the if ends with an if Then the message confusing-consecutive-elif must be triggered. """ example_code = """ def foo(a, b, c): if a > b: #@ if a > 0: return a elif a > c: #@ return c """ if_node_to_test, elif_node = astroid.extract_node(example_code) with self.assertAddsMessages( Message(msg_id=MSG_ID_CONFUSING_CONSECUTIVE_ELIF, node=elif_node) ): self.checker.visit_if(if_node_to_test) def test_not_triggered_if_indented_block_ends_with_else(self): """ Given an if-elif construct When the body of the if ends with an else Then no message shall be triggered. """ example_code = """ def foo(a, b, c): if a > b: #@ if a > 0: return a else: return 0 elif a > c: return c """ if_node_to_test = astroid.extract_node(example_code) with self.assertNoMessages(): self.checker.visit_if(if_node_to_test) def test_not_triggered_if_indentend_block_ends_with_call(self): """ Given an if-elif construct When the body of the if ends with a function call Then no message shall be triggered. Note: There is nothing special about the body ending with a function call. This is just taken as a representative value for the equivalence class of "every node class unrelated to if/elif/else". """ example_code = """ def foo(a, b, c): result = None if a > b: #@ if a > 0: result = a print("result is", result) elif a > c: result = c return result """ if_node_to_test = astroid.extract_node(example_code) with self.assertNoMessages(): self.checker.visit_if(if_node_to_test) def test_not_triggered_if_indented_block_ends_with_ifexp(self): """ Given an if-elif construct When the body of the if ends with an if expression Then no message shall be triggered. """ example_code = """ def foo(a, b, c): result = None if a > b: #@ if a > 0: result = a result = b if b > c else c elif a > c: result = c return result """ if_node_to_test = astroid.extract_node(example_code) with self.assertNoMessages(): self.checker.visit_if(if_node_to_test) def test_not_triggered_if_outer_block_does_not_have_elif(self): """ Given an if construct without an elif When the body of the if ends with an if Then no message shall be triggered. """ example_code = """ def foo(a, b, c): result = None if a > b: #@ if a > 0: result = a elif a < 0: result = 0 else: result = c return result """ if_node_to_test = astroid.extract_node(example_code) with self.assertNoMessages(): self.checker.visit_if(if_node_to_test) def test_not_triggered_if_outer_block_continues_with_if(self): """ Given an if construct which continues with a new if construct When the body of the first if ends with an if expression Then no message shall be triggered. """ example_code = """ def foo(a, b, c): result = None if a > b: #@ if a > 0: result = a elif a < 0: result = 0 if b > c: result = c return result """ if_node_to_test = astroid.extract_node(example_code) with self.assertNoMessages(): self.checker.visit_if(if_node_to_test)