~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_globbing.py

  • Committer: Ian Clatworthy
  • Date: 2007-08-13 14:33:10 UTC
  • mto: (2733.1.1 ianc-integration)
  • mto: This revision was merged to the branch mainline in revision 2734.
  • Revision ID: ian.clatworthy@internode.on.net-20070813143310-twhj4la0qnupvze8
Added Quick Start Summary

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006 Canonical Ltd
2
2
# -*- coding: utf-8 -*-
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
13
13
#
14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
 
 
18
 
import re
19
 
 
20
 
from bzrlib import errors
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
21
18
from bzrlib.globbing import (
22
19
    Globster,
23
 
    ExceptionGlobster,
24
 
    _OrderedGlobster,
25
 
    normalize_pattern
26
20
    )
27
21
from bzrlib.tests import (
28
 
    TestCase,
 
22
    TestCase, 
29
23
    TestCaseInTempDir,
30
24
    )
31
25
 
55
49
    def test_char_group_digit(self):
56
50
        self.assertMatchBasenameAndFullpath([
57
51
            # The definition of digit this uses includes arabic digits from
58
 
            # non-latin scripts (arabic, indic, etc.) but neither roman
59
 
            # numerals nor vulgar fractions. Some characters such as
60
 
            # subscript/superscript digits may or may not match depending on
61
 
            # the Python version used, see: <http://bugs.python.org/issue6561>
 
52
            # non-latin scripts (arabic, indic, etc.) and subscript/superscript
 
53
            # digits, but neither roman numerals nor vulgar fractions.
62
54
            (u'[[:digit:]]',
63
 
             [u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21'],
 
55
             [u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21', u'\xb9'],
64
56
             [u'T', u'q', u' ', u'\u8336', u'.']),
65
57
            (u'[^[:digit:]]',
66
58
             [u'T', u'q', u' ', u'\u8336', u'.'],
67
 
             [u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21']),
 
59
             [u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21', u'\xb9']),
68
60
            ])
69
61
 
70
62
    def test_char_group_space(self):
178
170
             [u'foo/x', u'foo/bax', u'foo/a.x', u'foo/.x', u'foo/.q.x'],
179
171
             [u'foo/bar/bax']),
180
172
            (u'*/*x',
181
 
             [u'\u8336/x', u'foo/x', u'foo/bax', u'x/a.x', u'.foo/x',
 
173
             [u'\u8336/x', u'foo/x', u'foo/bax', u'x/a.x', u'.foo/x', 
182
174
              u'\u8336/.x', u'foo/.q.x'],
183
175
             [u'foo/bar/bax']),
184
176
            (u'f*',
185
177
             [u'foo', u'foo.bar'],
186
178
             [u'.foo', u'foo/bar', u'foo/.bar']),
187
179
            (u'*bar',
188
 
             [u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar',
 
180
             [u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar', 
189
181
              u'foo/foobar', u'foo/f.bar', u'.bar', u'foo/.bar'],
190
182
             []),
191
183
            ])
198
190
             [u'foox', u'foo/bax', u'foo/.x', u'foo/bar/bax']),
199
191
            (u'**/bar',
200
192
             [u'bar', u'foo/bar'],
201
 
             [u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar',
 
193
             [u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar', 
202
194
              u'.bar', u'foo/.bar']),
203
195
            # check that we ignore extra *s, so *** is treated like ** not *.
204
196
            (u'foo/***/x',
206
198
             [u'foox', u'foo/bax', u'foo/.x', u'foo/bar/bax']),
207
199
            (u'***/bar',
208
200
             [u'bar', u'foo/bar'],
209
 
             [u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar',
 
201
             [u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar', 
210
202
              u'.bar', u'foo/.bar']),
211
203
            # the remaining tests check that ** is interpreted as *
212
204
            # unless it is a whole path component
223
215
             [u'foo', u'foo.bar'],
224
216
             [u'.foo', u'foo/bar', u'foo/.bar']),
225
217
            (u'**bar',
226
 
             [u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar',
 
218
             [u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar', 
227
219
              u'foo/foobar', u'foo/f.bar', u'.bar', u'foo/.bar'],
228
220
             []),
229
221
            ])
264
256
    def test_leading_asterisk_dot(self):
265
257
        self.assertMatch([
266
258
            (u'*.x',
267
 
             [u'foo/bar/baz.x', u'\u8336/Q.x', u'foo.y.x', u'.foo.x',
 
259
             [u'foo/bar/baz.x', u'\u8336/Q.x', u'foo.y.x', u'.foo.x', 
268
260
              u'bar/.foo.x', u'.x',],
269
261
             [u'foo.x.y']),
270
262
            (u'foo/*.bar',
300
292
    def test_large_globset(self):
301
293
        """tests that the globster can handle a large set of patterns.
302
294
 
303
 
        Large is defined as more than supported by python regex groups,
 
295
        Large is defined as more than supported by python regex groups, 
304
296
        i.e. 99.
305
297
        This test assumes the globs are broken into regexs containing 99
306
298
        groups.
313
305
            self.assertEqual(patterns[x],globster.match(filename))
314
306
        self.assertEqual(None,globster.match('foobar.300'))
315
307
 
316
 
    def test_bad_pattern(self):
317
 
        """Ensure that globster handles bad patterns cleanly."""
318
 
        patterns = [u'RE:[', u'/home/foo', u'RE:*.cpp']
319
 
        g = Globster(patterns)
320
 
        e = self.assertRaises(errors.InvalidPattern, g.match, 'filename')
321
 
        self.assertContainsRe(e.msg,
322
 
            "File.*ignore.*contains error.*RE:\[.*RE:\*\.cpp", flags=re.DOTALL)
323
 
 
324
 
 
325
 
class TestExceptionGlobster(TestCase):
326
 
 
327
 
    def test_exclusion_patterns(self):
328
 
        """test that exception patterns are not matched"""
329
 
        patterns = [ u'*', u'!./local', u'!./local/**/*', u'!RE:\.z.*',u'!!./.zcompdump' ]
330
 
        globster = ExceptionGlobster(patterns)
331
 
        self.assertEqual(u'*', globster.match('tmp/foo.txt'))
332
 
        self.assertEqual(None, globster.match('local'))
333
 
        self.assertEqual(None, globster.match('local/bin/wombat'))
334
 
        self.assertEqual(None, globster.match('.zshrc'))
335
 
        self.assertEqual(None, globster.match('.zfunctions/fiddle/flam'))
336
 
        self.assertEqual(u'!!./.zcompdump', globster.match('.zcompdump'))
337
 
 
338
 
    def test_exclusion_order(self):
339
 
        """test that ordering of exclusion patterns does not matter"""
340
 
        patterns = [ u'static/**/*.html', u'!static/**/versionable.html']
341
 
        globster = ExceptionGlobster(patterns)
342
 
        self.assertEqual(u'static/**/*.html', globster.match('static/foo.html'))
343
 
        self.assertEqual(None, globster.match('static/versionable.html'))
344
 
        self.assertEqual(None, globster.match('static/bar/versionable.html'))
345
 
        globster = ExceptionGlobster(reversed(patterns))
346
 
        self.assertEqual(u'static/**/*.html', globster.match('static/foo.html'))
347
 
        self.assertEqual(None, globster.match('static/versionable.html'))
348
 
        self.assertEqual(None, globster.match('static/bar/versionable.html'))
349
 
 
350
 
class TestOrderedGlobster(TestCase):
351
 
 
352
 
    def test_ordered_globs(self):
353
 
        """test that the first match in a list is the one found"""
354
 
        patterns = [ u'*.foo', u'bar.*']
355
 
        globster = _OrderedGlobster(patterns)
356
 
        self.assertEqual(u'*.foo', globster.match('bar.foo'))
357
 
        self.assertEqual(None, globster.match('foo.bar'))
358
 
        globster = _OrderedGlobster(reversed(patterns))
359
 
        self.assertEqual(u'bar.*', globster.match('bar.foo'))
360
 
        self.assertEqual(None, globster.match('foo.bar'))
361
 
 
362
 
 
363
 
class TestNormalizePattern(TestCase):
364
 
 
365
 
    def test_backslashes(self):
366
 
        """tests that backslashes are converted to forward slashes, multiple
367
 
        backslashes are collapsed to single forward slashes and trailing
368
 
        backslashes are removed"""
369
 
        self.assertEqual(u'/', normalize_pattern(u'\\'))
370
 
        self.assertEqual(u'/', normalize_pattern(u'\\\\'))
371
 
        self.assertEqual(u'/foo/bar', normalize_pattern(u'\\foo\\bar'))
372
 
        self.assertEqual(u'foo/bar', normalize_pattern(u'foo\\bar\\'))
373
 
        self.assertEqual(u'/foo/bar', normalize_pattern(u'\\\\foo\\\\bar\\\\'))
374
 
 
375
 
    def test_forward_slashes(self):
376
 
        """tests that multiple foward slashes are collapsed to single forward
377
 
        slashes and trailing forward slashes are removed"""
378
 
        self.assertEqual(u'/', normalize_pattern(u'/'))
379
 
        self.assertEqual(u'/', normalize_pattern(u'//'))
380
 
        self.assertEqual(u'/foo/bar', normalize_pattern(u'/foo/bar'))
381
 
        self.assertEqual(u'foo/bar', normalize_pattern(u'foo/bar/'))
382
 
        self.assertEqual(u'/foo/bar', normalize_pattern(u'//foo//bar//'))
383
 
 
384
 
    def test_mixed_slashes(self):
385
 
        """tests that multiple mixed slashes are collapsed to single forward
386
 
        slashes and trailing mixed slashes are removed"""
387
 
        self.assertEqual(u'/foo/bar', normalize_pattern(u'\\/\\foo//\\///bar/\\\\/'))