test_main.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. import re
  4. import textwrap
  5. import unittest
  6. import importlib
  7. import importlib_metadata
  8. from . import fixtures
  9. from .. import (
  10. Distribution, EntryPoint, MetadataPathFinder,
  11. PackageNotFoundError, distributions,
  12. entry_points, metadata, version,
  13. )
  14. try:
  15. from builtins import str as text
  16. except ImportError:
  17. from __builtin__ import unicode as text
  18. class BasicTests(fixtures.DistInfoPkg, unittest.TestCase):
  19. version_pattern = r'\d+\.\d+(\.\d)?'
  20. def test_retrieves_version_of_self(self):
  21. dist = Distribution.from_name('distinfo-pkg')
  22. assert isinstance(dist.version, text)
  23. assert re.match(self.version_pattern, dist.version)
  24. def test_for_name_does_not_exist(self):
  25. with self.assertRaises(PackageNotFoundError):
  26. Distribution.from_name('does-not-exist')
  27. def test_new_style_classes(self):
  28. self.assertIsInstance(Distribution, type)
  29. self.assertIsInstance(MetadataPathFinder, type)
  30. class ImportTests(fixtures.DistInfoPkg, unittest.TestCase):
  31. def test_import_nonexistent_module(self):
  32. # Ensure that the MetadataPathFinder does not crash an import of a
  33. # non-existant module.
  34. with self.assertRaises(ImportError):
  35. importlib.import_module('does_not_exist')
  36. def test_resolve(self):
  37. entries = dict(entry_points()['entries'])
  38. ep = entries['main']
  39. self.assertEqual(ep.load().__name__, "main")
  40. def test_resolve_without_attr(self):
  41. ep = EntryPoint(
  42. name='ep',
  43. value='importlib_metadata',
  44. group='grp',
  45. )
  46. assert ep.load() is importlib_metadata
  47. class NameNormalizationTests(
  48. fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase):
  49. @staticmethod
  50. def pkg_with_dashes(site_dir):
  51. """
  52. Create minimal metadata for a package with dashes
  53. in the name (and thus underscores in the filename).
  54. """
  55. metadata_dir = site_dir / 'my_pkg.dist-info'
  56. metadata_dir.mkdir()
  57. metadata = metadata_dir / 'METADATA'
  58. with metadata.open('w') as strm:
  59. strm.write('Version: 1.0\n')
  60. return 'my-pkg'
  61. def test_dashes_in_dist_name_found_as_underscores(self):
  62. """
  63. For a package with a dash in the name, the dist-info metadata
  64. uses underscores in the name. Ensure the metadata loads.
  65. """
  66. pkg_name = self.pkg_with_dashes(self.site_dir)
  67. assert version(pkg_name) == '1.0'
  68. @staticmethod
  69. def pkg_with_mixed_case(site_dir):
  70. """
  71. Create minimal metadata for a package with mixed case
  72. in the name.
  73. """
  74. metadata_dir = site_dir / 'CherryPy.dist-info'
  75. metadata_dir.mkdir()
  76. metadata = metadata_dir / 'METADATA'
  77. with metadata.open('w') as strm:
  78. strm.write('Version: 1.0\n')
  79. return 'CherryPy'
  80. def test_dist_name_found_as_any_case(self):
  81. """
  82. Ensure the metadata loads when queried with any case.
  83. """
  84. pkg_name = self.pkg_with_mixed_case(self.site_dir)
  85. assert version(pkg_name) == '1.0'
  86. assert version(pkg_name.lower()) == '1.0'
  87. assert version(pkg_name.upper()) == '1.0'
  88. class NonASCIITests(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase):
  89. @staticmethod
  90. def pkg_with_non_ascii_description(site_dir):
  91. """
  92. Create minimal metadata for a package with non-ASCII in
  93. the description.
  94. """
  95. metadata_dir = site_dir / 'portend.dist-info'
  96. metadata_dir.mkdir()
  97. metadata = metadata_dir / 'METADATA'
  98. with metadata.open('w', encoding='utf-8') as fp:
  99. fp.write('Description: pôrˈtend\n')
  100. return 'portend'
  101. @staticmethod
  102. def pkg_with_non_ascii_description_egg_info(site_dir):
  103. """
  104. Create minimal metadata for an egg-info package with
  105. non-ASCII in the description.
  106. """
  107. metadata_dir = site_dir / 'portend.dist-info'
  108. metadata_dir.mkdir()
  109. metadata = metadata_dir / 'METADATA'
  110. with metadata.open('w', encoding='utf-8') as fp:
  111. fp.write(textwrap.dedent("""
  112. Name: portend
  113. pôrˈtend
  114. """).lstrip())
  115. return 'portend'
  116. def test_metadata_loads(self):
  117. pkg_name = self.pkg_with_non_ascii_description(self.site_dir)
  118. meta = metadata(pkg_name)
  119. assert meta['Description'] == 'pôrˈtend'
  120. def test_metadata_loads_egg_info(self):
  121. pkg_name = self.pkg_with_non_ascii_description_egg_info(self.site_dir)
  122. meta = metadata(pkg_name)
  123. assert meta.get_payload() == 'pôrˈtend\n'
  124. class DiscoveryTests(fixtures.EggInfoPkg,
  125. fixtures.DistInfoPkg,
  126. unittest.TestCase):
  127. def test_package_discovery(self):
  128. dists = list(distributions())
  129. assert all(
  130. isinstance(dist, Distribution)
  131. for dist in dists
  132. )
  133. assert any(
  134. dist.metadata['Name'] == 'egginfo-pkg'
  135. for dist in dists
  136. )
  137. assert any(
  138. dist.metadata['Name'] == 'distinfo-pkg'
  139. for dist in dists
  140. )
  141. class DirectoryTest(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase):
  142. def test(self):
  143. # make an `EGG-INFO` directory that's unrelated
  144. self.site_dir.joinpath('EGG-INFO').mkdir()
  145. # used to crash with `IsADirectoryError`
  146. self.assertIsNone(version('unknown-package'))