bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
1 |
# Copyright (C) 2006 Canonical Ltd
|
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
|
|
16 |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
17 |
||
18 |
from bzrlib.tests import TestCase, TestCaseInTempDir |
|
19 |
||
20 |
from bzrlib.glob import ( |
|
21 |
Globster
|
|
22 |
)
|
|
23 |
||
24 |
||
25 |
class TestGlobster(TestCase): |
|
26 |
||
27 |
def assertMatch(self, matchset, glob_prefix=None): |
|
28 |
for glob, positive, negative in matchset: |
|
29 |
if glob_prefix: |
|
30 |
glob = glob_prefix + glob |
|
31 |
globster = Globster([glob]) |
|
32 |
for name in positive: |
|
33 |
self.failUnless(globster.match(name), repr( |
|
34 |
u'name "%s" does not match glob "%s" (re=%s)' % |
|
35 |
(name, glob, globster._regex_patterns[0][0].pattern))) |
|
36 |
for name in negative: |
|
37 |
self.failIf(globster.match(name), repr( |
|
38 |
u'name "%s" does match glob "%s" (re=%s)' % |
|
39 |
(name, glob, globster._regex_patterns[0][0].pattern))) |
|
40 |
||
41 |
def test_char_groups(self): |
|
42 |
# The definition of digit this uses includes arabic digits from
|
|
43 |
# non-latin scripts (arabic, indic, etc.) and subscript/superscript
|
|
44 |
# digits, but neither roman numerals nor vulgar fractions.
|
|
45 |
matchset = [ |
|
46 |
(u'[[:digit:]]', |
|
47 |
[u'0', u'5', u'\u0663', u'\u06f9', u'\u0f21', u'\xb9'], |
|
48 |
[u'T', u'q', u' ', u'\u8336', u'.']), |
|
49 |
(u'[[:space:]]', |
|
50 |
[u' ', u'\t', u'\n', u'\xa0', u'\u2000', u'\u2002'], |
|
51 |
[u'a', u'-', u'\u8336', u'.']), |
|
52 |
(u'[^[:space:]]', |
|
|
2135.2.2
by Kent Gibson
Ignore pattern matcher (glob.py) patches: |
53 |
[u'a', u'-', u'\u8336', u'.'], |
54 |
[u' ', u'\t', u'\n', u'\xa0', u'\u2000', u'\u2002']), |
|
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
55 |
(u'[[:alnum:]]', |
56 |
[u'a', u'Z', u'\u017e', u'\u8336'], |
|
57 |
[u':', u'-', u'\u25cf', u'.']), |
|
58 |
(u'[^[:alnum:]]', |
|
|
2135.2.2
by Kent Gibson
Ignore pattern matcher (glob.py) patches: |
59 |
[u':', u'-', u'\u25cf', u'.'], |
60 |
[u'a']), |
|
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
61 |
(u'[[:ascii:]]', |
|
2135.2.2
by Kent Gibson
Ignore pattern matcher (glob.py) patches: |
62 |
[u'a', u'Q', u'^', u'.'], |
63 |
[u'\xcc', u'\u8336']), |
|
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
64 |
(u'[^[:ascii:]]', |
65 |
[u'\xcc', u'\u8336'], |
|
66 |
[u'a', u'Q', u'^', u'.']), |
|
67 |
(u'[[:blank:]]', |
|
68 |
[u'\t'], |
|
69 |
[u'x', u'y', u'z', u'.']), |
|
70 |
(u'[^[:blank:]]', |
|
|
2135.2.2
by Kent Gibson
Ignore pattern matcher (glob.py) patches: |
71 |
[u'x', u'y', u'z', u'.'], |
72 |
[u'\t']), |
|
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
73 |
(u'[[:cntrl:]]', |
74 |
[u'\b', u'\t', '\x7f'], |
|
75 |
[u'a', u'Q', u'\u8336', u'.']), |
|
76 |
(u'[a-z]', |
|
77 |
[u'a', u'q', u'f'], |
|
78 |
[u'A', u'Q', u'F']), |
|
79 |
(ur'[^a-z]', |
|
80 |
[u'A', u'Q', u'F'], |
|
81 |
[u'a', u'q', u'f']), |
|
82 |
(u'[!a-z]foo', |
|
|
2135.2.2
by Kent Gibson
Ignore pattern matcher (glob.py) patches: |
83 |
[u'Afoo', u'.foo'], |
84 |
[u'afoo', u'ABfoo']), |
|
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
85 |
(ur'foo[!a-z]bar', |
86 |
[u'fooAbar', u'foo.bar'], |
|
87 |
[u'foojbar']), |
|
88 |
(ur'[\x20-\x30\u8336]', |
|
89 |
[u'\040', u'\044', u'\u8336'], |
|
90 |
[]),
|
|
91 |
(ur'[^\x20-\x30\u8336]', |
|
92 |
[],
|
|
93 |
[u'\040', u'\044', u'\u8336']), |
|
94 |
]
|
|
95 |
self.assertMatch(matchset) |
|
96 |
self.assertMatch(matchset,glob_prefix='./') |
|
97 |
||
98 |
def test_regex(self): |
|
99 |
self.assertMatch([ |
|
100 |
(ur'RE:(a|b|c+)', |
|
101 |
[u'a', u'b', u'ccc'], |
|
102 |
[u'd', u'aa', u'c+', u'-a']), |
|
103 |
(ur'RE:(?:a|b|c+)', |
|
104 |
[u'a', u'b', u'ccc'], |
|
105 |
[u'd', u'aa', u'c+', u'-a']), |
|
106 |
(ur'RE:(?P<a>.)(?P=a)', |
|
107 |
[u'a'], |
|
108 |
[u'ab', u'aa', u'aaa']), |
|
109 |
])
|
|
110 |
||
111 |
def test_question_mark(self): |
|
112 |
self.assertMatch([ |
|
113 |
(u'?foo', |
|
|
2135.2.2
by Kent Gibson
Ignore pattern matcher (glob.py) patches: |
114 |
[u'xfoo', u'bar/xfoo', u'bar/\u8336foo', u'.foo', u'bar/.foo'], |
115 |
[u'bar/foo', u'foo']), |
|
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
116 |
(u'foo?bar', |
117 |
[u'fooxbar', u'foo.bar', u'foo\u8336bar', u'qyzzy/foo.bar'], |
|
118 |
[u'foo/bar']), |
|
119 |
(u'foo/?bar', |
|
|
2135.2.2
by Kent Gibson
Ignore pattern matcher (glob.py) patches: |
120 |
[u'foo/xbar', u'foo/\u8336bar', u'foo/.bar'], |
121 |
[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) |
122 |
])
|
123 |
||
124 |
def test_asterisk(self): |
|
125 |
self.assertMatch([ |
|
126 |
(u'x*x', |
|
127 |
[u'xx', u'x.x', u'x\u8336..x', u'\u8336/x.x', u'x.y.x'], |
|
128 |
[u'x/x', u'bar/x/bar/x', u'bax/abaxab']), |
|
129 |
(u'foo/*x', |
|
|
2135.2.2
by Kent Gibson
Ignore pattern matcher (glob.py) patches: |
130 |
[u'foo/x', u'foo/bax', u'foo/a.x', u'foo/.x', u'foo/.q.x'], |
131 |
[u'foo/bar/bax']), |
|
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
132 |
(u'*/*x', |
|
2135.2.2
by Kent Gibson
Ignore pattern matcher (glob.py) patches: |
133 |
[u'\u8336/x', u'foo/x', u'foo/bax', u'x/a.x', u'.foo/x', |
134 |
u'\u8336/.x', u'foo/.q.x'], |
|
135 |
[u'foo/bar/bax']), |
|
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
136 |
(u'f*', |
137 |
[u'foo', u'foo.bar'], |
|
138 |
[u'.foo', u'foo/bar', u'foo/.bar']), |
|
139 |
(u'*bar', |
|
140 |
[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: |
141 |
u'foo/foobar', u'foo/f.bar', u'.bar', u'foo/.bar'], |
142 |
[]),
|
|
143 |
])
|
|
144 |
||
145 |
def test_double_asterisk(self): |
|
146 |
self.assertMatch([ |
|
147 |
# expected uses of double asterisk
|
|
148 |
(u'foo/**/x', |
|
149 |
[u'foo/x', u'foo/bar/x'], |
|
150 |
[u'foox', u'foo/bax', u'foo/.x', u'foo/bar/bax']), |
|
151 |
(u'**/bar', |
|
152 |
[u'bar', u'foo/bar'], |
|
153 |
[u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar', |
|
154 |
u'.bar', u'foo/.bar']), |
|
155 |
# check that we ignore extra *s, so *** is treated like ** not *.
|
|
156 |
(u'foo/***/x', |
|
157 |
[u'foo/x', u'foo/bar/x'], |
|
158 |
[u'foox', u'foo/bax', u'foo/.x', u'foo/bar/bax']), |
|
159 |
(u'***/bar', |
|
160 |
[u'bar', u'foo/bar'], |
|
161 |
[u'foobar', u'foo.bar', u'foo/foobar', u'foo/f.bar', |
|
162 |
u'.bar', u'foo/.bar']), |
|
163 |
# the remaining tests check that ** is interpreted as *
|
|
164 |
# unless it is a whole path component
|
|
165 |
(u'x**/x', |
|
166 |
[u'x\u8336/x', u'x/x'], |
|
167 |
[u'xx', u'x.x', u'bar/x/bar/x', u'x.y.x', u'x/y/x']), |
|
168 |
(u'x**x', |
|
169 |
[u'xx', u'x.x', u'x\u8336..x', u'foo/x.x', u'x.y.x'], |
|
170 |
[u'bar/x/bar/x', u'xfoo/bar/x', u'x/x', u'bax/abaxab']), |
|
171 |
(u'foo/**x', |
|
172 |
[u'foo/x', u'foo/bax', u'foo/a.x', u'foo/.x', u'foo/.q.x'], |
|
173 |
[u'foo/bar/bax']), |
|
174 |
(u'f**', |
|
175 |
[u'foo', u'foo.bar'], |
|
176 |
[u'.foo', u'foo/bar', u'foo/.bar']), |
|
177 |
(u'**bar', |
|
178 |
[u'bar', u'foobar', ur'foo\nbar', u'foo.bar', u'foo/bar', |
|
179 |
u'foo/foobar', u'foo/f.bar', u'.bar', u'foo/.bar'], |
|
180 |
[]),
|
|
181 |
])
|
|
182 |
||
183 |
def test_leading_dot_slash(self): |
|
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
184 |
self.assertMatch([ |
185 |
(u'./foo', |
|
186 |
[u'foo'], |
|
187 |
[u'\u8336/foo', u'barfoo', u'x/y/foo']), |
|
188 |
(u'./f*', |
|
189 |
[u'foo'], |
|
190 |
[u'foo/bar', u'foo/.bar', u'x/foo/y']), |
|
191 |
])
|
|
192 |
||
|
2135.2.2
by Kent Gibson
Ignore pattern matcher (glob.py) patches: |
193 |
def test_leading_asterisk_dot(self): |
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
194 |
self.assertMatch([ |
195 |
(u'*.x', |
|
|
2135.2.2
by Kent Gibson
Ignore pattern matcher (glob.py) patches: |
196 |
[u'foo/bar/baz.x', u'\u8336/Q.x', u'foo.y.x', u'.foo.x', |
197 |
u'bar/.foo.x', u'.x',], |
|
198 |
[u'foo.x.y']), |
|
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
199 |
(u'foo/*.bar', |
|
2135.2.2
by Kent Gibson
Ignore pattern matcher (glob.py) patches: |
200 |
[u'foo/b.bar', u'foo/a.b.bar', u'foo/.bar'], |
201 |
[u'foo/bar']), |
|
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
202 |
(u'*.~*', |
|
2135.2.2
by Kent Gibson
Ignore pattern matcher (glob.py) patches: |
203 |
[u'foo.py.~1~', u'.foo.py.~1~'], |
204 |
[]),
|
|
|
2135.2.1
by Kent Gibson
Added glob module to replace broken fnmatch based ignore pattern matching (#57637) |
205 |
])
|
206 |
||
207 |
def test_end_anchor(self): |
|
208 |
self.assertMatch([ |
|
209 |
(u'*.333', |
|
210 |
[u'foo.333'], |
|
211 |
[u'foo.3']), |
|
212 |
(u'*.3', |
|
213 |
[u'foo.3'], |
|
214 |
[u'foo.333']), |
|
215 |
])
|
|
216 |
||
217 |
def test_mixed_globs(self): |
|
218 |
"""tests handling of combinations of path type matches. |
|
219 |
||
220 |
The types being extension, basename and full path.
|
|
221 |
"""
|
|
222 |
patterns = [ u'*.foo', u'.*.swp', u'./*.png'] |
|
223 |
globster = Globster(patterns) |
|
224 |
self.assertEqual(u'*.foo', globster.match('bar.foo')) |
|
225 |
self.assertEqual(u'./*.png', globster.match('foo.png')) |
|
226 |
self.assertEqual(None, globster.match('foo/bar.png')) |
|
227 |
self.assertEqual(u'.*.swp', globster.match('foo/.bar.py.swp')) |
|
228 |
||
229 |
def test_large_globset(self): |
|
230 |
"""tests that the globster can handle a large set of patterns. |
|
231 |
||
232 |
Large is defined as more than supported by python regex groups,
|
|
233 |
i.e. 99.
|
|
234 |
This test assumes the globs are broken into regexs containing 99
|
|
235 |
groups.
|
|
236 |
"""
|
|
237 |
patterns = [ u'*.%03d' % i for i in xrange(0,300) ] |
|
238 |
globster = Globster(patterns) |
|
239 |
# test the fence posts
|
|
240 |
for x in (0,98,99,197,198,296,297,299): |
|
241 |
filename = u'foo.%03d' % x |
|
242 |
self.assertEqual(patterns[x],globster.match(filename)) |
|
243 |
self.assertEqual(None,globster.match('foobar.300')) |
|
244 |