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'] } metadata = LegacyMetadata(mapping=fields) PKG_INFO = StringIO() metadata.write_file(PKG_INFO) PKG_INFO.seek(0) metadata = LegacyMetadata(fileobj=PKG_INFO) 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_instantiation(self): PKG_INFO = os.path.join(HERE, 'PKG-INFO') f = codecs.open(PKG_INFO, 'r', encoding='utf-8') try: contents = f.read() finally: f.close() fp = StringIO(contents) m = LegacyMetadata() self.assertRaises(MetadataUnrecognizedVersionError, m.items) m = LegacyMetadata(PKG_INFO) self.assertEqual(len(m.items()), 22) m = LegacyMetadata(fileobj=fp) self.assertEqual(len(m.items()), 22) m = LegacyMetadata(mapping=dict(name='Test', version='1.0')) self.assertEqual(len(m.items()), 17) d = dict(m.items()) self.assertRaises(TypeError, LegacyMetadata, PKG_INFO, fileobj=fp) self.assertRaises(TypeError, LegacyMetadata, PKG_INFO, mapping=d) self.assertRaises(TypeError, LegacyMetadata, fileobj=fp, mapping=d) self.assertRaises(TypeError, LegacyMetadata, PKG_INFO, mapping=m, fileobj=fp)
def test_metadata_read_write(self): PKG_INFO = os.path.join(HERE, 'PKG-INFO') metadata = LegacyMetadata(PKG_INFO) out = StringIO() metadata.write_file(out) out.seek(0) res = LegacyMetadata() res.read_file(out) self.assertEqual(metadata.values(), res.values())
def test_check_homepage(self): metadata = LegacyMetadata() metadata['Version'] = '1.0' metadata['Name'] = 'vimpdb' metadata['Author'] = 'Monty Python' missing, warnings = metadata.check() self.assertEqual(missing, ['Home-page'])
def test_check_author(self): metadata = LegacyMetadata() metadata['Version'] = '1.0' metadata['Name'] = 'vimpdb' metadata['Home-page'] = 'http://pypi.org' missing, warnings = metadata.check() self.assertEqual(missing, ['Author'])
def test_project_url(self): metadata = LegacyMetadata() metadata['Project-URL'] = [('one', 'http://ok')] self.assertEqual(metadata['Project-URL'], [('one', 'http://ok')]) metadata.set_metadata_version() 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 = LegacyMetadata() metadata.read_file(fp) self.assertEqual(metadata['Project-Url'], [('one', 'http://ok')])
def test_fullname(self): md = LegacyMetadata() md['Name'] = 'a b c' md['Version'] = '1 0 0' s = md.get_fullname() self.assertEqual(s, 'a b c-1 0 0') s = md.get_fullname(True) self.assertEqual(s, 'a-b-c-1.0.0')
def test_write_metadata(self): # check support of non-ASCII values tmp_dir = self.mkdtemp() my_file = os.path.join(tmp_dir, 'f') metadata = LegacyMetadata( mapping={ 'author': 'Mister Café', 'name': 'my.project', 'author': 'Café Junior', 'summary': 'Café torréfié', 'description': 'Héhéhé', 'keywords': ['café', 'coffee'] }) metadata.write(my_file) # the file should use UTF-8 metadata2 = LegacyMetadata() fp = codecs.open(my_file, encoding='utf-8') try: metadata2.read_file(fp) finally: fp.close() # XXX when keywords are not defined, metadata will have # 'Keywords': [] but metadata2 will have 'Keywords': [''] # because of a value.split(',') in LegacyMetadata.get self.assertEqual(metadata.items(), metadata2.items()) # ASCII also works, it's a subset of UTF-8 metadata = LegacyMetadata( mapping={ 'author': 'Mister Cafe', 'name': 'my.project', 'author': 'Cafe Junior', 'summary': 'Cafe torrefie', 'description': 'Hehehe' }) metadata.write(my_file) metadata2 = LegacyMetadata() fp = codecs.open(my_file, encoding='utf-8') try: metadata2.read_file(fp) finally: fp.close()
def test_version(self): LegacyMetadata(mapping={ 'author': 'xxx', 'name': 'xxx', 'version': 'xxx', 'home_page': 'xxxx' }) logs = self.get_logs() self.assertEqual(1, len(logs)) self.assertIn('not a valid version', logs[0])
def test_provides_dist(self): fields = { 'name': 'project', 'version': '1.0', 'provides_dist': ['project', 'my.project'] } metadata = LegacyMetadata(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)
def test_check_matchers(self): metadata = LegacyMetadata() metadata['Version'] = 'rr' metadata['Name'] = 'vimpdb' metadata['Home-page'] = 'http://pypi.org' metadata['Author'] = 'Monty Python' metadata['Requires-dist'] = ['Foo (a)'] metadata['Obsoletes-dist'] = ['Foo (a)'] metadata['Provides-dist'] = ['Foo (a)'] missing, warnings = metadata.check() self.assertEqual(len(warnings), 4)
def test_description(self): content = self.get_file_contents('PKG-INFO') metadata = LegacyMetadata() metadata.read_file(StringIO(content)) # see if we can read the description now DESC = os.path.join(HERE, '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 = LegacyMetadata() metadata.read_file(out) self.assertEqual(wanted, metadata['Description'])
def test_requires_dist(self): fields = { 'name': 'project', 'version': '1.0', 'requires_dist': ['other', 'another (==1.0)'] } metadata = LegacyMetadata(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 constraints # XXX this would cause no warnings if we used update (or the mapping # argument of the constructor), see comment in LegacyMetadata.update metadata = LegacyMetadata() metadata['Requires-Dist'] = 'Funky (Groovie)' metadata['Requires-Python'] = '1a-4' self.assertEqual(len(self.get_logs()), 2) # test multiple version matches metadata = LegacyMetadata() # 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(), [])
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 = LegacyMetadata() metadata['description'] = desc metadata.write_file(out) # folded_desc = desc.replace('\n', '\n' + (7 * ' ') + '|') folded_desc = desc.replace('\n', '\n' + (8 * ' ')) self.assertIn(folded_desc, out.getvalue())
def test_mapping_api(self): content = self.get_file_contents('PKG-INFO') metadata = LegacyMetadata(fileobj=StringIO(content)) self.assertIn('Version', metadata.keys()) self.assertIn('0.5', metadata.values()) self.assertIn(('Version', '0.5'), metadata.items()) metadata.update({'version': '0.6'}) self.assertEqual(metadata['Version'], '0.6') metadata.update([('version', '0.7')]) self.assertEqual(metadata['Version'], '0.7') # use a kwarg to update metadata.update(version='0.6') self.assertEqual(metadata['Version'], '0.6') # make sure update method checks values like the set method does metadata.update({'version': '1--2'}) self.assertEqual(len(self.get_logs()), 1) self.assertEqual(list(metadata), metadata.keys())
def test_attribute_access(self): content = self.get_file_contents('PKG-INFO') metadata = LegacyMetadata(fileobj=StringIO(content)) for attr in _ATTR2FIELD: self.assertEqual(getattr(metadata, attr), metadata[attr])
def test_fields(self): md = LegacyMetadata() self.assertTrue(md.is_multi_field('Requires-Dist')) self.assertFalse(md.is_multi_field('Name')) self.assertTrue(md.is_field('Obsoleted-By')) self.assertFalse(md.is_field('Frobozz'))
def test_check_name_strict(self): metadata = LegacyMetadata() metadata['Version'] = '1.0' metadata['Home-page'] = 'http://pypi.org' metadata['Author'] = 'Monty Python' self.assertRaises(MetadataMissingError, metadata.check, strict=True)
def test_check_version_strict(self): metadata = LegacyMetadata() metadata['Name'] = 'vimpdb' metadata['Home-page'] = 'http://pypi.python.org' metadata['Author'] = 'Monty Python' self.assertRaises(MetadataMissingError, metadata.check, strict=True)
def test_metadata_versions(self): metadata = LegacyMetadata(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'] metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '1.1') metadata = LegacyMetadata() metadata['Download-URL'] = 'ok' metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '1.1') metadata = LegacyMetadata() metadata['Obsoletes'] = 'ok' metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '1.1') del metadata['Obsoletes'] metadata['Obsoletes-Dist'] = 'ok' metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '1.2') metadata.set('Obsoletes', 'ok') # See issue #140. Relaxed checking on Obsoletes # self.assertRaises(MetadataConflictError, # metadata.set_metadata_version) metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '2.0') del metadata['Obsoletes'] del metadata['Obsoletes-Dist'] metadata.set_metadata_version() metadata['Version'] = '1' self.assertEqual(metadata['Metadata-Version'], '1.1') # 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 = LegacyMetadata() metadata['Requires-Python'] = '3' metadata['Classifier'] = ['Programming language :: Python :: 3'] metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '1.2') PKG_INFO = os.path.join(HERE, 'SETUPTOOLS-PKG-INFO') metadata = LegacyMetadata(PKG_INFO) self.assertEqual(metadata['Metadata-Version'], '1.0') PKG_INFO = os.path.join(HERE, 'SETUPTOOLS-PKG-INFO2') metadata = LegacyMetadata(PKG_INFO) self.assertEqual(metadata['Metadata-Version'], '1.1') # make sure an empty list for Obsoletes and Requires-dist gets ignored metadata['Obsoletes'] = [] metadata['Requires-dist'] = [] metadata.set_metadata_version() 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) # add a test for 2.1 metadata = LegacyMetadata() metadata[ 'Description-Content-Type'] = 'text/markdown; charset=UTF-8; variant=CommonMark' metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '2.1')