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__"
35 from SCons.Util import *
44 self.buffer = self.buffer + str
47 class UtilTestCase(unittest.TestCase):
48 def test_subst_PathList(self):
49 """Test the subst function with PathLists"""
51 loc['TARGETS'] = PathList(map(os.path.normpath, [ "./foo/bar.exe",
54 loc['TARGET'] = loc['TARGETS'][0]
55 loc['SOURCES'] = PathList(map(os.path.normpath, [ "./foo/blah.cpp",
58 loc['SOURCE'] = loc['SOURCES'][0]
68 return string.replace(str, '/', os.sep)
70 newcom = scons_subst("test $TARGETS $SOURCES", loc, {})
71 assert newcom == cvt("test foo/bar.exe /bar/baz.obj ../foo/baz.obj foo/blah.cpp /bar/ack.cpp ../foo/ack.c")
73 newcom = scons_subst("test ${TARGETS[:]} ${SOURCES[0]}", loc, {})
74 assert newcom == cvt("test foo/bar.exe /bar/baz.obj ../foo/baz.obj foo/blah.cpp")
76 newcom = scons_subst("test ${TARGETS[1:]}v", loc, {})
77 assert newcom == cvt("test /bar/baz.obj ../foo/baz.objv")
79 newcom = scons_subst("test $TARGET", loc, {})
80 assert newcom == cvt("test foo/bar.exe")
82 newcom = scons_subst("test $TARGET$FOO[0]", loc, {})
83 assert newcom == cvt("test foo/bar.exe[0]")
85 newcom = scons_subst("test ${TARGET.file}", loc, {})
86 assert newcom == cvt("test bar.exe")
88 newcom = scons_subst("test ${TARGET.filebase}", loc, {})
89 assert newcom == cvt("test bar")
91 newcom = scons_subst("test ${TARGET.suffix}", loc, {})
92 assert newcom == cvt("test .exe")
94 newcom = scons_subst("test ${TARGET.base}", loc, {})
95 assert newcom == cvt("test foo/bar")
97 newcom = scons_subst("test ${TARGET.dir}", loc, {})
98 assert newcom == cvt("test foo")
100 cwd = SCons.Util.updrive(os.getcwd())
102 newcom = scons_subst("test ${TARGET.abspath}", loc, {})
103 assert newcom == cvt("test %s/foo/bar.exe" % (cwd)), newcom
105 newcom = scons_subst("test ${SOURCES.abspath}", loc, {})
106 assert newcom == cvt("test %s/foo/blah.cpp %s %s/foo/ack.c"%(cwd,
107 SCons.Util.updrive(os.path.abspath(os.path.normpath("/bar/ack.cpp"))),
108 SCons.Util.updrive(os.path.normpath(os.getcwd()+"/..")))), newcom
110 newcom = scons_subst("test ${SOURCE.abspath}", loc, {})
111 assert newcom == cvt("test %s/foo/blah.cpp" % (cwd)), newcom
113 newcom = scons_subst("test $xxx", loc, {})
114 assert newcom == cvt("test"), newcom
116 newcom = scons_subst("test $($xxx$)", loc, {})
117 assert newcom == cvt("test $($)"), newcom
119 newcom = scons_subst("test $( $xxx $)", loc, {})
120 assert newcom == cvt("test $( $)"), newcom
122 newcom = scons_subst("test $($xxx$)", loc, {}, re.compile('\$[()]'))
123 assert newcom == cvt("test"), newcom
125 newcom = scons_subst("test $( $xxx $)", loc, {}, re.compile('\$[()]'))
126 assert newcom == cvt("test"), newcom
128 newcom = scons_subst("test $zero", loc, {})
129 assert newcom == cvt("test 0"), newcom
131 newcom = scons_subst("test $one", loc, {})
132 assert newcom == cvt("test 1"), newcom
134 newcom = scons_subst("test aXbXcXd", loc, {}, re.compile('X'))
135 assert newcom == cvt("test abcd"), newcom
137 glob = { 'a' : 1, 'b' : 2 }
138 loc = {'a' : 3, 'c' : 4 }
139 newcom = scons_subst("test $a $b $c $d test", glob, loc)
140 assert newcom == "test 3 2 4 test", newcom
142 # Test against a former bug in scons_subst_list()
143 glob = { "FOO" : "$BAR",
146 "BARXYX" : "BADNEWS" }
147 newcom = scons_subst("$FOO$BLAT", glob, {})
148 assert newcom == "BAZXYX", newcom
150 # Test for double-dollar-sign behavior
151 glob = { "FOO" : "BAR",
153 newcom = scons_subst("$$FOO$BAZ", glob, {})
154 assert newcom == "$FOOBLAT", newcom
156 def test_subst_Lister(self):
157 """Test the subst function with Listers"""
159 loc['TARGETS'] = Lister('t%d')
160 loc['TARGET'] = loc['TARGETS'][0]
161 loc['SOURCES'] = Lister('s%d')
162 loc['SOURCE'] = loc['SOURCES'][0]
172 return string.replace(str, '/', os.sep)
174 newcom = scons_subst("test $TARGETS $SOURCES", loc, {})
175 assert newcom == cvt("test t1 t2 s1 s2"), newcom
177 newcom = scons_subst("test ${TARGETS[:]} ${SOURCES[0]}", loc, {})
178 assert newcom == cvt("test t1 t2 s1"), newcom
180 newcom = scons_subst("test ${TARGETS[1:]}v", loc, {})
181 assert newcom == cvt("test t2 t3v"), newcom
183 newcom = scons_subst("test $TARGET", loc, {})
184 assert newcom == cvt("test t1"), newcom
186 newcom = scons_subst("test $TARGET$FOO[0]", loc, {})
187 assert newcom == cvt("test t1[0]"), newcom
189 newcom = scons_subst("test ${TARGET.file}", loc, {})
190 assert newcom == cvt("test t1"), newcom
192 newcom = scons_subst("test ${TARGET.filebase}", loc, {})
193 assert newcom == cvt("test t1"), newcom
195 newcom = scons_subst("test ${TARGET.suffix}", loc, {})
196 assert newcom == cvt("test"), newcom
198 newcom = scons_subst("test ${TARGET.base}", loc, {})
199 assert newcom == cvt("test t1"), newcom
201 newcom = scons_subst("test ${TARGET.dir}", loc, {})
202 assert newcom == cvt("test"), newcom
204 cwd = SCons.Util.updrive(os.getcwd())
206 newcom = scons_subst("test ${TARGET.abspath}", loc, {})
207 assert newcom == cvt("test %s/t1" % (cwd)), newcom
209 newcom = scons_subst("test ${SOURCES.abspath}", loc, {})
210 assert newcom == cvt("test %s/s1 %s/s2" % (cwd, cwd)), newcom
212 newcom = scons_subst("test ${SOURCE.abspath}", loc, {})
213 assert newcom == cvt("test %s/s1" % cwd), newcom
215 def test_splitext(self):
216 assert splitext('foo') == ('foo','')
217 assert splitext('foo.bar') == ('foo','.bar')
218 assert splitext(os.path.join('foo.bar', 'blat')) == (os.path.join('foo.bar', 'blat'),'')
220 def test_subst_list(self):
221 """Testing the scons_subst_list() method..."""
224 def __init__(self, name):
228 def is_literal(self):
232 loc['TARGETS'] = PathList(map(os.path.normpath, [ "./foo/bar.exe",
233 "/bar/baz with spaces.obj",
235 loc['TARGET'] = loc['TARGETS'][0]
236 loc['SOURCES'] = PathList(map(os.path.normpath, [ "./foo/blah with spaces.cpp",
240 loc['NEWLINE'] = 'before\nafter'
242 loc['DO'] = Node('do something')
243 loc['FOO'] = Node('foo.in')
244 loc['BAR'] = Node('bar with spaces.out')
245 loc['CRAZY'] = Node('crazy\nfile.in')
252 return string.replace(str, '/', os.sep)
254 cmd_list = scons_subst_list("$TARGETS", loc, {})
255 assert cmd_list[0][1] == cvt("/bar/baz with spaces.obj"), cmd_list[0][1]
257 cmd_list = scons_subst_list("$SOURCES $NEWLINE $TARGETS", loc, {})
258 assert len(cmd_list) == 2, cmd_list
259 assert cmd_list[0][0] == cvt('foo/blah with spaces.cpp'), cmd_list[0][0]
260 assert cmd_list[1][2] == cvt("/bar/baz with spaces.obj"), cmd_list[1]
262 cmd_list = scons_subst_list("$SOURCES$NEWLINE", loc, {})
263 assert len(cmd_list) == 2, cmd_list
264 assert cmd_list[1][0] == 'after', cmd_list[1][0]
265 assert cmd_list[0][2] == cvt('../foo/ack.cbefore'), cmd_list[0][2]
267 cmd_list = scons_subst_list("$DO --in=$FOO --out=$BAR", loc, {})
268 assert len(cmd_list) == 1, cmd_list
269 assert len(cmd_list[0]) == 3, cmd_list
270 assert cmd_list[0][0] == 'do something', cmd_list[0][0]
271 assert cmd_list[0][1] == '--in=foo.in', cmd_list[0][1]
272 assert cmd_list[0][2] == '--out=bar with spaces.out', cmd_list[0][2]
274 # This test is now fixed, and works like it should.
275 cmd_list = scons_subst_list("$DO --in=$CRAZY --out=$BAR", loc, {})
276 assert len(cmd_list) == 1, map(str, cmd_list[0])
277 assert len(cmd_list[0]) == 3, cmd_list
278 assert cmd_list[0][0] == 'do something', cmd_list[0][0]
279 assert cmd_list[0][1] == '--in=crazy\nfile.in', cmd_list[0][1]
280 assert cmd_list[0][2] == '--out=bar with spaces.out', cmd_list[0][2]
282 # Test inputting a list to scons_subst_list()
283 cmd_list = scons_subst_list([ "$SOURCES$NEWLINE", "$TARGETS",
286 assert len(cmd_list) == 2, len(cmd_list)
287 assert cmd_list[0][0] == cvt('foo/blah with spaces.cpp'), cmd_list[0][0]
288 assert cmd_list[1][0] == cvt("after"), cmd_list[1]
289 assert cmd_list[1][4] == "This is a test", cmd_list[1]
291 glob = { 'a' : 1, 'b' : 2 }
292 loc = {'a' : 3, 'c' : 4 }
293 cmd_list = scons_subst_list("test $a $b $c $d test", glob, loc)
294 assert len(cmd_list) == 1, cmd_list
295 assert map(str, cmd_list[0]) == ['test', '3', '2', '4', 'test'], map(str, cmd_list[0])
297 # Test against a former bug in scons_subst_list()
298 glob = { "FOO" : "$BAR",
301 "BARXYX" : "BADNEWS" }
302 cmd_list = scons_subst_list("$FOO$BLAT", glob, {})
303 assert cmd_list[0][0] == "BAZXYX", cmd_list[0][0]
305 # Test for double-dollar-sign behavior
306 glob = { "FOO" : "BAR",
308 cmd_list = scons_subst_list("$$FOO$BAZ", glob, {})
309 assert cmd_list[0][0] == "$FOOBLAT", cmd_list[0][0]
311 # Now test escape functionality
312 def escape_func(foo):
313 return '**' + foo + '**'
316 glob = { "FOO" : PathList([ 'foo\nwith\nnewlines',
317 'bar\nwith\nnewlines' ]) }
318 cmd_list = scons_subst_list("$FOO", glob, {})
319 assert cmd_list[0][0] == 'foo\nwith\nnewlines', cmd_list[0][0]
320 cmd_list[0][0].escape(escape_func)
321 assert cmd_list[0][0] == '**foo\nwith\nnewlines**', cmd_list[0][0]
322 assert cmd_list[0][1] == 'bar\nwith\nnewlines', cmd_list[0][0]
323 cmd_list[0][1].escape(escape_func)
324 assert cmd_list[0][1] == '**bar\nwith\nnewlines**', cmd_list[0][0]
326 def test_quote_spaces(self):
327 """Testing the quote_spaces() method..."""
328 q = quote_spaces('x')
331 q = quote_spaces('x x')
332 assert q == '"x x"', q
334 q = quote_spaces('x\tx')
335 assert q == '"x\tx"', q
337 def test_render_tree(self):
339 def __init__(self, name, children=[]):
340 self.children = children
345 def get_children(node):
348 windows_h = Node("windows.h")
349 stdlib_h = Node("stdlib.h")
350 stdio_h = Node("stdio.h")
351 bar_c = Node("bar.c", [stdlib_h, windows_h])
352 bar_o = Node("bar.o", [bar_c])
353 foo_c = Node("foo.c", [stdio_h])
354 foo_o = Node("foo.o", [foo_c])
355 foo = Node("foo", [foo_o, bar_o])
368 actual = render_tree(foo, get_children)
369 assert expect == actual, (expect, actual)
371 bar_h = Node('bar.h', [stdlib_h])
372 blat_h = Node('blat.h', [stdlib_h])
373 blat_c = Node('blat.c', [blat_h, bar_h])
374 blat_o = Node('blat.o', [blat_c])
384 actual = render_tree(blat_o, get_children, 1)
385 assert expect == actual, (expect, actual)
387 def test_is_Dict(self):
390 assert is_Dict(UserDict.UserDict())
391 assert not is_Dict([])
392 assert not is_Dict("")
393 if hasattr(types, 'UnicodeType'):
394 exec "assert not is_Dict(u'')"
396 def test_is_List(self):
399 assert is_List(UserList.UserList())
400 assert not is_List({})
401 assert not is_List("")
402 if hasattr(types, 'UnicodeType'):
403 exec "assert not is_List(u'')"
405 def test_Split(self):
406 assert Split("foo bar") == ["foo", "bar"]
407 assert Split(["foo", "bar"]) == ["foo", "bar"]
408 assert Split("foo") == ["foo"]
410 def test_is_String(self):
412 if hasattr(types, 'UnicodeType'):
413 exec "assert is_String(u'')"
419 assert is_String(UserString.UserString(''))
420 assert not is_String({})
421 assert not is_String([])
423 def test_to_String(self):
424 """Test the to_String() method."""
425 assert to_String(1) == "1", to_String(1)
426 assert to_String([ 1, 2, 3]) == str([1, 2, 3]), to_String([1,2,3])
427 assert to_String("foo") == "foo", to_String("foo")
432 s1=UserString.UserString('blah')
433 assert to_String(s1) == s1, s1
434 assert to_String(s1) == 'blah', s1
436 class Derived(UserString.UserString):
439 assert to_String(s2) == s2, s2
440 assert to_String(s2) == 'foo', s2
442 if hasattr(types, 'UnicodeType'):
443 s3=UserString.UserString(unicode('bar'))
444 assert to_String(s3) == s3, s3
445 assert to_String(s3) == unicode('bar'), s3
446 assert type(to_String(s3)) is types.UnicodeType, \
451 if hasattr(types, 'UnicodeType'):
453 assert to_String(s4) == unicode('baz'), to_String(s4)
454 assert type(to_String(s4)) is types.UnicodeType, \
457 def test_WhereIs(self):
458 test = TestCmd.TestCmd(workdir = '')
460 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
461 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
462 sub3_xxx_exe = test.workpath('sub3', 'xxx.exe')
463 sub4_xxx_exe = test.workpath('sub4', 'xxx.exe')
465 test.subdir('subdir', 'sub1', 'sub2', 'sub3', 'sub4')
467 if sys.platform != 'win32':
468 test.write(sub1_xxx_exe, "\n")
470 os.mkdir(sub2_xxx_exe)
472 test.write(sub3_xxx_exe, "\n")
473 os.chmod(sub3_xxx_exe, 0777)
475 test.write(sub4_xxx_exe, "\n")
476 os.chmod(sub4_xxx_exe, 0777)
478 env_path = os.environ['PATH']
480 pathdirs_1234 = [ test.workpath('sub1'),
481 test.workpath('sub2'),
482 test.workpath('sub3'),
483 test.workpath('sub4'),
484 ] + string.split(env_path, os.pathsep)
486 pathdirs_1243 = [ test.workpath('sub1'),
487 test.workpath('sub2'),
488 test.workpath('sub4'),
489 test.workpath('sub3'),
490 ] + string.split(env_path, os.pathsep)
492 os.environ['PATH'] = string.join(pathdirs_1234, os.pathsep)
493 wi = WhereIs('xxx.exe')
494 assert wi == test.workpath(sub3_xxx_exe), wi
495 wi = WhereIs('xxx.exe', pathdirs_1243)
496 assert wi == test.workpath(sub4_xxx_exe), wi
497 wi = WhereIs('xxx.exe', string.join(pathdirs_1243, os.pathsep))
498 assert wi == test.workpath(sub4_xxx_exe), wi
500 os.environ['PATH'] = string.join(pathdirs_1243, os.pathsep)
501 wi = WhereIs('xxx.exe')
502 assert wi == test.workpath(sub4_xxx_exe), wi
503 wi = WhereIs('xxx.exe', pathdirs_1234)
504 assert wi == test.workpath(sub3_xxx_exe), wi
505 wi = WhereIs('xxx.exe', string.join(pathdirs_1234, os.pathsep))
506 assert wi == test.workpath(sub3_xxx_exe), wi
508 if sys.platform == 'win32':
509 wi = WhereIs('xxx', pathext = '')
510 assert wi is None, wi
512 wi = WhereIs('xxx', pathext = '.exe')
513 assert wi == test.workpath(sub4_xxx_exe), wi
515 wi = WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
516 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
518 def test_get_env_var(self):
519 """Testing get_environment_var()."""
520 assert get_environment_var("$FOO") == "FOO", get_environment_var("$FOO")
521 assert get_environment_var("${BAR}") == "BAR", get_environment_var("${BAR}")
522 assert get_environment_var("${BAR}FOO") == None, get_environment_var("${BAR}FOO")
523 assert get_environment_var("$BAR ") == None, get_environment_var("$BAR ")
524 assert get_environment_var("FOO$BAR") == None, get_environment_var("FOO$BAR")
526 def test_Proxy(self):
527 """Test generic Proxy class."""
537 class ProxyTest(Proxy):
543 assert p.foo() == 1, p.foo()
544 assert p.bar() == 4, p.bar()
545 assert p.baz == 3, p.baz
550 assert p.baz == 5, p.baz
552 def test_Literal(self):
553 """Test the Literal() function."""
554 cmd_list = [ '$FOO', Literal('$BAR') ]
555 cmd_list = scons_subst_list(cmd_list,
557 'BAR' : 'BLAT' }, {})
558 def escape_func(cmd):
559 return '**' + cmd + '**'
561 map(lambda x, e=escape_func: x.escape(e), cmd_list[0])
562 cmd_list = map(str, cmd_list[0])
563 assert cmd_list[0] == 'BAZ', cmd_list[0]
564 assert cmd_list[1] == '**$BAR**', cmd_list[1]
566 def test_mapPaths(self):
567 """Test the mapPaths function"""
568 fs = SCons.Node.FS.FS()
570 file=fs.File('bar/file')
573 def subst(self, arg):
576 res = mapPaths([ file, 'baz', 'blat/boo', '#test' ], dir)
577 assert res[0] == file, res[0]
578 assert res[1] == os.path.join('foo', 'baz'), res[1]
579 assert res[2] == os.path.join('foo', 'blat/boo'), res[2]
580 assert res[3] == '#test', res[3]
583 res=mapPaths('bleh', dir, env)
584 assert res[0] == os.path.normpath('foo/bar'), res[1]
586 def test_display(self):
587 old_stdout = sys.stdout
588 sys.stdout = OutBuffer()
589 SCons.Util.display("line1")
591 SCons.Util.display("line2")
593 SCons.Util.display("line3")
595 assert sys.stdout.buffer == "line1\nline3\n"
596 sys.stdout = old_stdout
598 def test_fs_delete(self):
599 test = TestCmd.TestCmd(workdir = '')
600 base = test.workpath('')
601 xxx = test.workpath('xxx.xxx')
602 sub1_yyy = test.workpath('sub1', 'yyy.yyy')
604 test.write(xxx, "\n")
605 test.write(sub1_yyy, "\n")
607 old_stdout = sys.stdout
608 sys.stdout = OutBuffer()
610 exp = "Removed " + os.path.join(base, sub1_yyy) + '\n' + \
611 "Removed directory " + os.path.join(base, 'sub1') + '\n' + \
612 "Removed " + os.path.join(base, xxx) + '\n' + \
613 "Removed directory " + base + '\n'
615 SCons.Util.fs_delete(base, remove=0)
616 assert sys.stdout.buffer == exp
617 assert os.path.exists(sub1_yyy)
619 sys.stdout.buffer = ""
620 SCons.Util.fs_delete(base, remove=1)
621 assert sys.stdout.buffer == exp
622 assert not os.path.exists(base)
625 sys.stdout = old_stdout
628 if __name__ == "__main__":
629 suite = unittest.makeSuite(UtilTestCase, 'test_')
630 if not unittest.TextTestRunner().run(suite).wasSuccessful():