test_filelist.py 9.84 KB
Newer Older
1
"""Tests for distutils.filelist."""
2
import os
3
import re
4
import unittest
5 6 7 8
from distutils import debug
from distutils.log import WARN
from distutils.errors import DistutilsTemplateError
from distutils.filelist import glob_to_re, translate_pattern, FileList
9

10
from test.support import captured_stdout, run_unittest
11 12
from distutils.tests import support

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
MANIFEST_IN = """\
include ok
include xo
exclude xo
include foo.tmp
include buildout.cfg
global-include *.x
global-include *.txt
global-exclude *.tmp
recursive-include f *.oo
recursive-exclude global *.x
graft dir
prune dir3
"""


def make_local_path(s):
    """Converts '/' in a string to os.sep"""
    return s.replace('/', os.sep)

33 34 35

class FileListTestCase(support.LoggingSilencer,
                       unittest.TestCase):
36

37 38 39 40 41 42 43
    def assertNoWarnings(self):
        self.assertEqual(self.get_logs(WARN), [])
        self.clear_logs()

    def assertWarnings(self):
        self.assertGreater(len(self.get_logs(WARN)), 0)
        self.clear_logs()
44 45

    def test_glob_to_re(self):
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
        sep = os.sep
        if os.sep == '\\':
            sep = re.escape(os.sep)

        for glob, regex in (
            # simple cases
            ('foo*', r'foo[^%(sep)s]*\Z(?ms)'),
            ('foo?', r'foo[^%(sep)s]\Z(?ms)'),
            ('foo??', r'foo[^%(sep)s][^%(sep)s]\Z(?ms)'),
            # special cases
            (r'foo\\*', r'foo\\\\[^%(sep)s]*\Z(?ms)'),
            (r'foo\\\*', r'foo\\\\\\[^%(sep)s]*\Z(?ms)'),
            ('foo????', r'foo[^%(sep)s][^%(sep)s][^%(sep)s][^%(sep)s]\Z(?ms)'),
            (r'foo\\??', r'foo\\\\[^%(sep)s][^%(sep)s]\Z(?ms)')):
            regex = regex % {'sep': sep}
            self.assertEqual(glob_to_re(glob), regex)

    def test_process_template_line(self):
        # testing  all MANIFEST.in template patterns
        file_list = FileList()
        l = make_local_path

        # simulated file list
        file_list.allfiles = ['foo.tmp', 'ok', 'xo', 'four.txt',
                              'buildout.cfg',
                              # filelist does not filter out VCS directories,
                              # it's sdist that does
                              l('.hg/last-message.txt'),
                              l('global/one.txt'),
                              l('global/two.txt'),
                              l('global/files.x'),
                              l('global/here.tmp'),
                              l('f/o/f.oo'),
                              l('dir/graft-one'),
                              l('dir/dir2/graft2'),
                              l('dir3/ok'),
                              l('dir3/sub/ok.txt'),
                             ]

        for line in MANIFEST_IN.split('\n'):
            if line.strip() == '':
                continue
            file_list.process_template_line(line)

        wanted = ['ok',
                  'buildout.cfg',
                  'four.txt',
                  l('.hg/last-message.txt'),
                  l('global/one.txt'),
                  l('global/two.txt'),
                  l('f/o/f.oo'),
                  l('dir/graft-one'),
                  l('dir/dir2/graft2'),
                 ]

        self.assertEqual(file_list.files, wanted)
102

103 104 105 106
    def test_debug_print(self):
        file_list = FileList()
        with captured_stdout() as stdout:
            file_list.debug_print('xxx')
107
        self.assertEqual(stdout.getvalue(), '')
108 109 110 111 112

        debug.DEBUG = True
        try:
            with captured_stdout() as stdout:
                file_list.debug_print('xxx')
113
            self.assertEqual(stdout.getvalue(), 'xxx\n')
114 115 116
        finally:
            debug.DEBUG = False

117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
    def test_set_allfiles(self):
        file_list = FileList()
        files = ['a', 'b', 'c']
        file_list.set_allfiles(files)
        self.assertEqual(file_list.allfiles, files)

    def test_remove_duplicates(self):
        file_list = FileList()
        file_list.files = ['a', 'b', 'a', 'g', 'c', 'g']
        # files must be sorted beforehand (sdist does it)
        file_list.sort()
        file_list.remove_duplicates()
        self.assertEqual(file_list.files, ['a', 'b', 'c', 'g'])

    def test_translate_pattern(self):
        # not regex
        self.assertTrue(hasattr(
            translate_pattern('a', anchor=True, is_regex=False),
            'search'))

        # is a regex
        regex = re.compile('a')
        self.assertEqual(
            translate_pattern(regex, anchor=True, is_regex=True),
            regex)

        # plain string flagged as regex
        self.assertTrue(hasattr(
            translate_pattern('a', anchor=True, is_regex=True),
            'search'))

        # glob support
        self.assertTrue(translate_pattern(
            '*.py', anchor=True, is_regex=False).search('filelist.py'))

    def test_exclude_pattern(self):
        # return False if no match
        file_list = FileList()
        self.assertFalse(file_list.exclude_pattern('*.py'))

        # return True if files match
        file_list = FileList()
        file_list.files = ['a.py', 'b.py']
        self.assertTrue(file_list.exclude_pattern('*.py'))

        # test excludes
        file_list = FileList()
        file_list.files = ['a.py', 'a.txt']
        file_list.exclude_pattern('*.py')
        self.assertEqual(file_list.files, ['a.txt'])

    def test_include_pattern(self):
        # return False if no match
        file_list = FileList()
        file_list.set_allfiles([])
        self.assertFalse(file_list.include_pattern('*.py'))

        # return True if files match
        file_list = FileList()
        file_list.set_allfiles(['a.py', 'b.txt'])
        self.assertTrue(file_list.include_pattern('*.py'))

        # test * matches all files
        file_list = FileList()
        self.assertIsNone(file_list.allfiles)
        file_list.set_allfiles(['a.py', 'b.txt'])
        file_list.include_pattern('*')
        self.assertEqual(file_list.allfiles, ['a.py', 'b.txt'])

    def test_process_template(self):
187
        l = make_local_path
188 189 190 191 192 193 194 195 196 197
        # invalid lines
        file_list = FileList()
        for action in ('include', 'exclude', 'global-include',
                       'global-exclude', 'recursive-include',
                       'recursive-exclude', 'graft', 'prune', 'blarg'):
            self.assertRaises(DistutilsTemplateError,
                              file_list.process_template_line, action)

        # include
        file_list = FileList()
198
        file_list.set_allfiles(['a.py', 'b.txt', l('d/c.py')])
199 200 201 202 203 204 205 206 207 208 209

        file_list.process_template_line('include *.py')
        self.assertEqual(file_list.files, ['a.py'])
        self.assertNoWarnings()

        file_list.process_template_line('include *.rb')
        self.assertEqual(file_list.files, ['a.py'])
        self.assertWarnings()

        # exclude
        file_list = FileList()
210
        file_list.files = ['a.py', 'b.txt', l('d/c.py')]
211 212

        file_list.process_template_line('exclude *.py')
213
        self.assertEqual(file_list.files, ['b.txt', l('d/c.py')])
214 215 216
        self.assertNoWarnings()

        file_list.process_template_line('exclude *.rb')
217
        self.assertEqual(file_list.files, ['b.txt', l('d/c.py')])
218 219 220 221
        self.assertWarnings()

        # global-include
        file_list = FileList()
222
        file_list.set_allfiles(['a.py', 'b.txt', l('d/c.py')])
223 224

        file_list.process_template_line('global-include *.py')
225
        self.assertEqual(file_list.files, ['a.py', l('d/c.py')])
226 227 228
        self.assertNoWarnings()

        file_list.process_template_line('global-include *.rb')
229
        self.assertEqual(file_list.files, ['a.py', l('d/c.py')])
230 231 232 233
        self.assertWarnings()

        # global-exclude
        file_list = FileList()
234
        file_list.files = ['a.py', 'b.txt', l('d/c.py')]
235 236 237 238 239 240 241 242 243 244 245

        file_list.process_template_line('global-exclude *.py')
        self.assertEqual(file_list.files, ['b.txt'])
        self.assertNoWarnings()

        file_list.process_template_line('global-exclude *.rb')
        self.assertEqual(file_list.files, ['b.txt'])
        self.assertWarnings()

        # recursive-include
        file_list = FileList()
246 247
        file_list.set_allfiles(['a.py', l('d/b.py'), l('d/c.txt'),
                                l('d/d/e.py')])
248 249

        file_list.process_template_line('recursive-include d *.py')
250
        self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')])
251 252 253
        self.assertNoWarnings()

        file_list.process_template_line('recursive-include e *.py')
254
        self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')])
255 256 257 258
        self.assertWarnings()

        # recursive-exclude
        file_list = FileList()
259
        file_list.files = ['a.py', l('d/b.py'), l('d/c.txt'), l('d/d/e.py')]
260 261

        file_list.process_template_line('recursive-exclude d *.py')
262
        self.assertEqual(file_list.files, ['a.py', l('d/c.txt')])
263 264 265
        self.assertNoWarnings()

        file_list.process_template_line('recursive-exclude e *.py')
266
        self.assertEqual(file_list.files, ['a.py', l('d/c.txt')])
267 268 269 270
        self.assertWarnings()

        # graft
        file_list = FileList()
271 272
        file_list.set_allfiles(['a.py', l('d/b.py'), l('d/d/e.py'),
                                l('f/f.py')])
273 274

        file_list.process_template_line('graft d')
275
        self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')])
276 277 278
        self.assertNoWarnings()

        file_list.process_template_line('graft e')
279
        self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')])
280 281 282 283
        self.assertWarnings()

        # prune
        file_list = FileList()
284
        file_list.files = ['a.py', l('d/b.py'), l('d/d/e.py'), l('f/f.py')]
285 286

        file_list.process_template_line('prune d')
287
        self.assertEqual(file_list.files, ['a.py', l('f/f.py')])
288 289 290
        self.assertNoWarnings()

        file_list.process_template_line('prune e')
291
        self.assertEqual(file_list.files, ['a.py', l('f/f.py')])
292 293 294
        self.assertWarnings()


295 296 297 298
def test_suite():
    return unittest.makeSuite(FileListTestCase)

if __name__ == "__main__":
299
    run_unittest(test_suite())