~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_globbing.py

  • Committer: Aaron Bentley
  • Date: 2006-12-21 04:34:42 UTC
  • mto: (2255.1.1 bzr.ab.integration)
  • mto: This revision was merged to the branch mainline in revision 2220.
  • Revision ID: aaron.bentley@utoronto.ca-20061221043442-x3mv0kxnsu7c2z5j
restore register_lazy, remove register_factory, other updates

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2011 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, 
 
23
    TestCaseInTempDir,
29
24
    )
30
25
 
31
26
 
37
32
                glob = glob_prefix + glob
38
33
            globster = Globster([glob])
39
34
            for name in positive:
40
 
                self.assertTrue(globster.match(name), repr(
 
35
                self.failUnless(globster.match(name), repr(
41
36
                    u'name "%s" does not match glob "%s" (re=%s)' %
42
37
                    (name, glob, globster._regex_patterns[0][0].pattern)))
43
38
            for name in negative:
44
 
                self.assertFalse(globster.match(name), repr(
 
39
                self.failIf(globster.match(name), repr(
45
40
                    u'name "%s" does match glob "%s" (re=%s)' %
46
41
                    (name, glob, globster._regex_patterns[0][0].pattern)))
47
42
 
54
49
    def test_char_group_digit(self):
55
50
        self.assertMatchBasenameAndFullpath([
56
51
            # The definition of digit this uses includes arabic digits from
57
 
            # non-latin scripts (arabic, indic, etc.) but neither roman
58
 
            # numerals nor vulgar fractions. Some characters such as
59
 
            # subscript/superscript digits may or may not match depending on
60
 
            # 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.
61
54
            (u'[[:digit:]]',
62
 
             [u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21'],
 
55
             [u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21', u'\xb9'],
63
56
             [u'T', u'q', u' ', u'\u8336', u'.']),
64
57
            (u'[^[:digit:]]',
65
58
             [u'T', u'q', u' ', u'\u8336', u'.'],
66
 
             [u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21']),
 
59
             [u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21', u'\xb9']),
67
60
            ])
68
61
 
69
62
    def test_char_group_space(self):
121
114
            (u'[a-z]',
122
115
             [u'a', u'q', u'f'],
123
116
             [u'A', u'Q', u'F']),
124
 
            (u'[^a-z]',
 
117
            (ur'[^a-z]',
125
118
             [u'A', u'Q', u'F'],
126
119
             [u'a', u'q', u'f']),
127
120
            (u'[!a-z]foo',
128
121
             [u'Afoo', u'.foo'],
129
122
             [u'afoo', u'ABfoo']),
130
 
            (u'foo[!a-z]bar',
 
123
            (ur'foo[!a-z]bar',
131
124
             [u'fooAbar', u'foo.bar'],
132
125
             [u'foojbar']),
133
 
            (u'[\x20-\x30\u8336]',
 
126
            (ur'[\x20-\x30\u8336]',
134
127
             [u'\040', u'\044', u'\u8336'],
135
128
             [u'\x1f']),
136
 
            (u'[^\x20-\x30\u8336]',
 
129
            (ur'[^\x20-\x30\u8336]',
137
130
             [u'\x1f'],
138
131
             [u'\040', u'\044', u'\u8336']),
139
132
            ])
140
133
 
141
134
    def test_regex(self):
142
135
        self.assertMatch([
143
 
            (u'RE:(a|b|c+)',
144
 
             [u'a', u'b', u'ccc'],
145
 
             [u'd', u'aa', u'c+', u'-a']),
146
 
            (u'RE:(?:a|b|c+)',
147
 
             [u'a', u'b', u'ccc'],
148
 
             [u'd', u'aa', u'c+', u'-a']),
149
 
            (u'RE:(?P<a>.)(?P=a)',
 
136
            (ur'RE:(a|b|c+)',
 
137
             [u'a', u'b', u'ccc'],
 
138
             [u'd', u'aa', u'c+', u'-a']),
 
139
            (ur'RE:(?:a|b|c+)',
 
140
             [u'a', u'b', u'ccc'],
 
141
             [u'd', u'aa', u'c+', u'-a']),
 
142
            (ur'RE:(?P<a>.)(?P=a)',
150
143
             [u'a'],
151
144
             [u'ab', u'aa', u'aaa']),
152
 
            # test we can handle odd numbers of trailing backslashes
153
 
            (u'RE:a\\\\\\',
154
 
             [u'a\\'],
155
 
             [u'a', u'ab', u'aa', u'aaa']),
156
145
            ])
157
146
 
158
147
    def test_question_mark(self):
177
166
             [u'foo/x', u'foo/bax', u'foo/a.x', u'foo/.x', u'foo/.q.x'],
178
167
             [u'foo/bar/bax']),
179
168
            (u'*/*x',
180
 
             [u'\u8336/x', u'foo/x', u'foo/bax', u'x/a.x', u'.foo/x',
 
169
             [u'\u8336/x', u'foo/x', u'foo/bax', u'x/a.x', u'.foo/x', 
181
170
              u'\u8336/.x', u'foo/.q.x'],
182
171
             [u'foo/bar/bax']),
183
172
            (u'f*',
184
173
             [u'foo', u'foo.bar'],
185
174
             [u'.foo', u'foo/bar', u'foo/.bar']),
186
175
            (u'*bar',
187
 
             [u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar',
 
176
             [u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar', 
188
177
              u'foo/foobar', u'foo/f.bar', u'.bar', u'foo/.bar'],
189
178
             []),
190
179
            ])
197
186
             [u'foox', u'foo/bax', u'foo/.x', u'foo/bar/bax']),
198
187
            (u'**/bar',
199
188
             [u'bar', u'foo/bar'],
200
 
             [u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar',
 
189
             [u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar', 
201
190
              u'.bar', u'foo/.bar']),
202
191
            # check that we ignore extra *s, so *** is treated like ** not *.
203
192
            (u'foo/***/x',
205
194
             [u'foox', u'foo/bax', u'foo/.x', u'foo/bar/bax']),
206
195
            (u'***/bar',
207
196
             [u'bar', u'foo/bar'],
208
 
             [u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar',
 
197
             [u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar', 
209
198
              u'.bar', u'foo/.bar']),
210
199
            # the remaining tests check that ** is interpreted as *
211
200
            # unless it is a whole path component
222
211
             [u'foo', u'foo.bar'],
223
212
             [u'.foo', u'foo/bar', u'foo/.bar']),
224
213
            (u'**bar',
225
 
             [u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar',
 
214
             [u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar', 
226
215
              u'foo/foobar', u'foo/f.bar', u'.bar', u'foo/.bar'],
227
216
             []),
228
217
            ])
237
226
             [u'foo/bar', u'foo/.bar', u'x/foo/y']),
238
227
            ])
239
228
 
240
 
    def test_backslash(self):
241
 
        self.assertMatch([
242
 
            (u'.\\foo',
243
 
             [u'foo'],
244
 
             [u'\u8336/foo', u'barfoo', u'x/y/foo']),
245
 
            (u'.\\f*',
246
 
             [u'foo'],
247
 
             [u'foo/bar', u'foo/.bar', u'x/foo/y']),
248
 
            (u'foo\\**\\x',
249
 
             [u'foo/x', u'foo/bar/x'],
250
 
             [u'foox', u'foo/bax', u'foo/.x', u'foo/bar/bax']),
251
 
            ])
252
 
 
253
 
    def test_trailing_slash(self):
254
 
        self.assertMatch([
255
 
            (u'./foo/',
256
 
             [u'foo'],
257
 
             [u'\u8336/foo', u'barfoo', u'x/y/foo']),
258
 
            (u'.\\foo\\',
259
 
             [u'foo'],
260
 
             [u'foo/', u'\u8336/foo', u'barfoo', u'x/y/foo']),
261
 
            ])
262
 
 
263
229
    def test_leading_asterisk_dot(self):
264
230
        self.assertMatch([
265
231
            (u'*.x',
266
 
             [u'foo/bar/baz.x', u'\u8336/Q.x', u'foo.y.x', u'.foo.x',
 
232
             [u'foo/bar/baz.x', u'\u8336/Q.x', u'foo.y.x', u'.foo.x', 
267
233
              u'bar/.foo.x', u'.x',],
268
234
             [u'foo.x.y']),
269
235
            (u'foo/*.bar',
299
265
    def test_large_globset(self):
300
266
        """tests that the globster can handle a large set of patterns.
301
267
 
302
 
        Large is defined as more than supported by python regex groups,
 
268
        Large is defined as more than supported by python regex groups, 
303
269
        i.e. 99.
304
270
        This test assumes the globs are broken into regexs containing 99
305
271
        groups.
312
278
            self.assertEqual(patterns[x],globster.match(filename))
313
279
        self.assertEqual(None,globster.match('foobar.300'))
314
280
 
315
 
    def test_bad_pattern(self):
316
 
        """Ensure that globster handles bad patterns cleanly."""
317
 
        patterns = [u'RE:[', u'/home/foo', u'RE:*.cpp']
318
 
        g = Globster(patterns)
319
 
        e = self.assertRaises(errors.InvalidPattern, g.match, 'filename')
320
 
        self.assertContainsRe(e.msg,
321
 
            "File.*ignore.*contains error.*RE:\[.*RE:\*\.cpp", flags=re.DOTALL)
322
 
 
323
 
 
324
 
class TestExceptionGlobster(TestCase):
325
 
 
326
 
    def test_exclusion_patterns(self):
327
 
        """test that exception patterns are not matched"""
328
 
        patterns = [ u'*', u'!./local', u'!./local/**/*', u'!RE:\.z.*',u'!!./.zcompdump' ]
329
 
        globster = ExceptionGlobster(patterns)
330
 
        self.assertEqual(u'*', globster.match('tmp/foo.txt'))
331
 
        self.assertEqual(None, globster.match('local'))
332
 
        self.assertEqual(None, globster.match('local/bin/wombat'))
333
 
        self.assertEqual(None, globster.match('.zshrc'))
334
 
        self.assertEqual(None, globster.match('.zfunctions/fiddle/flam'))
335
 
        self.assertEqual(u'!!./.zcompdump', globster.match('.zcompdump'))
336
 
 
337
 
    def test_exclusion_order(self):
338
 
        """test that ordering of exclusion patterns does not matter"""
339
 
        patterns = [ u'static/**/*.html', u'!static/**/versionable.html']
340
 
        globster = ExceptionGlobster(patterns)
341
 
        self.assertEqual(u'static/**/*.html', globster.match('static/foo.html'))
342
 
        self.assertEqual(None, globster.match('static/versionable.html'))
343
 
        self.assertEqual(None, globster.match('static/bar/versionable.html'))
344
 
        globster = ExceptionGlobster(reversed(patterns))
345
 
        self.assertEqual(u'static/**/*.html', globster.match('static/foo.html'))
346
 
        self.assertEqual(None, globster.match('static/versionable.html'))
347
 
        self.assertEqual(None, globster.match('static/bar/versionable.html'))
348
 
 
349
 
class TestOrderedGlobster(TestCase):
350
 
 
351
 
    def test_ordered_globs(self):
352
 
        """test that the first match in a list is the one found"""
353
 
        patterns = [ u'*.foo', u'bar.*']
354
 
        globster = _OrderedGlobster(patterns)
355
 
        self.assertEqual(u'*.foo', globster.match('bar.foo'))
356
 
        self.assertEqual(None, globster.match('foo.bar'))
357
 
        globster = _OrderedGlobster(reversed(patterns))
358
 
        self.assertEqual(u'bar.*', globster.match('bar.foo'))
359
 
        self.assertEqual(None, globster.match('foo.bar'))
360
 
 
361
 
 
362
 
class TestNormalizePattern(TestCase):
363
 
 
364
 
    def test_backslashes(self):
365
 
        """tests that backslashes are converted to forward slashes, multiple
366
 
        backslashes are collapsed to single forward slashes and trailing
367
 
        backslashes are removed"""
368
 
        self.assertEqual(u'/', normalize_pattern(u'\\'))
369
 
        self.assertEqual(u'/', normalize_pattern(u'\\\\'))
370
 
        self.assertEqual(u'/foo/bar', normalize_pattern(u'\\foo\\bar'))
371
 
        self.assertEqual(u'foo/bar', normalize_pattern(u'foo\\bar\\'))
372
 
        self.assertEqual(u'/foo/bar', normalize_pattern(u'\\\\foo\\\\bar\\\\'))
373
 
 
374
 
    def test_forward_slashes(self):
375
 
        """tests that multiple foward slashes are collapsed to single forward
376
 
        slashes and trailing forward slashes are removed"""
377
 
        self.assertEqual(u'/', normalize_pattern(u'/'))
378
 
        self.assertEqual(u'/', normalize_pattern(u'//'))
379
 
        self.assertEqual(u'/foo/bar', normalize_pattern(u'/foo/bar'))
380
 
        self.assertEqual(u'foo/bar', normalize_pattern(u'foo/bar/'))
381
 
        self.assertEqual(u'/foo/bar', normalize_pattern(u'//foo//bar//'))
382
 
 
383
 
    def test_mixed_slashes(self):
384
 
        """tests that multiple mixed slashes are collapsed to single forward
385
 
        slashes and trailing mixed slashes are removed"""
386
 
        self.assertEqual(u'/foo/bar', normalize_pattern(u'\\/\\foo//\\///bar/\\\\/'))