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:
12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software.
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.
24 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
32 from SCons.Util import *
40 self.buffer = self.buffer + str
43 """Simple node work-alike."""
44 def __init__(self, name):
45 self.name = os.path.normpath(name)
52 def get_subst_proxy(self):
56 def __init__(self, dict={}):
59 def Dictionary(self, key = None):
65 dict = self.dict.copy()
66 dict["TARGETS"] = 'tsig'
67 dict["SOURCES"] = 'ssig'
70 def cs(target=None, source=None, env=None, for_signature=None):
73 def cl(target=None, source=None, env=None, for_signature=None):
76 def CmdGen1(target, source, env, for_signature):
77 # Nifty trick...since Environment references are interpolated,
78 # instantiate an instance of a callable class with this one,
79 # which will then get evaluated.
80 assert str(target) == 't', target
81 assert str(source) == 's', source
82 return "${CMDGEN2('foo', %d)}" % for_signature
85 def __init__(self, mystr, forsig):
87 self.expect_for_signature = forsig
89 def __call__(self, target, source, env, for_signature):
90 assert str(target) == 't', target
91 assert str(source) == 's', source
92 assert for_signature == self.expect_for_signature, for_signature
93 return [ self.mystr, env.Dictionary('BAR') ]
100 return string.replace(str, '/', os.sep)
102 class UtilTestCase(unittest.TestCase):
103 def test_subst(self):
104 """Test the subst function"""
105 class MyNode(DummyNode):
106 """Simple node work-alike with some extra stuff for testing."""
107 def get_stuff(self, extra):
108 return self.name + extra
112 def __init__(self, literal):
113 self.literal = literal
116 def is_literal(self):
119 def function_foo(arg):
122 target = [ MyNode("./foo/bar.exe"),
123 MyNode("/bar/baz.obj"),
124 MyNode("../foo/baz.obj") ]
125 source = [ MyNode("./foo/blah.cpp"),
126 MyNode("/bar/ack.cpp"),
127 MyNode("../foo/ack.c") ]
143 # $XXX$HHH should expand to GGGIII, not BADNEWS.
147 'FFFIII' : 'BADNEWS',
149 'LITERAL' : TestLiteral("$XXX"),
151 # Test that we can expand to and return a function.
152 #'FUNCTION' : function_foo,
160 # Test various combinations of strings, lists and functions.
171 # Test function calls within ${}.
172 'FUNCCALL' : '${FUNC1("$AAA $FUNC2 $BBB")}',
173 'FUNC1' : lambda x: x,
174 'FUNC2' : lambda target, source, env, for_signature: ['x$CCC'],
177 #'RECURSE' : 'foo $RECURSE bar',
178 #'RRR' : 'foo $SSS bar',
184 # Basic tests of substitution functionality.
186 # Basics: strings without expansions are left alone, and
187 # the simplest possible expansion to a null-string value.
191 # Test expansion of integer values.
192 "test $zero", "test 0",
193 "test $one", "test 1",
195 # Test multiple re-expansion of values.
196 "test $ONE", "test four",
198 # Test a whole bunch of $TARGET[S] and $SOURCE[S] expansions.
199 "test $TARGETS $SOURCES",
200 "test foo/bar.exe /bar/baz.obj ../foo/baz.obj foo/blah.cpp /bar/ack.cpp ../foo/ack.c",
202 "test ${TARGETS[:]} ${SOURCES[0]}",
203 "test foo/bar.exe /bar/baz.obj ../foo/baz.obj foo/blah.cpp",
205 "test ${TARGETS[1:]}v",
206 "test /bar/baz.obj ../foo/baz.objv",
211 "test $TARGET$FOO[0]",
212 "test foo/bar.exe[0]",
217 "test ${SOURCES[0:2].foo}",
223 "test ${TARGET.get_stuff('blah')}",
224 "test foo/bar.exeblah",
226 "test ${SOURCES.get_stuff('blah')}",
227 "test foo/blah.cppblah /bar/ack.cppblah ../foo/ack.cblah",
229 "test ${SOURCES[0:2].get_stuff('blah')}",
230 "test foo/blah.cppblah /bar/ack.cppblah",
232 "test ${SOURCES[0:2].get_stuff('blah')}",
233 "test foo/blah.cppblah /bar/ack.cppblah",
235 # Test that adjacent expansions don't get re-interpreted
236 # together. The correct disambiguated expansion should be:
237 # $XXX$HHH => ${FFF}III => GGGIII
239 # $XXX$HHH => ${FFFIII} => BADNEWS
240 "$XXX$HHH", "GGGIII",
242 # Test double-dollar-sign behavior.
243 "$$FFF$HHH", "$FFFIII",
245 # Test that a Literal will stop dollar-sign substitution.
246 "$XXX $LITERAL $FFF", "GGG $XXX GGG",
248 # Test that we don't blow up even if they subscript
249 # something in ways they "can't."
255 # Test various combinations of strings and lists.
272 # Test function calls within ${}.
273 '$FUNCCALL', 'a xc b',
276 kwargs = {'target' : target, 'source' : source}
280 input, expect = cases[:2]
283 result = apply(scons_subst, (input, env), kwargs)
285 if failed == 0: print
286 print " input %s => %s did not match %s" % (repr(input), repr(result), repr(expect))
289 assert failed == 0, "%d subst() cases failed" % failed
291 # Tests of the various SUBST_* modes of substitution.
308 "$AAA ${AAA}A $BBBB $BBB",
326 input, eraw, ecmd, esig = subst_cases[:4]
327 result = scons_subst(input, env, mode=SUBST_RAW)
329 if failed == 0: print
330 print " input %s => RAW %s did not match %s" % (repr(input), repr(result), repr(eraw))
332 result = scons_subst(input, env, mode=SUBST_CMD)
334 if failed == 0: print
335 print " input %s => CMD %s did not match %s" % (repr(input), repr(result), repr(ecmd))
337 result = scons_subst(input, env, mode=SUBST_SIG)
339 if failed == 0: print
340 print " input %s => SIG %s did not match %s" % (repr(input), repr(result), repr(esig))
343 assert failed == 0, "%d subst() mode cases failed" % failed
345 # Test interpolating a callable.
346 newcom = scons_subst("test $CMDGEN1 $SOURCES $TARGETS",
347 env, target=MyNode('t'), source=MyNode('s'))
348 assert newcom == "test foo baz s t", newcom
350 # Test returning a function.
351 #env = DummyEnv({'FUNCTION' : foo})
352 #func = scons_subst("$FUNCTION", env, mode=SUBST_RAW, call=None)
353 #assert func is function_foo, func
354 #func = scons_subst("$FUNCTION", env, mode=SUBST_CMD, call=None)
355 #assert func is function_foo, func
356 #func = scons_subst("$FUNCTION", env, mode=SUBST_SIG, call=None)
357 #assert func is function_foo, func
359 def test_subst_list(self):
360 """Testing the scons_subst_list() method..."""
361 target = [ DummyNode("./foo/bar.exe"),
362 DummyNode("/bar/baz with spaces.obj"),
363 DummyNode("../foo/baz.obj") ]
364 source = [ DummyNode("./foo/blah with spaces.cpp"),
365 DummyNode("/bar/ack.cpp"),
366 DummyNode("../foo/ack.c") ]
370 'NEWLINE' : 'before\nafter',
376 'DO' : DummyNode('do something'),
377 'FOO' : DummyNode('foo.in'),
378 'BAR' : DummyNode('bar with spaces.out'),
379 'CRAZY' : DummyNode('crazy\nfile.in'),
381 # $XXX$HHH should expand to GGGIII, not BADNEWS.
385 'FFFIII' : 'BADNEWS',
390 'LITERALS' : [ Literal('foo\nwith\nnewlines'),
391 Literal('bar\nwith\nnewlines') ],
393 # Test various combinations of strings, lists and functions.
404 # Test function calls within ${}.
405 'FUNCCALL' : '${FUNC1("$AAA $FUNC2 $BBB")}',
406 'FUNC1' : lambda x: x,
407 'FUNC2' : lambda target, source, env, for_signature: ['x$CCC'],
415 ["foo/bar.exe", "/bar/baz with spaces.obj", "../foo/baz.obj"],
418 "$SOURCES $NEWLINE $TARGETS",
420 ["foo/blah with spaces.cpp", "/bar/ack.cpp", "../foo/ack.c", "before"],
421 ["after", "foo/bar.exe", "/bar/baz with spaces.obj", "../foo/baz.obj"],
426 ["foo/blah with spaces.cpp", "/bar/ack.cpp", "../foo/ack.cbefore"],
430 "$DO --in=$FOO --out=$BAR",
432 ["do something", "--in=foo.in", "--out=bar with spaces.out"],
435 # This test is now fixed, and works like it should.
436 "$DO --in=$CRAZY --out=$BAR",
438 ["do something", "--in=crazy\nfile.in", "--out=bar with spaces.out"],
441 # Try passing a list to scons_subst_list().
442 [ "$SOURCES$NEWLINE", "$TARGETS", "This is a test"],
444 ["foo/blah with spaces.cpp", "/bar/ack.cpp", "../foo/ack.cbefore"],
445 ["after", "foo/bar.exe", "/bar/baz with spaces.obj", "../foo/baz.obj", "This is a test"],
448 # Test against a former bug in scons_subst_list().
454 # Test double-dollar-sign behavior.
460 # Test various combinations of strings, lists and functions.
469 ['x', 'y'], [['x', 'y']],
479 ['$S'], [['x', 'y']],
483 ['$L'], [['x', 'y']],
494 '$FUNCCALL', [['a', 'xc', 'b']],
497 kwargs = {'target' : target, 'source' : source}
501 input, expect = cases[:2]
502 expect = map(lambda l: map(cvt, l), expect)
503 result = apply(scons_subst_list, (input, env), kwargs)
505 if failed == 0: print
506 print " input %s => %s did not match %s" % (repr(input), result, repr(expect))
509 assert failed == 0, "%d subst_list() cases failed" % failed
511 # Test interpolating a callable.
514 cmd_list = scons_subst_list("testing $CMDGEN1 $TARGETS $SOURCES",
515 env, target=_t, source=_s)
516 assert cmd_list == [['testing', 'foo', 'bar with spaces.out', 't', 's']], cmd_list
518 # Test escape functionality.
519 def escape_func(foo):
520 return '**' + foo + '**'
521 cmd_list = scons_subst_list("abc $LITERALS xyz", env)
522 assert cmd_list == [['abc',
523 'foo\nwith\nnewlines',
524 'bar\nwith\nnewlines',
526 cmd_list[0][0].escape(escape_func)
527 assert cmd_list[0][0] == 'abc', c
528 cmd_list[0][1].escape(escape_func)
529 assert cmd_list[0][1] == '**foo\nwith\nnewlines**', c
530 cmd_list[0][2].escape(escape_func)
531 assert cmd_list[0][2] == '**bar\nwith\nnewlines**', c
532 cmd_list[0][3].escape(escape_func)
533 assert cmd_list[0][3] == 'xyz', c
535 def test_splitext(self):
536 assert splitext('foo') == ('foo','')
537 assert splitext('foo.bar') == ('foo','.bar')
538 assert splitext(os.path.join('foo.bar', 'blat')) == (os.path.join('foo.bar', 'blat'),'')
540 def test_quote_spaces(self):
541 """Testing the quote_spaces() method..."""
542 q = quote_spaces('x')
545 q = quote_spaces('x x')
546 assert q == '"x x"', q
548 q = quote_spaces('x\tx')
549 assert q == '"x\tx"', q
551 def test_render_tree(self):
553 def __init__(self, name, children=[]):
554 self.children = children
559 def get_children(node):
562 windows_h = Node("windows.h")
563 stdlib_h = Node("stdlib.h")
564 stdio_h = Node("stdio.h")
565 bar_c = Node("bar.c", [stdlib_h, windows_h])
566 bar_o = Node("bar.o", [bar_c])
567 foo_c = Node("foo.c", [stdio_h])
568 foo_o = Node("foo.o", [foo_c])
569 foo = Node("foo", [foo_o, bar_o])
582 actual = render_tree(foo, get_children)
583 assert expect == actual, (expect, actual)
585 bar_h = Node('bar.h', [stdlib_h])
586 blat_h = Node('blat.h', [stdlib_h])
587 blat_c = Node('blat.c', [blat_h, bar_h])
588 blat_o = Node('blat.o', [blat_c])
598 actual = render_tree(blat_o, get_children, 1)
599 assert expect == actual, (expect, actual)
601 def test_is_Dict(self):
604 assert is_Dict(UserDict.UserDict())
605 assert not is_Dict([])
606 assert not is_Dict("")
607 if hasattr(types, 'UnicodeType'):
608 exec "assert not is_Dict(u'')"
610 def test_is_List(self):
613 assert is_List(UserList.UserList())
614 assert not is_List({})
615 assert not is_List("")
616 if hasattr(types, 'UnicodeType'):
617 exec "assert not is_List(u'')"
619 def test_is_String(self):
621 if hasattr(types, 'UnicodeType'):
622 exec "assert is_String(u'')"
628 assert is_String(UserString.UserString(''))
629 assert not is_String({})
630 assert not is_String([])
632 def test_to_String(self):
633 """Test the to_String() method."""
634 assert to_String(1) == "1", to_String(1)
635 assert to_String([ 1, 2, 3]) == str([1, 2, 3]), to_String([1,2,3])
636 assert to_String("foo") == "foo", to_String("foo")
641 s1=UserString.UserString('blah')
642 assert to_String(s1) == s1, s1
643 assert to_String(s1) == 'blah', s1
645 class Derived(UserString.UserString):
648 assert to_String(s2) == s2, s2
649 assert to_String(s2) == 'foo', s2
651 if hasattr(types, 'UnicodeType'):
652 s3=UserString.UserString(unicode('bar'))
653 assert to_String(s3) == s3, s3
654 assert to_String(s3) == unicode('bar'), s3
655 assert type(to_String(s3)) is types.UnicodeType, \
660 if hasattr(types, 'UnicodeType'):
662 assert to_String(s4) == unicode('baz'), to_String(s4)
663 assert type(to_String(s4)) is types.UnicodeType, \
666 def test_WhereIs(self):
667 test = TestCmd.TestCmd(workdir = '')
669 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
670 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
671 sub3_xxx_exe = test.workpath('sub3', 'xxx.exe')
672 sub4_xxx_exe = test.workpath('sub4', 'xxx.exe')
674 test.subdir('subdir', 'sub1', 'sub2', 'sub3', 'sub4')
676 if sys.platform != 'win32':
677 test.write(sub1_xxx_exe, "\n")
679 os.mkdir(sub2_xxx_exe)
681 test.write(sub3_xxx_exe, "\n")
682 os.chmod(sub3_xxx_exe, 0777)
684 test.write(sub4_xxx_exe, "\n")
685 os.chmod(sub4_xxx_exe, 0777)
687 env_path = os.environ['PATH']
689 pathdirs_1234 = [ test.workpath('sub1'),
690 test.workpath('sub2'),
691 test.workpath('sub3'),
692 test.workpath('sub4'),
693 ] + string.split(env_path, os.pathsep)
695 pathdirs_1243 = [ test.workpath('sub1'),
696 test.workpath('sub2'),
697 test.workpath('sub4'),
698 test.workpath('sub3'),
699 ] + string.split(env_path, os.pathsep)
701 os.environ['PATH'] = string.join(pathdirs_1234, os.pathsep)
702 wi = WhereIs('xxx.exe')
703 assert wi == test.workpath(sub3_xxx_exe), wi
704 wi = WhereIs('xxx.exe', pathdirs_1243)
705 assert wi == test.workpath(sub4_xxx_exe), wi
706 wi = WhereIs('xxx.exe', string.join(pathdirs_1243, os.pathsep))
707 assert wi == test.workpath(sub4_xxx_exe), wi
709 os.environ['PATH'] = string.join(pathdirs_1243, os.pathsep)
710 wi = WhereIs('xxx.exe')
711 assert wi == test.workpath(sub4_xxx_exe), wi
712 wi = WhereIs('xxx.exe', pathdirs_1234)
713 assert wi == test.workpath(sub3_xxx_exe), wi
714 wi = WhereIs('xxx.exe', string.join(pathdirs_1234, os.pathsep))
715 assert wi == test.workpath(sub3_xxx_exe), wi
717 if sys.platform == 'win32':
718 wi = WhereIs('xxx', pathext = '')
719 assert wi is None, wi
721 wi = WhereIs('xxx', pathext = '.exe')
722 assert wi == test.workpath(sub4_xxx_exe), wi
724 wi = WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
725 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
727 # Test that we return a normalized path even when
728 # the path contains forward slashes.
729 forward_slash = test.workpath('') + '/sub3'
730 wi = WhereIs('xxx', path = forward_slash, pathext = '.EXE')
731 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
733 def test_is_valid_construction_var(self):
734 """Testing is_valid_construction_var()"""
735 r = is_valid_construction_var("_a")
736 assert not r is None, r
737 r = is_valid_construction_var("z_")
738 assert not r is None, r
739 r = is_valid_construction_var("X_")
740 assert not r is None, r
741 r = is_valid_construction_var("2a")
743 r = is_valid_construction_var("a2_")
744 assert not r is None, r
745 r = is_valid_construction_var("/")
747 r = is_valid_construction_var("_/")
749 r = is_valid_construction_var("a/")
751 r = is_valid_construction_var(".b")
753 r = is_valid_construction_var("_.b")
755 r = is_valid_construction_var("b1._")
757 r = is_valid_construction_var("-b")
759 r = is_valid_construction_var("_-b")
761 r = is_valid_construction_var("b1-_")
764 def test_get_env_var(self):
765 """Testing get_environment_var()."""
766 assert get_environment_var("$FOO") == "FOO", get_environment_var("$FOO")
767 assert get_environment_var("${BAR}") == "BAR", get_environment_var("${BAR}")
768 assert get_environment_var("$FOO_BAR1234") == "FOO_BAR1234", get_environment_var("$FOO_BAR1234")
769 assert get_environment_var("${BAR_FOO1234}") == "BAR_FOO1234", get_environment_var("${BAR_FOO1234}")
770 assert get_environment_var("${BAR}FOO") == None, get_environment_var("${BAR}FOO")
771 assert get_environment_var("$BAR ") == None, get_environment_var("$BAR ")
772 assert get_environment_var("FOO$BAR") == None, get_environment_var("FOO$BAR")
773 assert get_environment_var("$FOO[0]") == None, get_environment_var("$FOO[0]")
774 assert get_environment_var("${some('complex expression')}") == None, get_environment_var("${some('complex expression')}")
776 def test_Proxy(self):
777 """Test generic Proxy class."""
787 class ProxyTest(Proxy):
793 assert p.foo() == 1, p.foo()
794 assert p.bar() == 4, p.bar()
795 assert p.baz == 3, p.baz
800 assert p.baz == 5, p.baz
801 assert p.get() == s, p.get()
803 def test_Literal(self):
804 """Test the Literal() function."""
805 input_list = [ '$FOO', Literal('$BAR') ]
806 dummy_env = DummyEnv({ 'FOO' : 'BAZ', 'BAR' : 'BLAT' })
808 def escape_func(cmd):
809 return '**' + cmd + '**'
811 cmd_list = scons_subst_list(input_list, dummy_env)
812 map(lambda x, e=escape_func: x.escape(e), cmd_list[0])
813 cmd_list = map(str, cmd_list[0])
814 assert cmd_list == ['BAZ', '**$BAR**'], cmd_list
816 def test_SpecialAttrWrapper(self):
817 """Test the SpecialAttrWrapper() function."""
818 input_list = [ '$FOO', SpecialAttrWrapper('$BAR', 'BLEH') ]
819 dummy_env = DummyEnv({ 'FOO' : 'BAZ', 'BAR' : 'BLAT' })
821 def escape_func(cmd):
822 return '**' + cmd + '**'
824 cmd_list = scons_subst_list(input_list, dummy_env)
825 map(lambda x, e=escape_func: x.escape(e), cmd_list[0])
826 cmd_list = map(str, cmd_list[0])
827 assert cmd_list == ['BAZ', '**$BAR**'], cmd_list
829 cmd_list = scons_subst_list(input_list, dummy_env, mode=SUBST_SIG)
830 map(lambda x, e=escape_func: x.escape(e), cmd_list[0])
831 cmd_list = map(str, cmd_list[0])
832 assert cmd_list == ['BAZ', '**BLEH**'], cmd_list
834 def test_mapPaths(self):
835 """Test the mapPaths function"""
837 def __init__(self, path):
842 dir=MyFileNode('foo')
843 file=MyFileNode('bar/file')
846 def subst(self, arg):
849 res = mapPaths([ file, 'baz', 'blat/boo', '#test' ], dir)
850 assert res[0] == file, res[0]
851 assert res[1] == os.path.join('foo', 'baz'), res[1]
852 assert res[2] == os.path.join('foo', 'blat/boo'), res[2]
853 assert res[3] == '#test', res[3]
856 res=mapPaths('bleh', dir, env)
857 assert res[0] == os.path.normpath('foo/bar'), res[1]
859 def test_display(self):
860 old_stdout = sys.stdout
861 sys.stdout = OutBuffer()
868 assert sys.stdout.buffer == "line1\nline3\n"
869 sys.stdout = old_stdout
871 def test_fs_delete(self):
872 test = TestCmd.TestCmd(workdir = '')
873 base = test.workpath('')
874 xxx = test.workpath('xxx.xxx')
875 ZZZ = test.workpath('ZZZ.ZZZ')
876 sub1_yyy = test.workpath('sub1', 'yyy.yyy')
879 test.write(xxx, "\n")
880 test.write(ZZZ, "\n")
881 test.write(sub1_yyy, "\n")
883 old_stdout = sys.stdout
884 sys.stdout = OutBuffer()
886 exp = "Removed " + os.path.join(base, ZZZ) + "\n" + \
887 "Removed " + os.path.join(base, sub1_yyy) + '\n' + \
888 "Removed directory " + os.path.join(base, 'sub1') + '\n' + \
889 "Removed " + os.path.join(base, xxx) + '\n' + \
890 "Removed directory " + base + '\n'
892 fs_delete(base, remove=0)
893 assert sys.stdout.buffer == exp, sys.stdout.buffer
894 assert os.path.exists(sub1_yyy)
896 sys.stdout.buffer = ""
897 fs_delete(base, remove=1)
898 assert sys.stdout.buffer == exp
899 assert not os.path.exists(base)
902 sys.stdout = old_stdout
904 def test_get_native_path(self):
905 """Test the get_native_path() function."""
907 filename = tempfile.mktemp()
908 str = '1234567890 ' + filename
909 open(filename, 'w').write(str)
910 assert open(get_native_path(filename)).read() == str
912 def test_subst_dict(self):
913 """Test substituting dictionary values in an Action
915 env = DummyEnv({'a' : 'A', 'b' : 'B'})
916 d = subst_dict([], [], env)
917 assert d['__env__'] is env, d['__env__']
919 d = subst_dict(target = DummyNode('t'), source = DummyNode('s'), env=DummyEnv())
920 assert str(d['TARGETS'][0]) == 't', d['TARGETS']
921 assert str(d['TARGET']) == 't', d['TARGET']
922 assert str(d['SOURCES'][0]) == 's', d['SOURCES']
923 assert str(d['SOURCE']) == 's', d['SOURCE']
925 d = subst_dict(target = [DummyNode('t1'), DummyNode('t2')],
926 source = [DummyNode('s1'), DummyNode('s2')],
928 TARGETS = map(lambda x: str(x), d['TARGETS'])
930 assert TARGETS == ['t1', 't2'], d['TARGETS']
931 assert str(d['TARGET']) == 't1', d['TARGET']
932 SOURCES = map(lambda x: str(x), d['SOURCES'])
934 assert SOURCES == ['s1', 's2'], d['SOURCES']
935 assert str(d['SOURCE']) == 's1', d['SOURCE']
938 def __init__(self, name):
943 return self.__class__('rstr-' + self.name)
944 def get_subst_proxy(self):
947 d = subst_dict(target = [N('t3'), DummyNode('t4')],
948 source = [DummyNode('s3'), N('s4')],
950 TARGETS = map(lambda x: str(x), d['TARGETS'])
952 assert TARGETS == ['t3', 't4'], d['TARGETS']
953 SOURCES = map(lambda x: str(x), d['SOURCES'])
955 assert SOURCES == ['rstr-s4', 's3'], d['SOURCES']
957 def test_PrependPath(self):
958 """Test prepending to a path"""
959 p1 = r'C:\dir\num\one;C:\dir\num\two'
960 p2 = r'C:\mydir\num\one;C:\mydir\num\two'
961 # have to include the pathsep here so that the test will work on UNIX too.
962 p1 = PrependPath(p1,r'C:\dir\num\two',sep = ';')
963 p1 = PrependPath(p1,r'C:\dir\num\three',sep = ';')
964 p2 = PrependPath(p2,r'C:\mydir\num\three',sep = ';')
965 p2 = PrependPath(p2,r'C:\mydir\num\one',sep = ';')
966 assert(p1 == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
967 assert(p2 == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
969 def test_AppendPath(self):
970 """Test appending to a path."""
971 p1 = r'C:\dir\num\one;C:\dir\num\two'
972 p2 = r'C:\mydir\num\one;C:\mydir\num\two'
973 # have to include the pathsep here so that the test will work on UNIX too.
974 p1 = AppendPath(p1,r'C:\dir\num\two',sep = ';')
975 p1 = AppendPath(p1,r'C:\dir\num\three',sep = ';')
976 p2 = AppendPath(p2,r'C:\mydir\num\three',sep = ';')
977 p2 = AppendPath(p2,r'C:\mydir\num\one',sep = ';')
978 assert(p1 == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
979 assert(p2 == r'C:\mydir\num\two;C:\mydir\num\three;C:\mydir\num\one')
981 def test_NodeList(self):
982 """Test NodeList class"""
984 def __init__(self, name, child=None):
988 return self.bar + "foo"
992 t1 = TestClass('t1', TestClass('t1child'))
993 t2 = TestClass('t2', TestClass('t2child'))
996 nl = NodeList([t1, t2, t3])
997 assert nl.foo() == [ 't1foo', 't2foo', 't3foo' ], nl.foo()
998 assert nl.bar == [ 't1', 't2', 't3' ], nl.bar
999 assert nl.getself().bar == [ 't1', 't2', 't3' ], nl.getself().bar
1000 assert nl[0:2].child.foo() == [ 't1childfoo', 't2childfoo' ], \
1002 assert nl[0:2].child.bar == [ 't1child', 't2child' ], \
1005 def test_Selector(self):
1006 """Test the Selector class"""
1008 s = Selector({'a' : 'AAA', 'b' : 'BBB'})
1009 assert s['a'] == 'AAA', s['a']
1010 assert s['b'] == 'BBB', s['b']
1016 assert exc_caught, "should have caught a KeyError"
1018 assert s['c'] == 'CCC', s['c']
1020 class DummyEnv(UserDict.UserDict):
1021 def subst(self, key):
1023 return self[key[1:]]
1028 s = Selector({'.d' : 'DDD', '.e' : 'EEE'})
1029 ret = s(env, ['foo.d'])
1030 assert ret == 'DDD', ret
1031 ret = s(env, ['bar.e'])
1032 assert ret == 'EEE', ret
1033 ret = s(env, ['bar.x'])
1034 assert ret == None, ret
1036 ret = s(env, ['bar.x'])
1037 assert ret == 'XXX', ret
1039 env = DummyEnv({'FSUFF' : '.f', 'GSUFF' : '.g'})
1041 s = Selector({'$FSUFF' : 'FFF', '$GSUFF' : 'GGG'})
1042 ret = s(env, ['foo.f'])
1043 assert ret == 'FFF', ret
1044 ret = s(env, ['bar.g'])
1045 assert ret == 'GGG', ret
1047 if __name__ == "__main__":
1048 suite = unittest.makeSuite(UtilTestCase, 'test_')
1049 if not unittest.TextTestRunner().run(suite).wasSuccessful():