comparison tests/test-match.py @ 38953:987d3a4b989f

match: add tests for visitdir functionality There are a few cases that we could have done better with some additional logic; I tried to annotate these when I noticed them, but may have missed some. The tests are not exhaustive; there are certainly some patterns that I didn't test well, and many that I didn't test at all. The primary motivation was to get coverage on visitdir so that I can cover identical cases in a similar method I'm working on, to make sure that this new method behaves the same (or better). Differential Revision: https://phab.mercurial-scm.org/D4128
author spectral <spectral@google.com>
date Sun, 05 Aug 2018 18:31:19 -0700
parents 44bc181b9835
children 081cc9a95b65
comparison
equal deleted inserted replaced
38952:0e58c5b20745 38953:987d3a4b989f
4 4
5 import silenttestrunner 5 import silenttestrunner
6 6
7 from mercurial import ( 7 from mercurial import (
8 match as matchmod, 8 match as matchmod,
9 util,
9 ) 10 )
11
12 class BaseMatcherTests(unittest.TestCase):
13
14 def testVisitdir(self):
15 m = matchmod.basematcher('', '')
16 self.assertTrue(m.visitdir('.'))
17 self.assertTrue(m.visitdir('dir'))
18
19 class AlwaysMatcherTests(unittest.TestCase):
20
21 def testVisitdir(self):
22 m = matchmod.alwaysmatcher('', '')
23 self.assertEqual(m.visitdir('.'), 'all')
24 self.assertEqual(m.visitdir('dir'), 'all')
10 25
11 class NeverMatcherTests(unittest.TestCase): 26 class NeverMatcherTests(unittest.TestCase):
12 27
13 def testVisitdir(self): 28 def testVisitdir(self):
14 m = matchmod.nevermatcher('', '') 29 m = matchmod.nevermatcher('', '')
15 self.assertFalse(m.visitdir('.')) 30 self.assertFalse(m.visitdir('.'))
16 self.assertFalse(m.visitdir('dir')) 31 self.assertFalse(m.visitdir('dir'))
17 32
33 class PredicateMatcherTests(unittest.TestCase):
34 # predicatematcher does not currently define either of these methods, so
35 # this is equivalent to BaseMatcherTests.
36
37 def testVisitdir(self):
38 m = matchmod.predicatematcher('', '', lambda *a: False)
39 self.assertTrue(m.visitdir('.'))
40 self.assertTrue(m.visitdir('dir'))
41
42 class PatternMatcherTests(unittest.TestCase):
43
44 def testVisitdirPrefix(self):
45 m = matchmod.match('x', '', patterns=['path:dir/subdir'])
46 assert isinstance(m, matchmod.patternmatcher)
47 self.assertTrue(m.visitdir('.'))
48 self.assertTrue(m.visitdir('dir'))
49 self.assertEqual(m.visitdir('dir/subdir'), 'all')
50 # OPT: This should probably be 'all' if its parent is?
51 self.assertTrue(m.visitdir('dir/subdir/x'))
52 self.assertFalse(m.visitdir('folder'))
53
54 def testVisitdirRootfilesin(self):
55 m = matchmod.match('x', '', patterns=['rootfilesin:dir/subdir'])
56 assert isinstance(m, matchmod.patternmatcher)
57 self.assertTrue(m.visitdir('.'))
58 self.assertFalse(m.visitdir('dir/subdir/x'))
59 self.assertFalse(m.visitdir('folder'))
60 # FIXME: These should probably be True.
61 self.assertFalse(m.visitdir('dir'))
62 self.assertFalse(m.visitdir('dir/subdir'))
63
64 def testVisitdirGlob(self):
65 m = matchmod.match('x', '', patterns=['glob:dir/z*'])
66 assert isinstance(m, matchmod.patternmatcher)
67 self.assertTrue(m.visitdir('.'))
68 self.assertTrue(m.visitdir('dir'))
69 self.assertFalse(m.visitdir('folder'))
70 # OPT: these should probably be False.
71 self.assertTrue(m.visitdir('dir/subdir'))
72 self.assertTrue(m.visitdir('dir/subdir/x'))
73
74 class IncludeMatcherTests(unittest.TestCase):
75
76 def testVisitdirPrefix(self):
77 m = matchmod.match('x', '', include=['path:dir/subdir'])
78 assert isinstance(m, matchmod.includematcher)
79 self.assertTrue(m.visitdir('.'))
80 self.assertTrue(m.visitdir('dir'))
81 self.assertEqual(m.visitdir('dir/subdir'), 'all')
82 # OPT: This should probably be 'all' if its parent is?
83 self.assertTrue(m.visitdir('dir/subdir/x'))
84 self.assertFalse(m.visitdir('folder'))
85
86 def testVisitdirRootfilesin(self):
87 m = matchmod.match('x', '', include=['rootfilesin:dir/subdir'])
88 assert isinstance(m, matchmod.includematcher)
89 self.assertTrue(m.visitdir('.'))
90 self.assertTrue(m.visitdir('dir'))
91 self.assertTrue(m.visitdir('dir/subdir'))
92 self.assertFalse(m.visitdir('dir/subdir/x'))
93 self.assertFalse(m.visitdir('folder'))
94
95 def testVisitdirGlob(self):
96 m = matchmod.match('x', '', include=['glob:dir/z*'])
97 assert isinstance(m, matchmod.includematcher)
98 self.assertTrue(m.visitdir('.'))
99 self.assertTrue(m.visitdir('dir'))
100 self.assertFalse(m.visitdir('folder'))
101 # OPT: these should probably be False.
102 self.assertTrue(m.visitdir('dir/subdir'))
103 self.assertTrue(m.visitdir('dir/subdir/x'))
104
105 class ExactMatcherTests(unittest.TestCase):
106
107 def testVisitdir(self):
108 m = matchmod.match('x', '', patterns=['dir/subdir/foo.txt'], exact=True)
109 assert isinstance(m, matchmod.exactmatcher)
110 self.assertTrue(m.visitdir('.'))
111 self.assertTrue(m.visitdir('dir'))
112 self.assertTrue(m.visitdir('dir/subdir'))
113 self.assertFalse(m.visitdir('dir/subdir/foo.txt'))
114 self.assertFalse(m.visitdir('dir/foo'))
115 self.assertFalse(m.visitdir('dir/subdir/x'))
116 self.assertFalse(m.visitdir('folder'))
117
118 class DifferenceMatcherTests(unittest.TestCase):
119
120 def testVisitdirM2always(self):
121 m1 = matchmod.alwaysmatcher('', '')
122 m2 = matchmod.alwaysmatcher('', '')
123 dm = matchmod.differencematcher(m1, m2)
124 # dm should be equivalent to a nevermatcher.
125 self.assertFalse(dm.visitdir('.'))
126 self.assertFalse(dm.visitdir('dir'))
127 self.assertFalse(dm.visitdir('dir/subdir'))
128 self.assertFalse(dm.visitdir('dir/subdir/z'))
129 self.assertFalse(dm.visitdir('dir/foo'))
130 self.assertFalse(dm.visitdir('dir/subdir/x'))
131 self.assertFalse(dm.visitdir('folder'))
132
133 def testVisitdirM2never(self):
134 m1 = matchmod.alwaysmatcher('', '')
135 m2 = matchmod.nevermatcher('', '')
136 dm = matchmod.differencematcher(m1, m2)
137 # dm should be equivalent to a alwaysmatcher. OPT: if m2 is a
138 # nevermatcher, we could return 'all' for these.
139 #
140 # We're testing Equal-to-True instead of just 'assertTrue' since
141 # assertTrue does NOT verify that it's a bool, just that it's truthy.
142 # While we may want to eventually make these return 'all', they should
143 # not currently do so.
144 self.assertEqual(dm.visitdir('.'), True)
145 self.assertEqual(dm.visitdir('dir'), True)
146 self.assertEqual(dm.visitdir('dir/subdir'), True)
147 self.assertEqual(dm.visitdir('dir/subdir/z'), True)
148 self.assertEqual(dm.visitdir('dir/foo'), True)
149 self.assertEqual(dm.visitdir('dir/subdir/x'), True)
150 self.assertEqual(dm.visitdir('folder'), True)
151
152 def testVisitdirM2SubdirPrefix(self):
153 m1 = matchmod.alwaysmatcher('', '')
154 m2 = matchmod.match('', '', patterns=['path:dir/subdir'])
155 dm = matchmod.differencematcher(m1, m2)
156 self.assertEqual(dm.visitdir('.'), True)
157 self.assertEqual(dm.visitdir('dir'), True)
158 self.assertFalse(dm.visitdir('dir/subdir'))
159 # OPT: We should probably return False for these; we don't because
160 # patternmatcher.visitdir() (our m2) doesn't return 'all' for subdirs of
161 # an 'all' pattern, just True.
162 self.assertEqual(dm.visitdir('dir/subdir/z'), True)
163 self.assertEqual(dm.visitdir('dir/subdir/x'), True)
164 # OPT: We could return 'all' for these.
165 self.assertEqual(dm.visitdir('dir/foo'), True)
166 self.assertEqual(dm.visitdir('folder'), True)
167
168 # We're using includematcher instead of patterns because it behaves slightly
169 # better (giving narrower results) than patternmatcher.
170 def testVisitdirIncludeIncludfe(self):
171 m1 = matchmod.match('', '', include=['path:dir/subdir'])
172 m2 = matchmod.match('', '', include=['rootfilesin:dir'])
173 dm = matchmod.differencematcher(m1, m2)
174 self.assertEqual(dm.visitdir('.'), True)
175 self.assertEqual(dm.visitdir('dir'), True)
176 self.assertEqual(dm.visitdir('dir/subdir'), True)
177 self.assertFalse(dm.visitdir('dir/foo'))
178 self.assertFalse(dm.visitdir('folder'))
179 # OPT: We should probably return False for these; we don't because
180 # patternmatcher.visitdir() (our m2) doesn't return 'all' for subdirs of
181 # an 'all' pattern, just True.
182 self.assertEqual(dm.visitdir('dir/subdir/z'), True)
183 self.assertEqual(dm.visitdir('dir/subdir/x'), True)
184
185 class IntersectionMatcherTests(unittest.TestCase):
186
187 def testVisitdirM2always(self):
188 m1 = matchmod.alwaysmatcher('', '')
189 m2 = matchmod.alwaysmatcher('', '')
190 im = matchmod.intersectmatchers(m1, m2)
191 # im should be equivalent to a alwaysmatcher.
192 self.assertEqual(im.visitdir('.'), 'all')
193 self.assertEqual(im.visitdir('dir'), 'all')
194 self.assertEqual(im.visitdir('dir/subdir'), 'all')
195 self.assertEqual(im.visitdir('dir/subdir/z'), 'all')
196 self.assertEqual(im.visitdir('dir/foo'), 'all')
197 self.assertEqual(im.visitdir('dir/subdir/x'), 'all')
198 self.assertEqual(im.visitdir('folder'), 'all')
199
200 def testVisitdirM2never(self):
201 m1 = matchmod.alwaysmatcher('', '')
202 m2 = matchmod.nevermatcher('', '')
203 im = matchmod.intersectmatchers(m1, m2)
204 # im should be equivalent to a nevermatcher.
205 self.assertFalse(im.visitdir('.'))
206 self.assertFalse(im.visitdir('dir'))
207 self.assertFalse(im.visitdir('dir/subdir'))
208 self.assertFalse(im.visitdir('dir/subdir/z'))
209 self.assertFalse(im.visitdir('dir/foo'))
210 self.assertFalse(im.visitdir('dir/subdir/x'))
211 self.assertFalse(im.visitdir('folder'))
212
213 def testVisitdirM2SubdirPrefix(self):
214 m1 = matchmod.alwaysmatcher('', '')
215 m2 = matchmod.match('', '', patterns=['path:dir/subdir'])
216 im = matchmod.intersectmatchers(m1, m2)
217 self.assertEqual(im.visitdir('.'), True)
218 self.assertEqual(im.visitdir('dir'), True)
219 self.assertEqual(im.visitdir('dir/subdir'), 'all')
220 self.assertFalse(im.visitdir('dir/foo'))
221 self.assertFalse(im.visitdir('folder'))
222 # OPT: We should probably return 'all' for these; we don't because
223 # patternmatcher.visitdir() (our m2) doesn't return 'all' for subdirs of
224 # an 'all' pattern, just True.
225 self.assertEqual(im.visitdir('dir/subdir/z'), True)
226 self.assertEqual(im.visitdir('dir/subdir/x'), True)
227
228 # We're using includematcher instead of patterns because it behaves slightly
229 # better (giving narrower results) than patternmatcher.
230 def testVisitdirIncludeIncludfe(self):
231 m1 = matchmod.match('', '', include=['path:dir/subdir'])
232 m2 = matchmod.match('', '', include=['rootfilesin:dir'])
233 im = matchmod.intersectmatchers(m1, m2)
234 self.assertEqual(im.visitdir('.'), True)
235 self.assertEqual(im.visitdir('dir'), True)
236 self.assertFalse(im.visitdir('dir/subdir'))
237 self.assertFalse(im.visitdir('dir/foo'))
238 self.assertFalse(im.visitdir('folder'))
239 self.assertFalse(im.visitdir('dir/subdir/z'))
240 self.assertFalse(im.visitdir('dir/subdir/x'))
241
242 # We're using includematcher instead of patterns because it behaves slightly
243 # better (giving narrower results) than patternmatcher.
244 def testVisitdirIncludeInclude2(self):
245 m1 = matchmod.match('', '', include=['path:dir/subdir'])
246 m2 = matchmod.match('', '', include=['path:folder'])
247 im = matchmod.intersectmatchers(m1, m2)
248 # FIXME: is True correct here?
249 self.assertEqual(im.visitdir('.'), True)
250 self.assertFalse(im.visitdir('dir'))
251 self.assertFalse(im.visitdir('dir/subdir'))
252 self.assertFalse(im.visitdir('dir/foo'))
253 self.assertFalse(im.visitdir('folder'))
254 self.assertFalse(im.visitdir('dir/subdir/z'))
255 self.assertFalse(im.visitdir('dir/subdir/x'))
256
257 # We're using includematcher instead of patterns because it behaves slightly
258 # better (giving narrower results) than patternmatcher.
259 def testVisitdirIncludeInclude3(self):
260 m1 = matchmod.match('', '', include=['path:dir/subdir/x'])
261 m2 = matchmod.match('', '', include=['path:dir/subdir'])
262 im = matchmod.intersectmatchers(m1, m2)
263 self.assertEqual(im.visitdir('.'), True)
264 self.assertEqual(im.visitdir('dir'), True)
265 self.assertEqual(im.visitdir('dir/subdir'), True)
266 self.assertFalse(im.visitdir('dir/foo'))
267 self.assertFalse(im.visitdir('folder'))
268 self.assertFalse(im.visitdir('dir/subdir/z'))
269 # OPT: this should probably be 'all' not True.
270 self.assertEqual(im.visitdir('dir/subdir/x'), True)
271
272 # We're using includematcher instead of patterns because it behaves slightly
273 # better (giving narrower results) than patternmatcher.
274 def testVisitdirIncludeInclude4(self):
275 m1 = matchmod.match('', '', include=['path:dir/subdir/x'])
276 m2 = matchmod.match('', '', include=['path:dir/subdir/z'])
277 im = matchmod.intersectmatchers(m1, m2)
278 # OPT: these next three could probably be False as well.
279 self.assertEqual(im.visitdir('.'), True)
280 self.assertEqual(im.visitdir('dir'), True)
281 self.assertEqual(im.visitdir('dir/subdir'), True)
282 self.assertFalse(im.visitdir('dir/foo'))
283 self.assertFalse(im.visitdir('folder'))
284 self.assertFalse(im.visitdir('dir/subdir/z'))
285 self.assertFalse(im.visitdir('dir/subdir/x'))
286
287 class UnionMatcherTests(unittest.TestCase):
288
289 def testVisitdirM2always(self):
290 m1 = matchmod.alwaysmatcher('', '')
291 m2 = matchmod.alwaysmatcher('', '')
292 um = matchmod.unionmatcher([m1, m2])
293 # um should be equivalent to a alwaysmatcher.
294 self.assertEqual(um.visitdir('.'), 'all')
295 self.assertEqual(um.visitdir('dir'), 'all')
296 self.assertEqual(um.visitdir('dir/subdir'), 'all')
297 self.assertEqual(um.visitdir('dir/subdir/z'), 'all')
298 self.assertEqual(um.visitdir('dir/foo'), 'all')
299 self.assertEqual(um.visitdir('dir/subdir/x'), 'all')
300 self.assertEqual(um.visitdir('folder'), 'all')
301
302 def testVisitdirM1never(self):
303 m1 = matchmod.nevermatcher('', '')
304 m2 = matchmod.alwaysmatcher('', '')
305 um = matchmod.unionmatcher([m1, m2])
306 # um should be equivalent to a alwaysmatcher.
307 self.assertEqual(um.visitdir('.'), 'all')
308 self.assertEqual(um.visitdir('dir'), 'all')
309 self.assertEqual(um.visitdir('dir/subdir'), 'all')
310 self.assertEqual(um.visitdir('dir/subdir/z'), 'all')
311 self.assertEqual(um.visitdir('dir/foo'), 'all')
312 self.assertEqual(um.visitdir('dir/subdir/x'), 'all')
313 self.assertEqual(um.visitdir('folder'), 'all')
314
315 def testVisitdirM2never(self):
316 m1 = matchmod.alwaysmatcher('', '')
317 m2 = matchmod.nevermatcher('', '')
318 um = matchmod.unionmatcher([m1, m2])
319 # um should be equivalent to a alwaysmatcher.
320 self.assertEqual(um.visitdir('.'), 'all')
321 self.assertEqual(um.visitdir('dir'), 'all')
322 self.assertEqual(um.visitdir('dir/subdir'), 'all')
323 self.assertEqual(um.visitdir('dir/subdir/z'), 'all')
324 self.assertEqual(um.visitdir('dir/foo'), 'all')
325 self.assertEqual(um.visitdir('dir/subdir/x'), 'all')
326 self.assertEqual(um.visitdir('folder'), 'all')
327
328 def testVisitdirM2SubdirPrefix(self):
329 m1 = matchmod.alwaysmatcher('', '')
330 m2 = matchmod.match('', '', patterns=['path:dir/subdir'])
331 um = matchmod.unionmatcher([m1, m2])
332 self.assertEqual(um.visitdir('.'), 'all')
333 self.assertEqual(um.visitdir('dir'), 'all')
334 self.assertEqual(um.visitdir('dir/subdir'), 'all')
335 self.assertEqual(um.visitdir('dir/foo'), 'all')
336 self.assertEqual(um.visitdir('folder'), 'all')
337 self.assertEqual(um.visitdir('dir/subdir/z'), 'all')
338 self.assertEqual(um.visitdir('dir/subdir/x'), 'all')
339
340 # We're using includematcher instead of patterns because it behaves slightly
341 # better (giving narrower results) than patternmatcher.
342 def testVisitdirIncludeIncludfe(self):
343 m1 = matchmod.match('', '', include=['path:dir/subdir'])
344 m2 = matchmod.match('', '', include=['rootfilesin:dir'])
345 um = matchmod.unionmatcher([m1, m2])
346 self.assertEqual(um.visitdir('.'), True)
347 self.assertEqual(um.visitdir('dir'), True)
348 self.assertEqual(um.visitdir('dir/subdir'), 'all')
349 self.assertFalse(um.visitdir('dir/foo'))
350 self.assertFalse(um.visitdir('folder'))
351 # OPT: These two should probably be 'all' not True.
352 self.assertEqual(um.visitdir('dir/subdir/z'), True)
353 self.assertEqual(um.visitdir('dir/subdir/x'), True)
354
355 # We're using includematcher instead of patterns because it behaves slightly
356 # better (giving narrower results) than patternmatcher.
357 def testVisitdirIncludeInclude2(self):
358 m1 = matchmod.match('', '', include=['path:dir/subdir'])
359 m2 = matchmod.match('', '', include=['path:folder'])
360 um = matchmod.unionmatcher([m1, m2])
361 self.assertEqual(um.visitdir('.'), True)
362 self.assertEqual(um.visitdir('dir'), True)
363 self.assertEqual(um.visitdir('dir/subdir'), 'all')
364 self.assertFalse(um.visitdir('dir/foo'))
365 self.assertEqual(um.visitdir('folder'), 'all')
366 # OPT: These should probably be 'all' not True.
367 self.assertEqual(um.visitdir('dir/subdir/z'), True)
368 self.assertEqual(um.visitdir('dir/subdir/x'), True)
369
370 # We're using includematcher instead of patterns because it behaves slightly
371 # better (giving narrower results) than patternmatcher.
372 def testVisitdirIncludeInclude3(self):
373 m1 = matchmod.match('', '', include=['path:dir/subdir/x'])
374 m2 = matchmod.match('', '', include=['path:dir/subdir'])
375 um = matchmod.unionmatcher([m1, m2])
376 self.assertEqual(um.visitdir('.'), True)
377 self.assertEqual(um.visitdir('dir'), True)
378 self.assertEqual(um.visitdir('dir/subdir'), 'all')
379 self.assertFalse(um.visitdir('dir/foo'))
380 self.assertFalse(um.visitdir('folder'))
381 self.assertEqual(um.visitdir('dir/subdir/x'), 'all')
382 # OPT: this should probably be 'all' not True.
383 self.assertEqual(um.visitdir('dir/subdir/z'), True)
384
385 # We're using includematcher instead of patterns because it behaves slightly
386 # better (giving narrower results) than patternmatcher.
387 def testVisitdirIncludeInclude4(self):
388 m1 = matchmod.match('', '', include=['path:dir/subdir/x'])
389 m2 = matchmod.match('', '', include=['path:dir/subdir/z'])
390 um = matchmod.unionmatcher([m1, m2])
391 # OPT: these next three could probably be False as well.
392 self.assertEqual(um.visitdir('.'), True)
393 self.assertEqual(um.visitdir('dir'), True)
394 self.assertEqual(um.visitdir('dir/subdir'), True)
395 self.assertFalse(um.visitdir('dir/foo'))
396 self.assertFalse(um.visitdir('folder'))
397 self.assertEqual(um.visitdir('dir/subdir/z'), 'all')
398 self.assertEqual(um.visitdir('dir/subdir/x'), 'all')
399
400 class SubdirMatcherTests(unittest.TestCase):
401
402 def testVisitdir(self):
403 m = matchmod.match('', '', include=['path:dir/subdir'])
404 sm = matchmod.subdirmatcher('dir', m)
405
406 self.assertEqual(sm.visitdir('.'), True)
407 self.assertEqual(sm.visitdir('subdir'), 'all')
408 # OPT: These next two should probably be 'all' not True.
409 self.assertEqual(sm.visitdir('subdir/x'), True)
410 self.assertEqual(sm.visitdir('subdir/z'), True)
411 self.assertFalse(sm.visitdir('foo'))
412
413 class PrefixdirMatcherTests(unittest.TestCase):
414
415 def testVisitdir(self):
416 m = matchmod.match(util.localpath('root/d'), 'e/f',
417 ['../a.txt', 'b.txt'])
418 pm = matchmod.prefixdirmatcher('root', 'd/e/f', 'd', m)
419
420 # `m` elides 'd' because it's part of the root, and the rest of the
421 # patterns are relative.
422 self.assertEqual(bool(m('a.txt')), False)
423 self.assertEqual(bool(m('b.txt')), False)
424 self.assertEqual(bool(m('e/a.txt')), True)
425 self.assertEqual(bool(m('e/b.txt')), False)
426 self.assertEqual(bool(m('e/f/b.txt')), True)
427
428 # The prefix matcher re-adds 'd' to the paths, so they need to be
429 # specified when using the prefixdirmatcher.
430 self.assertEqual(bool(pm('a.txt')), False)
431 self.assertEqual(bool(pm('b.txt')), False)
432 self.assertEqual(bool(pm('d/e/a.txt')), True)
433 self.assertEqual(bool(pm('d/e/b.txt')), False)
434 self.assertEqual(bool(pm('d/e/f/b.txt')), True)
435
436 self.assertEqual(m.visitdir('.'), True)
437 self.assertEqual(m.visitdir('e'), True)
438 self.assertEqual(m.visitdir('e/f'), True)
439 self.assertEqual(m.visitdir('e/f/g'), False)
440
441 self.assertEqual(pm.visitdir('.'), True)
442 self.assertEqual(pm.visitdir('d'), True)
443 self.assertEqual(pm.visitdir('d/e'), True)
444 self.assertEqual(pm.visitdir('d/e/f'), True)
445 self.assertEqual(pm.visitdir('d/e/f/g'), False)
446
18 if __name__ == '__main__': 447 if __name__ == '__main__':
19 silenttestrunner.main(__name__) 448 silenttestrunner.main(__name__)