diff options
Diffstat (limited to 'Lib/packaging/tests/test_manifest.py')
-rw-r--r-- | Lib/packaging/tests/test_manifest.py | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/Lib/packaging/tests/test_manifest.py b/Lib/packaging/tests/test_manifest.py new file mode 100644 index 0000000..f768c47 --- /dev/null +++ b/Lib/packaging/tests/test_manifest.py @@ -0,0 +1,263 @@ +"""Tests for packaging.manifest.""" +import os +import re +from io import StringIO +from packaging.errors import PackagingTemplateError +from packaging.manifest import Manifest, _translate_pattern, _glob_to_re + +from packaging.tests import unittest, support + +_MANIFEST = """\ +recursive-include foo *.py # ok +# nothing here + +# + +recursive-include bar \\ + *.dat *.txt +""" + +_MANIFEST2 = """\ +README +file1 +""" + + +class ManifestTestCase(support.TempdirManager, + support.LoggingCatcher, + unittest.TestCase): + + def assertNoWarnings(self): + self.assertEqual(self.get_logs(), []) + + def assertWarnings(self): + self.assertNotEqual(self.get_logs(), []) + + def test_manifest_reader(self): + tmpdir = self.mkdtemp() + MANIFEST = os.path.join(tmpdir, 'MANIFEST.in') + with open(MANIFEST, 'w') as f: + f.write(_MANIFEST) + + manifest = Manifest() + manifest.read_template(MANIFEST) + + warnings = self.get_logs() + # the manifest should have been read and 3 warnings issued + # (we didn't provide the files) + self.assertEqual(3, len(warnings)) + for warning in warnings: + self.assertIn('no files found matching', warning) + + # manifest also accepts file-like objects + with open(MANIFEST) as f: + manifest.read_template(f) + + # the manifest should have been read and 3 warnings issued + # (we didn't provide the files) + self.assertEqual(3, len(warnings)) + + def test_default_actions(self): + tmpdir = self.mkdtemp() + self.addCleanup(os.chdir, os.getcwd()) + os.chdir(tmpdir) + self.write_file('README', 'xxx') + self.write_file('file1', 'xxx') + content = StringIO(_MANIFEST2) + manifest = Manifest() + manifest.read_template(content) + self.assertEqual(['README', 'file1'], manifest.files) + + def test_glob_to_re(self): + # simple cases + self.assertEqual(_glob_to_re('foo*'), 'foo[^/]*\\Z(?ms)') + self.assertEqual(_glob_to_re('foo?'), 'foo[^/]\\Z(?ms)') + self.assertEqual(_glob_to_re('foo??'), 'foo[^/][^/]\\Z(?ms)') + + # special cases + self.assertEqual(_glob_to_re(r'foo\\*'), r'foo\\\\[^/]*\Z(?ms)') + self.assertEqual(_glob_to_re(r'foo\\\*'), r'foo\\\\\\[^/]*\Z(?ms)') + self.assertEqual(_glob_to_re('foo????'), r'foo[^/][^/][^/][^/]\Z(?ms)') + self.assertEqual(_glob_to_re(r'foo\\??'), r'foo\\\\[^/][^/]\Z(?ms)') + + def test_remove_duplicates(self): + manifest = Manifest() + manifest.files = ['a', 'b', 'a', 'g', 'c', 'g'] + # files must be sorted beforehand + manifest.sort() + manifest.remove_duplicates() + self.assertEqual(manifest.files, ['a', 'b', 'c', 'g']) + + def test_translate_pattern(self): + # blackbox test of a private function + + # not regex + pattern = _translate_pattern('a', anchor=True, is_regex=False) + self.assertTrue(hasattr(pattern, 'search')) + + # is a regex + regex = re.compile('a') + pattern = _translate_pattern(regex, anchor=True, is_regex=True) + self.assertEqual(pattern, regex) + + # plain string flagged as regex + pattern = _translate_pattern('a', anchor=True, is_regex=True) + self.assertTrue(hasattr(pattern, 'search')) + + # glob support + pattern = _translate_pattern('*.py', anchor=True, is_regex=False) + self.assertTrue(pattern.search('filelist.py')) + + def test_exclude_pattern(self): + # return False if no match + manifest = Manifest() + self.assertFalse(manifest.exclude_pattern('*.py')) + + # return True if files match + manifest = Manifest() + manifest.files = ['a.py', 'b.py'] + self.assertTrue(manifest.exclude_pattern('*.py')) + + # test excludes + manifest = Manifest() + manifest.files = ['a.py', 'a.txt'] + manifest.exclude_pattern('*.py') + self.assertEqual(manifest.files, ['a.txt']) + + def test_include_pattern(self): + # return False if no match + manifest = Manifest() + manifest.allfiles = [] + self.assertFalse(manifest._include_pattern('*.py')) + + # return True if files match + manifest = Manifest() + manifest.allfiles = ['a.py', 'b.txt'] + self.assertTrue(manifest._include_pattern('*.py')) + + # test * matches all files + manifest = Manifest() + self.assertIsNone(manifest.allfiles) + manifest.allfiles = ['a.py', 'b.txt'] + manifest._include_pattern('*') + self.assertEqual(manifest.allfiles, ['a.py', 'b.txt']) + + def test_process_template(self): + # invalid lines + manifest = Manifest() + for action in ('include', 'exclude', 'global-include', + 'global-exclude', 'recursive-include', + 'recursive-exclude', 'graft', 'prune'): + self.assertRaises(PackagingTemplateError, + manifest._process_template_line, action) + + # implicit include + manifest = Manifest() + manifest.allfiles = ['a.py', 'b.txt', 'd/c.py'] + + manifest._process_template_line('*.py') + self.assertEqual(manifest.files, ['a.py']) + self.assertNoWarnings() + + # include + manifest = Manifest() + manifest.allfiles = ['a.py', 'b.txt', 'd/c.py'] + + manifest._process_template_line('include *.py') + self.assertEqual(manifest.files, ['a.py']) + self.assertNoWarnings() + + manifest._process_template_line('include *.rb') + self.assertEqual(manifest.files, ['a.py']) + self.assertWarnings() + + # exclude + manifest = Manifest() + manifest.files = ['a.py', 'b.txt', 'd/c.py'] + + manifest._process_template_line('exclude *.py') + self.assertEqual(manifest.files, ['b.txt', 'd/c.py']) + self.assertNoWarnings() + + manifest._process_template_line('exclude *.rb') + self.assertEqual(manifest.files, ['b.txt', 'd/c.py']) + self.assertWarnings() + + # global-include + manifest = Manifest() + manifest.allfiles = ['a.py', 'b.txt', 'd/c.py'] + + manifest._process_template_line('global-include *.py') + self.assertEqual(manifest.files, ['a.py', 'd/c.py']) + self.assertNoWarnings() + + manifest._process_template_line('global-include *.rb') + self.assertEqual(manifest.files, ['a.py', 'd/c.py']) + self.assertWarnings() + + # global-exclude + manifest = Manifest() + manifest.files = ['a.py', 'b.txt', 'd/c.py'] + + manifest._process_template_line('global-exclude *.py') + self.assertEqual(manifest.files, ['b.txt']) + self.assertNoWarnings() + + manifest._process_template_line('global-exclude *.rb') + self.assertEqual(manifest.files, ['b.txt']) + self.assertWarnings() + + # recursive-include + manifest = Manifest() + manifest.allfiles = ['a.py', 'd/b.py', 'd/c.txt', 'd/d/e.py'] + + manifest._process_template_line('recursive-include d *.py') + self.assertEqual(manifest.files, ['d/b.py', 'd/d/e.py']) + self.assertNoWarnings() + + manifest._process_template_line('recursive-include e *.py') + self.assertEqual(manifest.files, ['d/b.py', 'd/d/e.py']) + self.assertWarnings() + + # recursive-exclude + manifest = Manifest() + manifest.files = ['a.py', 'd/b.py', 'd/c.txt', 'd/d/e.py'] + + manifest._process_template_line('recursive-exclude d *.py') + self.assertEqual(manifest.files, ['a.py', 'd/c.txt']) + self.assertNoWarnings() + + manifest._process_template_line('recursive-exclude e *.py') + self.assertEqual(manifest.files, ['a.py', 'd/c.txt']) + self.assertWarnings() + + # graft + manifest = Manifest() + manifest.allfiles = ['a.py', 'd/b.py', 'd/d/e.py', 'f/f.py'] + + manifest._process_template_line('graft d') + self.assertEqual(manifest.files, ['d/b.py', 'd/d/e.py']) + self.assertNoWarnings() + + manifest._process_template_line('graft e') + self.assertEqual(manifest.files, ['d/b.py', 'd/d/e.py']) + self.assertWarnings() + + # prune + manifest = Manifest() + manifest.files = ['a.py', 'd/b.py', 'd/d/e.py', 'f/f.py'] + + manifest._process_template_line('prune d') + self.assertEqual(manifest.files, ['a.py', 'f/f.py']) + self.assertNoWarnings() + + manifest._process_template_line('prune e') + self.assertEqual(manifest.files, ['a.py', 'f/f.py']) + self.assertWarnings() + + +def test_suite(): + return unittest.makeSuite(ManifestTestCase) + +if __name__ == '__main__': + unittest.main(defaultTest='test_suite') |