test_check.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. """Tests for distutils.command.check."""
  2. import os
  3. import textwrap
  4. from distutils.command.check import check
  5. from distutils.errors import DistutilsSetupError
  6. from distutils.tests import support
  7. import pytest
  8. try:
  9. import pygments
  10. except ImportError:
  11. pygments = None
  12. HERE = os.path.dirname(__file__)
  13. @support.combine_markers
  14. class TestCheck(support.TempdirManager):
  15. def _run(self, metadata=None, cwd=None, **options):
  16. if metadata is None:
  17. metadata = {}
  18. if cwd is not None:
  19. old_dir = os.getcwd()
  20. os.chdir(cwd)
  21. pkg_info, dist = self.create_dist(**metadata)
  22. cmd = check(dist)
  23. cmd.initialize_options()
  24. for name, value in options.items():
  25. setattr(cmd, name, value)
  26. cmd.ensure_finalized()
  27. cmd.run()
  28. if cwd is not None:
  29. os.chdir(old_dir)
  30. return cmd
  31. def test_check_metadata(self):
  32. # let's run the command with no metadata at all
  33. # by default, check is checking the metadata
  34. # should have some warnings
  35. cmd = self._run()
  36. assert cmd._warnings == 1
  37. # now let's add the required fields
  38. # and run it again, to make sure we don't get
  39. # any warning anymore
  40. metadata = {
  41. 'url': 'xxx',
  42. 'author': 'xxx',
  43. 'author_email': 'xxx',
  44. 'name': 'xxx',
  45. 'version': 'xxx',
  46. }
  47. cmd = self._run(metadata)
  48. assert cmd._warnings == 0
  49. # now with the strict mode, we should
  50. # get an error if there are missing metadata
  51. with pytest.raises(DistutilsSetupError):
  52. self._run({}, **{'strict': 1})
  53. # and of course, no error when all metadata are present
  54. cmd = self._run(metadata, strict=True)
  55. assert cmd._warnings == 0
  56. # now a test with non-ASCII characters
  57. metadata = {
  58. 'url': 'xxx',
  59. 'author': '\u00c9ric',
  60. 'author_email': 'xxx',
  61. 'name': 'xxx',
  62. 'version': 'xxx',
  63. 'description': 'Something about esszet \u00df',
  64. 'long_description': 'More things about esszet \u00df',
  65. }
  66. cmd = self._run(metadata)
  67. assert cmd._warnings == 0
  68. def test_check_author_maintainer(self):
  69. for kind in ("author", "maintainer"):
  70. # ensure no warning when author_email or maintainer_email is given
  71. # (the spec allows these fields to take the form "Name <email>")
  72. metadata = {
  73. 'url': 'xxx',
  74. kind + '_email': 'Name <name@email.com>',
  75. 'name': 'xxx',
  76. 'version': 'xxx',
  77. }
  78. cmd = self._run(metadata)
  79. assert cmd._warnings == 0
  80. # the check should not warn if only email is given
  81. metadata[kind + '_email'] = 'name@email.com'
  82. cmd = self._run(metadata)
  83. assert cmd._warnings == 0
  84. # the check should not warn if only the name is given
  85. metadata[kind] = "Name"
  86. del metadata[kind + '_email']
  87. cmd = self._run(metadata)
  88. assert cmd._warnings == 0
  89. def test_check_document(self):
  90. pytest.importorskip('docutils')
  91. pkg_info, dist = self.create_dist()
  92. cmd = check(dist)
  93. # let's see if it detects broken rest
  94. broken_rest = 'title\n===\n\ntest'
  95. msgs = cmd._check_rst_data(broken_rest)
  96. assert len(msgs) == 1
  97. # and non-broken rest
  98. rest = 'title\n=====\n\ntest'
  99. msgs = cmd._check_rst_data(rest)
  100. assert len(msgs) == 0
  101. def test_check_restructuredtext(self):
  102. pytest.importorskip('docutils')
  103. # let's see if it detects broken rest in long_description
  104. broken_rest = 'title\n===\n\ntest'
  105. pkg_info, dist = self.create_dist(long_description=broken_rest)
  106. cmd = check(dist)
  107. cmd.check_restructuredtext()
  108. assert cmd._warnings == 1
  109. # let's see if we have an error with strict=True
  110. metadata = {
  111. 'url': 'xxx',
  112. 'author': 'xxx',
  113. 'author_email': 'xxx',
  114. 'name': 'xxx',
  115. 'version': 'xxx',
  116. 'long_description': broken_rest,
  117. }
  118. with pytest.raises(DistutilsSetupError):
  119. self._run(metadata, **{'strict': 1, 'restructuredtext': 1})
  120. # and non-broken rest, including a non-ASCII character to test #12114
  121. metadata['long_description'] = 'title\n=====\n\ntest \u00df'
  122. cmd = self._run(metadata, strict=True, restructuredtext=True)
  123. assert cmd._warnings == 0
  124. # check that includes work to test #31292
  125. metadata['long_description'] = 'title\n=====\n\n.. include:: includetest.rst'
  126. cmd = self._run(metadata, cwd=HERE, strict=True, restructuredtext=True)
  127. assert cmd._warnings == 0
  128. def test_check_restructuredtext_with_syntax_highlight(self):
  129. pytest.importorskip('docutils')
  130. # Don't fail if there is a `code` or `code-block` directive
  131. example_rst_docs = [
  132. textwrap.dedent(
  133. """\
  134. Here's some code:
  135. .. code:: python
  136. def foo():
  137. pass
  138. """
  139. ),
  140. textwrap.dedent(
  141. """\
  142. Here's some code:
  143. .. code-block:: python
  144. def foo():
  145. pass
  146. """
  147. ),
  148. ]
  149. for rest_with_code in example_rst_docs:
  150. pkg_info, dist = self.create_dist(long_description=rest_with_code)
  151. cmd = check(dist)
  152. cmd.check_restructuredtext()
  153. msgs = cmd._check_rst_data(rest_with_code)
  154. if pygments is not None:
  155. assert len(msgs) == 0
  156. else:
  157. assert len(msgs) == 1
  158. assert (
  159. str(msgs[0][1])
  160. == 'Cannot analyze code. Pygments package not found.'
  161. )
  162. def test_check_all(self):
  163. with pytest.raises(DistutilsSetupError):
  164. self._run({}, **{'strict': 1, 'restructuredtext': 1})