[Python-checkins] distutils2: Consolidate tests for d2.metadata.
eric.araujo
python-checkins at python.org
Mon Sep 19 15:12:39 CEST 2011
http://hg.python.org/distutils2/rev/d6a26dfd2456
changeset: 1174:d6a26dfd2456
user: Éric Araujo <merwok at netwok.org>
date: Mon Sep 19 04:44:00 2011 +0200
summary:
Consolidate tests for d2.metadata.
New tests were added in test_metadata and old tests inherited from
distutils were still in test_dist, so I moved them into test_metadata
(except for one which was more at home in test_run) and merged
duplicates.
I also added some skips to lure contributors <wink>, optimized the
Metadata.update method a trifle, and added notes about a number of
issues.
A note: The tests in test_dist used to dump the Metadata objects to a
file in the METADATA format and look for strings in its contents; I
updated them to use the mapping API of Metadata instead. For some
fields with special writing rules, I have added tests to ensure my
conversion did not lose anything.
files:
distutils2/metadata.py | 16 +-
distutils2/tests/test_dist.py | 246 +---------
distutils2/tests/test_metadata.py | 415 ++++++++++++-----
distutils2/tests/test_run.py | 19 +-
4 files changed, 350 insertions(+), 346 deletions(-)
diff --git a/distutils2/metadata.py b/distutils2/metadata.py
--- a/distutils2/metadata.py
+++ b/distutils2/metadata.py
@@ -371,11 +371,20 @@
Keys that don't match a metadata field or that have an empty value are
dropped.
"""
+ # XXX the code should just use self.set, which does tbe same checks and
+ # conversions already, but that would break packaging.pypi: it uses the
+ # update method, which does not call _set_best_version (which set
+ # does), and thus allows having a Metadata object (as long as you don't
+ # modify or write it) with extra fields from PyPI that are not fields
+ # defined in Metadata PEPs. to solve it, the best_version system
+ # should be reworked so that it's called only for writing, or in a new
+ # strict mode, or with a new, more lax Metadata subclass in p7g.pypi
def _set(key, value):
if key in _ATTR2FIELD and value:
self.set(self._convert_name(key), value)
- if other is None:
+ if not other:
+ # other is None or empty container
pass
elif hasattr(other, 'keys'):
for k in other.keys():
@@ -385,7 +394,8 @@
_set(k, v)
if kwargs:
- self.update(kwargs)
+ for k, v in kwargs.items():
+ _set(k, v)
def set(self, name, value):
"""Control then set a metadata field."""
@@ -550,7 +560,7 @@
# Mapping API
def keys(self):
- return _version2fieldlist(self['Metadata-Version'])
+ return list(_version2fieldlist(self['Metadata-Version']))
def __iter__(self):
for key in self.keys():
diff --git a/distutils2/tests/test_dist.py b/distutils2/tests/test_dist.py
--- a/distutils2/tests/test_dist.py
+++ b/distutils2/tests/test_dist.py
@@ -4,14 +4,12 @@
import codecs
import logging
import textwrap
-from distutils2._backport import sysconfig
+
import distutils2.dist
-from StringIO import StringIO
from distutils2.dist import Distribution
from distutils2.command import set_command
from distutils2.command.cmd import Command
-from distutils2.metadata import Metadata
from distutils2.errors import PackagingModuleError, PackagingOptionError
from distutils2.tests import captured_stdout
from distutils2.tests import support, unittest
@@ -72,37 +70,7 @@
__, stdout = captured_stdout(create_distribution, files)
self.assertEqual(stdout, '')
finally:
- distutils2.dist.DEBUG = False
-
- def test_write_pkg_file(self):
- # Check Metadata handling of Unicode fields
- tmp_dir = self.mkdtemp()
- my_file = os.path.join(tmp_dir, 'f')
- cls = Distribution
-
- dist = cls(attrs={'author': u'Mister Caf\xe9',
- 'name': 'my.package',
- 'maintainer': u'Caf\xe9 Junior',
- 'summary': u'Caf\xe9 torr\xe9fi\xe9',
- 'description': u'H\xe9h\xe9h\xe9'})
-
- # let's make sure the file can be written
- # with Unicode fields. they are encoded with
- # PKG_INFO_ENCODING
- fp = codecs.open(my_file, 'w', encoding='utf-8')
- dist.metadata.write_file(fp)
- fp.close()
-
- # regular ascii is of course always usable
- dist = cls(attrs={'author': 'Mister Cafe',
- 'name': 'my.package',
- 'maintainer': 'Cafe Junior',
- 'summary': 'Cafe torrefie',
- 'description': 'Hehehe'})
-
- fp = open(my_file, 'w')
- dist.metadata.write_file(fp)
- fp.close()
+ packaging.dist.DEBUG = False
def test_bad_attr(self):
Distribution(attrs={'author': 'xxx',
@@ -114,15 +82,6 @@
self.assertEqual(len(logs), 1)
self.assertIn('unknown argument', logs[0])
- def test_bad_version(self):
- Distribution(attrs={'author': 'xxx',
- 'name': 'xxx',
- 'version': 'xxx',
- 'home_page': 'xxxx'})
- logs = self.get_logs(logging.WARNING)
- self.assertEqual(1, len(logs))
- self.assertIn('not a valid version', logs[0])
-
def test_empty_options(self):
# an empty options dictionary should not stay in the
# list of attributes
@@ -160,6 +119,27 @@
self.assertEqual(dist.metadata['platform'], ['one', 'two'])
self.assertEqual(dist.metadata['keywords'], ['one', 'two'])
+ def test_custom_pydistutils(self):
+ # Bug #2166: make sure pydistutils.cfg is found
+ if os.name == 'posix':
+ user_filename = ".pydistutils.cfg"
+ else:
+ user_filename = "pydistutils.cfg"
+
+ temp_dir = self.mkdtemp()
+ user_filename = os.path.join(temp_dir, user_filename)
+ f = open(user_filename, 'w')
+ try:
+ f.write('.')
+ finally:
+ f.close()
+
+ dist = Distribution()
+
+ os.environ['HOME'] = temp_dir
+ files = dist.find_config_files()
+ self.assertIn(user_filename, files)
+
def test_find_config_files_disable(self):
# Bug #1180: Allow users to disable their own config file.
temp_home = self.mkdtemp()
@@ -281,186 +261,8 @@
self.assertRaises(PackagingOptionError, d.run_command, 'test_dist')
-class MetadataTestCase(support.TempdirManager,
- support.LoggingCatcher,
- support.EnvironRestorer,
- unittest.TestCase):
-
- restore_environ = ['HOME']
-
- def setUp(self):
- super(MetadataTestCase, self).setUp()
- self.argv = sys.argv, sys.argv[:]
-
- def tearDown(self):
- sys.argv = self.argv[0]
- sys.argv[:] = self.argv[1]
- super(MetadataTestCase, self).tearDown()
-
- def test_simple_metadata(self):
- attrs = {"name": "package",
- "version": "1.0"}
- dist = Distribution(attrs)
- meta = self.format_metadata(dist)
- self.assertIn("Metadata-Version: 1.0", meta)
- self.assertNotIn("provides:", meta.lower())
- self.assertNotIn("requires:", meta.lower())
- self.assertNotIn("obsoletes:", meta.lower())
-
- def test_provides_dist(self):
- attrs = {"name": "package",
- "version": "1.0",
- "provides_dist": ["package", "package.sub"]}
- dist = Distribution(attrs)
- self.assertEqual(dist.metadata['Provides-Dist'],
- ["package", "package.sub"])
- meta = self.format_metadata(dist)
- self.assertIn("Metadata-Version: 1.2", meta)
- self.assertNotIn("requires:", meta.lower())
- self.assertNotIn("obsoletes:", meta.lower())
-
- def _test_provides_illegal(self):
- # XXX to do: check the versions
- self.assertRaises(ValueError, Distribution,
- {"name": "package",
- "version": "1.0",
- "provides_dist": ["my.pkg (splat)"]})
-
- def test_requires_dist(self):
- attrs = {"name": "package",
- "version": "1.0",
- "requires_dist": ["other", "another (==1.0)"]}
- dist = Distribution(attrs)
- self.assertEqual(dist.metadata['Requires-Dist'],
- ["other", "another (==1.0)"])
- meta = self.format_metadata(dist)
- self.assertIn("Metadata-Version: 1.2", meta)
- self.assertNotIn("provides:", meta.lower())
- self.assertIn("Requires-Dist: other", meta)
- self.assertIn("Requires-Dist: another (==1.0)", meta)
- self.assertNotIn("obsoletes:", meta.lower())
-
- def _test_requires_illegal(self):
- # XXX
- self.assertRaises(ValueError, Distribution,
- {"name": "package",
- "version": "1.0",
- "requires": ["my.pkg (splat)"]})
-
- def test_obsoletes_dist(self):
- attrs = {"name": "package",
- "version": "1.0",
- "obsoletes_dist": ["other", "another (<1.0)"]}
- dist = Distribution(attrs)
- self.assertEqual(dist.metadata['Obsoletes-Dist'],
- ["other", "another (<1.0)"])
- meta = self.format_metadata(dist)
- self.assertIn("Metadata-Version: 1.2", meta)
- self.assertNotIn("provides:", meta.lower())
- self.assertNotIn("requires:", meta.lower())
- self.assertIn("Obsoletes-Dist: other", meta)
- self.assertIn("Obsoletes-Dist: another (<1.0)", meta)
-
- def _test_obsoletes_illegal(self):
- # XXX
- self.assertRaises(ValueError, Distribution,
- {"name": "package",
- "version": "1.0",
- "obsoletes": ["my.pkg (splat)"]})
-
- def format_metadata(self, dist):
- sio = StringIO()
- dist.metadata.write_file(sio)
- return sio.getvalue()
-
- def test_custom_pydistutils(self):
- # fixes #2166
- # make sure pydistutils.cfg is found
- if os.name == 'posix':
- user_filename = ".pydistutils.cfg"
- else:
- user_filename = "pydistutils.cfg"
-
- temp_dir = self.mkdtemp()
- user_filename = os.path.join(temp_dir, user_filename)
- f = open(user_filename, 'w')
- f.write('.')
- f.close()
-
- dist = Distribution()
-
- # linux-style
- if sys.platform in ('linux', 'darwin'):
- os.environ['HOME'] = temp_dir
- files = dist.find_config_files()
- self.assertIn(user_filename, files)
-
- # win32-style
- if sys.platform == 'win32':
- # home drive should be found
- os.environ['HOME'] = temp_dir
- files = dist.find_config_files()
- self.assertIn(user_filename, files)
-
- def test_show_help(self):
- # smoke test, just makes sure some help is displayed
- dist = Distribution()
- sys.argv = []
- dist.help = True
- dist.script_name = os.path.join(sysconfig.get_path('scripts'),
- 'pysetup')
- __, stdout = captured_stdout(dist.parse_command_line)
- output = [line for line in stdout.split('\n')
- if line.strip() != '']
- self.assertGreater(len(output), 0)
-
- def test_description(self):
- desc = textwrap.dedent("""\
- example::
- We start here
- and continue here
- and end here.""")
- attrs = {"name": "package",
- "version": "1.0",
- "description": desc}
-
- dist = distutils2.dist.Distribution(attrs)
- meta = self.format_metadata(dist)
- meta = meta.replace('\n' + 7 * ' ' + '|', '\n')
- self.assertIn(desc, meta)
-
- def test_read_metadata(self):
- attrs = {"name": "package",
- "version": "1.0",
- "description": "desc",
- "summary": "xxx",
- "download_url": "http://example.com",
- "keywords": ['one', 'two'],
- "requires_dist": ['foo']}
-
- dist = Distribution(attrs)
- PKG_INFO = StringIO()
- dist.metadata.write_file(PKG_INFO)
- PKG_INFO.seek(0)
-
- metadata = Metadata()
- metadata.read_file(PKG_INFO)
-
- self.assertEqual(metadata['name'], "package")
- self.assertEqual(metadata['version'], "1.0")
- self.assertEqual(metadata['summary'], "xxx")
- self.assertEqual(metadata['download_url'], 'http://example.com')
- self.assertEqual(metadata['keywords'], ['one', 'two'])
- self.assertEqual(metadata['platform'], [])
- self.assertEqual(metadata['obsoletes'], [])
- self.assertEqual(metadata['requires-dist'], ['foo'])
-
-
def test_suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(DistributionTestCase))
- suite.addTest(unittest.makeSuite(MetadataTestCase))
- return suite
+ return unittest.makeSuite(DistributionTestCase)
if __name__ == "__main__":
unittest.main(defaultTest="test_suite")
diff --git a/distutils2/tests/test_metadata.py b/distutils2/tests/test_metadata.py
--- a/distutils2/tests/test_metadata.py
+++ b/distutils2/tests/test_metadata.py
@@ -1,21 +1,40 @@
+# encoding: utf-8
"""Tests for distutils2.metadata."""
import os
import sys
import codecs
import logging
+from textwrap import dedent
from StringIO import StringIO
from distutils2.errors import (MetadataConflictError, MetadataMissingError,
- MetadataUnrecognizedVersionError)
+ MetadataUnrecognizedVersionError)
from distutils2.metadata import Metadata, PKG_INFO_PREFERRED_VERSION
from distutils2.tests import unittest
-from distutils2.tests.support import LoggingCatcher
+from distutils2.tests.support import (LoggingCatcher, TempdirManager,
+ EnvironRestorer)
class MetadataTestCase(LoggingCatcher,
+ TempdirManager,
+ EnvironRestorer,
unittest.TestCase):
+ maxDiff = None
+ restore_environ = ['HOME']
+
+ def setUp(self):
+ super(MetadataTestCase, self).setUp()
+ self.argv = sys.argv, sys.argv[:]
+
+ def tearDown(self):
+ sys.argv = self.argv[0]
+ sys.argv[:] = self.argv[1]
+ super(MetadataTestCase, self).tearDown()
+
+ #### Test various methods of the Metadata class
+
def test_instantiation(self):
PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
@@ -48,17 +67,6 @@
self.assertRaises(TypeError, Metadata,
PKG_INFO, mapping=m, fileobj=fp)
- def test_metadata_read_write(self):
- PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
- metadata = Metadata(PKG_INFO)
- out = StringIO()
- metadata.write_file(out)
- out.seek(0)
- res = Metadata()
- res.read_file(out)
- for k in metadata:
- self.assertEqual(metadata[k], res[k])
-
def test_metadata_markers(self):
# see if we can be platform-aware
PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
@@ -82,32 +90,6 @@
metadata.read_file(StringIO(content))
self.assertEqual(metadata['Requires-Dist'], ['foo'])
- def test_description(self):
- PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
- f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
- try:
- content = f.read() % sys.platform
- finally:
- f.close()
- metadata = Metadata()
- metadata.read_file(StringIO(content))
-
- # see if we can read the description now
- DESC = os.path.join(os.path.dirname(__file__), 'LONG_DESC.txt')
- f = open(DESC)
- try:
- wanted = f.read()
- finally:
- f.close()
- self.assertEqual(wanted, metadata['Description'])
-
- # save the file somewhere and make sure we can read it back
- out = StringIO()
- metadata.write_file(out)
- out.seek(0)
- metadata.read_file(out)
- self.assertEqual(wanted, metadata['Description'])
-
def test_mapping_api(self):
PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
@@ -125,80 +107,90 @@
metadata.update([('version', '0.7')])
self.assertEqual(metadata['Version'], '0.7')
- self.assertEqual(list(metadata), list(metadata.keys()))
+ # make sure update method checks values like the set method does
+ metadata.update({'version': '1--2'})
+ self.assertEqual(len(self.get_logs()), 1)
- def test_versions(self):
- metadata = Metadata()
- metadata['Obsoletes'] = 'ok'
- self.assertEqual(metadata['Metadata-Version'], '1.1')
+ self.assertEqual(list(metadata), metadata.keys())
- del metadata['Obsoletes']
- metadata['Obsoletes-Dist'] = 'ok'
- self.assertEqual(metadata['Metadata-Version'], '1.2')
+ def test_read_metadata(self):
+ fields = {'name': 'project',
+ 'version': '1.0',
+ 'description': 'desc',
+ 'summary': 'xxx',
+ 'download_url': 'http://example.com',
+ 'keywords': ['one', 'two'],
+ 'requires_dist': ['foo']}
- self.assertRaises(MetadataConflictError, metadata.set,
- 'Obsoletes', 'ok')
+ metadata = Metadata(mapping=fields)
+ PKG_INFO = StringIO()
+ metadata.write_file(PKG_INFO)
+ PKG_INFO.seek(0)
- del metadata['Obsoletes']
- del metadata['Obsoletes-Dist']
- metadata['Version'] = '1'
- self.assertEqual(metadata['Metadata-Version'], '1.0')
+ metadata = Metadata(fileobj=PKG_INFO)
- PKG_INFO = os.path.join(os.path.dirname(__file__),
- 'SETUPTOOLS-PKG-INFO')
- f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
+ self.assertEqual(metadata['name'], 'project')
+ self.assertEqual(metadata['version'], '1.0')
+ self.assertEqual(metadata['summary'], 'xxx')
+ self.assertEqual(metadata['download_url'], 'http://example.com')
+ self.assertEqual(metadata['keywords'], ['one', 'two'])
+ self.assertEqual(metadata['platform'], [])
+ self.assertEqual(metadata['obsoletes'], [])
+ self.assertEqual(metadata['requires-dist'], ['foo'])
+
+ def test_write_metadata(self):
+ # check support of non-ASCII values
+ tmp_dir = self.mkdtemp()
+ my_file = os.path.join(tmp_dir, 'f')
+
+ metadata = Metadata(mapping={'author': u'Mister Café',
+ 'name': u'my.project',
+ 'author': u'Café Junior',
+ 'summary': u'Café torréfié',
+ 'description': u'Héhéhé',
+ 'keywords': [u'café', u'coffee']})
+ metadata.write(my_file)
+
+ # the file should use UTF-8
+ metadata2 = Metadata()
+ fp = codecs.open(my_file, encoding='utf-8')
try:
- content = f.read()
+ metadata2.read_file(fp)
finally:
- f.close()
- metadata.read_file(StringIO(content))
- self.assertEqual(metadata['Metadata-Version'], '1.0')
+ fp.close()
- PKG_INFO = os.path.join(os.path.dirname(__file__),
- 'SETUPTOOLS-PKG-INFO2')
- f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
+ # XXX when keywords are not defined, metadata will have
+ # 'Keywords': [] but metadata2 will have 'Keywords': ['']
+ # because of a value.split(',') in Metadata.get
+ self.assertEqual(metadata.items(), metadata2.items())
+
+ # ASCII also works, it's a subset of UTF-8
+ metadata = Metadata(mapping={'author': u'Mister Cafe',
+ 'name': u'my.project',
+ 'author': u'Cafe Junior',
+ 'summary': u'Cafe torrefie',
+ 'description': u'Hehehe'})
+ metadata.write(my_file)
+
+ metadata2 = Metadata()
+ fp = codecs.open(my_file, encoding='utf-8')
try:
- content = f.read()
+ metadata2.read_file(fp)
finally:
- f.close()
+ fp.close()
- metadata.read_file(StringIO(content))
- self.assertEqual(metadata['Metadata-Version'], '1.1')
+ def test_metadata_read_write(self):
+ PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
+ metadata = Metadata(PKG_INFO)
+ out = StringIO()
+ metadata.write_file(out)
- # Update the _fields dict directly to prevent 'Metadata-Version'
- # from being updated by the _set_best_version() method.
- metadata._fields['Metadata-Version'] = '1.618'
- self.assertRaises(MetadataUnrecognizedVersionError, metadata.keys)
+ out.seek(0)
+ res = Metadata()
+ res.read_file(out)
+ self.assertEqual(metadata.values(), res.values())
- def test_warnings(self):
- metadata = Metadata()
-
- # these should raise a warning
- values = (('Requires-Dist', 'Funky (Groovie)'),
- ('Requires-Python', '1-4'))
-
- for name, value in values:
- metadata.set(name, value)
-
- # we should have a certain amount of warnings
- self.assertEqual(len(self.get_logs()), 2)
-
- def test_multiple_predicates(self):
- metadata = Metadata()
-
- # see for "3" instead of "3.0" ???
- # its seems like the MINOR VERSION can be omitted
- metadata['Requires-Python'] = '>=2.6, <3.0'
- metadata['Requires-Dist'] = ['Foo (>=2.6, <3.0)']
-
- self.assertEqual([], self.get_logs(logging.WARNING))
-
- def test_project_url(self):
- metadata = Metadata()
- metadata['Project-URL'] = [('one', 'http://ok')]
- self.assertEqual(metadata['Project-URL'],
- [('one', 'http://ok')])
- self.assertEqual(metadata['Metadata-Version'], '1.2')
+ #### Test checks
def test_check_version(self):
metadata = Metadata()
@@ -261,38 +253,221 @@
metadata['Requires-dist'] = ['Foo (a)']
metadata['Obsoletes-dist'] = ['Foo (a)']
metadata['Provides-dist'] = ['Foo (a)']
- if metadata.docutils_support:
- missing, warnings = metadata.check()
- self.assertEqual(len(warnings), 4)
- metadata.docutils_support = False
missing, warnings = metadata.check()
self.assertEqual(len(warnings), 4)
- def test_best_choice(self):
- metadata = Metadata()
- metadata['Version'] = '1.0'
+ #### Test fields and metadata versions
+
+ def test_metadata_versions(self):
+ metadata = Metadata(mapping={'name': 'project', 'version': '1.0'})
self.assertEqual(metadata['Metadata-Version'],
PKG_INFO_PREFERRED_VERSION)
+ self.assertNotIn('Provides', metadata)
+ self.assertNotIn('Requires', metadata)
+ self.assertNotIn('Obsoletes', metadata)
+
metadata['Classifier'] = ['ok']
self.assertEqual(metadata['Metadata-Version'], '1.2')
- def test_project_urls(self):
- # project-url is a bit specific, make sure we write it
- # properly in PKG-INFO
metadata = Metadata()
- metadata['Version'] = '1.0'
- metadata['Project-Url'] = [('one', 'http://ok')]
+ metadata['Download-URL'] = 'ok'
+ self.assertEqual(metadata['Metadata-Version'], '1.2')
+
+ metadata = Metadata()
+ metadata['Obsoletes'] = 'ok'
+ self.assertEqual(metadata['Metadata-Version'], '1.1')
+
+ del metadata['Obsoletes']
+ metadata['Obsoletes-Dist'] = 'ok'
+ self.assertEqual(metadata['Metadata-Version'], '1.2')
+
+ self.assertRaises(MetadataConflictError, metadata.set,
+ 'Obsoletes', 'ok')
+
+ del metadata['Obsoletes']
+ del metadata['Obsoletes-Dist']
+ metadata['Version'] = '1'
+ self.assertEqual(metadata['Metadata-Version'], '1.0')
+
+ # make sure the _best_version function works okay with
+ # non-conflicting fields from 1.1 and 1.2 (i.e. we want only the
+ # requires/requires-dist and co. pairs to cause a conflict, not all
+ # fields in _314_MARKERS)
+ metadata = Metadata()
+ metadata['Requires-Python'] = '3'
+ metadata['Classifier'] = ['Programming language :: Python :: 3']
+ self.assertEqual(metadata['Metadata-Version'], '1.2')
+
+ PKG_INFO = os.path.join(os.path.dirname(__file__),
+ 'SETUPTOOLS-PKG-INFO')
+ metadata = Metadata(PKG_INFO)
+ self.assertEqual(metadata['Metadata-Version'], '1.0')
+
+ PKG_INFO = os.path.join(os.path.dirname(__file__),
+ 'SETUPTOOLS-PKG-INFO2')
+ metadata = Metadata(PKG_INFO)
+ self.assertEqual(metadata['Metadata-Version'], '1.1')
+
+ # Update the _fields dict directly to prevent 'Metadata-Version'
+ # from being updated by the _set_best_version() method.
+ metadata._fields['Metadata-Version'] = '1.618'
+ self.assertRaises(MetadataUnrecognizedVersionError, metadata.keys)
+
+ def test_version(self):
+ Metadata(mapping={'author': 'xxx',
+ 'name': 'xxx',
+ 'version': 'xxx',
+ 'home_page': 'xxxx'})
+ logs = self.get_logs(logging.WARNING)
+ self.assertEqual(1, len(logs))
+ self.assertIn('not a valid version', logs[0])
+
+ def test_description(self):
+ PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
+ f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
+ try:
+ content = f.read() % sys.platform
+ finally:
+ f.close()
+ metadata = Metadata()
+ metadata.read_file(StringIO(content))
+
+ # see if we can read the description now
+ DESC = os.path.join(os.path.dirname(__file__), 'LONG_DESC.txt')
+ f = open(DESC)
+ try:
+ wanted = f.read()
+ finally:
+ f.close()
+ self.assertEqual(wanted, metadata['Description'])
+
+ # save the file somewhere and make sure we can read it back
+ out = StringIO()
+ metadata.write_file(out)
+ out.seek(0)
+
+ out.seek(0)
+ metadata = Metadata()
+ metadata.read_file(out)
+ self.assertEqual(wanted, metadata['Description'])
+
+ def test_description_folding(self):
+ # make sure the indentation is preserved
+ out = StringIO()
+ desc = dedent("""\
+ example::
+ We start here
+ and continue here
+ and end here.
+ """)
+
+ metadata = Metadata()
+ metadata['description'] = desc
+ metadata.write_file(out)
+
+ folded_desc = desc.replace('\n', '\n' + (7 * ' ') + '|')
+ self.assertIn(folded_desc, out.getvalue())
+
+ def test_project_url(self):
+ metadata = Metadata()
+ metadata['Project-URL'] = [('one', 'http://ok')]
+ self.assertEqual(metadata['Project-URL'], [('one', 'http://ok')])
+ self.assertEqual(metadata['Metadata-Version'], '1.2')
+
+ # make sure this particular field is handled properly when written
+ fp = StringIO()
+ metadata.write_file(fp)
+ self.assertIn('Project-URL: one,http://ok', fp.getvalue().split('\n'))
+
+ fp.seek(0)
+ metadata = Metadata()
+ metadata.read_file(fp)
self.assertEqual(metadata['Project-Url'], [('one', 'http://ok')])
- file_ = StringIO()
- metadata.write_file(file_)
- file_.seek(0)
- res = file_.read().split('\n')
- self.assertIn('Project-URL: one,http://ok', res)
- file_.seek(0)
+ # TODO copy tests for v1.1 requires, obsoletes and provides from distutils
+ # (they're useless but we support them so we should test them anyway)
+
+ def test_provides_dist(self):
+ fields = {'name': 'project',
+ 'version': '1.0',
+ 'provides_dist': ['project', 'my.project']}
+ metadata = Metadata(mapping=fields)
+ self.assertEqual(metadata['Provides-Dist'],
+ ['project', 'my.project'])
+ self.assertEqual(metadata['Metadata-Version'], '1.2', metadata)
+ self.assertNotIn('Requires', metadata)
+ self.assertNotIn('Obsoletes', metadata)
+
+ @unittest.skip('needs to be implemented')
+ def test_provides_illegal(self):
+ # TODO check the versions (like distutils does for old provides field)
+ self.assertRaises(ValueError, Metadata,
+ mapping={'name': 'project',
+ 'version': '1.0',
+ 'provides_dist': ['my.pkg (splat)']})
+
+ def test_requires_dist(self):
+ fields = {'name': 'project',
+ 'version': '1.0',
+ 'requires_dist': ['other', 'another (==1.0)']}
+ metadata = Metadata(mapping=fields)
+ self.assertEqual(metadata['Requires-Dist'],
+ ['other', 'another (==1.0)'])
+ self.assertEqual(metadata['Metadata-Version'], '1.2')
+ self.assertNotIn('Provides', metadata)
+ self.assertEqual(metadata['Requires-Dist'],
+ ['other', 'another (==1.0)'])
+ self.assertNotIn('Obsoletes', metadata)
+
+ # make sure write_file uses one RFC 822 header per item
+ fp = StringIO()
+ metadata.write_file(fp)
+ lines = fp.getvalue().split('\n')
+ self.assertIn('Requires-Dist: other', lines)
+ self.assertIn('Requires-Dist: another (==1.0)', lines)
+
+ # test warnings for invalid version predicates
+ # XXX this would cause no warnings if we used update (or the mapping
+ # argument of the constructor), see comment in Metadata.update
metadata = Metadata()
- metadata.read_file(file_)
- self.assertEqual(metadata['Project-Url'], [('one', 'http://ok')])
+ metadata['Requires-Dist'] = 'Funky (Groovie)'
+ metadata['Requires-Python'] = '1-4'
+ self.assertEqual(len(self.get_logs()), 2)
+
+ # test multiple version predicates
+ metadata = Metadata()
+
+ # XXX check PEP and see if 3 == 3.0
+ metadata['Requires-Python'] = '>=2.6, <3.0'
+ metadata['Requires-Dist'] = ['Foo (>=2.6, <3.0)']
+ self.assertEqual([], self.get_logs(logging.WARNING))
+
+ @unittest.skip('needs to be implemented')
+ def test_requires_illegal(self):
+ self.assertRaises(ValueError, Metadata,
+ mapping={'name': 'project',
+ 'version': '1.0',
+ 'requires': ['my.pkg (splat)']})
+
+ def test_obsoletes_dist(self):
+ fields = {'name': 'project',
+ 'version': '1.0',
+ 'obsoletes_dist': ['other', 'another (<1.0)']}
+ metadata = Metadata(mapping=fields)
+ self.assertEqual(metadata['Obsoletes-Dist'],
+ ['other', 'another (<1.0)'])
+ self.assertEqual(metadata['Metadata-Version'], '1.2')
+ self.assertNotIn('Provides', metadata)
+ self.assertNotIn('Requires', metadata)
+ self.assertEqual(metadata['Obsoletes-Dist'],
+ ['other', 'another (<1.0)'])
+
+ @unittest.skip('needs to be implemented')
+ def test_obsoletes_illegal(self):
+ self.assertRaises(ValueError, Metadata,
+ mapping={'name': 'project',
+ 'version': '1.0',
+ 'obsoletes': ['my.pkg (splat)']})
def test_suite():
diff --git a/distutils2/tests/test_run.py b/distutils2/tests/test_run.py
--- a/distutils2/tests/test_run.py
+++ b/distutils2/tests/test_run.py
@@ -2,13 +2,14 @@
import os
import sys
-import shutil
from StringIO import StringIO
from distutils2 import install
from distutils2.tests import unittest, support
from distutils2.run import main
+from distutils2.tests.support import assert_python_ok
+
# setup script that uses __file__
setup_using___file__ = """\
__file__
@@ -61,6 +62,22 @@
os.chmod(install_path, old_mod)
install.get_path = old_get_path
+ def test_show_help(self):
+ # smoke test, just makes sure some help is displayed
+ pythonpath = os.environ.get('PYTHONPATH')
+ d2parent = os.path.dirname(os.path.dirname(__file__))
+ if pythonpath is not None:
+ pythonpath = os.pathsep.join((pythonpath, d2parent))
+ else:
+ pythonpath = d2parent
+
+ status, out, err = assert_python_ok(
+ '-c', 'from distutils2.run import main; main()', '--help',
+ PYTHONPATH=pythonpath)
+ self.assertEqual(status, 0)
+ self.assertGreater(out, '')
+ self.assertEqual(err, '')
+
def test_suite():
return unittest.makeSuite(RunTestCase)
--
Repository URL: http://hg.python.org/distutils2
More information about the Python-checkins
mailing list