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
20
from bzrlib import errors
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
18
from bzrlib.globbing import (
27
22
from bzrlib.tests import (
37
33
glob = glob_prefix + glob
38
34
globster = Globster([glob])
39
35
for name in positive:
40
self.assertTrue(globster.match(name), repr(
36
self.failUnless(globster.match(name), repr(
41
37
u'name "%s" does not match glob "%s" (re=%s)' %
42
38
(name, glob, globster._regex_patterns[0][0].pattern)))
43
39
for name in negative:
44
self.assertFalse(globster.match(name), repr(
40
self.failIf(globster.match(name), repr(
45
41
u'name "%s" does match glob "%s" (re=%s)' %
46
42
(name, glob, globster._regex_patterns[0][0].pattern)))
54
50
def test_char_group_digit(self):
55
51
self.assertMatchBasenameAndFullpath([
56
52
# 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>
53
# non-latin scripts (arabic, indic, etc.) and subscript/superscript
54
# digits, but neither roman numerals nor vulgar fractions.
62
[u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21'],
56
[u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21', u'\xb9'],
63
57
[u'T', u'q', u' ', u'\u8336', u'.']),
65
59
[u'T', u'q', u' ', u'\u8336', u'.'],
66
[u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21']),
60
[u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21', u'\xb9']),
69
63
def test_char_group_space(self):
177
171
[u'foo/x', u'foo/bax', u'foo/a.x', u'foo/.x', u'foo/.q.x'],
178
172
[u'foo/bar/bax']),
180
[u'\u8336/x', u'foo/x', u'foo/bax', u'x/a.x', u'.foo/x',
174
[u'\u8336/x', u'foo/x', u'foo/bax', u'x/a.x', u'.foo/x',
181
175
u'\u8336/.x', u'foo/.q.x'],
182
176
[u'foo/bar/bax']),
184
178
[u'foo', u'foo.bar'],
185
179
[u'.foo', u'foo/bar', u'foo/.bar']),
187
[u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar',
181
[u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar',
188
182
u'foo/foobar', u'foo/f.bar', u'.bar', u'foo/.bar'],
197
191
[u'foox', u'foo/bax', u'foo/.x', u'foo/bar/bax']),
199
193
[u'bar', u'foo/bar'],
200
[u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar',
194
[u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar',
201
195
u'.bar', u'foo/.bar']),
202
196
# check that we ignore extra *s, so *** is treated like ** not *.
205
199
[u'foox', u'foo/bax', u'foo/.x', u'foo/bar/bax']),
207
201
[u'bar', u'foo/bar'],
208
[u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar',
202
[u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar',
209
203
u'.bar', u'foo/.bar']),
210
204
# the remaining tests check that ** is interpreted as *
211
205
# unless it is a whole path component
222
216
[u'foo', u'foo.bar'],
223
217
[u'.foo', u'foo/bar', u'foo/.bar']),
225
[u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar',
219
[u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar',
226
220
u'foo/foobar', u'foo/f.bar', u'.bar', u'foo/.bar'],
263
257
def test_leading_asterisk_dot(self):
264
258
self.assertMatch([
266
[u'foo/bar/baz.x', u'\u8336/Q.x', u'foo.y.x', u'.foo.x',
260
[u'foo/bar/baz.x', u'\u8336/Q.x', u'foo.y.x', u'.foo.x',
267
261
u'bar/.foo.x', u'.x',],
299
293
def test_large_globset(self):
300
294
"""tests that the globster can handle a large set of patterns.
302
Large is defined as more than supported by python regex groups,
296
Large is defined as more than supported by python regex groups,
304
298
This test assumes the globs are broken into regexs containing 99
312
306
self.assertEqual(patterns[x],globster.match(filename))
313
307
self.assertEqual(None,globster.match('foobar.300'))
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)
324
class TestExceptionGlobster(TestCase):
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'))
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'))
349
310
class TestOrderedGlobster(TestCase):
357
318
globster = _OrderedGlobster(reversed(patterns))
358
319
self.assertEqual(u'bar.*', globster.match('bar.foo'))
359
320
self.assertEqual(None, globster.match('foo.bar'))
362
class TestNormalizePattern(TestCase):
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\\\\'))
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//'))
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/\\\\/'))