blob: 0c8873f970efff9c8b5181348efd90752089f108 [file] [log] [blame]
hippo911f7c29c2020-08-20 18:40:19 +02001# Copyright (c) 2015-2018, 2020 Claudiu Popa <pcmanticore@gmail.com>
Ashley Whetter33b81852019-06-14 22:28:42 -07002# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com>
Pierre Sassoulas391c8aa2021-02-28 21:13:57 +01003# Copyright (c) 2019-2021 Pierre Sassoulas <pierre.sassoulas@gmail.com>
Claudiu Popa369d9522020-04-27 11:04:14 +02004# Copyright (c) 2019 Ashley Whetter <ashley@awhetter.co.uk>
Pierre Sassoulasac852232021-02-21 15:13:06 +01005# Copyright (c) 2020 hippo91 <guillaume.peillex@gmail.com>
hippo911f7c29c2020-08-20 18:40:19 +02006# Copyright (c) 2020 Damien Baty <damien.baty@polyconseil.fr>
Pierre Sassoulasaa688de2021-07-01 14:33:09 +02007# Copyright (c) 2021 Marc Mueller <30130371+cdce8p@users.noreply.github.com>
Pierre Sassoulasea448b82021-08-20 22:07:21 +02008# Copyright (c) 2021 Andreas Finkler <andi.finkler@gmail.com>
9# Copyright (c) 2021 Mark Byrne <31762852+mbyrnepr2@users.noreply.github.com>
Ashley Whetter33b81852019-06-14 22:28:42 -070010
11# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
Marc Mueller21290862021-07-01 12:47:58 +020012# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
Ashley Whetter33b81852019-06-14 22:28:42 -070013
14"""
15 for the visitors.diadefs module
16"""
Pierre Sassoulasec2957f2020-05-01 13:53:10 +020017# pylint: disable=redefined-outer-name
18
Ashley Whetter33b81852019-06-14 22:28:42 -070019import os
20
21import astroid
22import pytest
Marc Mueller7ed757e2021-08-19 09:01:49 +020023from astroid import nodes
Ashley Whetter33b81852019-06-14 22:28:42 -070024
25from pylint.pyreverse import inspector
Ashley Whetter33b81852019-06-14 22:28:42 -070026
27
28@pytest.fixture
DudeNr3321501962021-08-09 06:44:21 +020029def project(get_project):
Ashley Whetter33b81852019-06-14 22:28:42 -070030 project = get_project("data", "data")
31 linker = inspector.Linker(project)
32 linker.visit(project)
33 return project
34
35
36def test_class_implements(project):
37 klass = project.get_module("data.clientmodule_test")["Ancestor"]
38 assert hasattr(klass, "implements")
39 assert len(klass.implements) == 1
Marc Mueller7ed757e2021-08-19 09:01:49 +020040 assert isinstance(klass.implements[0], nodes.ClassDef)
Ashley Whetter33b81852019-06-14 22:28:42 -070041 assert klass.implements[0].name == "Interface"
42
43
44def test_class_implements_specialization(project):
45 klass = project.get_module("data.clientmodule_test")["Specialization"]
46 assert hasattr(klass, "implements")
47 assert len(klass.implements) == 0
48
49
50def test_locals_assignment_resolution(project):
51 klass = project.get_module("data.clientmodule_test")["Specialization"]
52 assert hasattr(klass, "locals_type")
53 type_dict = klass.locals_type
54 assert len(type_dict) == 2
55 keys = sorted(type_dict.keys())
56 assert keys == ["TYPE", "top"]
57 assert len(type_dict["TYPE"]) == 1
58 assert type_dict["TYPE"][0].value == "final class"
59 assert len(type_dict["top"]) == 1
60 assert type_dict["top"][0].value == "class"
61
62
63def test_instance_attrs_resolution(project):
64 klass = project.get_module("data.clientmodule_test")["Specialization"]
65 assert hasattr(klass, "instance_attrs_type")
66 type_dict = klass.instance_attrs_type
Mark Byrneb71be8a2021-07-30 20:21:02 +020067 assert len(type_dict) == 3
Ashley Whetter33b81852019-06-14 22:28:42 -070068 keys = sorted(type_dict.keys())
Mark Byrneb71be8a2021-07-30 20:21:02 +020069 assert keys == ["_id", "relation", "relation2"]
Pierre Sassoulas14f20e22021-03-27 15:21:29 +010070 assert isinstance(type_dict["relation"][0], astroid.bases.Instance), type_dict[
71 "relation"
72 ]
Ashley Whetter33b81852019-06-14 22:28:42 -070073 assert type_dict["relation"][0].name == "DoNothing"
74 assert type_dict["_id"][0] is astroid.Uninferable
75
76
77def test_concat_interfaces():
78 cls = astroid.extract_node(
79 '''
80 class IMachin: pass
81
82 class Correct2:
83 """docstring"""
84 __implements__ = (IMachin,)
85
86 class BadArgument:
87 """docstring"""
88 __implements__ = (IMachin,)
89
90 class InterfaceCanNowBeFound: #@
91 """docstring"""
92 __implements__ = BadArgument.__implements__ + Correct2.__implements__
93 '''
94 )
95 interfaces = inspector.interfaces(cls)
96 assert [i.name for i in interfaces] == ["IMachin"]
97
98
99def test_interfaces():
100 module = astroid.parse(
101 """
102 class Interface(object): pass
103 class MyIFace(Interface): pass
104 class AnotherIFace(Interface): pass
105 class Concrete0(object):
106 __implements__ = MyIFace
107 class Concrete1:
108 __implements__ = (MyIFace, AnotherIFace)
109 class Concrete2:
110 __implements__ = (MyIFace, AnotherIFace)
111 class Concrete23(Concrete1): pass
112 """
113 )
114
115 for klass, interfaces in (
116 ("Concrete0", ["MyIFace"]),
117 ("Concrete1", ["MyIFace", "AnotherIFace"]),
118 ("Concrete2", ["MyIFace", "AnotherIFace"]),
119 ("Concrete23", ["MyIFace", "AnotherIFace"]),
120 ):
121 klass = module[klass]
122 assert [i.name for i in inspector.interfaces(klass)] == interfaces
123
124
125def test_from_directory(project):
126 expected = os.path.join("tests", "data", "__init__.py")
127 assert project.name == "data"
128 assert project.path.endswith(expected)
129
130
131def test_project_node(project):
132 expected = ["data", "data.clientmodule_test", "data.suppliermodule_test"]
133 assert sorted(project.keys()) == expected