test_pydoctor.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. Tests for L{twisted.python._pydoctor}.
  5. """
  6. from collections import namedtuple
  7. from twisted.python.compat import _PY3
  8. from twisted.python.reflect import requireModule
  9. from twisted.trial.unittest import TestCase
  10. model = requireModule('pydoctor.model')
  11. pydoctorSkip = None
  12. TwistedSphinxInventory = object
  13. TwistedSystem = object
  14. if model is None:
  15. pydoctorSkip = 'Pydoctor is not present.'
  16. elif _PY3:
  17. pydoctorSkip = 'Pydoctor not supported on Python3.'
  18. else:
  19. # We have a valid pydoctor.
  20. from twisted.python._pydoctor import TwistedSphinxInventory, TwistedSystem
  21. class TwistedSystemTests(TestCase):
  22. """
  23. Tests for L{TwistedSystem}.
  24. """
  25. skip = pydoctorSkip
  26. def test_initCustomSphinxInventory(self):
  27. """
  28. After initialization it has a custom C{intersphinx} member.
  29. """
  30. sut = TwistedSystem()
  31. self.assertIsInstance(sut.intersphinx, TwistedSphinxInventory)
  32. def test_privacyClassBaseTestPackage(self):
  33. """
  34. The base I{twisted.test} package is visible to allow traversal to a
  35. few selected test API which is visible.
  36. """
  37. sut = TwistedSystem()
  38. twistedPackage = model.Package(
  39. system=sut,
  40. name='twisted',
  41. docstring='ignored',
  42. parent=None,
  43. )
  44. twistedTestPackage = model.Package(
  45. system=sut,
  46. name='test',
  47. docstring='ignored',
  48. parent=twistedPackage,
  49. )
  50. result = sut.privacyClass(twistedTestPackage)
  51. self.assertIs(result, model.PrivacyClass.VISIBLE)
  52. def test_privacyClassProtoHelpers(self):
  53. """
  54. The I{twisted.test.proto_helpers} module is visible.
  55. """
  56. sut = TwistedSystem()
  57. twistedPackage = model.Package(
  58. system=sut,
  59. name='twisted',
  60. docstring='ignored',
  61. parent=None,
  62. )
  63. twistedTestPackage = model.Package(
  64. system=sut,
  65. name='test',
  66. docstring='ignored',
  67. parent=twistedPackage,
  68. )
  69. twistedProtoHelpersModule = model.Module(
  70. system=sut,
  71. name='proto_helpers',
  72. docstring='ignored',
  73. parent=twistedTestPackage,
  74. )
  75. result = sut.privacyClass(twistedProtoHelpersModule)
  76. self.assertIs(result, model.PrivacyClass.VISIBLE)
  77. def test_privacyClassChildTestModule(self):
  78. """
  79. Any child of the I{twisted.test} package is hidden.
  80. """
  81. sut = TwistedSystem()
  82. twistedPackage = model.Package(
  83. system=sut,
  84. name='twisted',
  85. docstring='ignored',
  86. parent=None,
  87. )
  88. twistedTestPackage = model.Package(
  89. system=sut,
  90. name='test',
  91. docstring='ignored',
  92. parent=twistedPackage,
  93. )
  94. twistedAnyTestModule = model.Module(
  95. system=sut,
  96. name='other_child',
  97. docstring='ignored',
  98. parent=twistedTestPackage,
  99. )
  100. result = sut.privacyClass(twistedAnyTestModule)
  101. self.assertIs(result, model.PrivacyClass.HIDDEN)
  102. def test_privacyClassPublicCode(self):
  103. """
  104. Any child of the I{twisted} package has a privacy according to the
  105. general rules defined in pydoctor.
  106. """
  107. sut = TwistedSystem()
  108. twistedPackage = model.Package(
  109. system=sut,
  110. name='twisted',
  111. docstring='ignored',
  112. parent=None,
  113. )
  114. twistedSubProjectPackage = model.Package(
  115. system=sut,
  116. name='subproject',
  117. docstring='ignored',
  118. parent=twistedPackage,
  119. )
  120. twistedSubProjectModule = model.Module(
  121. system=sut,
  122. name='other_child',
  123. docstring='ignored',
  124. parent=twistedSubProjectPackage,
  125. )
  126. twistedPrivateModule = model.Module(
  127. system=sut,
  128. name='_private_child',
  129. docstring='ignored',
  130. parent=twistedSubProjectPackage,
  131. )
  132. result = sut.privacyClass(twistedSubProjectPackage)
  133. self.assertIs(result, model.PrivacyClass.VISIBLE)
  134. result = sut.privacyClass(twistedSubProjectModule)
  135. self.assertIs(result, model.PrivacyClass.VISIBLE)
  136. result = sut.privacyClass(twistedPrivateModule)
  137. self.assertIs(result, model.PrivacyClass.PRIVATE)
  138. class TwistedSphinxInventoryTests(TestCase):
  139. """
  140. Tests for L{TwistedSphinxInventory}.
  141. """
  142. skip = pydoctorSkip
  143. def getInventoryWithZope(self):
  144. """
  145. Initialized a pre-loaded inventory.
  146. @return: A new inventory which already has a few I{zope.interface}
  147. inter sphinx links loaded.
  148. @rtype: L{TwistedSphinxInventory}
  149. """
  150. inventory = TwistedSphinxInventory(
  151. logger=object(), project_name='Super Duper')
  152. zopeBaseURL = 'https://zope.tld'
  153. zopeAPIURL = 'api.html#$'
  154. inventory._links.update({
  155. 'zope.interface.interfaces.IInterface': (zopeBaseURL, zopeAPIURL),
  156. 'zope.interface.declarations.implementer': (
  157. zopeBaseURL, zopeAPIURL),
  158. })
  159. return inventory
  160. def test_getLinkExistentInInterSphinx(self):
  161. """
  162. Return the full URL based on pre-loaded inter sphinx objects.
  163. """
  164. sut = self.getInventoryWithZope()
  165. result = sut.getLink('zope.interface.interfaces.IInterface')
  166. self.assertEqual(
  167. 'https://zope.tld/api.html#zope.interface.interfaces.IInterface',
  168. result)
  169. def test_getLinkZopeNonExistent(self):
  170. """
  171. Any reference to I{zope.interface} which is not in the inter sphinx
  172. database returns L{None}.
  173. """
  174. sut = self.getInventoryWithZope()
  175. # Interface is at zope.interface.interfaces.IInterface so using the
  176. # short name will fail to find the url.
  177. result = sut.getLink('zope.interface.Interface')
  178. self.assertIsNone(result)
  179. # Any unknown reference returns None.
  180. result = sut.getLink('zope.interface.NoSuchReference')
  181. self.assertIsNone(result)
  182. def test_getLinkZopeAdapterRegistry(self):
  183. """
  184. I{zope.interface.adapter.AdapterRegistry} is a special case for which
  185. the link the narrative docs is returned as there is no API docs yet.
  186. """
  187. sut = self.getInventoryWithZope()
  188. result = sut.getLink('zope.interface.adapter.AdapterRegistry')
  189. self.assertEqual('https://zope.tld/adapter.html', result)
  190. def test_getLinkWin32APIExistingMethod(self):
  191. """
  192. Will return a link to the activestate.com python 2.7 API for
  193. pywin32 methods.
  194. """
  195. activeStateURL = (
  196. 'http://docs.activestate.com/activepython/2.7/pywin32/'
  197. 'win32api__FormatMessage_meth.html'
  198. )
  199. Response = namedtuple('Animal', 'code')
  200. response = Response(code=200)
  201. sut = self.getInventoryWithZope()
  202. sut._getURLAsHEAD = lambda url: {activeStateURL: response}[url]
  203. result = sut.getLink('win32api.FormatMessage')
  204. self.assertEqual(activeStateURL, result)
  205. def test_getLinkWin32APIUnknown(self):
  206. """
  207. Will return L{None} when the auto created link don't exist on the
  208. activestate.com site.
  209. """
  210. activeStateURL = (
  211. 'http://docs.activestate.com/activepython/2.7/pywin32/'
  212. 'win32api__FormatMessage_meth.html'
  213. )
  214. Response = namedtuple('Animal', 'code')
  215. response = Response(code=404)
  216. sut = self.getInventoryWithZope()
  217. sut._getURLAsHEAD = lambda url: {activeStateURL: response}[url]
  218. result = sut.getLink('win32api.FormatMessage')
  219. self.assertIsNone(result)