test_api.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import re
  2. import textwrap
  3. import unittest
  4. import itertools
  5. from . import fixtures
  6. from .. import (
  7. Distribution, PackageNotFoundError, __version__, distribution,
  8. entry_points, files, metadata, requires, version,
  9. )
  10. try:
  11. from collections.abc import Iterator
  12. except ImportError:
  13. from collections import Iterator # noqa: F401
  14. try:
  15. from builtins import str as text
  16. except ImportError:
  17. from __builtin__ import unicode as text
  18. class APITests(
  19. fixtures.EggInfoPkg,
  20. fixtures.DistInfoPkg,
  21. fixtures.EggInfoFile,
  22. unittest.TestCase):
  23. version_pattern = r'\d+\.\d+(\.\d)?'
  24. def test_retrieves_version_of_self(self):
  25. pkg_version = version('egginfo-pkg')
  26. assert isinstance(pkg_version, text)
  27. assert re.match(self.version_pattern, pkg_version)
  28. def test_retrieves_version_of_distinfo_pkg(self):
  29. pkg_version = version('distinfo-pkg')
  30. assert isinstance(pkg_version, text)
  31. assert re.match(self.version_pattern, pkg_version)
  32. def test_for_name_does_not_exist(self):
  33. with self.assertRaises(PackageNotFoundError):
  34. distribution('does-not-exist')
  35. def test_for_top_level(self):
  36. self.assertEqual(
  37. distribution('egginfo-pkg').read_text('top_level.txt').strip(),
  38. 'mod')
  39. def test_read_text(self):
  40. top_level = [
  41. path for path in files('egginfo-pkg')
  42. if path.name == 'top_level.txt'
  43. ][0]
  44. self.assertEqual(top_level.read_text(), 'mod\n')
  45. def test_entry_points(self):
  46. entries = dict(entry_points()['entries'])
  47. ep = entries['main']
  48. self.assertEqual(ep.value, 'mod:main')
  49. self.assertEqual(ep.extras, [])
  50. def test_metadata_for_this_package(self):
  51. md = metadata('egginfo-pkg')
  52. assert md['author'] == 'Steven Ma'
  53. assert md['LICENSE'] == 'Unknown'
  54. assert md['Name'] == 'egginfo-pkg'
  55. classifiers = md.get_all('Classifier')
  56. assert 'Topic :: Software Development :: Libraries' in classifiers
  57. def test_importlib_metadata_version(self):
  58. assert re.match(self.version_pattern, __version__)
  59. @staticmethod
  60. def _test_files(files_iter):
  61. assert isinstance(files_iter, Iterator), files_iter
  62. files = list(files_iter)
  63. root = files[0].root
  64. for file in files:
  65. assert file.root == root
  66. assert not file.hash or file.hash.value
  67. assert not file.hash or file.hash.mode == 'sha256'
  68. assert not file.size or file.size >= 0
  69. assert file.locate().exists()
  70. assert isinstance(file.read_binary(), bytes)
  71. if file.name.endswith('.py'):
  72. file.read_text()
  73. def test_file_hash_repr(self):
  74. try:
  75. assertRegex = self.assertRegex
  76. except AttributeError:
  77. # Python 2
  78. assertRegex = self.assertRegexpMatches
  79. util = [
  80. p for p in files('distinfo-pkg')
  81. if p.name == 'mod.py'
  82. ][0]
  83. assertRegex(
  84. repr(util.hash),
  85. '<FileHash mode: sha256 value: .*>')
  86. def test_files_dist_info(self):
  87. self._test_files(files('distinfo-pkg'))
  88. def test_files_egg_info(self):
  89. self._test_files(files('egginfo-pkg'))
  90. def test_version_egg_info_file(self):
  91. self.assertEqual(version('egginfo-file'), '0.1')
  92. def test_requires_egg_info_file(self):
  93. requirements = requires('egginfo-file')
  94. self.assertIsNone(requirements)
  95. def test_requires(self):
  96. deps = requires('egginfo-pkg')
  97. assert any(
  98. dep == 'wheel >= 1.0; python_version >= "2.7"'
  99. for dep in deps
  100. )
  101. def test_requires_dist_info(self):
  102. deps = list(requires('distinfo-pkg'))
  103. assert deps and all(deps)
  104. def test_more_complex_deps_requires_text(self):
  105. requires = textwrap.dedent("""
  106. dep1
  107. dep2
  108. [:python_version < "3"]
  109. dep3
  110. [extra1]
  111. dep4
  112. [extra2:python_version < "3"]
  113. dep5
  114. """)
  115. deps = sorted(Distribution._deps_from_requires_text(requires))
  116. expected = [
  117. 'dep1',
  118. 'dep2',
  119. 'dep3; python_version < "3"',
  120. 'dep4; extra == "extra1"',
  121. 'dep5; (python_version < "3") and extra == "extra2"',
  122. ]
  123. # It's important that the environment marker expression be
  124. # wrapped in parentheses to avoid the following 'and' binding more
  125. # tightly than some other part of the environment expression.
  126. assert deps == expected
  127. class OffSysPathTests(fixtures.DistInfoPkgOffPath, unittest.TestCase):
  128. def test_find_distributions_specified_path(self):
  129. dists = itertools.chain.from_iterable(
  130. resolver(path=[str(self.site_dir)])
  131. for resolver in Distribution._discover_resolvers()
  132. )
  133. assert any(
  134. dist.metadata['Name'] == 'distinfo-pkg'
  135. for dist in dists
  136. )