~bzr-pqm/bzr/bzr.dev

5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2006-2011 Canonical Ltd
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
2
# -*- coding: utf-8 -*-
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
17
5339.3.3 by Parth Malwankar
fixed globbing test case
18
import re
19
5326.2.4 by Parth Malwankar
updated InvalidPattern test cases to use assertRaises
20
from bzrlib import errors
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
21
from bzrlib.globbing import (
22
    Globster,
4948.5.7 by John Whitley
Terminology change: exclusion => exception.
23
    ExceptionGlobster,
3398.1.2 by Ian Clatworthy
add tests for _OrderedGlobster
24
    _OrderedGlobster,
4792.4.1 by Gordon Tyler
Fixed globbing.normalize_pattern to not strip '/' down to '' and normalize multiple slashes.
25
    normalize_pattern
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
26
    )
27
from bzrlib.tests import (
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
28
    TestCase,
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
29
    )
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
30
31
32
class TestGlobster(TestCase):
33
34
    def assertMatch(self, matchset, glob_prefix=None):
35
        for glob, positive, negative in matchset:
36
            if glob_prefix:
37
                glob = glob_prefix + glob
38
            globster = Globster([glob])
39
            for name in positive:
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
40
                self.assertTrue(globster.match(name), repr(
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
41
                    u'name "%s" does not match glob "%s" (re=%s)' %
42
                    (name, glob, globster._regex_patterns[0][0].pattern)))
43
            for name in negative:
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
44
                self.assertFalse(globster.match(name), repr(
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
45
                    u'name "%s" does match glob "%s" (re=%s)' %
46
                    (name, glob, globster._regex_patterns[0][0].pattern)))
47
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
48
    def assertMatchBasenameAndFullpath(self, matchset):
49
        # test basename matcher
50
        self.assertMatch(matchset)
51
        # test fullpath matcher
52
        self.assertMatch(matchset, glob_prefix='./')
53
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
54
    def test_char_group_digit(self):
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
55
        self.assertMatchBasenameAndFullpath([
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
56
            # The definition of digit this uses includes arabic digits from
5340.6.4 by Martin
Stop testing that superscript one is in category digit as it no longer is in Python 2.7
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>
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
61
            (u'[[:digit:]]',
5340.6.4 by Martin
Stop testing that superscript one is in category digit as it no longer is in Python 2.7
62
             [u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21'],
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
63
             [u'T', u'q', u' ', u'\u8336', u'.']),
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
64
            (u'[^[:digit:]]',
65
             [u'T', u'q', u' ', u'\u8336', u'.'],
5340.6.4 by Martin
Stop testing that superscript one is in category digit as it no longer is in Python 2.7
66
             [u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21']),
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
67
            ])
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
68
69
    def test_char_group_space(self):
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
70
        self.assertMatchBasenameAndFullpath([
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
71
            (u'[[:space:]]',
72
             [u' ', u'\t', u'\n', u'\xa0', u'\u2000', u'\u2002'],
73
             [u'a', u'-', u'\u8336', u'.']),
74
            (u'[^[:space:]]',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
75
             [u'a', u'-', u'\u8336', u'.'],
76
             [u' ', u'\t', u'\n', u'\xa0', u'\u2000', u'\u2002']),
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
77
            ])
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
78
79
    def test_char_group_alnum(self):
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
80
        self.assertMatchBasenameAndFullpath([
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
81
            (u'[[:alnum:]]',
82
             [u'a', u'Z', u'\u017e', u'\u8336'],
83
             [u':', u'-', u'\u25cf', u'.']),
84
            (u'[^[:alnum:]]',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
85
             [u':', u'-', u'\u25cf', u'.'],
86
             [u'a']),
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
87
            ])
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
88
89
    def test_char_group_ascii(self):
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
90
        self.assertMatchBasenameAndFullpath([
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
91
            (u'[[:ascii:]]',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
92
             [u'a', u'Q', u'^', u'.'],
93
             [u'\xcc', u'\u8336']),
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
94
            (u'[^[:ascii:]]',
95
             [u'\xcc', u'\u8336'],
96
             [u'a', u'Q', u'^', u'.']),
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
97
            ])
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
98
99
    def test_char_group_blank(self):
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
100
        self.assertMatchBasenameAndFullpath([
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
101
            (u'[[:blank:]]',
102
             [u'\t'],
103
             [u'x', u'y', u'z', u'.']),
104
            (u'[^[:blank:]]',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
105
             [u'x', u'y', u'z', u'.'],
106
             [u'\t']),
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
107
            ])
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
108
109
    def test_char_group_cntrl(self):
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
110
        self.assertMatchBasenameAndFullpath([
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
111
            (u'[[:cntrl:]]',
112
             [u'\b', u'\t', '\x7f'],
113
             [u'a', u'Q', u'\u8336', u'.']),
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
114
            (u'[^[:cntrl:]]',
115
             [u'a', u'Q', u'\u8336', u'.'],
116
             [u'\b', u'\t', '\x7f']),
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
117
            ])
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
118
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
119
    def test_char_group_range(self):
120
        self.assertMatchBasenameAndFullpath([
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
121
            (u'[a-z]',
122
             [u'a', u'q', u'f'],
123
             [u'A', u'Q', u'F']),
2298.8.2 by Kent Gibson
Review fixes for lp86451 patch.
124
            (u'[^a-z]',
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
125
             [u'A', u'Q', u'F'],
126
             [u'a', u'q', u'f']),
127
            (u'[!a-z]foo',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
128
             [u'Afoo', u'.foo'],
129
             [u'afoo', u'ABfoo']),
2298.8.2 by Kent Gibson
Review fixes for lp86451 patch.
130
            (u'foo[!a-z]bar',
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
131
             [u'fooAbar', u'foo.bar'],
132
             [u'foojbar']),
2298.8.2 by Kent Gibson
Review fixes for lp86451 patch.
133
            (u'[\x20-\x30\u8336]',
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
134
             [u'\040', u'\044', u'\u8336'],
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
135
             [u'\x1f']),
2298.8.2 by Kent Gibson
Review fixes for lp86451 patch.
136
            (u'[^\x20-\x30\u8336]',
2135.2.7 by Kent Gibson
Implement JAM's review suggestions.
137
             [u'\x1f'],
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
138
             [u'\040', u'\044', u'\u8336']),
2135.2.8 by Kent Gibson
Add helper method to simplify test_char_group cases.
139
            ])
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
140
141
    def test_regex(self):
142
        self.assertMatch([
2298.8.2 by Kent Gibson
Review fixes for lp86451 patch.
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)',
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
150
             [u'a'],
151
             [u'ab', u'aa', u'aaa']),
2298.8.1 by Kent Gibson
Normalise ignore patterns to use '/' path separator.
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']),
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
156
            ])
157
158
    def test_question_mark(self):
159
        self.assertMatch([
160
            (u'?foo',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
161
             [u'xfoo', u'bar/xfoo', u'bar/\u8336foo', u'.foo', u'bar/.foo'],
162
             [u'bar/foo', u'foo']),
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
163
            (u'foo?bar',
164
             [u'fooxbar', u'foo.bar', u'foo\u8336bar', u'qyzzy/foo.bar'],
165
             [u'foo/bar']),
166
            (u'foo/?bar',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
167
             [u'foo/xbar', u'foo/\u8336bar', u'foo/.bar'],
168
             [u'foo/bar', u'bar/foo/xbar']),
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
169
            ])
170
171
    def test_asterisk(self):
172
        self.assertMatch([
173
            (u'x*x',
174
             [u'xx', u'x.x', u'x\u8336..x', u'\u8336/x.x', u'x.y.x'],
175
             [u'x/x', u'bar/x/bar/x', u'bax/abaxab']),
176
            (u'foo/*x',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
177
             [u'foo/x', u'foo/bax', u'foo/a.x', u'foo/.x', u'foo/.q.x'],
178
             [u'foo/bar/bax']),
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
179
            (u'*/*x',
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
180
             [u'\u8336/x', u'foo/x', u'foo/bax', u'x/a.x', u'.foo/x',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
181
              u'\u8336/.x', u'foo/.q.x'],
182
             [u'foo/bar/bax']),
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
183
            (u'f*',
184
             [u'foo', u'foo.bar'],
185
             [u'.foo', u'foo/bar', u'foo/.bar']),
186
            (u'*bar',
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
187
             [u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
188
              u'foo/foobar', u'foo/f.bar', u'.bar', u'foo/.bar'],
189
             []),
190
            ])
191
192
    def test_double_asterisk(self):
193
        self.assertMatch([
194
            # expected uses of double asterisk
195
            (u'foo/**/x',
196
             [u'foo/x', u'foo/bar/x'],
197
             [u'foox', u'foo/bax', u'foo/.x', u'foo/bar/bax']),
198
            (u'**/bar',
199
             [u'bar', u'foo/bar'],
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
200
             [u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
201
              u'.bar', u'foo/.bar']),
202
            # check that we ignore extra *s, so *** is treated like ** not *.
203
            (u'foo/***/x',
204
             [u'foo/x', u'foo/bar/x'],
205
             [u'foox', u'foo/bax', u'foo/.x', u'foo/bar/bax']),
206
            (u'***/bar',
207
             [u'bar', u'foo/bar'],
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
208
             [u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
209
              u'.bar', u'foo/.bar']),
210
            # the remaining tests check that ** is interpreted as *
211
            # unless it is a whole path component
212
            (u'x**/x',
213
             [u'x\u8336/x', u'x/x'],
214
             [u'xx', u'x.x', u'bar/x/bar/x', u'x.y.x', u'x/y/x']),
215
            (u'x**x',
216
             [u'xx', u'x.x', u'x\u8336..x', u'foo/x.x', u'x.y.x'],
217
             [u'bar/x/bar/x', u'xfoo/bar/x', u'x/x', u'bax/abaxab']),
218
            (u'foo/**x',
219
             [u'foo/x', u'foo/bax', u'foo/a.x', u'foo/.x', u'foo/.q.x'],
220
             [u'foo/bar/bax']),
221
            (u'f**',
222
             [u'foo', u'foo.bar'],
223
             [u'.foo', u'foo/bar', u'foo/.bar']),
224
            (u'**bar',
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
225
             [u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
226
              u'foo/foobar', u'foo/f.bar', u'.bar', u'foo/.bar'],
227
             []),
228
            ])
229
230
    def test_leading_dot_slash(self):
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
231
        self.assertMatch([
232
            (u'./foo',
233
             [u'foo'],
234
             [u'\u8336/foo', u'barfoo', u'x/y/foo']),
235
            (u'./f*',
236
             [u'foo'],
237
             [u'foo/bar', u'foo/.bar', u'x/foo/y']),
238
            ])
239
2298.8.1 by Kent Gibson
Normalise ignore patterns to use '/' path separator.
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
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
263
    def test_leading_asterisk_dot(self):
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
264
        self.assertMatch([
265
            (u'*.x',
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
266
             [u'foo/bar/baz.x', u'\u8336/Q.x', u'foo.y.x', u'.foo.x',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
267
              u'bar/.foo.x', u'.x',],
268
             [u'foo.x.y']),
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
269
            (u'foo/*.bar',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
270
             [u'foo/b.bar', u'foo/a.b.bar', u'foo/.bar'],
271
             [u'foo/bar']),
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
272
            (u'*.~*',
2135.2.2 by Kent Gibson
Ignore pattern matcher (glob.py) patches:
273
             [u'foo.py.~1~', u'.foo.py.~1~'],
274
             []),
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
275
            ])
276
277
    def test_end_anchor(self):
278
        self.assertMatch([
279
            (u'*.333',
280
             [u'foo.333'],
281
             [u'foo.3']),
282
            (u'*.3',
283
             [u'foo.3'],
284
             [u'foo.333']),
285
            ])
286
287
    def test_mixed_globs(self):
288
        """tests handling of combinations of path type matches.
289
290
        The types being extension, basename and full path.
291
        """
292
        patterns = [ u'*.foo', u'.*.swp', u'./*.png']
293
        globster = Globster(patterns)
294
        self.assertEqual(u'*.foo', globster.match('bar.foo'))
295
        self.assertEqual(u'./*.png', globster.match('foo.png'))
296
        self.assertEqual(None, globster.match('foo/bar.png'))
297
        self.assertEqual(u'.*.swp', globster.match('foo/.bar.py.swp'))
298
299
    def test_large_globset(self):
300
        """tests that the globster can handle a large set of patterns.
301
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
302
        Large is defined as more than supported by python regex groups,
2135.2.1 by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637)
303
        i.e. 99.
304
        This test assumes the globs are broken into regexs containing 99
305
        groups.
306
        """
307
        patterns = [ u'*.%03d' % i for i in xrange(0,300) ]
308
        globster = Globster(patterns)
309
        # test the fence posts
310
        for x in (0,98,99,197,198,296,297,299):
311
            filename = u'foo.%03d' % x
312
            self.assertEqual(patterns[x],globster.match(filename))
313
        self.assertEqual(None,globster.match('foobar.300'))
314
5326.2.2 by Parth Malwankar
added tests for InvalidPattern errors
315
    def test_bad_pattern(self):
316
        """Ensure that globster handles bad patterns cleanly."""
5050.14.2 by Parth Malwankar
_add_patterns is now done in a specific order in Globster
317
        patterns = [u'RE:[', u'/home/foo', u'RE:*.cpp']
5326.2.4 by Parth Malwankar
updated InvalidPattern test cases to use assertRaises
318
        g = Globster(patterns)
5050.14.2 by Parth Malwankar
_add_patterns is now done in a specific order in Globster
319
        e = self.assertRaises(errors.InvalidPattern, g.match, 'filename')
5050.14.1 by Parth Malwankar
'bzr ignore' now fails on bad patterns. failing patterns are displayed.
320
        self.assertContainsRe(e.msg,
5339.3.3 by Parth Malwankar
fixed globbing test case
321
            "File.*ignore.*contains error.*RE:\[.*RE:\*\.cpp", flags=re.DOTALL)
5326.2.2 by Parth Malwankar
added tests for InvalidPattern errors
322
323
4948.5.7 by John Whitley
Terminology change: exclusion => exception.
324
class TestExceptionGlobster(TestCase):
4948.5.3 by John Whitley
Refactor the exclusion handling functionality out of
325
326
    def test_exclusion_patterns(self):
4948.5.7 by John Whitley
Terminology change: exclusion => exception.
327
        """test that exception patterns are not matched"""
4948.5.6 by John Whitley
A trial implementation of '!!' syntax for double-negative ignore exclusions.
328
        patterns = [ u'*', u'!./local', u'!./local/**/*', u'!RE:\.z.*',u'!!./.zcompdump' ]
4948.5.7 by John Whitley
Terminology change: exclusion => exception.
329
        globster = ExceptionGlobster(patterns)
4948.5.3 by John Whitley
Refactor the exclusion handling functionality out of
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'))
4948.5.6 by John Whitley
A trial implementation of '!!' syntax for double-negative ignore exclusions.
335
        self.assertEqual(u'!!./.zcompdump', globster.match('.zcompdump'))
4948.5.3 by John Whitley
Refactor the exclusion handling functionality out of
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']
4948.5.7 by John Whitley
Terminology change: exclusion => exception.
340
        globster = ExceptionGlobster(patterns)
4948.5.3 by John Whitley
Refactor the exclusion handling functionality out of
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'))
4948.5.7 by John Whitley
Terminology change: exclusion => exception.
344
        globster = ExceptionGlobster(reversed(patterns))
4948.5.3 by John Whitley
Refactor the exclusion handling functionality out of
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'))
3398.1.2 by Ian Clatworthy
add tests for _OrderedGlobster
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'))
4792.4.1 by Gordon Tyler
Fixed globbing.normalize_pattern to not strip '/' down to '' and normalize multiple slashes.
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/\\\\/'))