Give the subst logic its own SCons.Subst module. It's big enough.
[scons.git] / src / engine / SCons / UtilTests.py
1 #
2 # __COPYRIGHT__
3 #
4 # Permission is hereby granted, free of charge, to any person obtaining
5 # a copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including
7 # without limitation the rights to use, copy, modify, merge, publish,
8 # distribute, sublicense, and/or sell copies of the Software, and to
9 # permit persons to whom the Software is furnished to do so, subject to
10 # the following conditions:
11 #
12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software.
14 #
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
16 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
17 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 #
23
24 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
25
26 import os
27 import os.path
28 import string
29 import StringIO
30 import sys
31 import types
32 import unittest
33
34 from UserDict import UserDict
35
36 import TestCmd
37
38 import SCons.Errors
39
40 from SCons.Util import *
41
42 class OutBuffer:
43     def __init__(self):
44         self.buffer = ""
45
46     def write(self, str):
47         self.buffer = self.buffer + str
48
49 class UtilTestCase(unittest.TestCase):
50     def test_splitext(self):
51         assert splitext('foo') == ('foo','')
52         assert splitext('foo.bar') == ('foo','.bar')
53         assert splitext(os.path.join('foo.bar', 'blat')) == (os.path.join('foo.bar', 'blat'),'')
54
55     class Node:
56         def __init__(self, name, children=[]):
57             self.children = children
58             self.name = name
59         def __str__(self):
60             return self.name
61         def exists(self):
62             return 1
63         def rexists(self):
64             return 1
65         def has_builder(self):
66             return 1
67         def has_explicit_builder(self):
68             return 1
69         def side_effect(self):
70             return 1
71         def precious(self):
72             return 1
73         def always_build(self):
74             return 1
75         def current(self):
76             return 1
77
78     def tree_case_1(self):
79         """Fixture for the render_tree() and print_tree() tests."""
80         windows_h = self.Node("windows.h")
81         stdlib_h = self.Node("stdlib.h")
82         stdio_h = self.Node("stdio.h")
83         bar_c = self.Node("bar.c", [stdlib_h, windows_h])
84         bar_o = self.Node("bar.o", [bar_c])
85         foo_c = self.Node("foo.c", [stdio_h])
86         foo_o = self.Node("foo.o", [foo_c])
87         foo = self.Node("foo", [foo_o, bar_o])
88
89         expect = """\
90 +-foo
91   +-foo.o
92   | +-foo.c
93   |   +-stdio.h
94   +-bar.o
95     +-bar.c
96       +-stdlib.h
97       +-windows.h
98 """
99
100         lines = string.split(expect, '\n')[:-1]
101         lines = map(lambda l: '[E BSPAC]'+l, lines)
102         withtags = string.join(lines, '\n') + '\n'
103
104         return foo, expect, withtags
105
106     def tree_case_2(self):
107         """Fixture for the render_tree() and print_tree() tests."""
108
109         stdlib_h = self.Node("stdlib.h")
110         bar_h = self.Node('bar.h', [stdlib_h])
111         blat_h = self.Node('blat.h', [stdlib_h])
112         blat_c = self.Node('blat.c', [blat_h, bar_h])
113         blat_o = self.Node('blat.o', [blat_c])
114
115         expect = """\
116 +-blat.o
117   +-blat.c
118     +-blat.h
119     | +-stdlib.h
120     +-bar.h
121 """
122
123         lines = string.split(expect, '\n')[:-1]
124         lines = map(lambda l: '[E BSPAC]'+l, lines)
125         withtags = string.join(lines, '\n') + '\n'
126
127         return blat_o, expect, withtags
128
129     def test_render_tree(self):
130         """Test the render_tree() function"""
131         def get_children(node):
132             return node.children
133
134         node, expect, withtags = self.tree_case_1()
135         actual = render_tree(node, get_children)
136         assert expect == actual, (expect, actual)
137
138         node, expect, withtags = self.tree_case_2()
139         actual = render_tree(node, get_children, 1)
140         assert expect == actual, (expect, actual)
141
142     def test_print_tree(self):
143         """Test the print_tree() function"""
144         def get_children(node):
145             return node.children
146
147         save_stdout = sys.stdout
148
149         try:
150             node, expect, withtags = self.tree_case_1()
151
152             sys.stdout = StringIO.StringIO()
153             print_tree(node, get_children)
154             actual = sys.stdout.getvalue()
155             assert expect == actual, (expect, actual)
156
157             sys.stdout = StringIO.StringIO()
158             print_tree(node, get_children, showtags=1)
159             actual = sys.stdout.getvalue()
160             assert withtags == actual, (withtags, actual)
161
162             node, expect, withtags = self.tree_case_2()
163
164             sys.stdout = StringIO.StringIO()
165             print_tree(node, get_children, 1)
166             actual = sys.stdout.getvalue()
167             assert expect == actual, (expect, actual)
168
169             sys.stdout = StringIO.StringIO()
170             # The following call should work here:
171             #    print_tree(node, get_children, 1, showtags=1)
172             # For some reason I don't understand, though, *this*
173             # time that we call print_tree, the visited dictionary
174             # is still populated with the values from the last call!
175             # I can't see why this would be, short of a bug in Python,
176             # and rather than continue banging my head against the
177             # brick wall for a *test*, we're going to going with
178             # the cheap, easy workaround:
179             print_tree(node, get_children, 1, showtags=1, visited={})
180             actual = sys.stdout.getvalue()
181             assert withtags == actual, (withtags, actual)
182         finally:
183             sys.stdout = save_stdout
184
185     def test_is_Dict(self):
186         assert is_Dict({})
187         assert is_Dict(UserDict())
188         assert not is_Dict([])
189         assert not is_Dict("")
190         if hasattr(types, 'UnicodeType'):
191             exec "assert not is_Dict(u'')"
192
193     def test_is_List(self):
194         assert is_List([])
195         import UserList
196         assert is_List(UserList.UserList())
197         assert not is_List({})
198         assert not is_List("")
199         if hasattr(types, 'UnicodeType'):
200             exec "assert not is_List(u'')"
201
202     def test_is_String(self):
203         assert is_String("")
204         if hasattr(types, 'UnicodeType'):
205             exec "assert is_String(u'')"
206         try:
207             import UserString
208         except:
209             pass
210         else:
211             assert is_String(UserString.UserString(''))
212         assert not is_String({})
213         assert not is_String([])
214
215     def test_to_String(self):
216         """Test the to_String() method."""
217         assert to_String(1) == "1", to_String(1)
218         assert to_String([ 1, 2, 3]) == str([1, 2, 3]), to_String([1,2,3])
219         assert to_String("foo") == "foo", to_String("foo")
220
221         try:
222             import UserString
223
224             s1=UserString.UserString('blah')
225             assert to_String(s1) == s1, s1
226             assert to_String(s1) == 'blah', s1
227
228             class Derived(UserString.UserString):
229                 pass
230             s2 = Derived('foo')
231             assert to_String(s2) == s2, s2
232             assert to_String(s2) == 'foo', s2
233
234             if hasattr(types, 'UnicodeType'):
235                 s3=UserString.UserString(unicode('bar'))
236                 assert to_String(s3) == s3, s3
237                 assert to_String(s3) == unicode('bar'), s3
238                 assert type(to_String(s3)) is types.UnicodeType, \
239                        type(to_String(s3))
240         except ImportError:
241             pass
242
243         if hasattr(types, 'UnicodeType'):
244             s4 = unicode('baz')
245             assert to_String(s4) == unicode('baz'), to_String(s4)
246             assert type(to_String(s4)) is types.UnicodeType, \
247                    type(to_String(s4))
248
249     def test_WhereIs(self):
250         test = TestCmd.TestCmd(workdir = '')
251
252         sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
253         sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
254         sub3_xxx_exe = test.workpath('sub3', 'xxx.exe')
255         sub4_xxx_exe = test.workpath('sub4', 'xxx.exe')
256
257         test.subdir('subdir', 'sub1', 'sub2', 'sub3', 'sub4')
258
259         if sys.platform != 'win32':
260             test.write(sub1_xxx_exe, "\n")
261
262         os.mkdir(sub2_xxx_exe)
263
264         test.write(sub3_xxx_exe, "\n")
265         os.chmod(sub3_xxx_exe, 0777)
266
267         test.write(sub4_xxx_exe, "\n")
268         os.chmod(sub4_xxx_exe, 0777)
269
270         env_path = os.environ['PATH']
271
272         try:
273             pathdirs_1234 = [ test.workpath('sub1'),
274                               test.workpath('sub2'),
275                               test.workpath('sub3'),
276                               test.workpath('sub4'),
277                             ] + string.split(env_path, os.pathsep)
278
279             pathdirs_1243 = [ test.workpath('sub1'),
280                               test.workpath('sub2'),
281                               test.workpath('sub4'),
282                               test.workpath('sub3'),
283                             ] + string.split(env_path, os.pathsep)
284
285             os.environ['PATH'] = string.join(pathdirs_1234, os.pathsep)
286             wi = WhereIs('xxx.exe')
287             assert wi == test.workpath(sub3_xxx_exe), wi
288             wi = WhereIs('xxx.exe', pathdirs_1243)
289             assert wi == test.workpath(sub4_xxx_exe), wi
290             wi = WhereIs('xxx.exe', string.join(pathdirs_1243, os.pathsep))
291             assert wi == test.workpath(sub4_xxx_exe), wi
292
293             wi = WhereIs('xxx.exe',reject = sub3_xxx_exe)
294             assert wi == test.workpath(sub4_xxx_exe), wi
295             wi = WhereIs('xxx.exe', pathdirs_1243, reject = sub3_xxx_exe)
296             assert wi == test.workpath(sub4_xxx_exe), wi
297
298             os.environ['PATH'] = string.join(pathdirs_1243, os.pathsep)
299             wi = WhereIs('xxx.exe')
300             assert wi == test.workpath(sub4_xxx_exe), wi
301             wi = WhereIs('xxx.exe', pathdirs_1234)
302             assert wi == test.workpath(sub3_xxx_exe), wi
303             wi = WhereIs('xxx.exe', string.join(pathdirs_1234, os.pathsep))
304             assert wi == test.workpath(sub3_xxx_exe), wi
305
306             if sys.platform == 'win32':
307                 wi = WhereIs('xxx', pathext = '')
308                 assert wi is None, wi
309
310                 wi = WhereIs('xxx', pathext = '.exe')
311                 assert wi == test.workpath(sub4_xxx_exe), wi
312
313                 wi = WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
314                 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
315
316                 # Test that we return a normalized path even when
317                 # the path contains forward slashes.
318                 forward_slash = test.workpath('') + '/sub3'
319                 wi = WhereIs('xxx', path = forward_slash, pathext = '.EXE')
320                 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
321
322             del os.environ['PATH']
323             wi = WhereIs('xxx.exe')
324             assert wi is None, wi
325
326         finally:
327             os.environ['PATH'] = env_path
328             
329
330     def test_is_valid_construction_var(self):
331         """Testing is_valid_construction_var()"""
332         r = is_valid_construction_var("_a")
333         assert not r is None, r
334         r = is_valid_construction_var("z_")
335         assert not r is None, r
336         r = is_valid_construction_var("X_")
337         assert not r is None, r
338         r = is_valid_construction_var("2a")
339         assert r is None, r
340         r = is_valid_construction_var("a2_")
341         assert not r is None, r
342         r = is_valid_construction_var("/")
343         assert r is None, r
344         r = is_valid_construction_var("_/")
345         assert r is None, r
346         r = is_valid_construction_var("a/")
347         assert r is None, r
348         r = is_valid_construction_var(".b")
349         assert r is None, r
350         r = is_valid_construction_var("_.b")
351         assert r is None, r
352         r = is_valid_construction_var("b1._")
353         assert r is None, r
354         r = is_valid_construction_var("-b")
355         assert r is None, r
356         r = is_valid_construction_var("_-b")
357         assert r is None, r
358         r = is_valid_construction_var("b1-_")
359         assert r is None, r
360
361     def test_get_env_var(self):
362         """Testing get_environment_var()."""
363         assert get_environment_var("$FOO") == "FOO", get_environment_var("$FOO")
364         assert get_environment_var("${BAR}") == "BAR", get_environment_var("${BAR}")
365         assert get_environment_var("$FOO_BAR1234") == "FOO_BAR1234", get_environment_var("$FOO_BAR1234")
366         assert get_environment_var("${BAR_FOO1234}") == "BAR_FOO1234", get_environment_var("${BAR_FOO1234}")
367         assert get_environment_var("${BAR}FOO") == None, get_environment_var("${BAR}FOO")
368         assert get_environment_var("$BAR ") == None, get_environment_var("$BAR ")
369         assert get_environment_var("FOO$BAR") == None, get_environment_var("FOO$BAR")
370         assert get_environment_var("$FOO[0]") == None, get_environment_var("$FOO[0]")
371         assert get_environment_var("${some('complex expression')}") == None, get_environment_var("${some('complex expression')}")
372
373     def test_Proxy(self):
374         """Test generic Proxy class."""
375         class Subject:
376             def foo(self):
377                 return 1
378             def bar(self):
379                 return 2
380
381         s=Subject()
382         s.baz = 3
383
384         class ProxyTest(Proxy):
385             def bar(self):
386                 return 4
387
388         p=ProxyTest(s)
389
390         assert p.foo() == 1, p.foo()
391         assert p.bar() == 4, p.bar()
392         assert p.baz == 3, p.baz
393
394         p.baz = 5
395         s.baz = 6
396
397         assert p.baz == 5, p.baz
398         assert p.get() == s, p.get()
399
400     def test_display(self):
401         old_stdout = sys.stdout
402         sys.stdout = OutBuffer()
403         display("line1")
404         display.set_mode(0)
405         display("line2")
406         display.set_mode(1)
407         display("line3")
408         display("line4\n", append_newline=0)
409         display.set_mode(0)
410         display("dont print1")
411         display("dont print2\n", append_newline=0)
412         display.set_mode(1)
413         assert sys.stdout.buffer == "line1\nline3\nline4\n"
414         sys.stdout = old_stdout
415
416     def test_get_native_path(self):
417         """Test the get_native_path() function."""
418         import tempfile
419         filename = tempfile.mktemp()
420         str = '1234567890 ' + filename
421         try:
422             open(filename, 'w').write(str)
423             assert open(get_native_path(filename)).read() == str
424         finally:
425             try:
426                 os.unlink(filename)
427             except OSError:
428                 pass
429
430     def test_PrependPath(self):
431         """Test prepending to a path"""
432         p1 = r'C:\dir\num\one;C:\dir\num\two'
433         p2 = r'C:\mydir\num\one;C:\mydir\num\two'
434         # have to include the pathsep here so that the test will work on UNIX too.
435         p1 = PrependPath(p1,r'C:\dir\num\two',sep = ';')
436         p1 = PrependPath(p1,r'C:\dir\num\three',sep = ';')
437         p2 = PrependPath(p2,r'C:\mydir\num\three',sep = ';')
438         p2 = PrependPath(p2,r'C:\mydir\num\one',sep = ';')
439         assert(p1 == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
440         assert(p2 == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
441
442     def test_AppendPath(self):
443         """Test appending to a path."""
444         p1 = r'C:\dir\num\one;C:\dir\num\two'
445         p2 = r'C:\mydir\num\one;C:\mydir\num\two'
446         # have to include the pathsep here so that the test will work on UNIX too.
447         p1 = AppendPath(p1,r'C:\dir\num\two',sep = ';')
448         p1 = AppendPath(p1,r'C:\dir\num\three',sep = ';')
449         p2 = AppendPath(p2,r'C:\mydir\num\three',sep = ';')
450         p2 = AppendPath(p2,r'C:\mydir\num\one',sep = ';')
451         assert(p1 == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
452         assert(p2 == r'C:\mydir\num\two;C:\mydir\num\three;C:\mydir\num\one')
453
454     def test_NodeList(self):
455         """Test NodeList class"""
456         class TestClass:
457             def __init__(self, name, child=None):
458                 self.child = child
459                 self.bar = name
460             def foo(self):
461                 return self.bar + "foo"
462             def getself(self):
463                 return self
464
465         t1 = TestClass('t1', TestClass('t1child'))
466         t2 = TestClass('t2', TestClass('t2child'))
467         t3 = TestClass('t3')
468
469         nl = NodeList([t1, t2, t3])
470         assert nl.foo() == [ 't1foo', 't2foo', 't3foo' ], nl.foo()
471         assert nl.bar == [ 't1', 't2', 't3' ], nl.bar
472         assert nl.getself().bar == [ 't1', 't2', 't3' ], nl.getself().bar
473         assert nl[0:2].child.foo() == [ 't1childfoo', 't2childfoo' ], \
474                nl[0:2].child.foo()
475         assert nl[0:2].child.bar == [ 't1child', 't2child' ], \
476                nl[0:2].child.bar
477
478     def test_CLVar(self):
479         """Test the command-line construction variable class"""
480         f = SCons.Util.CLVar('a b')
481
482         r = f + 'c d'
483         assert isinstance(r, SCons.Util.CLVar), type(r)
484         assert r.data == ['a', 'b', 'c', 'd'], r.data
485         assert str(r) == 'a b c d', str(r)
486
487         r = f + ' c d'
488         assert isinstance(r, SCons.Util.CLVar), type(r)
489         assert r.data == ['a', 'b', 'c', 'd'], r.data
490         assert str(r) == 'a b c d', str(r)
491
492         r = f + ['c d']
493         assert isinstance(r, SCons.Util.CLVar), type(r)
494         assert r.data == ['a', 'b', 'c d'], r.data
495         assert str(r) == 'a b c d', str(r)
496
497         r = f + [' c d']
498         assert isinstance(r, SCons.Util.CLVar), type(r)
499         assert r.data == ['a', 'b', ' c d'], r.data
500         assert str(r) == 'a b  c d', str(r)
501
502         r = f + ['c', 'd']
503         assert isinstance(r, SCons.Util.CLVar), type(r)
504         assert r.data == ['a', 'b', 'c', 'd'], r.data
505         assert str(r) == 'a b c d', str(r)
506
507         r = f + [' c', 'd']
508         assert isinstance(r, SCons.Util.CLVar), type(r)
509         assert r.data == ['a', 'b', ' c', 'd'], r.data
510         assert str(r) == 'a b  c d', str(r)
511
512         f = SCons.Util.CLVar(['a b'])
513
514         r = f + 'c d'
515         assert isinstance(r, SCons.Util.CLVar), type(r)
516         assert r.data == ['a b', 'c', 'd'], r.data
517         assert str(r) == 'a b c d', str(r)
518
519         r = f + ' c d'
520         assert isinstance(r, SCons.Util.CLVar), type(r)
521         assert r.data == ['a b', 'c', 'd'], r.data
522         assert str(r) == 'a b c d', str(r)
523
524         r = f + ['c d']
525         assert isinstance(r, SCons.Util.CLVar), type(r)
526         assert r.data == ['a b', 'c d'], r.data
527         assert str(r) == 'a b c d', str(r)
528
529         r = f + [' c d']
530         assert isinstance(r, SCons.Util.CLVar), type(r)
531         assert r.data == ['a b', ' c d'], r.data
532         assert str(r) == 'a b  c d', str(r)
533
534         r = f + ['c', 'd']
535         assert isinstance(r, SCons.Util.CLVar), type(r)
536         assert r.data == ['a b', 'c', 'd'], r.data
537         assert str(r) == 'a b c d', str(r)
538
539         r = f + [' c', 'd']
540         assert isinstance(r, SCons.Util.CLVar), type(r)
541         assert r.data == ['a b', ' c', 'd'], r.data
542         assert str(r) == 'a b  c d', str(r)
543
544         f = SCons.Util.CLVar(['a', 'b'])
545
546         r = f + 'c d'
547         assert isinstance(r, SCons.Util.CLVar), type(r)
548         assert r.data == ['a', 'b', 'c', 'd'], r.data
549         assert str(r) == 'a b c d', str(r)
550
551         r = f + ' c d'
552         assert isinstance(r, SCons.Util.CLVar), type(r)
553         assert r.data == ['a', 'b', 'c', 'd'], r.data
554         assert str(r) == 'a b c d', str(r)
555
556         r = f + ['c d']
557         assert isinstance(r, SCons.Util.CLVar), type(r)
558         assert r.data == ['a', 'b', 'c d'], r.data
559         assert str(r) == 'a b c d', str(r)
560
561         r = f + [' c d']
562         assert isinstance(r, SCons.Util.CLVar), type(r)
563         assert r.data == ['a', 'b', ' c d'], r.data
564         assert str(r) == 'a b  c d', str(r)
565
566         r = f + ['c', 'd']
567         assert isinstance(r, SCons.Util.CLVar), type(r)
568         assert r.data == ['a', 'b', 'c', 'd'], r.data
569         assert str(r) == 'a b c d', str(r)
570
571         r = f + [' c', 'd']
572         assert isinstance(r, SCons.Util.CLVar), type(r)
573         assert r.data == ['a', 'b', ' c', 'd'], r.data
574         assert str(r) == 'a b  c d', str(r)
575
576     def test_Selector(self):
577         """Test the Selector class"""
578
579         s = Selector({'a' : 'AAA', 'b' : 'BBB'})
580         assert s['a'] == 'AAA', s['a']
581         assert s['b'] == 'BBB', s['b']
582         exc_caught = None
583         try:
584             x = s['c']
585         except KeyError:
586             exc_caught = 1
587         assert exc_caught, "should have caught a KeyError"
588         s['c'] = 'CCC'
589         assert s['c'] == 'CCC', s['c']
590
591         class DummyEnv(UserDict):
592             def subst(self, key):
593                 if key[0] == '$':
594                     return self[key[1:]]
595                 return key
596
597         env = DummyEnv()
598
599         s = Selector({'.d' : 'DDD', '.e' : 'EEE'})
600         ret = s(env, [])
601         assert ret == None, ret
602         ret = s(env, ['foo.d'])
603         assert ret == 'DDD', ret
604         ret = s(env, ['bar.e'])
605         assert ret == 'EEE', ret
606         ret = s(env, ['bar.x'])
607         assert ret == None, ret
608         s[None] = 'XXX'
609         ret = s(env, ['bar.x'])
610         assert ret == 'XXX', ret
611
612         env = DummyEnv({'FSUFF' : '.f', 'GSUFF' : '.g'})
613
614         s = Selector({'$FSUFF' : 'FFF', '$GSUFF' : 'GGG'})
615         ret = s(env, ['foo.f'])
616         assert ret == 'FFF', ret
617         ret = s(env, ['bar.g'])
618         assert ret == 'GGG', ret
619
620     def test_adjustixes(self):
621         """Test the adjustixes() function"""
622         r = adjustixes('file', 'pre-', '-suf')
623         assert r == 'pre-file-suf', r
624         r = adjustixes('pre-file', 'pre-', '-suf')
625         assert r == 'pre-file-suf', r
626         r = adjustixes('file-suf', 'pre-', '-suf')
627         assert r == 'pre-file-suf', r
628         r = adjustixes('pre-file-suf', 'pre-', '-suf')
629         assert r == 'pre-file-suf', r
630         r = adjustixes('pre-file.xxx', 'pre-', '-suf')
631         assert r == 'pre-file.xxx', r
632         r = adjustixes('dir/file', 'pre-', '-suf')
633         assert r == os.path.join('dir', 'pre-file-suf'), r
634
635     def test_containsAny(self):
636         """Test the containsAny() function"""
637         assert containsAny('*.py', '*?[]')
638         assert not containsAny('file.txt', '*?[]')
639
640     def test_containsAll(self):
641         """Test the containsAll() function"""
642         assert containsAll('43221', '123')
643         assert not containsAll('134', '123')
644
645     def test_containsOnly(self):
646         """Test the containsOnly() function"""
647         assert containsOnly('.83', '0123456789.')
648         assert not containsOnly('43221', '123')
649
650     def test_LogicalLines(self):
651         """Test the LogicalLines class"""
652         fobj = StringIO.StringIO(r"""
653 foo \
654 bar \
655 baz
656 foo
657 bling \
658 bling \ bling
659 bling
660 """)
661
662         lines = LogicalLines(fobj).readlines()
663         assert lines == [
664             '\n',
665             'foo bar baz\n',
666             'foo\n',
667             'bling bling \\ bling\n',
668             'bling\n',
669         ], lines
670
671 if __name__ == "__main__":
672     suite = unittest.makeSuite(UtilTestCase, 'test_')
673     if not unittest.TextTestRunner().run(suite).wasSuccessful():
674         sys.exit(1)