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 __init__(self, name):
108 DummyNode.__init__(self, name)
111 self.attribute = Attribute()
112 self.attribute.attr1 = 'attr$1-' + os.path.basename(name)
113 self.attribute.attr2 = 'attr$2-' + os.path.basename(name)
114 def get_stuff(self, extra):
115 return self.name + extra
119 def __init__(self, literal):
120 self.literal = literal
123 def is_literal(self):
126 def function_foo(arg):
129 target = [ MyNode("./foo/bar.exe"),
130 MyNode("/bar/baz.obj"),
131 MyNode("../foo/baz.obj") ]
132 source = [ MyNode("./foo/blah.cpp"),
133 MyNode("/bar/ack.cpp"),
134 MyNode("../foo/ack.c") ]
150 # $XXX$HHH should expand to GGGIII, not BADNEWS.
154 'FFFIII' : 'BADNEWS',
156 'LITERAL' : TestLiteral("$XXX"),
158 # Test that we can expand to and return a function.
159 #'FUNCTION' : function_foo,
167 # Test various combinations of strings, lists and functions.
178 # Test function calls within ${}.
179 'FUNCCALL' : '${FUNC1("$AAA $FUNC2 $BBB")}',
180 'FUNC1' : lambda x: x,
181 'FUNC2' : lambda target, source, env, for_signature: ['x$CCC'],
184 'RECURSE' : 'foo $RECURSE bar',
185 'RRR' : 'foo $SSS bar',
191 # Basic tests of substitution functionality.
193 # Basics: strings without expansions are left alone, and
194 # the simplest possible expansion to a null-string value.
198 # Test expansion of integer values.
199 "test $zero", "test 0",
200 "test $one", "test 1",
202 # Test multiple re-expansion of values.
203 "test $ONE", "test four",
205 # Test a whole bunch of $TARGET[S] and $SOURCE[S] expansions.
206 "test $TARGETS $SOURCES",
207 "test foo/bar.exe /bar/baz.obj ../foo/baz.obj foo/blah.cpp /bar/ack.cpp ../foo/ack.c",
209 "test ${TARGETS[:]} ${SOURCES[0]}",
210 "test foo/bar.exe /bar/baz.obj ../foo/baz.obj foo/blah.cpp",
212 "test ${TARGETS[1:]}v",
213 "test /bar/baz.obj ../foo/baz.objv",
218 "test $TARGET$FOO[0]",
219 "test foo/bar.exe[0]",
224 "test ${SOURCES[0:2].foo}",
230 "test ${TARGET.get_stuff('blah')}",
231 "test foo/bar.exeblah",
233 "test ${SOURCES.get_stuff('blah')}",
234 "test foo/blah.cppblah /bar/ack.cppblah ../foo/ack.cblah",
236 "test ${SOURCES[0:2].get_stuff('blah')}",
237 "test foo/blah.cppblah /bar/ack.cppblah",
239 "test ${SOURCES[0:2].get_stuff('blah')}",
240 "test foo/blah.cppblah /bar/ack.cppblah",
242 "test ${SOURCES.attribute.attr1}",
243 "test attr$1-blah.cpp attr$1-ack.cpp attr$1-ack.c",
245 "test ${SOURCES.attribute.attr2}",
246 "test attr$2-blah.cpp attr$2-ack.cpp attr$2-ack.c",
248 # Test adjacent expansions.
255 # Test that adjacent expansions don't get re-interpreted
256 # together. The correct disambiguated expansion should be:
257 # $XXX$HHH => ${FFF}III => GGGIII
259 # $XXX$HHH => ${FFFIII} => BADNEWS
260 "$XXX$HHH", "GGGIII",
262 # Test double-dollar-sign behavior.
263 "$$FFF$HHH", "$FFFIII",
265 # Test that a Literal will stop dollar-sign substitution.
266 "$XXX $LITERAL $FFF", "GGG $XXX GGG",
268 # Test that we don't blow up even if they subscript
269 # something in ways they "can't."
275 # Test various combinations of strings and lists.
292 # Test function calls within ${}.
293 '$FUNCCALL', 'a xc b',
296 kwargs = {'target' : target, 'source' : source}
300 input, expect = cases[:2]
302 result = apply(scons_subst, (input, env), kwargs)
304 if failed == 0: print
305 print " input %s => %s did not match %s" % (repr(input), repr(result), repr(expect))
308 assert failed == 0, "%d subst() cases failed" % failed
310 # Tests of the various SUBST_* modes of substitution.
327 "$AAA ${AAA}A $BBBB $BBB",
345 input, eraw, ecmd, esig = subst_cases[:4]
346 result = scons_subst(input, env, mode=SUBST_RAW)
348 if failed == 0: print
349 print " input %s => RAW %s did not match %s" % (repr(input), repr(result), repr(eraw))
351 result = scons_subst(input, env, mode=SUBST_CMD)
353 if failed == 0: print
354 print " input %s => CMD %s did not match %s" % (repr(input), repr(result), repr(ecmd))
356 result = scons_subst(input, env, mode=SUBST_SIG)
358 if failed == 0: print
359 print " input %s => SIG %s did not match %s" % (repr(input), repr(result), repr(esig))
362 assert failed == 0, "%d subst() mode cases failed" % failed
364 # Test interpolating a callable.
365 newcom = scons_subst("test $CMDGEN1 $SOURCES $TARGETS",
366 env, target=MyNode('t'), source=MyNode('s'))
367 assert newcom == "test foo baz s t", newcom
369 # Test returning a function.
370 #env = DummyEnv({'FUNCTION' : foo})
371 #func = scons_subst("$FUNCTION", env, mode=SUBST_RAW, call=None)
372 #assert func is function_foo, func
373 #func = scons_subst("$FUNCTION", env, mode=SUBST_CMD, call=None)
374 #assert func is function_foo, func
375 #func = scons_subst("$FUNCTION", env, mode=SUBST_SIG, call=None)
376 #assert func is function_foo, func
378 def test_subst_list(self):
379 """Testing the scons_subst_list() method..."""
380 class MyNode(DummyNode):
381 """Simple node work-alike with some extra stuff for testing."""
382 def __init__(self, name):
383 DummyNode.__init__(self, name)
386 self.attribute = Attribute()
387 self.attribute.attr1 = 'attr$1-' + os.path.basename(name)
388 self.attribute.attr2 = 'attr$2-' + os.path.basename(name)
390 target = [ MyNode("./foo/bar.exe"),
391 MyNode("/bar/baz with spaces.obj"),
392 MyNode("../foo/baz.obj") ]
393 source = [ MyNode("./foo/blah with spaces.cpp"),
394 MyNode("/bar/ack.cpp"),
395 MyNode("../foo/ack.c") ]
399 'NEWLINE' : 'before\nafter',
405 'DO' : DummyNode('do something'),
406 'FOO' : DummyNode('foo.in'),
407 'BAR' : DummyNode('bar with spaces.out'),
408 'CRAZY' : DummyNode('crazy\nfile.in'),
410 # $XXX$HHH should expand to GGGIII, not BADNEWS.
414 'FFFIII' : 'BADNEWS',
419 'LITERALS' : [ Literal('foo\nwith\nnewlines'),
420 Literal('bar\nwith\nnewlines') ],
422 # Test various combinations of strings, lists and functions.
433 # Test function calls within ${}.
434 'FUNCCALL' : '${FUNC1("$AAA $FUNC2 $BBB")}',
435 'FUNC1' : lambda x: x,
436 'FUNC2' : lambda target, source, env, for_signature: ['x$CCC'],
439 'RECURSE' : 'foo $RECURSE bar',
440 'RRR' : 'foo $SSS bar',
449 ["foo/bar.exe", "/bar/baz with spaces.obj", "../foo/baz.obj"],
452 "$SOURCES $NEWLINE $TARGETS",
454 ["foo/blah with spaces.cpp", "/bar/ack.cpp", "../foo/ack.c", "before"],
455 ["after", "foo/bar.exe", "/bar/baz with spaces.obj", "../foo/baz.obj"],
460 ["foo/blah with spaces.cpp", "/bar/ack.cpp", "../foo/ack.cbefore"],
474 "test ${SOURCES.attribute.attr1}",
476 ["test", "attr$1-blah with spaces.cpp", "attr$1-ack.cpp", "attr$1-ack.c"],
479 "test ${SOURCES.attribute.attr2}",
481 ["test", "attr$2-blah with spaces.cpp", "attr$2-ack.cpp", "attr$2-ack.c"],
484 "$DO --in=$FOO --out=$BAR",
486 ["do something", "--in=foo.in", "--out=bar with spaces.out"],
489 # This test is now fixed, and works like it should.
490 "$DO --in=$CRAZY --out=$BAR",
492 ["do something", "--in=crazy\nfile.in", "--out=bar with spaces.out"],
495 # Try passing a list to scons_subst_list().
496 [ "$SOURCES$NEWLINE", "$TARGETS", "This is a test"],
498 ["foo/blah with spaces.cpp", "/bar/ack.cpp", "../foo/ack.cbefore"],
499 ["after", "foo/bar.exe", "/bar/baz with spaces.obj", "../foo/baz.obj", "This is a test"],
502 # Test against a former bug in scons_subst_list().
508 # Test double-dollar-sign behavior.
514 # Test various combinations of strings, lists and functions.
523 ['x', 'y'], [['x', 'y']],
533 ['$S'], [['x', 'y']],
537 ['$L'], [['x', 'y']],
547 # Test function calls within ${}.
548 '$FUNCCALL', [['a', 'xc', 'b']],
550 # Test handling of newlines in white space.
551 'foo\nbar', [['foo'], ['bar']],
552 'foo\n\nbar', [['foo'], ['bar']],
553 'foo \n \n bar', [['foo'], ['bar']],
554 'foo \nmiddle\n bar', [['foo'], ['middle'], ['bar']],
557 kwargs = {'target' : target, 'source' : source}
561 input, expect = cases[:2]
562 expect = map(lambda l: map(cvt, l), expect)
563 result = apply(scons_subst_list, (input, env), kwargs)
565 if failed == 0: print
566 print " input %s => %s did not match %s" % (repr(input), result, repr(expect))
569 assert failed == 0, "%d subst_list() cases failed" % failed
571 # Test interpolating a callable.
574 cmd_list = scons_subst_list("testing $CMDGEN1 $TARGETS $SOURCES",
575 env, target=_t, source=_s)
576 assert cmd_list == [['testing', 'foo', 'bar with spaces.out', 't', 's']], cmd_list
578 # Test escape functionality.
579 def escape_func(foo):
580 return '**' + foo + '**'
581 cmd_list = scons_subst_list("abc $LITERALS xyz", env)
582 assert cmd_list == [['abc',
583 'foo\nwith\nnewlines',
584 'bar\nwith\nnewlines',
586 c = cmd_list[0][0].escape(escape_func)
588 c = cmd_list[0][1].escape(escape_func)
589 assert c == '**foo\nwith\nnewlines**', c
590 c = cmd_list[0][2].escape(escape_func)
591 assert c == '**bar\nwith\nnewlines**', c
592 c = cmd_list[0][3].escape(escape_func)
595 # Tests of the various SUBST_* modes of substitution.
608 [["test", "$(", "$)"]],
612 "$AAA ${AAA}A $BBBB $BBB",
629 while subst_list_cases:
630 input, eraw, ecmd, esig = subst_list_cases[:4]
631 result = scons_subst_list(input, env, mode=SUBST_RAW)
633 if failed == 0: print
634 print " input %s => RAW %s did not match %s" % (repr(input), repr(result), repr(eraw))
636 result = scons_subst_list(input, env, mode=SUBST_CMD)
638 if failed == 0: print
639 print " input %s => CMD %s did not match %s" % (repr(input), repr(result), repr(ecmd))
641 result = scons_subst_list(input, env, mode=SUBST_SIG)
643 if failed == 0: print
644 print " input %s => SIG %s did not match %s" % (repr(input), repr(result), repr(esig))
646 del subst_list_cases[:4]
647 assert failed == 0, "%d subst() mode cases failed" % failed
649 def test_splitext(self):
650 assert splitext('foo') == ('foo','')
651 assert splitext('foo.bar') == ('foo','.bar')
652 assert splitext(os.path.join('foo.bar', 'blat')) == (os.path.join('foo.bar', 'blat'),'')
654 def test_quote_spaces(self):
655 """Testing the quote_spaces() method..."""
656 q = quote_spaces('x')
659 q = quote_spaces('x x')
660 assert q == '"x x"', q
662 q = quote_spaces('x\tx')
663 assert q == '"x\tx"', q
665 def test_render_tree(self):
667 def __init__(self, name, children=[]):
668 self.children = children
673 def get_children(node):
676 windows_h = Node("windows.h")
677 stdlib_h = Node("stdlib.h")
678 stdio_h = Node("stdio.h")
679 bar_c = Node("bar.c", [stdlib_h, windows_h])
680 bar_o = Node("bar.o", [bar_c])
681 foo_c = Node("foo.c", [stdio_h])
682 foo_o = Node("foo.o", [foo_c])
683 foo = Node("foo", [foo_o, bar_o])
696 actual = render_tree(foo, get_children)
697 assert expect == actual, (expect, actual)
699 bar_h = Node('bar.h', [stdlib_h])
700 blat_h = Node('blat.h', [stdlib_h])
701 blat_c = Node('blat.c', [blat_h, bar_h])
702 blat_o = Node('blat.o', [blat_c])
712 actual = render_tree(blat_o, get_children, 1)
713 assert expect == actual, (expect, actual)
715 def test_is_Dict(self):
718 assert is_Dict(UserDict.UserDict())
719 assert not is_Dict([])
720 assert not is_Dict("")
721 if hasattr(types, 'UnicodeType'):
722 exec "assert not is_Dict(u'')"
724 def test_is_List(self):
727 assert is_List(UserList.UserList())
728 assert not is_List({})
729 assert not is_List("")
730 if hasattr(types, 'UnicodeType'):
731 exec "assert not is_List(u'')"
733 def test_is_String(self):
735 if hasattr(types, 'UnicodeType'):
736 exec "assert is_String(u'')"
742 assert is_String(UserString.UserString(''))
743 assert not is_String({})
744 assert not is_String([])
746 def test_to_String(self):
747 """Test the to_String() method."""
748 assert to_String(1) == "1", to_String(1)
749 assert to_String([ 1, 2, 3]) == str([1, 2, 3]), to_String([1,2,3])
750 assert to_String("foo") == "foo", to_String("foo")
755 s1=UserString.UserString('blah')
756 assert to_String(s1) == s1, s1
757 assert to_String(s1) == 'blah', s1
759 class Derived(UserString.UserString):
762 assert to_String(s2) == s2, s2
763 assert to_String(s2) == 'foo', s2
765 if hasattr(types, 'UnicodeType'):
766 s3=UserString.UserString(unicode('bar'))
767 assert to_String(s3) == s3, s3
768 assert to_String(s3) == unicode('bar'), s3
769 assert type(to_String(s3)) is types.UnicodeType, \
774 if hasattr(types, 'UnicodeType'):
776 assert to_String(s4) == unicode('baz'), to_String(s4)
777 assert type(to_String(s4)) is types.UnicodeType, \
780 def test_WhereIs(self):
781 test = TestCmd.TestCmd(workdir = '')
783 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
784 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
785 sub3_xxx_exe = test.workpath('sub3', 'xxx.exe')
786 sub4_xxx_exe = test.workpath('sub4', 'xxx.exe')
788 test.subdir('subdir', 'sub1', 'sub2', 'sub3', 'sub4')
790 if sys.platform != 'win32':
791 test.write(sub1_xxx_exe, "\n")
793 os.mkdir(sub2_xxx_exe)
795 test.write(sub3_xxx_exe, "\n")
796 os.chmod(sub3_xxx_exe, 0777)
798 test.write(sub4_xxx_exe, "\n")
799 os.chmod(sub4_xxx_exe, 0777)
801 env_path = os.environ['PATH']
803 pathdirs_1234 = [ test.workpath('sub1'),
804 test.workpath('sub2'),
805 test.workpath('sub3'),
806 test.workpath('sub4'),
807 ] + string.split(env_path, os.pathsep)
809 pathdirs_1243 = [ test.workpath('sub1'),
810 test.workpath('sub2'),
811 test.workpath('sub4'),
812 test.workpath('sub3'),
813 ] + string.split(env_path, os.pathsep)
815 os.environ['PATH'] = string.join(pathdirs_1234, os.pathsep)
816 wi = WhereIs('xxx.exe')
817 assert wi == test.workpath(sub3_xxx_exe), wi
818 wi = WhereIs('xxx.exe', pathdirs_1243)
819 assert wi == test.workpath(sub4_xxx_exe), wi
820 wi = WhereIs('xxx.exe', string.join(pathdirs_1243, os.pathsep))
821 assert wi == test.workpath(sub4_xxx_exe), wi
823 os.environ['PATH'] = string.join(pathdirs_1243, os.pathsep)
824 wi = WhereIs('xxx.exe')
825 assert wi == test.workpath(sub4_xxx_exe), wi
826 wi = WhereIs('xxx.exe', pathdirs_1234)
827 assert wi == test.workpath(sub3_xxx_exe), wi
828 wi = WhereIs('xxx.exe', string.join(pathdirs_1234, os.pathsep))
829 assert wi == test.workpath(sub3_xxx_exe), wi
831 if sys.platform == 'win32':
832 wi = WhereIs('xxx', pathext = '')
833 assert wi is None, wi
835 wi = WhereIs('xxx', pathext = '.exe')
836 assert wi == test.workpath(sub4_xxx_exe), wi
838 wi = WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
839 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
841 # Test that we return a normalized path even when
842 # the path contains forward slashes.
843 forward_slash = test.workpath('') + '/sub3'
844 wi = WhereIs('xxx', path = forward_slash, pathext = '.EXE')
845 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
847 def test_is_valid_construction_var(self):
848 """Testing is_valid_construction_var()"""
849 r = is_valid_construction_var("_a")
850 assert not r is None, r
851 r = is_valid_construction_var("z_")
852 assert not r is None, r
853 r = is_valid_construction_var("X_")
854 assert not r is None, r
855 r = is_valid_construction_var("2a")
857 r = is_valid_construction_var("a2_")
858 assert not r is None, r
859 r = is_valid_construction_var("/")
861 r = is_valid_construction_var("_/")
863 r = is_valid_construction_var("a/")
865 r = is_valid_construction_var(".b")
867 r = is_valid_construction_var("_.b")
869 r = is_valid_construction_var("b1._")
871 r = is_valid_construction_var("-b")
873 r = is_valid_construction_var("_-b")
875 r = is_valid_construction_var("b1-_")
878 def test_get_env_var(self):
879 """Testing get_environment_var()."""
880 assert get_environment_var("$FOO") == "FOO", get_environment_var("$FOO")
881 assert get_environment_var("${BAR}") == "BAR", get_environment_var("${BAR}")
882 assert get_environment_var("$FOO_BAR1234") == "FOO_BAR1234", get_environment_var("$FOO_BAR1234")
883 assert get_environment_var("${BAR_FOO1234}") == "BAR_FOO1234", get_environment_var("${BAR_FOO1234}")
884 assert get_environment_var("${BAR}FOO") == None, get_environment_var("${BAR}FOO")
885 assert get_environment_var("$BAR ") == None, get_environment_var("$BAR ")
886 assert get_environment_var("FOO$BAR") == None, get_environment_var("FOO$BAR")
887 assert get_environment_var("$FOO[0]") == None, get_environment_var("$FOO[0]")
888 assert get_environment_var("${some('complex expression')}") == None, get_environment_var("${some('complex expression')}")
890 def test_Proxy(self):
891 """Test generic Proxy class."""
901 class ProxyTest(Proxy):
907 assert p.foo() == 1, p.foo()
908 assert p.bar() == 4, p.bar()
909 assert p.baz == 3, p.baz
914 assert p.baz == 5, p.baz
915 assert p.get() == s, p.get()
917 def test_Literal(self):
918 """Test the Literal() function."""
919 input_list = [ '$FOO', Literal('$BAR') ]
920 dummy_env = DummyEnv({ 'FOO' : 'BAZ', 'BAR' : 'BLAT' })
922 def escape_func(cmd):
923 return '**' + cmd + '**'
925 cmd_list = scons_subst_list(input_list, dummy_env)
926 cmd_list = SCons.Util.escape_list(cmd_list[0], escape_func)
927 assert cmd_list == ['BAZ', '**$BAR**'], cmd_list
929 def test_SpecialAttrWrapper(self):
930 """Test the SpecialAttrWrapper() function."""
931 input_list = [ '$FOO', SpecialAttrWrapper('$BAR', 'BLEH') ]
932 dummy_env = DummyEnv({ 'FOO' : 'BAZ', 'BAR' : 'BLAT' })
934 def escape_func(cmd):
935 return '**' + cmd + '**'
937 cmd_list = scons_subst_list(input_list, dummy_env)
938 cmd_list = SCons.Util.escape_list(cmd_list[0], escape_func)
939 assert cmd_list == ['BAZ', '**$BAR**'], cmd_list
941 cmd_list = scons_subst_list(input_list, dummy_env, mode=SUBST_SIG)
942 cmd_list = SCons.Util.escape_list(cmd_list[0], escape_func)
943 assert cmd_list == ['BAZ', '**BLEH**'], cmd_list
945 def test_mapPaths(self):
946 """Test the mapPaths function"""
948 def __init__(self, path):
953 dir=MyFileNode('foo')
954 file=MyFileNode('bar/file')
957 def subst(self, arg):
960 res = mapPaths([ file, 'baz', 'blat/boo', '#test' ], dir)
961 assert res[0] == file, res[0]
962 assert res[1] == os.path.join('foo', 'baz'), res[1]
963 assert res[2] == os.path.join('foo', 'blat/boo'), res[2]
964 assert res[3] == '#test', res[3]
967 res=mapPaths('bleh', dir, env)
968 assert res[0] == os.path.normpath('foo/bar'), res[1]
970 def test_display(self):
971 old_stdout = sys.stdout
972 sys.stdout = OutBuffer()
979 assert sys.stdout.buffer == "line1\nline3\n"
980 sys.stdout = old_stdout
982 def test_fs_delete(self):
983 test = TestCmd.TestCmd(workdir = '')
984 base = test.workpath('')
985 xxx = test.workpath('xxx.xxx')
986 ZZZ = test.workpath('ZZZ.ZZZ')
987 sub1_yyy = test.workpath('sub1', 'yyy.yyy')
990 test.write(xxx, "\n")
991 test.write(ZZZ, "\n")
992 test.write(sub1_yyy, "\n")
994 old_stdout = sys.stdout
995 sys.stdout = OutBuffer()
997 exp = "Removed " + os.path.join(base, ZZZ) + "\n" + \
998 "Removed " + os.path.join(base, sub1_yyy) + '\n' + \
999 "Removed directory " + os.path.join(base, 'sub1') + '\n' + \
1000 "Removed " + os.path.join(base, xxx) + '\n' + \
1001 "Removed directory " + base + '\n'
1003 fs_delete(base, remove=0)
1004 assert sys.stdout.buffer == exp, sys.stdout.buffer
1005 assert os.path.exists(sub1_yyy)
1007 sys.stdout.buffer = ""
1008 fs_delete(base, remove=1)
1009 assert sys.stdout.buffer == exp
1010 assert not os.path.exists(base)
1012 test._dirlist = None
1013 sys.stdout = old_stdout
1015 def test_get_native_path(self):
1016 """Test the get_native_path() function."""
1018 filename = tempfile.mktemp()
1019 str = '1234567890 ' + filename
1020 open(filename, 'w').write(str)
1021 assert open(get_native_path(filename)).read() == str
1023 def test_subst_dict(self):
1024 """Test substituting dictionary values in an Action
1026 env = DummyEnv({'a' : 'A', 'b' : 'B'})
1027 d = subst_dict([], [], env)
1028 assert d['__env__'] is env, d['__env__']
1030 d = subst_dict(target = DummyNode('t'), source = DummyNode('s'), env=DummyEnv())
1031 assert str(d['TARGETS'][0]) == 't', d['TARGETS']
1032 assert str(d['TARGET']) == 't', d['TARGET']
1033 assert str(d['SOURCES'][0]) == 's', d['SOURCES']
1034 assert str(d['SOURCE']) == 's', d['SOURCE']
1036 d = subst_dict(target = [DummyNode('t1'), DummyNode('t2')],
1037 source = [DummyNode('s1'), DummyNode('s2')],
1039 TARGETS = map(lambda x: str(x), d['TARGETS'])
1041 assert TARGETS == ['t1', 't2'], d['TARGETS']
1042 assert str(d['TARGET']) == 't1', d['TARGET']
1043 SOURCES = map(lambda x: str(x), d['SOURCES'])
1045 assert SOURCES == ['s1', 's2'], d['SOURCES']
1046 assert str(d['SOURCE']) == 's1', d['SOURCE']
1049 def __init__(self, name):
1054 return self.__class__('rstr-' + self.name)
1055 def get_subst_proxy(self):
1058 d = subst_dict(target = [N('t3'), DummyNode('t4')],
1059 source = [DummyNode('s3'), N('s4')],
1061 TARGETS = map(lambda x: str(x), d['TARGETS'])
1063 assert TARGETS == ['t3', 't4'], d['TARGETS']
1064 SOURCES = map(lambda x: str(x), d['SOURCES'])
1066 assert SOURCES == ['rstr-s4', 's3'], d['SOURCES']
1068 def test_PrependPath(self):
1069 """Test prepending to a path"""
1070 p1 = r'C:\dir\num\one;C:\dir\num\two'
1071 p2 = r'C:\mydir\num\one;C:\mydir\num\two'
1072 # have to include the pathsep here so that the test will work on UNIX too.
1073 p1 = PrependPath(p1,r'C:\dir\num\two',sep = ';')
1074 p1 = PrependPath(p1,r'C:\dir\num\three',sep = ';')
1075 p2 = PrependPath(p2,r'C:\mydir\num\three',sep = ';')
1076 p2 = PrependPath(p2,r'C:\mydir\num\one',sep = ';')
1077 assert(p1 == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
1078 assert(p2 == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
1080 def test_AppendPath(self):
1081 """Test appending to a path."""
1082 p1 = r'C:\dir\num\one;C:\dir\num\two'
1083 p2 = r'C:\mydir\num\one;C:\mydir\num\two'
1084 # have to include the pathsep here so that the test will work on UNIX too.
1085 p1 = AppendPath(p1,r'C:\dir\num\two',sep = ';')
1086 p1 = AppendPath(p1,r'C:\dir\num\three',sep = ';')
1087 p2 = AppendPath(p2,r'C:\mydir\num\three',sep = ';')
1088 p2 = AppendPath(p2,r'C:\mydir\num\one',sep = ';')
1089 assert(p1 == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
1090 assert(p2 == r'C:\mydir\num\two;C:\mydir\num\three;C:\mydir\num\one')
1092 def test_NodeList(self):
1093 """Test NodeList class"""
1095 def __init__(self, name, child=None):
1099 return self.bar + "foo"
1103 t1 = TestClass('t1', TestClass('t1child'))
1104 t2 = TestClass('t2', TestClass('t2child'))
1105 t3 = TestClass('t3')
1107 nl = NodeList([t1, t2, t3])
1108 assert nl.foo() == [ 't1foo', 't2foo', 't3foo' ], nl.foo()
1109 assert nl.bar == [ 't1', 't2', 't3' ], nl.bar
1110 assert nl.getself().bar == [ 't1', 't2', 't3' ], nl.getself().bar
1111 assert nl[0:2].child.foo() == [ 't1childfoo', 't2childfoo' ], \
1113 assert nl[0:2].child.bar == [ 't1child', 't2child' ], \
1116 def test_Selector(self):
1117 """Test the Selector class"""
1119 s = Selector({'a' : 'AAA', 'b' : 'BBB'})
1120 assert s['a'] == 'AAA', s['a']
1121 assert s['b'] == 'BBB', s['b']
1127 assert exc_caught, "should have caught a KeyError"
1129 assert s['c'] == 'CCC', s['c']
1131 class DummyEnv(UserDict.UserDict):
1132 def subst(self, key):
1134 return self[key[1:]]
1139 s = Selector({'.d' : 'DDD', '.e' : 'EEE'})
1140 ret = s(env, ['foo.d'])
1141 assert ret == 'DDD', ret
1142 ret = s(env, ['bar.e'])
1143 assert ret == 'EEE', ret
1144 ret = s(env, ['bar.x'])
1145 assert ret == None, ret
1147 ret = s(env, ['bar.x'])
1148 assert ret == 'XXX', ret
1150 env = DummyEnv({'FSUFF' : '.f', 'GSUFF' : '.g'})
1152 s = Selector({'$FSUFF' : 'FFF', '$GSUFF' : 'GGG'})
1153 ret = s(env, ['foo.f'])
1154 assert ret == 'FFF', ret
1155 ret = s(env, ['bar.g'])
1156 assert ret == 'GGG', ret
1158 def test_adjustixes(self):
1159 """Test the adjustixes() function"""
1160 r = adjustixes('file', 'pre-', '-suf')
1161 assert r == 'pre-file-suf', r
1162 r = adjustixes('pre-file', 'pre-', '-suf')
1163 assert r == 'pre-file-suf', r
1164 r = adjustixes('file-suf', 'pre-', '-suf')
1165 assert r == 'pre-file-suf', r
1166 r = adjustixes('pre-file-suf', 'pre-', '-suf')
1167 assert r == 'pre-file-suf', r
1168 r = adjustixes('pre-file.xxx', 'pre-', '-suf')
1169 assert r == 'pre-file.xxx', r
1170 r = adjustixes('dir/file', 'pre-', '-suf')
1171 assert r == os.path.join('dir', 'pre-file-suf'), r
1173 if __name__ == "__main__":
1174 suite = unittest.makeSuite(UtilTestCase, 'test_')
1175 if not unittest.TextTestRunner().run(suite).wasSuccessful():