diff options
author | Daniƫl van Noord <13665637+DanielNoord@users.noreply.github.com> | 2021-09-04 18:52:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-04 18:52:55 +0200 |
commit | 25000863761220c1aa5db129e3cd41f5fe51b167 (patch) | |
tree | d211e4464a8aef25f969adffe7ba7cb6df8b8981 /tests/pyreverse | |
parent | 6c818310fd0e2396b6333ad623da577bf84e361e (diff) | |
download | pylint-git-25000863761220c1aa5db129e3cd41f5fe51b167.tar.gz |
Add typing with `PyAnnotate` to `./tests` (#4950)
* Add mypy_extensions to requirement for ``NoReturn``
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
Diffstat (limited to 'tests/pyreverse')
-rw-r--r-- | tests/pyreverse/conftest.py | 12 | ||||
-rw-r--r-- | tests/pyreverse/test_diadefs.py | 39 | ||||
-rw-r--r-- | tests/pyreverse/test_inspector.py | 20 | ||||
-rw-r--r-- | tests/pyreverse/test_printer.py | 2 | ||||
-rw-r--r-- | tests/pyreverse/test_utils.py | 13 | ||||
-rw-r--r-- | tests/pyreverse/test_writer.py | 49 |
6 files changed, 83 insertions, 52 deletions
diff --git a/tests/pyreverse/conftest.py b/tests/pyreverse/conftest.py index 982980101..3a037840f 100644 --- a/tests/pyreverse/conftest.py +++ b/tests/pyreverse/conftest.py @@ -1,6 +1,7 @@ -from typing import Callable, Optional, Tuple +from typing import Callable, List, Optional, Tuple import pytest +from astroid.nodes.scoped_nodes import Module from pylint.pyreverse.inspector import Project, project_from_files @@ -14,7 +15,7 @@ class PyreverseConfig: # pylint: disable=too-many-instance-attributes, too-many def __init__( self, mode: str = "PUB_ONLY", - classes: Tuple = tuple(), + classes: Optional[List[str]] = None, show_ancestors: Optional[int] = None, all_ancestors: Optional[bool] = None, show_associated: Optional[int] = None, @@ -30,7 +31,10 @@ class PyreverseConfig: # pylint: disable=too-many-instance-attributes, too-many output_directory: str = "", ): self.mode = mode - self.classes = classes + if classes: + self.classes = classes + else: + self.classes = [] self.show_ancestors = show_ancestors self.all_ancestors = all_ancestors self.show_associated = show_associated @@ -86,7 +90,7 @@ def get_project() -> Callable: def _get_project(module: str, name: Optional[str] = "No Name") -> Project: """return an astroid project representation""" - def _astroid_wrapper(func, modname): + def _astroid_wrapper(func: Callable, modname: str) -> Module: return func(modname) return project_from_files([module], _astroid_wrapper, project_name=name) diff --git a/tests/pyreverse/test_diadefs.py b/tests/pyreverse/test_diadefs.py index 497e1eebe..3c2ab7fda 100644 --- a/tests/pyreverse/test_diadefs.py +++ b/tests/pyreverse/test_diadefs.py @@ -22,9 +22,11 @@ # pylint: disable=redefined-outer-name import sys from pathlib import Path +from typing import Callable, Dict, List, Tuple import pytest from astroid import nodes +from conftest import PyreverseConfig # type: ignore #pylint: disable=no-name-in-module from pylint.pyreverse.diadefslib import ( ClassDiadefGenerator, @@ -32,15 +34,18 @@ from pylint.pyreverse.diadefslib import ( DiaDefGenerator, DiadefsHandler, ) -from pylint.pyreverse.inspector import Linker +from pylint.pyreverse.diagrams import DiagramEntity, Relationship +from pylint.pyreverse.inspector import Linker, Project -def _process_classes(classes): +def _process_classes(classes: List[DiagramEntity]) -> List[Tuple[bool, str]]: """extract class names of a list""" return sorted((isinstance(c.node, nodes.ClassDef), c.title) for c in classes) -def _process_relations(relations): +def _process_relations( + relations: Dict[str, List[Relationship]] +) -> List[Tuple[str, str, str]]: """extract relation indices from a relation list""" result = [] for rel_type, rels in relations.items(): @@ -51,7 +56,7 @@ def _process_relations(relations): @pytest.fixture -def HANDLER(default_config): +def HANDLER(default_config: PyreverseConfig) -> DiadefsHandler: return DiadefsHandler(default_config) @@ -60,7 +65,9 @@ def PROJECT(get_project): return get_project("data") -def test_option_values(default_config, HANDLER, PROJECT): +def test_option_values( + default_config: PyreverseConfig, HANDLER: DiadefsHandler, PROJECT: Project +) -> None: """test for ancestor, associated and module options""" df_h = DiaDefGenerator(Linker(PROJECT), HANDLER) cl_config = default_config @@ -91,7 +98,7 @@ def test_option_values(default_config, HANDLER, PROJECT): assert not hndl.module_names -def test_default_values(): +def test_default_values() -> None: """test default values for package or class diagrams""" # TODO : should test difference between default values for package or class diagrams pylint: disable=fixme @@ -105,14 +112,18 @@ class TestDefaultDiadefGenerator: ("specialization", "Specialization", "Ancestor"), ] - def test_exctract_relations(self, HANDLER, PROJECT): + def test_exctract_relations( + self, HANDLER: DiadefsHandler, PROJECT: Project + ) -> None: """test extract_relations between classes""" cd = DefaultDiadefGenerator(Linker(PROJECT), HANDLER).visit(PROJECT)[1] cd.extract_relationships() relations = _process_relations(cd.relationships) assert relations == self._should_rels - def test_functional_relation_extraction(self, default_config, get_project): + def test_functional_relation_extraction( + self, default_config: PyreverseConfig, get_project: Callable + ) -> None: """functional test of relations extraction; different classes possibly in different modules""" # XXX should be catching pyreverse environnement problem but doesn't @@ -125,7 +136,7 @@ class TestDefaultDiadefGenerator: assert relations == self._should_rels -def test_known_values1(HANDLER, PROJECT): +def test_known_values1(HANDLER: DiadefsHandler, PROJECT: Project) -> None: dd = DefaultDiadefGenerator(Linker(PROJECT), HANDLER).visit(PROJECT) assert len(dd) == 2 keys = [d.TYPE for d in dd] @@ -152,7 +163,7 @@ def test_known_values1(HANDLER, PROJECT): ] -def test_known_values2(HANDLER, get_project): +def test_known_values2(HANDLER: DiadefsHandler, get_project: Callable) -> None: project = get_project("data.clientmodule_test") dd = DefaultDiadefGenerator(Linker(project), HANDLER).visit(project) assert len(dd) == 1 @@ -164,7 +175,7 @@ def test_known_values2(HANDLER, get_project): assert classes == [(True, "Ancestor"), (True, "Specialization")] -def test_known_values3(HANDLER, PROJECT): +def test_known_values3(HANDLER: DiadefsHandler, PROJECT: Project) -> None: HANDLER.config.classes = ["Specialization"] cdg = ClassDiadefGenerator(Linker(PROJECT), HANDLER) special = "data.clientmodule_test.Specialization" @@ -179,7 +190,7 @@ def test_known_values3(HANDLER, PROJECT): ] -def test_known_values4(HANDLER, PROJECT): +def test_known_values4(HANDLER: DiadefsHandler, PROJECT: Project) -> None: HANDLER.config.classes = ["Specialization"] HANDLER.config.module_names = False cd = ClassDiadefGenerator(Linker(PROJECT), HANDLER).class_diagram( @@ -196,7 +207,9 @@ def test_known_values4(HANDLER, PROJECT): @pytest.mark.skipif(sys.version_info < (3, 8), reason="Requires dataclasses") -def test_regression_dataclasses_inference(HANDLER, get_project): +def test_regression_dataclasses_inference( + HANDLER: DiadefsHandler, get_project: Callable +) -> None: project_path = Path("regrtest_data") / "dataclasses_pyreverse" path = get_project(str(project_path)) diff --git a/tests/pyreverse/test_inspector.py b/tests/pyreverse/test_inspector.py index 0c8873f97..014838564 100644 --- a/tests/pyreverse/test_inspector.py +++ b/tests/pyreverse/test_inspector.py @@ -17,23 +17,25 @@ # pylint: disable=redefined-outer-name import os +from typing import Callable import astroid import pytest from astroid import nodes from pylint.pyreverse import inspector +from pylint.pyreverse.inspector import Project @pytest.fixture -def project(get_project): +def project(get_project: Callable) -> Project: project = get_project("data", "data") linker = inspector.Linker(project) linker.visit(project) return project -def test_class_implements(project): +def test_class_implements(project: Project) -> None: klass = project.get_module("data.clientmodule_test")["Ancestor"] assert hasattr(klass, "implements") assert len(klass.implements) == 1 @@ -41,13 +43,13 @@ def test_class_implements(project): assert klass.implements[0].name == "Interface" -def test_class_implements_specialization(project): +def test_class_implements_specialization(project: Project) -> None: klass = project.get_module("data.clientmodule_test")["Specialization"] assert hasattr(klass, "implements") assert len(klass.implements) == 0 -def test_locals_assignment_resolution(project): +def test_locals_assignment_resolution(project: Project) -> None: klass = project.get_module("data.clientmodule_test")["Specialization"] assert hasattr(klass, "locals_type") type_dict = klass.locals_type @@ -60,7 +62,7 @@ def test_locals_assignment_resolution(project): assert type_dict["top"][0].value == "class" -def test_instance_attrs_resolution(project): +def test_instance_attrs_resolution(project: Project) -> None: klass = project.get_module("data.clientmodule_test")["Specialization"] assert hasattr(klass, "instance_attrs_type") type_dict = klass.instance_attrs_type @@ -74,7 +76,7 @@ def test_instance_attrs_resolution(project): assert type_dict["_id"][0] is astroid.Uninferable -def test_concat_interfaces(): +def test_concat_interfaces() -> None: cls = astroid.extract_node( ''' class IMachin: pass @@ -96,7 +98,7 @@ def test_concat_interfaces(): assert [i.name for i in interfaces] == ["IMachin"] -def test_interfaces(): +def test_interfaces() -> None: module = astroid.parse( """ class Interface(object): pass @@ -122,12 +124,12 @@ def test_interfaces(): assert [i.name for i in inspector.interfaces(klass)] == interfaces -def test_from_directory(project): +def test_from_directory(project: Project) -> None: expected = os.path.join("tests", "data", "__init__.py") assert project.name == "data" assert project.path.endswith(expected) -def test_project_node(project): +def test_project_node(project: Project) -> None: expected = ["data", "data.clientmodule_test", "data.suppliermodule_test"] assert sorted(project.keys()) == expected diff --git a/tests/pyreverse/test_printer.py b/tests/pyreverse/test_printer.py index 77d12f630..b5606e37b 100644 --- a/tests/pyreverse/test_printer.py +++ b/tests/pyreverse/test_printer.py @@ -47,6 +47,6 @@ def test_unsupported_layout(layout: Layout, printer_class: Type[Printer]): class TestPlantUmlPrinter: printer = PlantUmlPrinter(title="unittest", layout=Layout.TOP_TO_BOTTOM) - def test_node_without_properties(self): + def test_node_without_properties(self) -> None: self.printer.emit_node(name="test", type_=NodeType.CLASS) assert self.printer.lines[-2:] == ['class "test" as test {\n', "}\n"] diff --git a/tests/pyreverse/test_utils.py b/tests/pyreverse/test_utils.py index 1d231eafa..5abd0126c 100644 --- a/tests/pyreverse/test_utils.py +++ b/tests/pyreverse/test_utils.py @@ -9,6 +9,7 @@ """Tests for pylint.pyreverse.utils""" +from typing import Any from unittest.mock import patch import astroid @@ -80,8 +81,8 @@ def test_get_annotation_assignattr(init_method, label): @patch("pylint.pyreverse.utils.get_annotation") -@patch("astroid.nodes.NodeNG.infer", side_effect=astroid.InferenceError) -def test_infer_node_1(mock_infer, mock_get_annotation): +@patch("astroid.node_classes.NodeNG.infer", side_effect=astroid.InferenceError) +def test_infer_node_1(mock_infer: Any, mock_get_annotation: Any) -> None: """Return set() when astroid.InferenceError is raised and an annotation has not been returned """ @@ -93,8 +94,8 @@ def test_infer_node_1(mock_infer, mock_get_annotation): @patch("pylint.pyreverse.utils.get_annotation") -@patch("astroid.nodes.NodeNG.infer") -def test_infer_node_2(mock_infer, mock_get_annotation): +@patch("astroid.node_classes.NodeNG.infer") +def test_infer_node_2(mock_infer: Any, mock_get_annotation: Any) -> None: """Return set(node.infer()) when InferenceError is not raised and an annotation has not been returned """ @@ -105,7 +106,7 @@ def test_infer_node_2(mock_infer, mock_get_annotation): assert mock_infer.called -def test_infer_node_3(): +def test_infer_node_3() -> None: """Return a set containing a nodes.ClassDef object when the attribute has a type annotation""" node = astroid.extract_node( @@ -123,7 +124,7 @@ def test_infer_node_3(): assert isinstance(infer_node(instance_attr).pop(), nodes.ClassDef) -def test_infer_node_4(): +def test_infer_node_4() -> None: """Verify the label for an argument with a typehint of the type nodes.Subscript """ diff --git a/tests/pyreverse/test_writer.py b/tests/pyreverse/test_writer.py index 66a150bbc..28ed16046 100644 --- a/tests/pyreverse/test_writer.py +++ b/tests/pyreverse/test_writer.py @@ -24,12 +24,14 @@ Unit test for ``DiagramWriter`` import codecs import os from difflib import unified_diff +from typing import Callable, Iterator, List from unittest.mock import Mock import pytest +from conftest import PyreverseConfig # type: ignore from pylint.pyreverse.diadefslib import DefaultDiadefGenerator, DiadefsHandler -from pylint.pyreverse.inspector import Linker +from pylint.pyreverse.inspector import Linker, Project from pylint.pyreverse.writer import DiagramWriter _DEFAULTS = { @@ -57,7 +59,7 @@ class Config: setattr(self, attr, value) -def _file_lines(path): +def _file_lines(path: str) -> List[str]: # we don't care about the actual encoding, but python3 forces us to pick one with codecs.open(path, encoding="latin1") as stream: lines = [ @@ -79,14 +81,16 @@ COLORIZED_PUML_FILES = ["packages_colorized.puml", "classes_colorized.puml"] @pytest.fixture() -def setup_dot(default_config, get_project): +def setup_dot(default_config: PyreverseConfig, get_project: Callable) -> Iterator: writer = DiagramWriter(default_config) project = get_project(os.path.join(os.path.dirname(__file__), "..", "data")) yield from _setup(project, default_config, writer) @pytest.fixture() -def setup_colorized_dot(colorized_dot_config, get_project): +def setup_colorized_dot( + colorized_dot_config: PyreverseConfig, get_project: Callable +) -> Iterator: writer = DiagramWriter(colorized_dot_config) project = get_project( os.path.join(os.path.dirname(__file__), "..", "data"), name="colorized" @@ -95,21 +99,23 @@ def setup_colorized_dot(colorized_dot_config, get_project): @pytest.fixture() -def setup_vcg(vcg_config, get_project): +def setup_vcg(vcg_config: PyreverseConfig, get_project: Callable) -> Iterator: writer = DiagramWriter(vcg_config) project = get_project(os.path.join(os.path.dirname(__file__), "..", "data")) yield from _setup(project, vcg_config, writer) @pytest.fixture() -def setup_puml(puml_config, get_project): +def setup_puml(puml_config: PyreverseConfig, get_project: Callable) -> Iterator: writer = DiagramWriter(puml_config) project = get_project(os.path.join(os.path.dirname(__file__), "..", "data")) yield from _setup(project, puml_config, writer) @pytest.fixture() -def setup_colorized_puml(colorized_puml_config, get_project): +def setup_colorized_puml( + colorized_puml_config: PyreverseConfig, get_project: Callable +) -> Iterator: writer = DiagramWriter(colorized_puml_config) project = get_project( os.path.join(os.path.dirname(__file__), "..", "data"), name="colorized" @@ -117,7 +123,9 @@ def setup_colorized_puml(colorized_puml_config, get_project): yield from _setup(project, colorized_puml_config, writer) -def _setup(project, config, writer): +def _setup( + project: Project, config: PyreverseConfig, writer: DiagramWriter +) -> Iterator: linker = Linker(project) handler = DiadefsHandler(config) dd = DefaultDiadefGenerator(linker, handler).visit(project) @@ -136,48 +144,51 @@ def _setup(project, config, writer): @pytest.mark.usefixtures("setup_dot") @pytest.mark.parametrize("generated_file", DOT_FILES) -def test_dot_files(generated_file): +def test_dot_files(generated_file: str) -> None: _assert_files_are_equal(generated_file) @pytest.mark.usefixtures("setup_colorized_dot") @pytest.mark.parametrize("generated_file", COLORIZED_DOT_FILES) -def test_colorized_dot_files(generated_file): +def test_colorized_dot_files(generated_file: str) -> None: _assert_files_are_equal(generated_file) @pytest.mark.usefixtures("setup_vcg") @pytest.mark.parametrize("generated_file", VCG_FILES) -def test_vcg_files(generated_file): +def test_vcg_files(generated_file: str) -> None: _assert_files_are_equal(generated_file) @pytest.mark.usefixtures("setup_puml") @pytest.mark.parametrize("generated_file", PUML_FILES) -def test_puml_files(generated_file): +def test_puml_files(generated_file: str) -> None: _assert_files_are_equal(generated_file) @pytest.mark.usefixtures("setup_colorized_puml") @pytest.mark.parametrize("generated_file", COLORIZED_PUML_FILES) -def test_colorized_puml_files(generated_file): +def test_colorized_puml_files(generated_file: str) -> None: _assert_files_are_equal(generated_file) -def _assert_files_are_equal(generated_file): +def _assert_files_are_equal(generated_file: str) -> None: expected_file = os.path.join(os.path.dirname(__file__), "data", generated_file) generated = _file_lines(generated_file) expected = _file_lines(expected_file) - generated = "\n".join(generated) - expected = "\n".join(expected) + joined_generated = "\n".join(generated) + joined_expected = "\n".join(expected) files = f"\n *** expected : {expected_file}, generated : {generated_file} \n" diff = "\n".join( - line for line in unified_diff(expected.splitlines(), generated.splitlines()) + line + for line in unified_diff( + joined_expected.splitlines(), joined_generated.splitlines() + ) ) - assert expected == generated, f"{files}{diff}" + assert joined_expected == joined_generated, f"{files}{diff}" -def test_color_for_stdlib_module(default_config): +def test_color_for_stdlib_module(default_config: PyreverseConfig) -> None: writer = DiagramWriter(default_config) obj = Mock() obj.node = Mock() |