test_github_links.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. import pathlib
  2. import sys
  3. from django.test import SimpleTestCase
  4. def last_n_parts(path, n):
  5. return "/".join(path.parts[-n:])
  6. # The import must happen at the end of setUpClass, so it can't be imported at
  7. # the top of the file.
  8. github_links = None
  9. class GitHubLinkTests(SimpleTestCase):
  10. @classmethod
  11. def setUpClass(cls):
  12. # The file implementing the code under test is in the docs folder and
  13. # is not part of the Django package. This means it cannot be imported
  14. # through standard means. Include its parent in the pythonpath for the
  15. # duration of the tests to allow the code to be imported.
  16. cls.ext_path = str((pathlib.Path(__file__).parents[2] / "docs/_ext").resolve())
  17. sys.path.insert(0, cls.ext_path)
  18. cls.addClassCleanup(sys.path.remove, cls.ext_path)
  19. cls.addClassCleanup(sys.modules.pop, "github_links", None)
  20. # Linters/IDEs may not be able to detect this as a valid import.
  21. import github_links as _github_links
  22. global github_links
  23. github_links = _github_links
  24. def test_code_locator(self):
  25. locator = github_links.CodeLocator.from_code(
  26. """
  27. from a import b, c
  28. from .d import e, f as g
  29. def h():
  30. pass
  31. class I:
  32. def j(self):
  33. pass"""
  34. )
  35. self.assertEqual(locator.node_line_numbers, {"h": 5, "I": 8, "I.j": 9})
  36. self.assertEqual(locator.import_locations, {"b": "a", "c": "a", "e": ".d"})
  37. def test_module_name_to_file_path_package(self):
  38. path = github_links.module_name_to_file_path("django")
  39. self.assertEqual(last_n_parts(path, 2), "django/__init__.py")
  40. def test_module_name_to_file_path_module(self):
  41. path = github_links.module_name_to_file_path("django.shortcuts")
  42. self.assertEqual(last_n_parts(path, 2), "django/shortcuts.py")
  43. def test_get_path_and_line_class(self):
  44. path, line = github_links.get_path_and_line(
  45. module="tests.sphinx.testdata.package.module", fullname="MyClass"
  46. )
  47. self.assertEqual(
  48. last_n_parts(path, 5), "tests/sphinx/testdata/package/module.py"
  49. )
  50. self.assertEqual(line, 12)
  51. def test_get_path_and_line_func(self):
  52. path, line = github_links.get_path_and_line(
  53. module="tests.sphinx.testdata.package.module", fullname="my_function"
  54. )
  55. self.assertEqual(
  56. last_n_parts(path, 5), "tests/sphinx/testdata/package/module.py"
  57. )
  58. self.assertEqual(line, 24)
  59. def test_get_path_and_line_method(self):
  60. path, line = github_links.get_path_and_line(
  61. module="tests.sphinx.testdata.package.module", fullname="MyClass.my_method"
  62. )
  63. self.assertEqual(
  64. last_n_parts(path, 5), "tests/sphinx/testdata/package/module.py"
  65. )
  66. self.assertEqual(line, 16)
  67. def test_get_path_and_line_cached_property(self):
  68. path, line = github_links.get_path_and_line(
  69. module="tests.sphinx.testdata.package.module",
  70. fullname="MyClass.my_cached_property",
  71. )
  72. self.assertEqual(
  73. last_n_parts(path, 5), "tests/sphinx/testdata/package/module.py"
  74. )
  75. self.assertEqual(line, 20)
  76. def test_get_path_and_line_forwarded_import(self):
  77. path, line = github_links.get_path_and_line(
  78. module="tests.sphinx.testdata.package.module", fullname="MyOtherClass"
  79. )
  80. self.assertEqual(
  81. last_n_parts(path, 5), "tests/sphinx/testdata/package/other_module.py"
  82. )
  83. self.assertEqual(line, 1)
  84. def test_get_path_and_line_wildcard_import(self):
  85. path, line = github_links.get_path_and_line(
  86. module="tests.sphinx.testdata.package.module", fullname="WildcardClass"
  87. )
  88. self.assertEqual(
  89. last_n_parts(path, 5),
  90. "tests/sphinx/testdata/package/wildcard_module.py",
  91. )
  92. self.assertEqual(line, 4)
  93. path, line = github_links.get_path_and_line(
  94. module="tests.sphinx.testdata.package.module",
  95. fullname="WildcardMixin",
  96. )
  97. self.assertEqual(
  98. last_n_parts(path, 5),
  99. "tests/sphinx/testdata/package/wildcard_base.py",
  100. )
  101. self.assertEqual(line, 1)
  102. def test_get_path_and_line_forwarded_import_module(self):
  103. path, line = github_links.get_path_and_line(
  104. module="tests.sphinx.testdata.package.module",
  105. fullname="other_module.MyOtherClass",
  106. )
  107. self.assertEqual(
  108. last_n_parts(path, 5), "tests/sphinx/testdata/package/other_module.py"
  109. )
  110. self.assertEqual(line, 1)
  111. def test_get_branch_stable(self):
  112. branch = github_links.get_branch(version="2.2", next_version="3.2")
  113. self.assertEqual(branch, "stable/2.2.x")
  114. def test_get_branch_latest(self):
  115. branch = github_links.get_branch(version="3.2", next_version="3.2")
  116. self.assertEqual(branch, "main")
  117. def test_github_linkcode_resolve_unspecified_domain(self):
  118. domain = "unspecified"
  119. info = {}
  120. self.assertIsNone(
  121. github_links.github_linkcode_resolve(
  122. domain, info, version="3.2", next_version="3.2"
  123. )
  124. )
  125. def test_github_linkcode_resolve_unspecified_info(self):
  126. domain = "py"
  127. info = {"module": None, "fullname": None}
  128. self.assertIsNone(
  129. github_links.github_linkcode_resolve(
  130. domain, info, version="3.2", next_version="3.2"
  131. )
  132. )
  133. def test_github_linkcode_resolve_not_found(self):
  134. info = {
  135. "module": "foo.bar.baz.hopefully_non_existant_module",
  136. "fullname": "MyClass",
  137. }
  138. self.assertIsNone(
  139. github_links.github_linkcode_resolve(
  140. "py", info, version="3.2", next_version="3.2"
  141. )
  142. )
  143. def test_github_linkcode_resolve_link_to_object(self):
  144. info = {
  145. "module": "tests.sphinx.testdata.package.module",
  146. "fullname": "MyClass",
  147. }
  148. self.assertEqual(
  149. github_links.github_linkcode_resolve(
  150. "py", info, version="3.2", next_version="3.2"
  151. ),
  152. "https://github.com/django/django/blob/main/tests/sphinx/"
  153. "testdata/package/module.py#L12",
  154. )
  155. def test_github_linkcode_resolve_link_to_class_older_version(self):
  156. info = {
  157. "module": "tests.sphinx.testdata.package.module",
  158. "fullname": "MyClass",
  159. }
  160. self.assertEqual(
  161. github_links.github_linkcode_resolve(
  162. "py", info, version="2.2", next_version="3.2"
  163. ),
  164. "https://github.com/django/django/blob/stable/2.2.x/tests/sphinx/"
  165. "testdata/package/module.py#L12",
  166. )
  167. def test_import_error(self):
  168. msg = "Could not import '.....test' in 'tests.sphinx.testdata.package'."
  169. with self.assertRaisesMessage(ImportError, msg):
  170. github_links.get_path_and_line(
  171. module="tests.sphinx.testdata.package.import_error", fullname="Test"
  172. )