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") ]
142 # $XXX$HHH should expand to GGGIII, not BADNEWS.
146 'FFFIII' : 'BADNEWS',
148 'LITERAL' : TestLiteral("$XXX"),
150 # Test that we can expand to and return a function.
151 #'FUNCTION' : function_foo,
159 # Test various combinations of strings, lists and functions.
171 #'RECURSE' : 'foo $RECURSE bar',
172 #'RRR' : 'foo $SSS bar',
178 # Basic tests of substitution functionality.
180 # Basics: strings without expansions are left alone, and
181 # the simplest possible expansion to a null-string value.
185 # Test expansion of integer values.
186 "test $zero", "test 0",
187 "test $one", "test 1",
189 # Test multiple re-expansion of values.
190 "test $ONE", "test four",
192 # Test a whole bunch of $TARGET[S] and $SOURCE[S] expansions.
193 "test $TARGETS $SOURCES",
194 "test foo/bar.exe /bar/baz.obj ../foo/baz.obj foo/blah.cpp /bar/ack.cpp ../foo/ack.c",
196 "test ${TARGETS[:]} ${SOURCES[0]}",
197 "test foo/bar.exe /bar/baz.obj ../foo/baz.obj foo/blah.cpp",
199 "test ${TARGETS[1:]}v",
200 "test /bar/baz.obj ../foo/baz.objv",
205 "test $TARGET$FOO[0]",
206 "test foo/bar.exe[0]",
211 "test ${SOURCES[0:2].foo}",
217 "test ${TARGET.get_stuff('blah')}",
218 "test foo/bar.exeblah",
220 "test ${SOURCES.get_stuff('blah')}",
221 "test foo/blah.cppblah /bar/ack.cppblah ../foo/ack.cblah",
223 "test ${SOURCES[0:2].get_stuff('blah')}",
224 "test foo/blah.cppblah /bar/ack.cppblah",
226 "test ${SOURCES[0:2].get_stuff('blah')}",
227 "test foo/blah.cppblah /bar/ack.cppblah",
229 # Test that adjacent expansions don't get re-interpreted
230 # together. The correct disambiguated expansion should be:
231 # $XXX$HHH => ${FFF}III => GGGIII
233 # $XXX$HHH => ${FFFIII} => BADNEWS
234 "$XXX$HHH", "GGGIII",
236 # Test double-dollar-sign behavior.
237 "$$FFF$HHH", "$FFFIII",
239 # Test that a Literal will stop dollar-sign substitution.
240 "$XXX $LITERAL $FFF", "GGG $XXX GGG",
242 # Test that we don't blow up even if they subscript
243 # something in ways they "can't."
249 # Test various combinations of strings and lists.
267 kwargs = {'target' : target, 'source' : source}
270 input, expect = cases[:2]
272 result = apply(scons_subst, (input, env), kwargs)
273 assert result == expect, \
274 "input %s => %s did not match %s" % (repr(input), result, expect)
277 # Tests of the various SUBST_* modes of substitution.
294 "$AAA ${AAA}A $BBBB $BBB",
311 input, eraw, ecmd, esig = subst_cases[:4]
312 result = scons_subst(input, env, mode=SUBST_RAW)
313 assert result == eraw, \
314 "input %s => RAW %s did not match %s" % (repr(input), result, eraw)
315 result = scons_subst(input, env, mode=SUBST_CMD)
316 assert result == ecmd, \
317 "input %s => CMD %s did not match %s" % (repr(input), result, ecmd)
318 result = scons_subst(input, env, mode=SUBST_SIG)
319 assert result == esig, \
320 "input %s => SIG %s did not match %s" % (repr(input), result, esig)
323 # Test interpolating a callable.
324 newcom = scons_subst("test $CMDGEN1 $SOURCES $TARGETS",
325 env, target=MyNode('t'), source=MyNode('s'))
326 assert newcom == "test foo baz s t", newcom
328 # Test returning a function.
329 #env = DummyEnv({'FUNCTION' : foo})
330 #func = scons_subst("$FUNCTION", env, mode=SUBST_RAW, call=None)
331 #assert func is function_foo, func
332 #func = scons_subst("$FUNCTION", env, mode=SUBST_CMD, call=None)
333 #assert func is function_foo, func
334 #func = scons_subst("$FUNCTION", env, mode=SUBST_SIG, call=None)
335 #assert func is function_foo, func
337 def test_subst_list(self):
338 """Testing the scons_subst_list() method..."""
339 target = [ DummyNode("./foo/bar.exe"),
340 DummyNode("/bar/baz with spaces.obj"),
341 DummyNode("../foo/baz.obj") ]
342 source = [ DummyNode("./foo/blah with spaces.cpp"),
343 DummyNode("/bar/ack.cpp"),
344 DummyNode("../foo/ack.c") ]
348 'NEWLINE' : 'before\nafter',
350 'DO' : DummyNode('do something'),
351 'FOO' : DummyNode('foo.in'),
352 'BAR' : DummyNode('bar with spaces.out'),
353 'CRAZY' : DummyNode('crazy\nfile.in'),
355 # $XXX$HHH should expand to GGGIII, not BADNEWS.
359 'FFFIII' : 'BADNEWS',
364 'LITERALS' : [ Literal('foo\nwith\nnewlines'),
365 Literal('bar\nwith\nnewlines') ],
367 # Test various combinations of strings, lists and functions.
384 ["foo/bar.exe", "/bar/baz with spaces.obj", "../foo/baz.obj"],
387 "$SOURCES $NEWLINE $TARGETS",
389 ["foo/blah with spaces.cpp", "/bar/ack.cpp", "../foo/ack.c", "before"],
390 ["after", "foo/bar.exe", "/bar/baz with spaces.obj", "../foo/baz.obj"],
395 ["foo/blah with spaces.cpp", "/bar/ack.cpp", "../foo/ack.cbefore"],
399 "$DO --in=$FOO --out=$BAR",
401 ["do something", "--in=foo.in", "--out=bar with spaces.out"],
404 # This test is now fixed, and works like it should.
405 "$DO --in=$CRAZY --out=$BAR",
407 ["do something", "--in=crazy\nfile.in", "--out=bar with spaces.out"],
410 # Try passing a list to scons_subst_list().
411 [ "$SOURCES$NEWLINE", "$TARGETS", "This is a test"],
413 ["foo/blah with spaces.cpp", "/bar/ack.cpp", "../foo/ack.cbefore"],
414 ["after", "foo/bar.exe", "/bar/baz with spaces.obj", "../foo/baz.obj", "This is a test"],
418 # Test against a former bug in scons_subst_list().
424 # Test double-dollar-sign behavior.
430 # Test various combinations of strings, lists and functions.
439 ['x', 'y'], [['x', 'y']],
449 ['$S'], [['x', 'y']],
453 ['$L'], [['x', 'y']],
464 kwargs = {'target' : target, 'source' : source}
467 input, expect = cases[:2]
468 expect = map(lambda l: map(cvt, l), expect)
469 result = apply(scons_subst_list, (input, env), kwargs)
470 assert result == expect, \
471 "input %s => %s did not match %s" % (repr(input), result, repr(expect))
474 # Test interpolating a callable.
475 cmd_list = scons_subst_list("testing $CMDGEN1 $TARGETS $SOURCES",
477 target=DummyNode('t'),
478 source=DummyNode('s'))
479 assert cmd_list == [['testing', 'foo', 'bar with spaces.out', 't', 's']], cmd_list
481 # Test escape functionality.
482 def escape_func(foo):
483 return '**' + foo + '**'
484 cmd_list = scons_subst_list("$LITERALS", env)
485 assert cmd_list == [['foo\nwith\nnewlines',
486 'bar\nwith\nnewlines']], cmd_list
487 cmd_list[0][0].escape(escape_func)
488 assert cmd_list[0][0] == '**foo\nwith\nnewlines**', cmd_list[0][0]
489 cmd_list[0][1].escape(escape_func)
490 assert cmd_list[0][1] == '**bar\nwith\nnewlines**', cmd_list[0][0]
492 def test_splitext(self):
493 assert splitext('foo') == ('foo','')
494 assert splitext('foo.bar') == ('foo','.bar')
495 assert splitext(os.path.join('foo.bar', 'blat')) == (os.path.join('foo.bar', 'blat'),'')
497 def test_quote_spaces(self):
498 """Testing the quote_spaces() method..."""
499 q = quote_spaces('x')
502 q = quote_spaces('x x')
503 assert q == '"x x"', q
505 q = quote_spaces('x\tx')
506 assert q == '"x\tx"', q
508 def test_render_tree(self):
510 def __init__(self, name, children=[]):
511 self.children = children
516 def get_children(node):
519 windows_h = Node("windows.h")
520 stdlib_h = Node("stdlib.h")
521 stdio_h = Node("stdio.h")
522 bar_c = Node("bar.c", [stdlib_h, windows_h])
523 bar_o = Node("bar.o", [bar_c])
524 foo_c = Node("foo.c", [stdio_h])
525 foo_o = Node("foo.o", [foo_c])
526 foo = Node("foo", [foo_o, bar_o])
539 actual = render_tree(foo, get_children)
540 assert expect == actual, (expect, actual)
542 bar_h = Node('bar.h', [stdlib_h])
543 blat_h = Node('blat.h', [stdlib_h])
544 blat_c = Node('blat.c', [blat_h, bar_h])
545 blat_o = Node('blat.o', [blat_c])
555 actual = render_tree(blat_o, get_children, 1)
556 assert expect == actual, (expect, actual)
558 def test_is_Dict(self):
561 assert is_Dict(UserDict.UserDict())
562 assert not is_Dict([])
563 assert not is_Dict("")
564 if hasattr(types, 'UnicodeType'):
565 exec "assert not is_Dict(u'')"
567 def test_is_List(self):
570 assert is_List(UserList.UserList())
571 assert not is_List({})
572 assert not is_List("")
573 if hasattr(types, 'UnicodeType'):
574 exec "assert not is_List(u'')"
576 def test_is_String(self):
578 if hasattr(types, 'UnicodeType'):
579 exec "assert is_String(u'')"
585 assert is_String(UserString.UserString(''))
586 assert not is_String({})
587 assert not is_String([])
589 def test_to_String(self):
590 """Test the to_String() method."""
591 assert to_String(1) == "1", to_String(1)
592 assert to_String([ 1, 2, 3]) == str([1, 2, 3]), to_String([1,2,3])
593 assert to_String("foo") == "foo", to_String("foo")
598 s1=UserString.UserString('blah')
599 assert to_String(s1) == s1, s1
600 assert to_String(s1) == 'blah', s1
602 class Derived(UserString.UserString):
605 assert to_String(s2) == s2, s2
606 assert to_String(s2) == 'foo', s2
608 if hasattr(types, 'UnicodeType'):
609 s3=UserString.UserString(unicode('bar'))
610 assert to_String(s3) == s3, s3
611 assert to_String(s3) == unicode('bar'), s3
612 assert type(to_String(s3)) is types.UnicodeType, \
617 if hasattr(types, 'UnicodeType'):
619 assert to_String(s4) == unicode('baz'), to_String(s4)
620 assert type(to_String(s4)) is types.UnicodeType, \
623 def test_WhereIs(self):
624 test = TestCmd.TestCmd(workdir = '')
626 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
627 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
628 sub3_xxx_exe = test.workpath('sub3', 'xxx.exe')
629 sub4_xxx_exe = test.workpath('sub4', 'xxx.exe')
631 test.subdir('subdir', 'sub1', 'sub2', 'sub3', 'sub4')
633 if sys.platform != 'win32':
634 test.write(sub1_xxx_exe, "\n")
636 os.mkdir(sub2_xxx_exe)
638 test.write(sub3_xxx_exe, "\n")
639 os.chmod(sub3_xxx_exe, 0777)
641 test.write(sub4_xxx_exe, "\n")
642 os.chmod(sub4_xxx_exe, 0777)
644 env_path = os.environ['PATH']
646 pathdirs_1234 = [ test.workpath('sub1'),
647 test.workpath('sub2'),
648 test.workpath('sub3'),
649 test.workpath('sub4'),
650 ] + string.split(env_path, os.pathsep)
652 pathdirs_1243 = [ test.workpath('sub1'),
653 test.workpath('sub2'),
654 test.workpath('sub4'),
655 test.workpath('sub3'),
656 ] + string.split(env_path, os.pathsep)
658 os.environ['PATH'] = string.join(pathdirs_1234, os.pathsep)
659 wi = WhereIs('xxx.exe')
660 assert wi == test.workpath(sub3_xxx_exe), wi
661 wi = WhereIs('xxx.exe', pathdirs_1243)
662 assert wi == test.workpath(sub4_xxx_exe), wi
663 wi = WhereIs('xxx.exe', string.join(pathdirs_1243, os.pathsep))
664 assert wi == test.workpath(sub4_xxx_exe), wi
666 os.environ['PATH'] = string.join(pathdirs_1243, os.pathsep)
667 wi = WhereIs('xxx.exe')
668 assert wi == test.workpath(sub4_xxx_exe), wi
669 wi = WhereIs('xxx.exe', pathdirs_1234)
670 assert wi == test.workpath(sub3_xxx_exe), wi
671 wi = WhereIs('xxx.exe', string.join(pathdirs_1234, os.pathsep))
672 assert wi == test.workpath(sub3_xxx_exe), wi
674 if sys.platform == 'win32':
675 wi = WhereIs('xxx', pathext = '')
676 assert wi is None, wi
678 wi = WhereIs('xxx', pathext = '.exe')
679 assert wi == test.workpath(sub4_xxx_exe), wi
681 wi = WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
682 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
684 # Test that we return a normalized path even when
685 # the path contains forward slashes.
686 forward_slash = test.workpath('') + '/sub3'
687 wi = WhereIs('xxx', path = forward_slash, pathext = '.EXE')
688 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
690 def test_is_valid_construction_var(self):
691 """Testing is_valid_construction_var()"""
692 r = is_valid_construction_var("_a")
693 assert not r is None, r
694 r = is_valid_construction_var("z_")
695 assert not r is None, r
696 r = is_valid_construction_var("X_")
697 assert not r is None, r
698 r = is_valid_construction_var("2a")
700 r = is_valid_construction_var("a2_")
701 assert not r is None, r
702 r = is_valid_construction_var("/")
704 r = is_valid_construction_var("_/")
706 r = is_valid_construction_var("a/")
708 r = is_valid_construction_var(".b")
710 r = is_valid_construction_var("_.b")
712 r = is_valid_construction_var("b1._")
714 r = is_valid_construction_var("-b")
716 r = is_valid_construction_var("_-b")
718 r = is_valid_construction_var("b1-_")
721 def test_get_env_var(self):
722 """Testing get_environment_var()."""
723 assert get_environment_var("$FOO") == "FOO", get_environment_var("$FOO")
724 assert get_environment_var("${BAR}") == "BAR", get_environment_var("${BAR}")
725 assert get_environment_var("$FOO_BAR1234") == "FOO_BAR1234", get_environment_var("$FOO_BAR1234")
726 assert get_environment_var("${BAR_FOO1234}") == "BAR_FOO1234", get_environment_var("${BAR_FOO1234}")
727 assert get_environment_var("${BAR}FOO") == None, get_environment_var("${BAR}FOO")
728 assert get_environment_var("$BAR ") == None, get_environment_var("$BAR ")
729 assert get_environment_var("FOO$BAR") == None, get_environment_var("FOO$BAR")
730 assert get_environment_var("$FOO[0]") == None, get_environment_var("$FOO[0]")
731 assert get_environment_var("${some('complex expression')}") == None, get_environment_var("${some('complex expression')}")
733 def test_Proxy(self):
734 """Test generic Proxy class."""
744 class ProxyTest(Proxy):
750 assert p.foo() == 1, p.foo()
751 assert p.bar() == 4, p.bar()
752 assert p.baz == 3, p.baz
757 assert p.baz == 5, p.baz
758 assert p.get() == s, p.get()
760 def test_Literal(self):
761 """Test the Literal() function."""
762 cmd_list = [ '$FOO', Literal('$BAR') ]
763 cmd_list = scons_subst_list(cmd_list,
764 DummyEnv({ 'FOO' : 'BAZ',
766 def escape_func(cmd):
767 return '**' + cmd + '**'
769 map(lambda x, e=escape_func: x.escape(e), cmd_list[0])
770 cmd_list = map(str, cmd_list[0])
771 assert cmd_list[0] == 'BAZ', cmd_list[0]
772 assert cmd_list[1] == '**$BAR**', cmd_list[1]
774 def test_SpecialAttrWrapper(self):
775 """Test the SpecialAttrWrapper() function."""
776 input_list = [ '$FOO', SpecialAttrWrapper('$BAR', 'BLEH') ]
778 def escape_func(cmd):
779 return '**' + cmd + '**'
781 cmd_list = scons_subst_list(input_list,
782 DummyEnv({ 'FOO' : 'BAZ',
784 map(lambda x, e=escape_func: x.escape(e), cmd_list[0])
785 cmd_list = map(str, cmd_list[0])
786 assert cmd_list[0] == 'BAZ', cmd_list[0]
787 assert cmd_list[1] == '**$BAR**', cmd_list[1]
789 cmd_list = scons_subst_list(input_list,
790 DummyEnv({ 'FOO' : 'BAZ',
793 map(lambda x, e=escape_func: x.escape(e), cmd_list[0])
794 cmd_list = map(str, cmd_list[0])
795 assert cmd_list[0] == 'BAZ', cmd_list[0]
796 assert cmd_list[1] == '**BLEH**', cmd_list[1]
798 def test_mapPaths(self):
799 """Test the mapPaths function"""
801 def __init__(self, path):
806 dir=MyFileNode('foo')
807 file=MyFileNode('bar/file')
810 def subst(self, arg):
813 res = mapPaths([ file, 'baz', 'blat/boo', '#test' ], dir)
814 assert res[0] == file, res[0]
815 assert res[1] == os.path.join('foo', 'baz'), res[1]
816 assert res[2] == os.path.join('foo', 'blat/boo'), res[2]
817 assert res[3] == '#test', res[3]
820 res=mapPaths('bleh', dir, env)
821 assert res[0] == os.path.normpath('foo/bar'), res[1]
823 def test_display(self):
824 old_stdout = sys.stdout
825 sys.stdout = OutBuffer()
832 assert sys.stdout.buffer == "line1\nline3\n"
833 sys.stdout = old_stdout
835 def test_fs_delete(self):
836 test = TestCmd.TestCmd(workdir = '')
837 base = test.workpath('')
838 xxx = test.workpath('xxx.xxx')
839 ZZZ = test.workpath('ZZZ.ZZZ')
840 sub1_yyy = test.workpath('sub1', 'yyy.yyy')
843 test.write(xxx, "\n")
844 test.write(ZZZ, "\n")
845 test.write(sub1_yyy, "\n")
847 old_stdout = sys.stdout
848 sys.stdout = OutBuffer()
850 exp = "Removed " + os.path.join(base, ZZZ) + "\n" + \
851 "Removed " + os.path.join(base, sub1_yyy) + '\n' + \
852 "Removed directory " + os.path.join(base, 'sub1') + '\n' + \
853 "Removed " + os.path.join(base, xxx) + '\n' + \
854 "Removed directory " + base + '\n'
856 fs_delete(base, remove=0)
857 assert sys.stdout.buffer == exp, sys.stdout.buffer
858 assert os.path.exists(sub1_yyy)
860 sys.stdout.buffer = ""
861 fs_delete(base, remove=1)
862 assert sys.stdout.buffer == exp
863 assert not os.path.exists(base)
866 sys.stdout = old_stdout
868 def test_get_native_path(self):
869 """Test the get_native_path() function."""
871 filename = tempfile.mktemp()
872 str = '1234567890 ' + filename
873 open(filename, 'w').write(str)
874 assert open(get_native_path(filename)).read() == str
876 def test_subst_dict(self):
877 """Test substituting dictionary values in an Action
879 env = DummyEnv({'a' : 'A', 'b' : 'B'})
880 d = subst_dict([], [], env)
881 assert d['__env__'] is env, d['__env__']
883 d = subst_dict(target = DummyNode('t'), source = DummyNode('s'), env=DummyEnv())
884 assert str(d['TARGETS'][0]) == 't', d['TARGETS']
885 assert str(d['TARGET']) == 't', d['TARGET']
886 assert str(d['SOURCES'][0]) == 's', d['SOURCES']
887 assert str(d['SOURCE']) == 's', d['SOURCE']
889 d = subst_dict(target = [DummyNode('t1'), DummyNode('t2')],
890 source = [DummyNode('s1'), DummyNode('s2')],
892 TARGETS = map(lambda x: str(x), d['TARGETS'])
894 assert TARGETS == ['t1', 't2'], d['TARGETS']
895 assert str(d['TARGET']) == 't1', d['TARGET']
896 SOURCES = map(lambda x: str(x), d['SOURCES'])
898 assert SOURCES == ['s1', 's2'], d['SOURCES']
899 assert str(d['SOURCE']) == 's1', d['SOURCE']
902 def __init__(self, name):
907 return self.__class__('rstr-' + self.name)
908 def get_subst_proxy(self):
911 d = subst_dict(target = [N('t3'), DummyNode('t4')],
912 source = [DummyNode('s3'), N('s4')],
914 TARGETS = map(lambda x: str(x), d['TARGETS'])
916 assert TARGETS == ['t3', 't4'], d['TARGETS']
917 SOURCES = map(lambda x: str(x), d['SOURCES'])
919 assert SOURCES == ['rstr-s4', 's3'], d['SOURCES']
921 def test_PrependPath(self):
922 """Test prepending to a path"""
923 p1 = r'C:\dir\num\one;C:\dir\num\two'
924 p2 = r'C:\mydir\num\one;C:\mydir\num\two'
925 # have to include the pathsep here so that the test will work on UNIX too.
926 p1 = PrependPath(p1,r'C:\dir\num\two',sep = ';')
927 p1 = PrependPath(p1,r'C:\dir\num\three',sep = ';')
928 p2 = PrependPath(p2,r'C:\mydir\num\three',sep = ';')
929 p2 = PrependPath(p2,r'C:\mydir\num\one',sep = ';')
930 assert(p1 == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
931 assert(p2 == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
933 def test_AppendPath(self):
934 """Test appending to a path."""
935 p1 = r'C:\dir\num\one;C:\dir\num\two'
936 p2 = r'C:\mydir\num\one;C:\mydir\num\two'
937 # have to include the pathsep here so that the test will work on UNIX too.
938 p1 = AppendPath(p1,r'C:\dir\num\two',sep = ';')
939 p1 = AppendPath(p1,r'C:\dir\num\three',sep = ';')
940 p2 = AppendPath(p2,r'C:\mydir\num\three',sep = ';')
941 p2 = AppendPath(p2,r'C:\mydir\num\one',sep = ';')
942 assert(p1 == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
943 assert(p2 == r'C:\mydir\num\two;C:\mydir\num\three;C:\mydir\num\one')
945 def test_NodeList(self):
946 """Test NodeList class"""
948 def __init__(self, name, child=None):
952 return self.bar + "foo"
956 t1 = TestClass('t1', TestClass('t1child'))
957 t2 = TestClass('t2', TestClass('t2child'))
960 nl = NodeList([t1, t2, t3])
961 assert nl.foo() == [ 't1foo', 't2foo', 't3foo' ], nl.foo()
962 assert nl.bar == [ 't1', 't2', 't3' ], nl.bar
963 assert nl.getself().bar == [ 't1', 't2', 't3' ], nl.getself().bar
964 assert nl[0:2].child.foo() == [ 't1childfoo', 't2childfoo' ], \
966 assert nl[0:2].child.bar == [ 't1child', 't2child' ], \
969 def test_Selector(self):
970 """Test the Selector class"""
972 s = Selector({'a' : 'AAA', 'b' : 'BBB'})
973 assert s['a'] == 'AAA', s['a']
974 assert s['b'] == 'BBB', s['b']
980 assert exc_caught, "should have caught a KeyError"
982 assert s['c'] == 'CCC', s['c']
984 class DummyEnv(UserDict.UserDict):
985 def subst(self, key):
992 s = Selector({'.d' : 'DDD', '.e' : 'EEE'})
993 ret = s(env, ['foo.d'])
994 assert ret == 'DDD', ret
995 ret = s(env, ['bar.e'])
996 assert ret == 'EEE', ret
997 ret = s(env, ['bar.x'])
998 assert ret == None, ret
1000 ret = s(env, ['bar.x'])
1001 assert ret == 'XXX', ret
1003 env = DummyEnv({'FSUFF' : '.f', 'GSUFF' : '.g'})
1005 s = Selector({'$FSUFF' : 'FFF', '$GSUFF' : 'GGG'})
1006 ret = s(env, ['foo.f'])
1007 assert ret == 'FFF', ret
1008 ret = s(env, ['bar.g'])
1009 assert ret == 'GGG', ret
1011 if __name__ == "__main__":
1012 suite = unittest.makeSuite(UtilTestCase, 'test_')
1013 if not unittest.TextTestRunner().run(suite).wasSuccessful():