diff options
Diffstat (limited to 'tests/checkers/unittest_non_ascii_name.py')
-rw-r--r-- | tests/checkers/unittest_non_ascii_name.py | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/tests/checkers/unittest_non_ascii_name.py b/tests/checkers/unittest_non_ascii_name.py new file mode 100644 index 000000000..d0e3a85ab --- /dev/null +++ b/tests/checkers/unittest_non_ascii_name.py @@ -0,0 +1,279 @@ +import sys +from typing import Iterable, Optional + +import astroid +import pytest +from astroid import nodes + +import pylint.checkers.non_ascii_names +import pylint.interfaces +import pylint.testutils + + +class TestNonAsciiChecker(pylint.testutils.CheckerTestCase): + CHECKER_CLASS = pylint.checkers.non_ascii_names.NonAsciiNameChecker + checker: pylint.checkers.non_ascii_names.NonAsciiNameChecker + + @pytest.mark.skipif( + sys.version_info < (3, 8), reason="requires python3.8 or higher" + ) + def test_kwargs_and_position_only(self): + """Even the new position only and keyword only should be found""" + node = astroid.extract_node( + """ + def name( + ok, + not_økay, + not_okay_defaułt=None, + /, + p_or_kw_okay=None, + p_or_kw_not_økay=None, + *, + kw_arg_okay, + kw_arg_not_økay, + ): + ... + """ + ) + assert isinstance(node, nodes.FunctionDef) + arguments = node.args + + posargs = list(arguments.posonlyargs) + args = list(arguments.args) + kwargs = list(arguments.kwonlyargs) + + with self.assertAddsMessages( + pylint.testutils.MessageTest( + msg_id="non-ascii-name", + node=posargs[1], + args=("Argument", "not_økay"), + confidence=pylint.interfaces.HIGH, + ), + pylint.testutils.MessageTest( + msg_id="non-ascii-name", + node=posargs[2], + args=("Argument", "not_okay_defaułt"), + confidence=pylint.interfaces.HIGH, + ), + pylint.testutils.MessageTest( + msg_id="non-ascii-name", + node=args[1], + args=("Argument", "p_or_kw_not_økay"), + confidence=pylint.interfaces.HIGH, + ), + pylint.testutils.MessageTest( + msg_id="non-ascii-name", + node=kwargs[1], + args=("Argument", "kw_arg_not_økay"), + confidence=pylint.interfaces.HIGH, + ), + ignore_position=True, + ): + self.checker.visit_functiondef(node) + + @pytest.mark.parametrize( + "code, assign_type", + [ + pytest.param( + """ + try: + ... + except ValueError as łol: #@ + ... + """, + "Variable", + id="try-except", + ), + pytest.param( + """ + class FooBar: + łol = "test" #@ + """, + "Attribute", + id="class_attribute", + ), + pytest.param( + """ + łol = "test" #@ + """, + "Variable", + id="global_assign", + ), + pytest.param( + """ + def foobar(): + łol="test" #@ + """, + "Variable", + id="function_variable", + ), + pytest.param( + """ + for łol in os.listdir("."): #@ + ... + """, + "Variable", + id="for_loop_variable", + ), + pytest.param( + """ + [łoł + for łol in os.listdir(".") #@ + ] + """, + "Variable", + id="inline_for_loop_variable", + ), + ], + ) + def test_assignname( + self, + code: str, + assign_type: str, + ): + """Variables defined no matter where, should be checked for non ascii""" + assign_node = astroid.extract_node(code) + + if not isinstance(assign_node, nodes.AssignName): + # For some elements we can't directly extract the assign + # node, so we have to manually look in the children for it + for child in assign_node.get_children(): + if isinstance(child, nodes.AssignName): + assign_node = child + break + + # Just to make sure we found the correct node + assert isinstance(assign_node, nodes.AssignName) + + with self.assertAddsMessages( + pylint.testutils.MessageTest( + msg_id="non-ascii-name", + node=assign_node, + args=(assign_type, "łol"), + confidence=pylint.interfaces.HIGH, + ), + ignore_position=True, + ): + self.checker.visit_assignname(assign_node) + + @pytest.mark.parametrize( + "import_statement, wrong_name", + [ + pytest.param("import fürimma", "fürimma", id="bad_single_main_module"), + pytest.param( + "import fürimma as okay", + None, + id="bad_single_main_module_with_okay_alias", + ), + pytest.param( + "import fürimma, pathlib", + "fürimma", + id="bad_single_main_module_with_stdlib_import", + ), + pytest.param( + "import pathlib, os, foobar, fürimma", + "fürimma", + id="stdlib_with_bad_single_main_module", + ), + pytest.param( + "import pathlib, os, foobar, sys as systëm", + "systëm", + id="stdlib_with_bad_alias", + ), + pytest.param( + "import fürimma as okay, pathlib", + None, + id="bad_single_main_module_with_okay_alias_with_stdlib_import", + ), + pytest.param( + "import fürimma.submodule", "fürimma.submodule", id="bad_main_module" + ), + pytest.param( + "import fürimma.submodule as submodule", + None, + id="bad_main_module_with_okay_alias", + ), + pytest.param( + "import main_module.fürimma", "main_module.fürimma", id="bad_submodule" + ), + pytest.param( + "import main_module.fürimma as okay", + None, + id="bad_submodule_with_okay_alias", + ), + pytest.param( + "import main_module.fürimma as not_økay", + "not_økay", + id="bad_submodule_with_bad_alias", + ), + pytest.param( + "from foo.bar import function", None, id="from_okay_module_import_okay" + ), + pytest.param( + "from foo.bär import function", None, id="from_bad_module_import_okay" + ), + pytest.param( + "from foo.bar import functiøn", + "functiøn", + id="from_okay_module_import_bad", + ), + pytest.param( + "from foo.bar import functiøn as function", + None, + id="from_okay_module_import_bad_as_good", + ), + pytest.param( + "from foo.bär import functiøn as function", + None, + id="from_bad_module_import_bad_as_good", + ), + pytest.param( + "from foo.bar import functiøn as føl", + "føl", + id="from_okay_module_import_bad_as_bad", + ), + pytest.param( + "from foo.bar import functiøn as good, bäd", + "bäd", + id="from_okay_module_import_bad_as_good_and_bad", + ), + pytest.param( + "from foo.bar import functiøn as good, bäd", + "bäd", + id="from_okay_module_import_bad_as_good_and_bad", + ), + pytest.param( + "from foo.bar import functiøn as good, *", + # We still have functiøn within our namespace and could detect this + # But to do this properly we would need to check all `*` imports + # -> Too much effort! + "functiøn", + id="from_okay_module_import_bad_as_good_and_star", + marks=pytest.mark.xfail( + reason="We don't know what is imported when using star" + ), + ), + ], + ) + def test_check_import(self, import_statement: str, wrong_name: Optional[str]): + """We expect that for everything that user can change there is a message""" + node = astroid.extract_node(f"{import_statement} #@") + + expected_msgs: Iterable[pylint.testutils.MessageTest] = tuple() + + if wrong_name: + expected_msgs = ( + pylint.testutils.MessageTest( + msg_id="non-ascii-module-import", + node=node, + args=("Module", wrong_name), + confidence=pylint.interfaces.HIGH, + ), + ) + with self.assertAddsMessages(*expected_msgs, ignore_position=True): + if import_statement.startswith("from"): + assert isinstance(node, nodes.ImportFrom) + self.checker.visit_importfrom(node) + else: + assert isinstance(node, nodes.Import) + self.checker.visit_import(node) |