Coverage for tests/test_objects.py: 100.00%

75 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-09 17:28 +0100

1"""Tests for [the `objects` module][pytkdocs.objects].""" 

2 

3import os 

4 

5from pytkdocs.loader import Loader 

6from pytkdocs.objects import Attribute, Class, Function, Method, Module, Object 

7from tests import FIXTURES_DIR 

8 

9 

10def test_creating_module() -> None: 

11 """Create a Module.""" 

12 assert Module(name="my_object", path="my.dotted.path", file_path="/my/absolute/path.py") 

13 

14 

15def test_creating_class() -> None: 

16 """Create a Class.""" 

17 assert Class(name="my_object", path="my.dotted.path", file_path="/my/absolute/path.py") 

18 

19 

20def test_creating_method() -> None: 

21 """Create a Method.""" 

22 assert Method(name="my_object", path="my.dotted.path", file_path="/my/absolute/path.py") 

23 

24 

25def test_creating_function() -> None: 

26 """Create a Function.""" 

27 assert Function(name="my_object", path="my.dotted.path", file_path="/my/absolute/path.py") 

28 

29 

30def test_creating_attribute() -> None: 

31 """Create an Attribute.""" 

32 assert Attribute(name="my_object", path="my.dotted.path", file_path="/my/absolute/path.py") 

33 

34 

35def test_add_child() -> None: 

36 """Add a child.""" 

37 parent = Module(name="my_module", path="my.dotted.path", file_path="/my/absolute/path.py") 

38 child = Attribute(name="my_attribute", path="my.dotted.path.my_attribute", file_path="/my/absolute/path.py") 

39 parent.add_child(child) 

40 assert parent.children[0] is child 

41 assert parent.attributes[0] is child 

42 

43 

44def test_do_not_add_child_if_parent_is_not_self() -> None: 

45 """Don't add a child the parent is not the right one.""" 

46 parent = Module(name="my_module", path="my.dotted.path", file_path="/my/absolute/path.py") 

47 child = Attribute(name="my_attribute", path="my.other.path.my_attribute", file_path="/my/absolute/path.py") 

48 parent.add_child(child) 

49 assert not parent.children 

50 assert not parent.attributes 

51 

52 

53def test_get_root() -> None: 

54 """Get the root object.""" 

55 root = Module(name="my_module", path="my.dotted.path", file_path="") 

56 node1 = Class(name="my_class1", path="my.dotted.path.my_class1", file_path="") 

57 node2 = Class(name="my_class2", path="my.dotted.path.my_class2", file_path="") 

58 leaf = Method(name="my_method", path="my.dotted.path.my_class1.my_method", file_path="") 

59 

60 root.add_children([node1, node2]) 

61 node1.add_child(leaf) 

62 

63 assert root.root is root 

64 assert node1.root is root 

65 assert node2.root is root 

66 assert leaf.root is root 

67 

68 

69def test_relative_file_path_for_root() -> None: 

70 """Get the relative file of a shallow object.""" 

71 obj = Object( 

72 name="nested_class", 

73 path="tests.fixtures.nested_class", 

74 file_path=str(FIXTURES_DIR / "nested_class.py"), 

75 ) 

76 assert obj.relative_file_path == os.path.join("tests", "fixtures", "nested_class.py") 

77 

78 

79def test_relative_file_path_for_leaf() -> None: 

80 """Get the relative file path of a deep object.""" 

81 obj = Loader().get_object_documentation("tests.fixtures.pkg1") 

82 leaf = obj.children[0].children[0].children[0].children[0] 

83 assert leaf.relative_file_path == os.path.join( 

84 "tests", 

85 "fixtures", 

86 "pkg1", 

87 "pkg2", 

88 "pkg3", 

89 "pkg4", 

90 "pkg5", 

91 "__init__.py", 

92 ) 

93 

94 

95def test_no_relative_file_path_for_non_existent_package() -> None: 

96 """Cannot find relative file path.""" 

97 obj = Object(name="o", path="a.b.o", file_path="/some/non_existent/path/a/b/o.py") 

98 assert not obj.relative_file_path 

99 

100 

101def test_no_relative_file_path_for_wrong_path() -> None: 

102 """Cannot find relative file path with wrong dotted path.""" 

103 obj = Object(name="o", path="wrong.dotted.path", file_path=str(FIXTURES_DIR / "nested_class.py")) 

104 assert not obj.relative_file_path 

105 

106 

107def test_no_relative_file_path_for_wrong_file_path() -> None: 

108 """Cannot find relative file path with wrong file path.""" 

109 obj = Object(name="o", path="tests.fixtures.nested_class", file_path="/wrong/module/path.py") 

110 assert not obj.relative_file_path 

111 

112 

113def test_add_children() -> None: 

114 """Add multiple children at once.""" 

115 root = Object(name="o", path="o", file_path="o.py") 

116 

117 class_ = Class(name="c", path="o.c", file_path="o.py") 

118 attribute = Attribute(name="a", path="o.c.a", file_path="o.py") 

119 class_.add_child(attribute) 

120 

121 root.add_children( 

122 [ 

123 # class has wrong path 

124 Class(name="w", path="wrong.path.w", file_path="/wrong/path/w.py"), 

125 # class OK 

126 class_, 

127 # not a direct child, 

128 attribute, 

129 # function OK 

130 Function(name="f", path="o.f", file_path="o.py"), 

131 # not a direct child, not even a child of known child 

132 Method(name="missing_node", path="o.mn.missing_node", file_path="o.py"), 

133 ], 

134 ) 

135 

136 assert len(root.children) == 2 

137 assert root.classes 

138 assert root.classes[0] is class_ 

139 assert root.functions 

140 assert root.functions[0].name == "f" 

141 

142 

143def test_has_contents() -> None: 

144 """Check if an object has contents.""" 

145 obj = Loader().get_object_documentation("tests.fixtures.pkg1") 

146 assert obj.has_contents() 

147 

148 obj = Loader().get_object_documentation("tests.fixtures.__init__") 

149 assert not obj.children 

150 assert obj.has_contents() # we specified that the root always 'has contents' 

151 

152 obj = Loader().get_object_documentation("tests.fixtures.no_contents") 

153 assert obj.children 

154 assert obj.has_contents 

155 assert not obj.children[0].has_contents() 

156 

157 

158def test_has_no_contents() -> None: 

159 """Check that an object has no contents.""" 

160 # TODO