test_main.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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 importlib_metadata import _hooks
  10. try:
  11. from builtins import str as text
  12. except ImportError:
  13. from __builtin__ import unicode as text
  14. class BasicTests(unittest.TestCase):
  15. version_pattern = r'\d+\.\d+(\.\d)?'
  16. def test_retrieves_version_of_pip(self):
  17. # Assume pip is installed and retrieve the version of pip.
  18. dist = importlib_metadata.Distribution.from_name('pip')
  19. assert isinstance(dist.version, text)
  20. assert re.match(self.version_pattern, dist.version)
  21. def test_for_name_does_not_exist(self):
  22. with self.assertRaises(importlib_metadata.PackageNotFoundError):
  23. importlib_metadata.Distribution.from_name('does-not-exist')
  24. def test_new_style_classes(self):
  25. self.assertIsInstance(importlib_metadata.Distribution, type)
  26. self.assertIsInstance(_hooks.MetadataPathFinder, type)
  27. self.assertIsInstance(_hooks.WheelMetadataFinder, type)
  28. self.assertIsInstance(_hooks.WheelDistribution, type)
  29. class ImportTests(unittest.TestCase):
  30. def test_import_nonexistent_module(self):
  31. # Ensure that the MetadataPathFinder does not crash an import of a
  32. # non-existant module.
  33. with self.assertRaises(ImportError):
  34. importlib.import_module('does_not_exist')
  35. def test_resolve(self):
  36. scripts = dict(importlib_metadata.entry_points()['console_scripts'])
  37. pip_ep = scripts['pip']
  38. import pip._internal
  39. self.assertEqual(pip_ep.load(), pip._internal.main)
  40. class NameNormalizationTests(fixtures.SiteDir, unittest.TestCase):
  41. @staticmethod
  42. def pkg_with_dashes(site_dir):
  43. """
  44. Create minimal metadata for a package with dashes
  45. in the name (and thus underscores in the filename).
  46. """
  47. metadata_dir = site_dir / 'my_pkg.dist-info'
  48. metadata_dir.mkdir()
  49. metadata = metadata_dir / 'METADATA'
  50. with metadata.open('w') as strm:
  51. strm.write('Version: 1.0\n')
  52. return 'my-pkg'
  53. def test_dashes_in_dist_name_found_as_underscores(self):
  54. """
  55. For a package with a dash in the name, the dist-info metadata
  56. uses underscores in the name. Ensure the metadata loads.
  57. """
  58. pkg_name = self.pkg_with_dashes(self.site_dir)
  59. assert importlib_metadata.version(pkg_name) == '1.0'
  60. @staticmethod
  61. def pkg_with_mixed_case(site_dir):
  62. """
  63. Create minimal metadata for a package with mixed case
  64. in the name.
  65. """
  66. metadata_dir = site_dir / 'CherryPy.dist-info'
  67. metadata_dir.mkdir()
  68. metadata = metadata_dir / 'METADATA'
  69. with metadata.open('w') as strm:
  70. strm.write('Version: 1.0\n')
  71. return 'CherryPy'
  72. def test_dist_name_found_as_any_case(self):
  73. """
  74. Ensure the metadata loads when queried with any case.
  75. """
  76. pkg_name = self.pkg_with_mixed_case(self.site_dir)
  77. assert importlib_metadata.version(pkg_name) == '1.0'
  78. assert importlib_metadata.version(pkg_name.lower()) == '1.0'
  79. assert importlib_metadata.version(pkg_name.upper()) == '1.0'
  80. class NonASCIITests(fixtures.SiteDir, unittest.TestCase):
  81. @staticmethod
  82. def pkg_with_non_ascii_description(site_dir):
  83. """
  84. Create minimal metadata for a package with non-ASCII in
  85. the description.
  86. """
  87. metadata_dir = site_dir / 'portend.dist-info'
  88. metadata_dir.mkdir()
  89. metadata = metadata_dir / 'METADATA'
  90. with metadata.open('w', encoding='utf-8') as fp:
  91. fp.write('Description: pôrˈtend\n')
  92. return 'portend'
  93. @staticmethod
  94. def pkg_with_non_ascii_description_egg_info(site_dir):
  95. """
  96. Create minimal metadata for an egg-info package with
  97. non-ASCII in the description.
  98. """
  99. metadata_dir = site_dir / 'portend.dist-info'
  100. metadata_dir.mkdir()
  101. metadata = metadata_dir / 'METADATA'
  102. with metadata.open('w', encoding='utf-8') as fp:
  103. fp.write(textwrap.dedent("""
  104. Name: portend
  105. pôrˈtend
  106. """).lstrip())
  107. return 'portend'
  108. def test_metadata_loads(self):
  109. pkg_name = self.pkg_with_non_ascii_description(self.site_dir)
  110. meta = importlib_metadata.metadata(pkg_name)
  111. assert meta['Description'] == 'pôrˈtend'
  112. def test_metadata_loads_egg_info(self):
  113. pkg_name = self.pkg_with_non_ascii_description_egg_info(self.site_dir)
  114. meta = importlib_metadata.metadata(pkg_name)
  115. assert meta.get_payload() == 'pôrˈtend\n'
  116. class DiscoveryTests(unittest.TestCase):
  117. def test_package_discovery(self):
  118. dists = list(importlib_metadata.api.distributions())
  119. assert all(
  120. isinstance(dist, importlib_metadata.Distribution)
  121. for dist in dists
  122. )
  123. assert any(
  124. dist.metadata['Name'] == 'importlib-metadata'
  125. for dist in dists
  126. )
  127. assert any(
  128. dist.metadata['Name'] == 'pip'
  129. for dist in dists
  130. )