e044065362854d0bb63557f4108c862a6d4a3ad7
[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 SCons.compat
27
28 import collections
29 import io
30 import os
31 import sys
32 import unittest
33
34
35 import TestCmd
36
37 import SCons.Errors
38
39 from SCons.Util import *
40
41 try: unicode
42 except NameError: HasUnicode = False
43 else:             HasUnicode = True
44
45 class OutBuffer:
46     def __init__(self):
47         self.buffer = ""
48
49     def write(self, str):
50         self.buffer = self.buffer + str
51
52 class dictifyTestCase(unittest.TestCase):
53     def test_dictify(self):
54         """Test the dictify() function"""
55         r = SCons.Util.dictify(['a', 'b', 'c'], [1, 2, 3])
56         assert r == {'a':1, 'b':2, 'c':3}, r
57
58         r = {}
59         SCons.Util.dictify(['a'], [1], r)
60         SCons.Util.dictify(['b'], [2], r)
61         SCons.Util.dictify(['c'], [3], r)
62         assert r == {'a':1, 'b':2, 'c':3}, r
63
64 class UtilTestCase(unittest.TestCase):
65     def test_splitext(self):
66         assert splitext('foo') == ('foo','')
67         assert splitext('foo.bar') == ('foo','.bar')
68         assert splitext(os.path.join('foo.bar', 'blat')) == (os.path.join('foo.bar', 'blat'),'')
69
70     class Node:
71         def __init__(self, name, children=[]):
72             self.children = children
73             self.name = name
74             self.nocache = None
75         def __str__(self):
76             return self.name
77         def exists(self):
78             return 1
79         def rexists(self):
80             return 1
81         def has_builder(self):
82             return 1
83         def has_explicit_builder(self):
84             return 1
85         def side_effect(self):
86             return 1
87         def precious(self):
88             return 1
89         def always_build(self):
90             return 1
91         def is_up_to_date(self):
92             return 1
93         def noclean(self):
94             return 1
95
96     def tree_case_1(self):
97         """Fixture for the render_tree() and print_tree() tests."""
98         windows_h = self.Node("windows.h")
99         stdlib_h = self.Node("stdlib.h")
100         stdio_h = self.Node("stdio.h")
101         bar_c = self.Node("bar.c", [stdlib_h, windows_h])
102         bar_o = self.Node("bar.o", [bar_c])
103         foo_c = self.Node("foo.c", [stdio_h])
104         foo_o = self.Node("foo.o", [foo_c])
105         foo = self.Node("foo", [foo_o, bar_o])
106
107         expect = """\
108 +-foo
109   +-foo.o
110   | +-foo.c
111   |   +-stdio.h
112   +-bar.o
113     +-bar.c
114       +-stdlib.h
115       +-windows.h
116 """
117
118         lines = expect.split('\n')[:-1]
119         lines = ['[E BSPACN ]'+l for l in lines]
120         withtags = '\n'.join(lines) + '\n'
121
122         return foo, expect, withtags
123
124     def tree_case_2(self, prune=1):
125         """Fixture for the render_tree() and print_tree() tests."""
126
127         stdlib_h = self.Node("stdlib.h")
128         bar_h = self.Node('bar.h', [stdlib_h])
129         blat_h = self.Node('blat.h', [stdlib_h])
130         blat_c = self.Node('blat.c', [blat_h, bar_h])
131         blat_o = self.Node('blat.o', [blat_c])
132
133         expect = """\
134 +-blat.o
135   +-blat.c
136     +-blat.h
137     | +-stdlib.h
138     +-bar.h
139       +-[stdlib.h]
140 """
141
142         if not prune:
143             expect = expect.replace('[', '')
144             expect = expect.replace(']', '')
145
146         lines = expect.split('\n')[:-1]
147         lines = ['[E BSPACN ]'+l for l in lines]
148         withtags = '\n'.join(lines) + '\n'
149
150         return blat_o, expect, withtags
151
152     def test_render_tree(self):
153         """Test the render_tree() function"""
154         def get_children(node):
155             return node.children
156
157         node, expect, withtags = self.tree_case_1()
158         actual = render_tree(node, get_children)
159         assert expect == actual, (expect, actual)
160
161         node, expect, withtags = self.tree_case_2()
162         actual = render_tree(node, get_children, 1)
163         assert expect == actual, (expect, actual)
164
165     def test_print_tree(self):
166         """Test the print_tree() function"""
167         def get_children(node):
168             return node.children
169
170         save_stdout = sys.stdout
171
172         try:
173             node, expect, withtags = self.tree_case_1()
174
175             sys.stdout = io.StringIO()
176             print_tree(node, get_children)
177             actual = sys.stdout.getvalue()
178             assert expect == actual, (expect, actual)
179
180             sys.stdout = io.StringIO()
181             print_tree(node, get_children, showtags=1)
182             actual = sys.stdout.getvalue()
183             assert withtags == actual, (withtags, actual)
184
185             node, expect, withtags = self.tree_case_2(prune=0)
186
187             sys.stdout = io.StringIO()
188             print_tree(node, get_children, 1)
189             actual = sys.stdout.getvalue()
190             assert expect == actual, (expect, actual)
191
192             sys.stdout = io.StringIO()
193             # The following call should work here:
194             #    print_tree(node, get_children, 1, showtags=1)
195             # For some reason I don't understand, though, *this*
196             # time that we call print_tree, the visited dictionary
197             # is still populated with the values from the last call!
198             # I can't see why this would be, short of a bug in Python,
199             # and rather than continue banging my head against the
200             # brick wall for a *test*, we're going to going with
201             # the cheap, easy workaround:
202             print_tree(node, get_children, 1, showtags=1, visited={})
203             actual = sys.stdout.getvalue()
204             assert withtags == actual, (withtags, actual)
205         finally:
206             sys.stdout = save_stdout
207
208     def test_is_Dict(self):
209         assert is_Dict({})
210         assert is_Dict(collections.UserDict())
211         try:
212             class mydict(dict):
213                 pass
214         except TypeError:
215             pass
216         else:
217             assert is_Dict(mydict({}))
218         assert not is_Dict([])
219         assert not is_Dict(())
220         assert not is_Dict("")
221         if HasUnicode:
222             exec "assert not is_Dict(u'')"
223
224     def test_is_List(self):
225         assert is_List([])
226         import UserList
227         assert is_List(collections.UserList())
228         try:
229             class mylist(list):
230                 pass
231         except TypeError:
232             pass
233         else:
234             assert is_List(mylist([]))
235         assert not is_List(())
236         assert not is_List({})
237         assert not is_List("")
238         if HasUnicode:
239             exec "assert not is_List(u'')"
240
241     def test_is_String(self):
242         assert is_String("")
243         if HasUnicode:
244             exec "assert is_String(u'')"
245         try:
246             import UserString
247         except:
248             pass
249         else:
250             assert is_String(collections.UserString(''))
251         try:
252             class mystr(str):
253                 pass
254         except TypeError:
255             pass
256         else:
257             assert is_String(mystr(''))
258         assert not is_String({})
259         assert not is_String([])
260         assert not is_String(())
261
262     def test_is_Tuple(self):
263         assert is_Tuple(())
264         try:
265             class mytuple(tuple):
266                 pass
267         except TypeError:
268             pass
269         else:
270             assert is_Tuple(mytuple(()))
271         assert not is_Tuple([])
272         assert not is_Tuple({})
273         assert not is_Tuple("")
274         if HasUnicode:
275             exec "assert not is_Tuple(u'')"
276
277     def test_to_String(self):
278         """Test the to_String() method."""
279         assert to_String(1) == "1", to_String(1)
280         assert to_String([ 1, 2, 3]) == str([1, 2, 3]), to_String([1,2,3])
281         assert to_String("foo") == "foo", to_String("foo")
282
283         try:
284             import UserString
285
286             s1=collections.UserString('blah')
287             assert to_String(s1) == s1, s1
288             assert to_String(s1) == 'blah', s1
289
290             class Derived(collections.UserString):
291                 pass
292             s2 = Derived('foo')
293             assert to_String(s2) == s2, s2
294             assert to_String(s2) == 'foo', s2
295
296             if HasUnicode:
297                 s3=collections.UserString(unicode('bar'))
298                 assert to_String(s3) == s3, s3
299                 assert to_String(s3) == unicode('bar'), s3
300                 assert isinstance(to_String(s3), unicode), \
301                        type(to_String(s3))
302         except ImportError:
303             pass
304
305         if HasUnicode:
306             s4 = unicode('baz')
307             assert to_String(s4) == unicode('baz'), to_String(s4)
308             assert isinstance(to_String(s4), unicode), \
309                    type(to_String(s4))
310
311     def test_WhereIs(self):
312         test = TestCmd.TestCmd(workdir = '')
313
314         sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
315         sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
316         sub3_xxx_exe = test.workpath('sub3', 'xxx.exe')
317         sub4_xxx_exe = test.workpath('sub4', 'xxx.exe')
318
319         test.subdir('subdir', 'sub1', 'sub2', 'sub3', 'sub4')
320
321         if sys.platform != 'win32':
322             test.write(sub1_xxx_exe, "\n")
323
324         os.mkdir(sub2_xxx_exe)
325
326         test.write(sub3_xxx_exe, "\n")
327         os.chmod(sub3_xxx_exe, 0777)
328
329         test.write(sub4_xxx_exe, "\n")
330         os.chmod(sub4_xxx_exe, 0777)
331
332         env_path = os.environ['PATH']
333
334         try:
335             pathdirs_1234 = [ test.workpath('sub1'),
336                               test.workpath('sub2'),
337                               test.workpath('sub3'),
338                               test.workpath('sub4'),
339                             ] + env_path.split(os.pathsep)
340
341             pathdirs_1243 = [ test.workpath('sub1'),
342                               test.workpath('sub2'),
343                               test.workpath('sub4'),
344                               test.workpath('sub3'),
345                             ] + env_path.split(os.pathsep)
346
347             os.environ['PATH'] = os.pathsep.join(pathdirs_1234)
348             wi = WhereIs('xxx.exe')
349             assert wi == test.workpath(sub3_xxx_exe), wi
350             wi = WhereIs('xxx.exe', pathdirs_1243)
351             assert wi == test.workpath(sub4_xxx_exe), wi
352             wi = WhereIs('xxx.exe', os.pathsep.join(pathdirs_1243))
353             assert wi == test.workpath(sub4_xxx_exe), wi
354
355             wi = WhereIs('xxx.exe',reject = sub3_xxx_exe)
356             assert wi == test.workpath(sub4_xxx_exe), wi
357             wi = WhereIs('xxx.exe', pathdirs_1243, reject = sub3_xxx_exe)
358             assert wi == test.workpath(sub4_xxx_exe), wi
359
360             os.environ['PATH'] = os.pathsep.join(pathdirs_1243)
361             wi = WhereIs('xxx.exe')
362             assert wi == test.workpath(sub4_xxx_exe), wi
363             wi = WhereIs('xxx.exe', pathdirs_1234)
364             assert wi == test.workpath(sub3_xxx_exe), wi
365             wi = WhereIs('xxx.exe', os.pathsep.join(pathdirs_1234))
366             assert wi == test.workpath(sub3_xxx_exe), wi
367
368             if sys.platform == 'win32':
369                 wi = WhereIs('xxx', pathext = '')
370                 assert wi is None, wi
371
372                 wi = WhereIs('xxx', pathext = '.exe')
373                 assert wi == test.workpath(sub4_xxx_exe), wi
374
375                 wi = WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
376                 assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
377
378                 # Test that we return a normalized path even when
379                 # the path contains forward slashes.
380                 forward_slash = test.workpath('') + '/sub3'
381                 wi = WhereIs('xxx', path = forward_slash, pathext = '.EXE')
382                 assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
383
384             del os.environ['PATH']
385             wi = WhereIs('xxx.exe')
386             assert wi is None, wi
387
388         finally:
389             os.environ['PATH'] = env_path
390
391     def test_get_env_var(self):
392         """Testing get_environment_var()."""
393         assert get_environment_var("$FOO") == "FOO", get_environment_var("$FOO")
394         assert get_environment_var("${BAR}") == "BAR", get_environment_var("${BAR}")
395         assert get_environment_var("$FOO_BAR1234") == "FOO_BAR1234", get_environment_var("$FOO_BAR1234")
396         assert get_environment_var("${BAR_FOO1234}") == "BAR_FOO1234", get_environment_var("${BAR_FOO1234}")
397         assert get_environment_var("${BAR}FOO") == None, get_environment_var("${BAR}FOO")
398         assert get_environment_var("$BAR ") == None, get_environment_var("$BAR ")
399         assert get_environment_var("FOO$BAR") == None, get_environment_var("FOO$BAR")
400         assert get_environment_var("$FOO[0]") == None, get_environment_var("$FOO[0]")
401         assert get_environment_var("${some('complex expression')}") == None, get_environment_var("${some('complex expression')}")
402
403     def test_Proxy(self):
404         """Test generic Proxy class."""
405         class Subject:
406             def foo(self):
407                 return 1
408             def bar(self):
409                 return 2
410
411         s=Subject()
412         s.baz = 3
413
414         class ProxyTest(Proxy):
415             def bar(self):
416                 return 4
417
418         p=ProxyTest(s)
419
420         assert p.foo() == 1, p.foo()
421         assert p.bar() == 4, p.bar()
422         assert p.baz == 3, p.baz
423
424         p.baz = 5
425         s.baz = 6
426
427         assert p.baz == 5, p.baz
428         assert p.get() == s, p.get()
429
430     def test_display(self):
431         old_stdout = sys.stdout
432         sys.stdout = OutBuffer()
433         display("line1")
434         display.set_mode(0)
435         display("line2")
436         display.set_mode(1)
437         display("line3")
438         display("line4\n", append_newline=0)
439         display.set_mode(0)
440         display("dont print1")
441         display("dont print2\n", append_newline=0)
442         display.set_mode(1)
443         assert sys.stdout.buffer == "line1\nline3\nline4\n"
444         sys.stdout = old_stdout
445
446     def test_get_native_path(self):
447         """Test the get_native_path() function."""
448         import tempfile
449         filename = tempfile.mktemp()
450         str = '1234567890 ' + filename
451         try:
452             open(filename, 'w').write(str)
453             assert open(get_native_path(filename)).read() == str
454         finally:
455             try:
456                 os.unlink(filename)
457             except OSError:
458                 pass
459
460     def test_PrependPath(self):
461         """Test prepending to a path"""
462         p1 = r'C:\dir\num\one;C:\dir\num\two'
463         p2 = r'C:\mydir\num\one;C:\mydir\num\two'
464         # have to include the pathsep here so that the test will work on UNIX too.
465         p1 = PrependPath(p1,r'C:\dir\num\two',sep = ';')
466         p1 = PrependPath(p1,r'C:\dir\num\three',sep = ';')
467         p2 = PrependPath(p2,r'C:\mydir\num\three',sep = ';')
468         p2 = PrependPath(p2,r'C:\mydir\num\one',sep = ';')
469         assert(p1 == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
470         assert(p2 == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
471
472     def test_AppendPath(self):
473         """Test appending to a path."""
474         p1 = r'C:\dir\num\one;C:\dir\num\two'
475         p2 = r'C:\mydir\num\one;C:\mydir\num\two'
476         # have to include the pathsep here so that the test will work on UNIX too.
477         p1 = AppendPath(p1,r'C:\dir\num\two',sep = ';')
478         p1 = AppendPath(p1,r'C:\dir\num\three',sep = ';')
479         p2 = AppendPath(p2,r'C:\mydir\num\three',sep = ';')
480         p2 = AppendPath(p2,r'C:\mydir\num\one',sep = ';')
481         assert(p1 == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
482         assert(p2 == r'C:\mydir\num\two;C:\mydir\num\three;C:\mydir\num\one')
483
484     def test_PrependPathPreserveOld(self):
485         """Test prepending to a path while preserving old paths"""
486         p1 = r'C:\dir\num\one;C:\dir\num\two'
487         # have to include the pathsep here so that the test will work on UNIX too.
488         p1 = PrependPath(p1,r'C:\dir\num\two',sep = ';', delete_existing=0)
489         p1 = PrependPath(p1,r'C:\dir\num\three',sep = ';')
490         assert(p1 == r'C:\dir\num\three;C:\dir\num\one;C:\dir\num\two')
491
492     def test_AppendPathPreserveOld(self):
493         """Test appending to a path while preserving old paths"""
494         p1 = r'C:\dir\num\one;C:\dir\num\two'
495         # have to include the pathsep here so that the test will work on UNIX too.
496         p1 = AppendPath(p1,r'C:\dir\num\one',sep = ';', delete_existing=0)
497         p1 = AppendPath(p1,r'C:\dir\num\three',sep = ';')
498         assert(p1 == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
499
500     def test_CLVar(self):
501         """Test the command-line construction variable class"""
502         f = SCons.Util.CLVar('a b')
503
504         r = f + 'c d'
505         assert isinstance(r, SCons.Util.CLVar), type(r)
506         assert r.data == ['a', 'b', 'c', 'd'], r.data
507         assert str(r) == 'a b c d', str(r)
508
509         r = f + ' c d'
510         assert isinstance(r, SCons.Util.CLVar), type(r)
511         assert r.data == ['a', 'b', 'c', 'd'], r.data
512         assert str(r) == 'a b c d', str(r)
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         f = SCons.Util.CLVar(['a b'])
535
536         r = f + 'c d'
537         assert isinstance(r, SCons.Util.CLVar), type(r)
538         assert r.data == ['a b', 'c', 'd'], r.data
539         assert str(r) == 'a b c d', str(r)
540
541         r = f + ' c d'
542         assert isinstance(r, SCons.Util.CLVar), type(r)
543         assert r.data == ['a b', 'c', 'd'], r.data
544         assert str(r) == 'a b c d', str(r)
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         f = SCons.Util.CLVar(['a', 'b'])
567
568         r = f + 'c d'
569         assert isinstance(r, SCons.Util.CLVar), type(r)
570         assert r.data == ['a', 'b', 'c', 'd'], r.data
571         assert str(r) == 'a b c d', str(r)
572
573         r = f + ' c d'
574         assert isinstance(r, SCons.Util.CLVar), type(r)
575         assert r.data == ['a', 'b', 'c', 'd'], r.data
576         assert str(r) == 'a b c d', str(r)
577
578         r = f + ['c d']
579         assert isinstance(r, SCons.Util.CLVar), type(r)
580         assert r.data == ['a', 'b', 'c d'], r.data
581         assert str(r) == 'a b c d', str(r)
582
583         r = f + [' c d']
584         assert isinstance(r, SCons.Util.CLVar), type(r)
585         assert r.data == ['a', 'b', ' c d'], r.data
586         assert str(r) == 'a b  c d', str(r)
587
588         r = f + ['c', 'd']
589         assert isinstance(r, SCons.Util.CLVar), type(r)
590         assert r.data == ['a', 'b', 'c', 'd'], r.data
591         assert str(r) == 'a b c d', str(r)
592
593         r = f + [' c', 'd']
594         assert isinstance(r, SCons.Util.CLVar), type(r)
595         assert r.data == ['a', 'b', ' c', 'd'], r.data
596         assert str(r) == 'a b  c d', str(r)
597
598     def test_Selector(self):
599         """Test the Selector class"""
600
601         class MyNode:
602             def __init__(self, name):
603                 self.name = name
604                 self.suffix = os.path.splitext(name)[1]
605
606             def __str__(self):
607                 return self.name
608
609         s = Selector({'a' : 'AAA', 'b' : 'BBB'})
610         assert s['a'] == 'AAA', s['a']
611         assert s['b'] == 'BBB', s['b']
612         exc_caught = None
613         try:
614             x = s['c']
615         except KeyError:
616             exc_caught = 1
617         assert exc_caught, "should have caught a KeyError"
618         s['c'] = 'CCC'
619         assert s['c'] == 'CCC', s['c']
620
621         class DummyEnv(collections.UserDict):
622             def subst(self, key):
623                 if key[0] == '$':
624                     return self[key[1:]]
625                 return key
626
627         env = DummyEnv()
628
629         s = Selector({'.d' : 'DDD', '.e' : 'EEE'})
630         ret = s(env, [])
631         assert ret is None, ret
632         ret = s(env, [MyNode('foo.d')])
633         assert ret == 'DDD', ret
634         ret = s(env, [MyNode('bar.e')])
635         assert ret == 'EEE', ret
636         ret = s(env, [MyNode('bar.x')])
637         assert ret is None, ret
638         s[None] = 'XXX'
639         ret = s(env, [MyNode('bar.x')])
640         assert ret == 'XXX', ret
641
642         env = DummyEnv({'FSUFF' : '.f', 'GSUFF' : '.g'})
643
644         s = Selector({'$FSUFF' : 'FFF', '$GSUFF' : 'GGG'})
645         ret = s(env, [MyNode('foo.f')])
646         assert ret == 'FFF', ret
647         ret = s(env, [MyNode('bar.g')])
648         assert ret == 'GGG', ret
649
650     def test_adjustixes(self):
651         """Test the adjustixes() function"""
652         r = adjustixes('file', 'pre-', '-suf')
653         assert r == 'pre-file-suf', r
654         r = adjustixes('pre-file', 'pre-', '-suf')
655         assert r == 'pre-file-suf', r
656         r = adjustixes('file-suf', 'pre-', '-suf')
657         assert r == 'pre-file-suf', r
658         r = adjustixes('pre-file-suf', 'pre-', '-suf')
659         assert r == 'pre-file-suf', r
660         r = adjustixes('pre-file.xxx', 'pre-', '-suf')
661         assert r == 'pre-file.xxx', r
662         r = adjustixes('dir/file', 'pre-', '-suf')
663         assert r == os.path.join('dir', 'pre-file-suf'), r
664
665     def test_containsAny(self):
666         """Test the containsAny() function"""
667         assert containsAny('*.py', '*?[]')
668         assert not containsAny('file.txt', '*?[]')
669
670     def test_containsAll(self):
671         """Test the containsAll() function"""
672         assert containsAll('43221', '123')
673         assert not containsAll('134', '123')
674
675     def test_containsOnly(self):
676         """Test the containsOnly() function"""
677         assert containsOnly('.83', '0123456789.')
678         assert not containsOnly('43221', '123')
679
680     def test_LogicalLines(self):
681         """Test the LogicalLines class"""
682         fobj = io.StringIO(r"""
683 foo \
684 bar \
685 baz
686 foo
687 bling \
688 bling \ bling
689 bling
690 """)
691
692         lines = LogicalLines(fobj).readlines()
693         assert lines == [
694             '\n',
695             'foo bar baz\n',
696             'foo\n',
697             'bling bling \\ bling\n',
698             'bling\n',
699         ], lines
700
701     def test_intern(self):
702         s1 = silent_intern("spam")
703         # Python 1.5 and 3.x do not have a unicode() built-in
704         if sys.version[0] == '2': 
705             s2 = silent_intern(unicode("unicode spam"))
706         s3 = silent_intern(42)
707         s4 = silent_intern("spam")
708         assert id(s1) == id(s4)
709
710
711 class MD5TestCase(unittest.TestCase):
712
713     def test_collect(self):
714         """Test collecting a list of signatures into a new signature value
715         """
716         s = list(map(MD5signature, ('111', '222', '333')))
717         
718         assert '698d51a19d8a121ce581499d7b701668' == MD5collect(s[0:1])
719         assert '8980c988edc2c78cc43ccb718c06efd5' == MD5collect(s[0:2])
720         assert '53fd88c84ff8a285eb6e0a687e55b8c7' == MD5collect(s)
721
722     def test_MD5signature(self):
723         """Test generating a signature"""
724         s = MD5signature('111')
725         assert '698d51a19d8a121ce581499d7b701668' == s, s
726
727         s = MD5signature('222')
728         assert 'bcbe3365e6ac95ea2c0343a2395834dd' == s, s
729
730 class NodeListTestCase(unittest.TestCase):
731     def test_simple_attributes(self):
732         """Test simple attributes of a NodeList class"""
733         class TestClass:
734             def __init__(self, name, child=None):
735                 self.child = child
736                 self.bar = name
737
738         t1 = TestClass('t1', TestClass('t1child'))
739         t2 = TestClass('t2', TestClass('t2child'))
740         t3 = TestClass('t3')
741
742         nl = NodeList([t1, t2, t3])
743         assert nl.bar == [ 't1', 't2', 't3' ], nl.bar
744         assert nl[0:2].child.bar == [ 't1child', 't2child' ], \
745                nl[0:2].child.bar
746
747     def test_callable_attributes(self):
748         """Test callable attributes of a NodeList class"""
749         class TestClass:
750             def __init__(self, name, child=None):
751                 self.child = child
752                 self.bar = name
753             def foo(self):
754                 return self.bar + "foo"
755             def getself(self):
756                 return self
757
758         t1 = TestClass('t1', TestClass('t1child'))
759         t2 = TestClass('t2', TestClass('t2child'))
760         t3 = TestClass('t3')
761
762         nl = NodeList([t1, t2, t3])
763         assert nl.foo() == [ 't1foo', 't2foo', 't3foo' ], nl.foo()
764         assert nl.bar == [ 't1', 't2', 't3' ], nl.bar
765         assert nl.getself().bar == [ 't1', 't2', 't3' ], nl.getself().bar
766         assert nl[0:2].child.foo() == [ 't1childfoo', 't2childfoo' ], \
767                nl[0:2].child.foo()
768         assert nl[0:2].child.bar == [ 't1child', 't2child' ], \
769                nl[0:2].child.bar
770
771     def test_null(self):
772         """Test a null NodeList"""
773         nl = NodeList([])
774         r = str(nl)
775         assert r == '', r
776         for node in nl:
777             raise Exception, "should not enter this loop"
778
779
780 class flattenTestCase(unittest.TestCase):
781
782     def test_scalar(self):
783         """Test flattening a scalar"""
784         result = flatten('xyz')
785         assert result == ['xyz'], result
786
787 if __name__ == "__main__":
788     suite = unittest.TestSuite()
789     tclasses = [ dictifyTestCase,
790                  flattenTestCase,
791                  MD5TestCase,
792                  NodeListTestCase,
793                  UtilTestCase,
794                ]
795     for tclass in tclasses:
796         names = unittest.getTestCaseNames(tclass, 'test_')
797         suite.addTests(list(map(tclass, names)))
798     if not unittest.TextTestRunner().run(suite).wasSuccessful():
799         sys.exit(1)
800
801 # Local Variables:
802 # tab-width:4
803 # indent-tabs-mode:nil
804 # End:
805 # vim: set expandtab tabstop=4 shiftwidth=4: