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__"
33 from SCons.Environment import *
36 def diff_env(env1, env2):
40 for k in env1._dict.keys() + env2._dict.keys():
47 if env1[k] != env2[k]:
48 s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n"
49 s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n"
51 s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n"
53 s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n"
58 def diff_dict(d1, d2):
62 for k in d1.keys() + d2.keys():
70 s1 = s1 + " " + repr(k) + " : " + repr(d1[k]) + "\n"
71 s2 = s2 + " " + repr(k) + " : " + repr(d2[k]) + "\n"
73 s1 = s1 + " " + repr(k) + " : " + repr(d1[k]) + "\n"
75 s2 = s2 + " " + repr(k) + " : " + repr(d2[k]) + "\n"
84 """A dummy Builder class for testing purposes. "Building"
85 a target is simply setting a value in the dictionary.
87 def __init__(self, name = None):
90 def __call__(self, env, **kw):
94 def execute(self, target = None, **kw):
103 """A dummy Scanner class for testing purposes. "Scanning"
104 a target is simply setting a value in the dictionary.
106 def __init__(self, name, skeys=[]):
110 def __call__(self, filename):
112 scanned_it[filename] = 1
114 def __cmp__(self, other):
116 return cmp(self.__dict__, other.__dict__)
117 except AttributeError:
120 def get_skeys(self, env):
125 class CLVar(UserList.UserList):
126 def __init__(self, seq):
127 if type(seq) == type(''):
128 seq = string.split(seq)
129 UserList.UserList.__init__(self, seq)
130 def __coerce__(self, other):
131 return (self, CLVar(other))
136 def __init__(self, name):
142 def get_subst_proxy(self):
147 class EnvironmentTestCase(unittest.TestCase):
149 def test___init__(self):
150 """Test construction Environment creation
152 Create two with identical arguments and check that
153 they compare the same.
155 env1 = Environment(XXX = 'x', YYY = 'y')
156 env2 = Environment(XXX = 'x', YYY = 'y')
157 assert env1 == env2, diff_env(env1, env2)
159 assert env1['__env__'] is env1, env1['__env__']
160 assert env2['__env__'] is env2, env2['__env__']
163 """Test the get() method."""
164 env = Environment(aaa = 'AAA')
168 x = env.get('aaa', 'XXX')
172 x = env.get('bbb', 'XXX')
175 def test_arg2nodes(self):
176 """Test the arg2nodes method
180 class X(SCons.Node.Node):
182 def Factory(name, directory = None, create = 1, dict=dict, X=X):
183 if not dict.has_key(name):
185 dict[name].name = name
188 nodes = env.arg2nodes("Util.py UtilTests.py", Factory)
189 assert len(nodes) == 1, nodes
190 assert isinstance(nodes[0], X)
191 assert nodes[0].name == "Util.py UtilTests.py"
194 if hasattr(types, 'UnicodeType'):
196 nodes = env.arg2nodes(u"Util.py UtilTests.py", Factory)
197 assert len(nodes) == 1, nodes
198 assert isinstance(nodes[0], X)
199 assert nodes[0].name == u"Util.py UtilTests.py"
201 exec code in globals(), locals()
203 nodes = env.arg2nodes(["Util.py", "UtilTests.py"], Factory)
204 assert len(nodes) == 2, nodes
205 assert isinstance(nodes[0], X)
206 assert isinstance(nodes[1], X)
207 assert nodes[0].name == "Util.py"
208 assert nodes[1].name == "UtilTests.py"
210 n1 = Factory("Util.py")
211 nodes = env.arg2nodes([n1, "UtilTests.py"], Factory)
212 assert len(nodes) == 2, nodes
213 assert isinstance(nodes[0], X)
214 assert isinstance(nodes[1], X)
215 assert nodes[0].name == "Util.py"
216 assert nodes[1].name == "UtilTests.py"
218 class SConsNode(SCons.Node.Node):
220 nodes = env.arg2nodes(SConsNode())
221 assert len(nodes) == 1, nodes
222 assert isinstance(nodes[0], SConsNode), node
226 nodes = env.arg2nodes(OtherNode())
227 assert len(nodes) == 1, nodes
228 assert isinstance(nodes[0], OtherNode), node
230 def lookup_a(str, F=Factory):
238 def lookup_b(str, F=Factory):
247 env_ll.lookup_list = [lookup_a, lookup_b]
249 nodes = env_ll.arg2nodes(['aaa', 'bbb', 'ccc'], Factory)
250 assert len(nodes) == 3, nodes
252 assert nodes[0].name == 'aaa', nodes[0]
253 assert nodes[0].a == 1, nodes[0]
254 assert not hasattr(nodes[0], 'b'), nodes[0]
256 assert nodes[1].name == 'bbb'
257 assert not hasattr(nodes[1], 'a'), nodes[1]
258 assert nodes[1].b == 1, nodes[1]
260 assert nodes[2].name == 'ccc'
261 assert not hasattr(nodes[2], 'a'), nodes[1]
262 assert not hasattr(nodes[2], 'b'), nodes[1]
264 def lookup_bbbb(str, F=Factory):
272 def lookup_c(str, F=Factory):
280 nodes = env.arg2nodes(['bbbb', 'ccc'], Factory,
281 [lookup_c, lookup_bbbb, lookup_b])
282 assert len(nodes) == 2, nodes
284 assert nodes[0].name == 'bbbb'
285 assert not hasattr(nodes[0], 'a'), nodes[1]
286 assert not hasattr(nodes[0], 'b'), nodes[1]
287 assert nodes[0].bbbb == 1, nodes[1]
288 assert not hasattr(nodes[0], 'c'), nodes[0]
290 assert nodes[1].name == 'ccc'
291 assert not hasattr(nodes[1], 'a'), nodes[1]
292 assert not hasattr(nodes[1], 'b'), nodes[1]
293 assert not hasattr(nodes[1], 'bbbb'), nodes[0]
294 assert nodes[1].c == 1, nodes[1]
296 def test_subst(self):
297 """Test substituting construction variables within strings
299 Check various combinations, including recursive expansion
300 of variables into other variables.
302 env = Environment(AAA = 'a', BBB = 'b')
303 mystr = env.subst("$AAA ${AAA}A $BBBB $BBB")
304 assert mystr == "a aA b", mystr
306 # Changed the tests below to reflect a bug fix in
308 env = Environment(AAA = '$BBB', BBB = 'b', BBBA = 'foo')
309 mystr = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
310 assert mystr == "b bA bB b", mystr
312 env = Environment(AAA = '$BBB', BBB = '$CCC', CCC = 'c')
313 mystr = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
314 assert mystr == "c cA cB c", mystr
321 env = Environment(AAA = 'aaa')
322 s = env.subst('$AAA $TARGET $SOURCES', target=[t1, t2], source=[s1, s2])
323 assert s == "aaa t1 s1 s2", s
324 s = env.subst('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2])
325 assert s == "aaa t1 t2 s1", s
326 s = env.subst('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2], dict={})
329 # Test callables in the Environment
330 def foo(target, source, env, for_signature):
331 assert str(target) == 't', target
332 assert str(source) == 's', source
335 env = Environment(BAR=foo, FOO='baz')
339 subst = env.subst('test $BAR', target=t, source=s)
340 assert subst == 'test baz', subst
342 # Test not calling callables in the Environment
344 # This will take some serious surgery to subst() and
345 # subst_list(), so just leave these tests out until we can
350 env = Environment(BAR=bar, FOO='$BAR')
352 subst = env.subst('$BAR', call=None)
353 assert subst is bar, subst
355 subst = env.subst('$FOO', call=None)
356 assert subst is bar, subst
358 def test_subst_kw(self):
359 """Test substituting construction variables within dictionaries"""
360 env = Environment(AAA = 'a', BBB = 'b')
361 kw = env.subst_kw({'$AAA' : 'aaa', 'bbb' : '$BBB'})
362 assert len(kw) == 2, kw
363 assert kw['a'] == 'aaa', kw['a']
364 assert kw['bbb'] == 'b', kw['bbb']
366 def test_subst_list(self):
367 """Test substituting construction variables in command lists
369 env = Environment(AAA = 'a', BBB = 'b')
370 l = env.subst_list("$AAA ${AAA}A $BBBB $BBB")
371 assert l == [["a", "aA", "b"]], l
373 # Changed the tests below to reflect a bug fix in
375 env = Environment(AAA = '$BBB', BBB = 'b', BBBA = 'foo')
376 l = env.subst_list("$AAA ${AAA}A ${AAA}B $BBB")
377 assert l == [["b", "bA", "bB", "b"]], l
379 env = Environment(AAA = '$BBB', BBB = '$CCC', CCC = 'c')
380 l = env.subst_list("$AAA ${AAA}A ${AAA}B $BBB")
381 assert l == [["c", "cA", "cB", "c"]], mystr
383 env = Environment(AAA = '$BBB', BBB = '$CCC', CCC = [ 'a', 'b\nc' ])
384 lst = env.subst_list([ "$AAA", "B $CCC" ])
385 assert lst == [[ "a", "b"], ["c", "B a", "b"], ["c"]], lst
392 env = Environment(AAA = 'aaa')
393 s = env.subst_list('$AAA $TARGET $SOURCES', target=[t1, t2], source=[s1, s2])
394 assert s == [["aaa", "t1", "s1", "s2"]], s
395 s = env.subst_list('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2])
396 assert s == [["aaa", "t1", "t2", "s1"]], s
397 s = env.subst_list('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2], dict={})
398 assert s == [["aaa"]], s
400 # Test callables in the Environment
401 def foo(target, source, env, for_signature):
402 assert str(target) == 't', target
403 assert str(source) == 's', source
406 env = Environment(BAR=foo, FOO='baz')
410 lst = env.subst_list('test $BAR', target=t, source=s)
411 assert lst == [['test', 'baz']], lst
413 # Test not calling callables in the Environment
415 # This will take some serious surgery to subst() and
416 # subst_list(), so just leave these tests out until we can
421 env = Environment(BAR=bar, FOO='$BAR')
423 subst = env.subst_list('$BAR', call=None)
424 assert subst is bar, subst
426 subst = env.subst_list('$FOO', call=None)
427 assert subst is bar, subst
429 def test_subst_path(self):
430 """Test substituting a path list
433 def __init__(self, val):
436 return self.val + '-proxy'
441 env = Environment(FOO='foo', BAR='bar', PROXY=MyProxy('my1'))
443 r = env.subst_path('$FOO')
444 assert r == ['foo'], r
446 r = env.subst_path(['$FOO', 'xxx', '$BAR'])
447 assert r == ['foo', 'xxx', 'bar'], r
451 r = env.subst_path(['$PROXY', MyProxy('my2'), n])
452 assert r == ['my1-proxy', 'my2-proxy', n], r
455 def __init__(self, s):
460 env = Environment(FOO=StringableObj("foo"),
461 BAR=StringableObj("bar"))
463 r = env.subst_path([ "${FOO}/bar", "${BAR}/baz" ])
464 assert r == [ "foo/bar", "bar/baz" ]
466 r = env.subst_path([ "bar/${FOO}", "baz/${BAR}" ])
467 assert r == [ "bar/foo", "baz/bar" ]
469 r = env.subst_path([ "bar/${FOO}/bar", "baz/${BAR}/baz" ])
470 assert r == [ "bar/foo/bar", "baz/bar/baz" ]
472 def test_Builder_calls(self):
473 """Test Builder calls through different environments
481 env.Replace(BUILDERS = { 'builder1' : b1,
484 env.builder1(target = 'out1')
485 assert called_it['target'] == 'out1', called_it
486 assert not called_it.has_key('source')
489 env.builder2(target = 'out2', xyzzy = 1)
490 assert called_it['target'] == 'out2', called_it
491 assert called_it['xyzzy'] == 1, called_it
492 assert not called_it.has_key('source')
495 env.builder1(foo = 'bar')
496 assert called_it['foo'] == 'bar', called_it
497 assert not called_it.has_key('target')
498 assert not called_it.has_key('source')
502 def test_Builder_execs(self):
503 """Test Builder execution through different environments
505 One environment is initialized with a single
506 Builder object, one with a list of a single Builder
507 object, and one with a list of two Builder objects.
516 env3.Replace(BUILDERS = { 'builder1' : b1,
518 env3.builder1.execute(target = 'out1')
519 env3.builder2.execute(target = 'out2')
520 env3.builder1.execute(target = 'out3')
521 assert built_it['out1']
522 assert built_it['out2']
523 assert built_it['out3']
526 assert env4.builder1.env is env4, "builder1.env (%s) == env3 (%s)?" % (env4.builder1.env, env3)
527 assert env4.builder2.env is env4, "builder2.env (%s) == env3 (%s)?" % (env4.builder1.env, env3)
529 # Now test BUILDERS as a dictionary.
531 env5 = Environment(BUILDERS={ 'foo' : b1 })
532 env5['BUILDERS']['bar'] = b2
533 env5.foo.execute(target='out1')
534 env5.bar.execute(target='out2')
535 assert built_it['out1']
536 assert built_it['out2']
540 env6['BUILDERS'] = { 'foo' : b1,
542 env6.foo.execute(target='out1')
543 env6.bar.execute(target='out2')
544 assert built_it['out1']
545 assert built_it['out2']
547 def test_Scanners(self):
548 """Test setting SCANNERS in various ways
550 One environment is initialized with a single
551 Scanner object, one with a list of a single Scanner
552 object, and one with a list of two Scanner objects.
556 s1 = Scanner(name = 'scanner1', skeys = [".c", ".cc"])
557 s2 = Scanner(name = 'scanner2', skeys = [".m4"])
558 s3 = Scanner(name = 'scanner3', skeys = [".m4", ".m5"])
560 # XXX Tests for scanner execution through different environments,
561 # XXX if we ever want to do that some day
563 # env1 = Environment(SCANNERS = s1)
564 # env1.scanner1(filename = 'out1')
565 # assert scanned_it['out1']
568 # env2 = Environment(SCANNERS = [s1])
569 # env1.scanner1(filename = 'out1')
570 # assert scanned_it['out1']
573 # env3 = Environment()
574 # env3.Replace(SCANNERS = [s1])
575 # env3.scanner1(filename = 'out1')
576 # env3.scanner2(filename = 'out2')
577 # env3.scanner1(filename = 'out3')
578 # assert scanned_it['out1']
579 # assert scanned_it['out2']
580 # assert scanned_it['out3']
582 suffixes = [".c", ".cc", ".cxx", ".m4", ".m5"]
584 env = Environment(SCANNERS = [])
585 s = map(env.get_scanner, suffixes)
586 assert s == [None, None, None, None, None], s
588 env.Replace(SCANNERS = [s1])
589 s = map(env.get_scanner, suffixes)
590 assert s == [s1, s1, None, None, None], s
592 env.Append(SCANNERS = [s2])
593 s = map(env.get_scanner, suffixes)
594 assert s == [s1, s1, None, s2, None], s
596 env.AppendUnique(SCANNERS = [s3])
597 s = map(env.get_scanner, suffixes)
598 assert s == [s1, s1, None, s2, s3], s
600 env = env.Copy(SCANNERS = [s2])
601 s = map(env.get_scanner, suffixes)
602 assert s == [None, None, None, s2, None], s
604 env['SCANNERS'] = [s1]
605 s = map(env.get_scanner, suffixes)
606 assert s == [s1, s1, None, None, None], s
608 env.PrependUnique(SCANNERS = [s2, s1])
609 s = map(env.get_scanner, suffixes)
610 assert s == [s1, s1, None, s2, None], s
612 env.Prepend(SCANNERS = [s3])
613 s = map(env.get_scanner, suffixes)
614 assert s == [s1, s1, None, s3, s3], s
617 """Test setting the external ENV in Environments
620 assert env.Dictionary().has_key('ENV')
622 env = Environment(ENV = { 'PATH' : '/foo:/bar' })
623 assert env.Dictionary('ENV')['PATH'] == '/foo:/bar'
625 def test_ReservedVariables(self):
626 """Test generation of warnings when reserved variable names
627 are set in an environment."""
629 SCons.Warnings.enableWarningClass(SCons.Warnings.ReservedVariableWarning)
630 old = SCons.Warnings.warningAsException(1)
634 for kw in ['TARGET', 'TARGETS', 'SOURCE', 'SOURCES']:
638 except SCons.Warnings.ReservedVariableWarning:
640 assert exc_caught, "Did not catch ReservedVariableWarning for `%s'" % kw
641 assert not env4.has_key(kw), "`%s' variable was incorrectly set" % kw
643 SCons.Warnings.warningAsException(old)
645 def test_IllegalVariables(self):
646 """Test that use of illegal variables raises an exception"""
648 def test_it(var, env=env):
652 except SCons.Errors.UserError:
654 assert exc_caught, "did not catch UserError for '%s'" % var
656 assert env['aaa'] == 1, env['aaa']
661 def test_autogenerate(dict):
662 """Test autogenerating variables in a dictionary."""
665 return SCons.Node.FS.default_fs.Rsearchall(pathlist,
666 clazz=SCons.Node.FS.Dir,
668 cwd=SCons.Node.FS.default_fs.Dir('xx'))
670 env = Environment(LIBS = [ 'foo', 'bar', 'baz' ],
671 LIBLINKPREFIX = 'foo',
672 LIBLINKSUFFIX = 'bar',
674 flags = env.subst_list('$_LIBFLAGS', 1)[0]
675 assert len(flags) == 3, flags
676 assert flags[0] == 'foobar', \
678 assert flags[1] == 'foobar', \
680 assert flags[2] == 'foobazbar', \
683 blat = SCons.Node.FS.default_fs.Dir('blat')
685 env = Environment(CPPPATH = [ 'foo', '$FOO/bar', blat ],
690 flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
691 assert len(flags) == 8, flags
692 assert flags[0] == '$(', \
694 assert flags[1] == os.path.normpath('foo'), \
696 assert flags[2] == os.path.normpath('xx/foobar'), \
698 assert flags[3] == os.path.normpath('foo'), \
700 assert flags[4] == os.path.normpath('xx/baz/bar'), \
702 assert flags[5] == os.path.normpath('foo'), \
704 assert flags[6] == os.path.normpath('blatbar'), \
706 assert flags[7] == '$)', \
709 env = Environment(F77PATH = [ 'foo', '$FOO/bar', blat ],
714 flags = env.subst_list('$_F77INCFLAGS', 1)[0]
715 assert len(flags) == 8, flags
716 assert flags[0] == '$(', \
718 assert flags[1] == os.path.normpath('foo'), \
720 assert flags[2] == os.path.normpath('xx/foobar'), \
722 assert flags[3] == os.path.normpath('foo'), \
724 assert flags[4] == os.path.normpath('xx/baz/bar'), \
726 assert flags[5] == os.path.normpath('foo'), \
728 assert flags[6] == os.path.normpath('blatbar'), \
730 assert flags[7] == '$)', \
733 env = Environment(CPPPATH = '', F77PATH = '', LIBPATH = '',
735 l = env.subst_list('$_CPPINCFLAGS')
736 assert len(l[0]) == 0, l[0]
737 l = env.subst_list('$_F77INCFLAGS')
738 assert len(l[0]) == 0, l[0]
739 l = env.subst_list('$_LIBDIRFLAGS')
740 assert len(l[0]) == 0, l[0]
742 SCons.Node.FS.default_fs.Repository('/rep1')
743 SCons.Node.FS.default_fs.Repository('/rep2')
744 env = Environment(CPPPATH = [ 'foo', '/a/b', '$FOO/bar', blat],
749 flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
750 assert flags[0] == '$(', \
752 assert flags[1] == '-I', \
754 assert flags[2] == os.path.normpath('xx/fooXXX'), \
756 assert flags[3] == '-I', \
758 assert flags[4] == os.path.normpath('/rep1/xx/fooXXX'), \
760 assert flags[5] == '-I', \
762 assert flags[6] == os.path.normpath('/rep2/xx/fooXXX'), \
764 assert flags[7] == '-I', \
766 assert flags[8] == os.path.normpath('/a/bXXX'), \
768 assert flags[9] == '-I', \
770 assert flags[10] == os.path.normpath('xx/baz/barXXX'), \
772 assert flags[11] == '-I', \
774 assert flags[12] == os.path.normpath('/rep1/xx/baz/barXXX'), \
776 assert flags[13] == '-I', \
778 assert flags[14] == os.path.normpath('/rep2/xx/baz/barXXX'), \
780 assert flags[15] == '-I', \
782 assert flags[16] == os.path.normpath('blatXXX'), \
784 assert flags[17] == '$)', \
787 def test_platform(self):
788 """Test specifying a platform callable when instantiating."""
790 def __str__(self): return "TestPlatform"
791 def __call__(self, env): env['XYZZY'] = 777
794 env['SET_TOOL'] = 'initialized'
795 assert env['PLATFORM'] == "TestPlatform"
797 env = Environment(platform = platform(), tools = [tool])
798 assert env['XYZZY'] == 777, env
799 assert env['PLATFORM'] == "TestPlatform"
800 assert env['SET_TOOL'] == "initialized"
802 def test_Default_PLATFORM(self):
803 """Test overriding the default PLATFORM variable"""
805 def __str__(self): return "DefaultTestPlatform"
806 def __call__(self, env): env['XYZZY'] = 888
809 env['SET_TOOL'] = 'abcde'
810 assert env['PLATFORM'] == "DefaultTestPlatform"
812 import SCons.Defaults
813 save = SCons.Defaults.ConstructionEnvironment.copy()
815 import SCons.Defaults
816 SCons.Defaults.ConstructionEnvironment.update({
817 'PLATFORM' : platform(),
819 env = Environment(tools = [tool])
820 assert env['XYZZY'] == 888, env
821 assert env['PLATFORM'] == "DefaultTestPlatform"
822 assert env['SET_TOOL'] == "abcde"
824 SCons.Defaults.ConstructionEnvironment = save
826 def test_tools(self):
827 """Test specifying a tool callable when instantiating."""
833 env['AAA'] = env['XYZ']
836 env = Environment(tools = [t1, t2, t3], XYZ = 'aaa')
837 assert env['TOOL1'] == 111, env['TOOL1']
838 assert env['TOOL2'] == 222, env
839 assert env['AAA'] == 'aaa', env
841 assert env['TOOL4'] == 444, env
843 def test_Default_TOOLS(self):
844 """Test overriding the default TOOLS variable"""
850 env['BBB'] = env['XYZ']
854 import SCons.Defaults
855 save = SCons.Defaults.ConstructionEnvironment.copy()
857 SCons.Defaults.ConstructionEnvironment.update({
858 'TOOLS' : [t5, t6, t7],
860 env = Environment(XYZ = 'bbb')
861 assert env['TOOL5'] == 555, env['TOOL5']
862 assert env['TOOL6'] == 666, env
863 assert env['BBB'] == 'bbb', env
865 assert env['TOOL8'] == 888, env
867 SCons.Defaults.ConstructionEnvironment = save
869 def test_concat(self):
871 e1 = Environment(PRE='pre', SUF='suf', STR='a b', LIST=['a', 'b'])
873 x = s("${_concat('', '', '', __env__)}")
875 x = s("${_concat('', [], '', __env__)}")
877 x = s("${_concat(PRE, '', SUF, __env__)}")
879 x = s("${_concat(PRE, STR, SUF, __env__)}")
880 assert x == 'prea bsuf', x
881 x = s("${_concat(PRE, LIST, SUF, __env__)}")
882 assert x == 'preasuf prebsuf', x
884 def test__update(self):
885 """Test the _update() method"""
886 env = Environment(X = 'x', Y = 'y', Z = 'z')
887 assert env['X'] == 'x', env['X']
888 assert env['Y'] == 'y', env['Y']
889 assert env['Z'] == 'z', env['Z']
890 env._update({'X' : 'xxx',
896 assert env['X'] == 'xxx', env['X']
897 assert env['Y'] == 'y', env['Y']
898 assert env['Z'] == 'zzz', env['Z']
899 assert env['TARGET'] == 't', env['TARGET']
900 assert env['TARGETS'] == 'ttt', env['TARGETS']
901 assert env['SOURCE'] == 's', env['SOURCE']
902 assert env['SOURCES'] == 'sss', env['SOURCES']
906 def test_Append(self):
907 """Test appending to construction variables in an Environment
910 b1 = Environment()['BUILDERS']
911 b2 = Environment()['BUILDERS']
912 assert b1 == b2, diff_dict(b1, b2)
915 UL = UserList.UserList
919 'a2', ['A2'], ['a2', 'A2'],
920 'a3', UL(['A3']), UL(['a', '3', 'A3']),
923 'a6', UL([]), UL(['a', '6']),
924 'a7', [''], ['a7', ''],
925 'a8', UL(['']), UL(['a', '8', '']),
927 ['e1'], 'E1', ['e1', 'E1'],
928 ['e2'], ['E2'], ['e2', 'E2'],
929 ['e3'], UL(['E3']), UL(['e3', 'E3']),
932 ['e6'], UL([]), UL(['e6']),
933 ['e7'], [''], ['e7', ''],
934 ['e8'], UL(['']), UL(['e8', '']),
936 UL(['i1']), 'I1', UL(['i1', 'I', '1']),
937 UL(['i2']), ['I2'], UL(['i2', 'I2']),
938 UL(['i3']), UL(['I3']), UL(['i3', 'I3']),
939 UL(['i4']), '', UL(['i4']),
940 UL(['i5']), [], UL(['i5']),
941 UL(['i6']), UL([]), UL(['i6']),
942 UL(['i7']), [''], UL(['i7', '']),
943 UL(['i8']), UL(['']), UL(['i8', '']),
947 '', UL(['M3']), UL(['M3']),
952 '', UL(['']), UL(['']),
956 [], UL(['N3']), UL(['N3']),
961 [], UL(['']), UL(['']),
963 UL([]), 'O1', ['O', '1'],
964 UL([]), ['O2'], ['O2'],
965 UL([]), UL(['O3']), UL(['O3']),
968 UL([]), UL([]), UL([]),
969 UL([]), [''], UL(['']),
970 UL([]), UL(['']), UL(['']),
972 [''], 'P1', ['', 'P1'],
973 [''], ['P2'], ['', 'P2'],
974 [''], UL(['P3']), UL(['', 'P3']),
977 [''], UL([]), UL(['']),
978 [''], [''], ['', ''],
979 [''], UL(['']), UL(['', '']),
981 UL(['']), 'Q1', ['', 'Q', '1'],
982 UL(['']), ['Q2'], ['', 'Q2'],
983 UL(['']), UL(['Q3']), UL(['', 'Q3']),
984 UL(['']), '', UL(['']),
985 UL(['']), [], UL(['']),
986 UL(['']), UL([]), UL(['']),
987 UL(['']), [''], UL(['', '']),
988 UL(['']), UL(['']), UL(['', '']),
994 input, append, expect = cases[:3]
996 env.Append(XXX = append)
999 if failed == 0: print
1000 print " %s Append %s => %s did not match %s" % \
1001 (repr(input), repr(append), repr(result), repr(expect))
1004 assert failed == 0, "%d Append() cases failed" % failed
1006 env['UL'] = UL(['foo'])
1007 env.Append(UL = 'bar')
1009 assert isinstance(result, UL), repr(result)
1010 assert result == ['foo', 'b', 'a', 'r'], result
1012 env['CLVar'] = CLVar(['foo'])
1013 env.Append(CLVar = 'bar')
1014 result = env['CLVar']
1015 assert isinstance(result, CLVar), repr(result)
1016 assert result == ['foo', 'bar'], result
1019 def __init__(self, name):
1023 def __cmp__(self, other):
1024 raise "should not compare"
1028 env2 = Environment(CCC1 = ['c1'], CCC2 = ccc)
1029 env2.Append(CCC1 = ccc, CCC2 = ['c2'])
1030 assert env2['CCC1'][0] == 'c1', env2['CCC1']
1031 assert env2['CCC1'][1] is ccc, env2['CCC1']
1032 assert env2['CCC2'][0] is ccc, env2['CCC2']
1033 assert env2['CCC2'][1] == 'c2', env2['CCC2']
1035 env3 = Environment(X = {'x1' : 7})
1036 env3.Append(X = {'x1' : 8, 'x2' : 9}, Y = {'y1' : 10})
1037 assert env3['X'] == {'x1': 8, 'x2': 9}, env3['X']
1038 assert env3['Y'] == {'y1': 10}, env3['Y']
1040 env4 = Environment(BUILDERS = {'z1' : 11})
1041 env4.Append(BUILDERS = {'z2' : 12})
1042 assert env4['BUILDERS'] == {'z1' : 11, 'z2' : 12}, env4['BUILDERS']
1043 assert hasattr(env4, 'z1')
1044 assert hasattr(env4, 'z2')
1046 def test_AppendENVPath(self):
1047 """Test appending to an ENV path."""
1048 env1 = Environment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
1049 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
1050 # have to include the pathsep here so that the test will work on UNIX too.
1051 env1.AppendENVPath('PATH',r'C:\dir\num\two', sep = ';')
1052 env1.AppendENVPath('PATH',r'C:\dir\num\three', sep = ';')
1053 env1.AppendENVPath('MYPATH',r'C:\mydir\num\three','MYENV', sep = ';')
1054 env1.AppendENVPath('MYPATH',r'C:\mydir\num\one','MYENV', sep = ';')
1055 assert(env1['ENV']['PATH'] == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
1056 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\two;C:\mydir\num\three;C:\mydir\num\one')
1058 def test_AppendUnique(self):
1059 """Test appending to unique values to construction variables
1061 This strips values that are already present when lists are
1063 env = Environment(AAA1 = 'a1',
1069 env.AppendUnique(AAA1 = 'a1',
1071 AAA3 = ['a3', 'b', 'c', 'a3'],
1074 BBB3 = ['b3', 'c', 'd', 'b3'])
1075 assert env['AAA1'] == 'a1a1', env['AAA1']
1076 assert env['AAA2'] == ['a2'], env['AAA2']
1077 assert env['AAA3'] == ['a3', 'b', 'c'], env['AAA3']
1078 assert env['BBB1'] == ['b1'], env['BBB1']
1079 assert env['BBB2'] == ['b2'], env['BBB2']
1080 assert env['BBB3'] == ['b3', 'c', 'd'], env['BBB3']
1082 def test_Copy(self):
1083 """Test construction Environment copying
1085 Update the copy independently afterwards and check that
1086 the original remains intact (that is, no dangling
1087 references point to objects in the copied environment).
1088 Copy the original with some construction variable
1089 updates and check that the original remains intact
1090 and the copy has the updated values.
1092 env1 = Environment(XXX = 'x', YYY = 'y')
1094 env1copy = env1.Copy()
1095 env2.Replace(YYY = 'yyy')
1097 assert env1 == env1copy
1099 env3 = env1.Copy(XXX = 'x3', ZZZ = 'z3')
1100 assert env3.Dictionary('XXX') == 'x3'
1101 assert env3.Dictionary('YYY') == 'y'
1102 assert env3.Dictionary('ZZZ') == 'z3'
1103 assert env1 == env1copy
1105 assert env1['__env__'] is env1, env1['__env__']
1106 assert env2['__env__'] is env2, env2['__env__']
1107 assert env3['__env__'] is env3, env3['__env__']
1109 # Ensure that lists and dictionaries are
1110 # deep copied, but not instances.
1113 env1 = Environment(XXX=TestA(), YYY = [ 1, 2, 3 ],
1116 env2.Dictionary('YYY').append(4)
1117 env2.Dictionary('ZZZ')[5] = 6
1118 assert env1.Dictionary('XXX') is env2.Dictionary('XXX')
1119 assert 4 in env2.Dictionary('YYY')
1120 assert not 4 in env1.Dictionary('YYY')
1121 assert env2.Dictionary('ZZZ').has_key(5)
1122 assert not env1.Dictionary('ZZZ').has_key(5)
1125 env1 = Environment(BUILDERS = {'b1' : 1})
1126 assert hasattr(env1, 'b1'), "env1.b1 was not set"
1127 assert env1.b1.env == env1, "b1.env doesn't point to env1"
1128 env2 = env1.Copy(BUILDERS = {'b2' : 2})
1129 assert hasattr(env1, 'b1'), "b1 was mistakenly cleared from env1"
1130 assert env1.b1.env == env1, "b1.env was changed"
1131 assert not hasattr(env2, 'b1'), "b1 was not cleared from env2"
1132 assert hasattr(env2, 'b2'), "env2.b2 was not set"
1133 assert env2.b2.env == env2, "b2.env doesn't point to env2"
1135 # Ensure that specifying new tools in a copied environment
1137 def foo(env): env['FOO'] = 1
1138 def bar(env): env['BAR'] = 2
1139 def baz(env): env['BAZ'] = 3
1140 env1 = Environment(tools=[foo])
1142 env3 = env1.Copy(tools=[bar, baz])
1144 assert env1.get('FOO') is 1
1145 assert env1.get('BAR') is None
1146 assert env1.get('BAZ') is None
1147 assert env2.get('FOO') is 1
1148 assert env2.get('BAR') is None
1149 assert env2.get('BAZ') is None
1150 assert env3.get('FOO') is 1
1151 assert env3.get('BAR') is 2
1152 assert env3.get('BAZ') is 3
1154 # Ensure that recursive variable substitution when copying
1155 # environments works properly.
1156 env1 = Environment(CCFLAGS = '-DFOO', XYZ = '-DXYZ')
1157 env2 = env1.Copy(CCFLAGS = '$CCFLAGS -DBAR',
1158 XYZ = ['-DABC', 'x $XYZ y', '-DDEF'])
1159 x = env2.get('CCFLAGS')
1160 assert x == '-DFOO -DBAR', x
1162 assert x == ['-DABC', 'x -DXYZ y', '-DDEF'], x
1164 # Ensure that special properties of a class don't get
1166 env1 = Environment(FLAGS = CLVar('flag1 flag2'))
1167 x = env1.get('FLAGS')
1168 assert x == ['flag1', 'flag2'], x
1170 env2.Append(FLAGS = 'flag3 flag4')
1171 x = env2.get('FLAGS')
1172 assert x == ['flag1', 'flag2', 'flag3', 'flag4'], x
1174 def test_Detect(self):
1175 """Test Detect()ing tools"""
1176 test = TestCmd.TestCmd(workdir = '')
1177 test.subdir('sub1', 'sub2')
1178 sub1 = test.workpath('sub1')
1179 sub2 = test.workpath('sub2')
1181 if sys.platform == 'win32':
1182 test.write(['sub1', 'xxx'], "sub1/xxx\n")
1183 test.write(['sub2', 'xxx'], "sub2/xxx\n")
1185 env = Environment(ENV = { 'PATH' : [sub1, sub2] })
1187 x = env.Detect('xxx.exe')
1190 test.write(['sub2', 'xxx.exe'], "sub2/xxx.exe\n")
1192 env = Environment(ENV = { 'PATH' : [sub1, sub2] })
1194 x = env.Detect('xxx.exe')
1195 assert x == 'xxx.exe', x
1197 test.write(['sub1', 'xxx.exe'], "sub1/xxx.exe\n")
1199 x = env.Detect('xxx.exe')
1200 assert x == 'xxx.exe', x
1203 test.write(['sub1', 'xxx.exe'], "sub1/xxx.exe\n")
1204 test.write(['sub2', 'xxx.exe'], "sub2/xxx.exe\n")
1206 env = Environment(ENV = { 'PATH' : [sub1, sub2] })
1208 x = env.Detect('xxx.exe')
1211 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
1212 os.chmod(sub2_xxx_exe, 0755)
1214 env = Environment(ENV = { 'PATH' : [sub1, sub2] })
1216 x = env.Detect('xxx.exe')
1217 assert x == 'xxx.exe', x
1219 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
1220 os.chmod(sub1_xxx_exe, 0755)
1222 x = env.Detect('xxx.exe')
1223 assert x == 'xxx.exe', x
1225 env = Environment(ENV = { 'PATH' : [] })
1226 x = env.Detect('xxx.exe')
1229 def test_Dictionary(self):
1230 """Test retrieval of known construction variables
1232 Fetch them from the Dictionary and check for well-known
1233 defaults that get inserted.
1235 env = Environment(XXX = 'x', YYY = 'y', ZZZ = 'z')
1236 assert env.Dictionary('XXX') == 'x'
1237 assert env.Dictionary('YYY') == 'y'
1238 assert env.Dictionary('XXX', 'ZZZ') == ['x', 'z']
1239 xxx, zzz = env.Dictionary('XXX', 'ZZZ')
1242 assert env.Dictionary().has_key('BUILDERS')
1243 assert env.Dictionary().has_key('CC')
1244 assert env.Dictionary().has_key('CCFLAGS')
1245 assert env.Dictionary().has_key('ENV')
1247 assert env['XXX'] == 'x'
1249 assert env.Dictionary('XXX') == 'foo'
1251 assert not env.Dictionary().has_key('XXX')
1253 def test_FindIxes(self):
1255 env = Environment(LIBPREFIX='lib',
1262 paths = [os.path.join('dir', 'libfoo.a'),
1263 os.path.join('dir', 'libfoo.so')]
1265 assert paths[0] == env.FindIxes(paths, 'LIBPREFIX', 'LIBSUFFIX')
1266 assert paths[1] == env.FindIxes(paths, 'SHLIBPREFIX', 'SHLIBSUFFIX')
1267 assert None == env.FindIxes(paths, 'PREFIX', 'POST')
1269 paths = ['libfoo.a', 'prefoopost']
1271 assert paths[0] == env.FindIxes(paths, 'LIBPREFIX', 'LIBSUFFIX')
1272 assert None == env.FindIxes(paths, 'SHLIBPREFIX', 'SHLIBSUFFIX')
1273 assert paths[1] == env.FindIxes(paths, 'PREFIX', 'SUFFIX')
1275 def test_Override(self):
1276 "Test overriding construction variables"
1277 env = Environment(ONE=1, TWO=2, THREE=3, FOUR=4)
1278 assert env['ONE'] == 1, env['ONE']
1279 assert env['TWO'] == 2, env['TWO']
1280 assert env['THREE'] == 3, env['THREE']
1281 assert env['FOUR'] == 4, env['FOUR']
1283 env2 = env.Override({'TWO' : '10',
1284 'THREE' :'x $THREE y',
1285 'FOUR' : ['x', '$FOUR', 'y']})
1286 assert env2['ONE'] == 1, env2['ONE']
1287 assert env2['TWO'] == '10', env2['TWO']
1288 assert env2['THREE'] == 'x 3 y', env2['THREE']
1289 assert env2['FOUR'] == ['x', 4, 'y'], env2['FOUR']
1291 assert env['ONE'] == 1, env['ONE']
1292 assert env['TWO'] == 2, env['TWO']
1293 assert env['THREE'] == 3, env['THREE']
1294 assert env['FOUR'] == 4, env['FOUR']
1296 env2.Replace(ONE = "won")
1297 assert env2['ONE'] == "won", env2['ONE']
1298 assert env['ONE'] == 1, env['ONE']
1300 assert env['__env__'] is env, env['__env__']
1301 assert env2['__env__'] is env2, env2['__env__']
1303 def test_ParseConfig(self):
1304 """Test the ParseConfig() method"""
1305 env = Environment(COMMAND='command',
1311 orig_popen = os.popen
1312 def my_popen(command, save_command=save_command):
1313 save_command.append(command)
1316 return "-I/usr/include/fum -Ibar -X\n" + \
1317 "-L/usr/fax -Lfoo -lxxx abc"
1321 libs = env.ParseConfig("fake $COMMAND")
1322 assert save_command == ['fake command'], save_command
1323 assert libs == ['abc'], libs
1324 assert env['CPPPATH'] == ['string', '/usr/include/fum', 'bar'], env['CPPPATH']
1325 assert env['LIBPATH'] == ['list', '/usr/fax', 'foo'], env['LIBPATH']
1326 assert env['LIBS'] == ['xxx'], env['LIBS']
1327 assert env['CCFLAGS'] == ['', '-X'], env['CCFLAGS']
1329 os.popen = orig_popen
1331 def test_Platform(self):
1332 """Test the Platform() method"""
1333 env = Environment(WIN32='win32', NONE='no-such-platform')
1337 env.Platform('does_not_exist')
1338 except SCons.Errors.UserError:
1340 assert exc_caught, "did not catch expected UserError"
1344 env.Platform('$NONE')
1345 except SCons.Errors.UserError:
1347 assert exc_caught, "did not catch expected UserError"
1349 env.Platform('posix')
1350 assert env['OBJSUFFIX'] == '.o', env['OBJSUFFIX']
1352 env.Platform('$WIN32')
1353 assert env['OBJSUFFIX'] == '.obj', env['OBJSUFFIX']
1355 def test_Prepend(self):
1356 """Test prepending to construction variables in an Environment
1359 UL = UserList.UserList
1363 'a2', ['A2'], ['A2', 'a2'],
1364 'a3', UL(['A3']), UL(['A3', 'a', '3']),
1367 'a6', UL([]), UL(['a', '6']),
1368 'a7', [''], ['', 'a7'],
1369 'a8', UL(['']), UL(['', 'a', '8']),
1371 ['e1'], 'E1', ['E1', 'e1'],
1372 ['e2'], ['E2'], ['E2', 'e2'],
1373 ['e3'], UL(['E3']), UL(['E3', 'e3']),
1376 ['e6'], UL([]), UL(['e6']),
1377 ['e7'], [''], ['', 'e7'],
1378 ['e8'], UL(['']), UL(['', 'e8']),
1380 UL(['i1']), 'I1', UL(['I', '1', 'i1']),
1381 UL(['i2']), ['I2'], UL(['I2', 'i2']),
1382 UL(['i3']), UL(['I3']), UL(['I3', 'i3']),
1383 UL(['i4']), '', UL(['i4']),
1384 UL(['i5']), [], UL(['i5']),
1385 UL(['i6']), UL([]), UL(['i6']),
1386 UL(['i7']), [''], UL(['', 'i7']),
1387 UL(['i8']), UL(['']), UL(['', 'i8']),
1391 '', UL(['M3']), UL(['M3']),
1396 '', UL(['']), UL(['']),
1400 [], UL(['N3']), UL(['N3']),
1405 [], UL(['']), UL(['']),
1407 UL([]), 'O1', UL(['O', '1']),
1408 UL([]), ['O2'], UL(['O2']),
1409 UL([]), UL(['O3']), UL(['O3']),
1412 UL([]), UL([]), UL([]),
1413 UL([]), [''], UL(['']),
1414 UL([]), UL(['']), UL(['']),
1416 [''], 'P1', ['P1', ''],
1417 [''], ['P2'], ['P2', ''],
1418 [''], UL(['P3']), UL(['P3', '']),
1421 [''], UL([]), UL(['']),
1422 [''], [''], ['', ''],
1423 [''], UL(['']), UL(['', '']),
1425 UL(['']), 'Q1', UL(['Q', '1', '']),
1426 UL(['']), ['Q2'], UL(['Q2', '']),
1427 UL(['']), UL(['Q3']), UL(['Q3', '']),
1428 UL(['']), '', UL(['']),
1429 UL(['']), [], UL(['']),
1430 UL(['']), UL([]), UL(['']),
1431 UL(['']), [''], UL(['', '']),
1432 UL(['']), UL(['']), UL(['', '']),
1438 input, prepend, expect = cases[:3]
1440 env.Prepend(XXX = prepend)
1442 if result != expect:
1443 if failed == 0: print
1444 print " %s Prepend %s => %s did not match %s" % \
1445 (repr(input), repr(prepend), repr(result), repr(expect))
1448 assert failed == 0, "%d Prepend() cases failed" % failed
1450 env['UL'] = UL(['foo'])
1451 env.Prepend(UL = 'bar')
1453 assert isinstance(result, UL), repr(result)
1454 assert result == ['b', 'a', 'r', 'foo'], result
1456 env['CLVar'] = CLVar(['foo'])
1457 env.Prepend(CLVar = 'bar')
1458 result = env['CLVar']
1459 assert isinstance(result, CLVar), repr(result)
1460 assert result == ['bar', 'foo'], result
1462 env3 = Environment(X = {'x1' : 7})
1463 env3.Prepend(X = {'x1' : 8, 'x2' : 9}, Y = {'y1' : 10})
1464 assert env3['X'] == {'x1': 8, 'x2' : 9}, env3['X']
1465 assert env3['Y'] == {'y1': 10}, env3['Y']
1467 env4 = Environment(BUILDERS = {'z1' : 11})
1468 env4.Prepend(BUILDERS = {'z2' : 12})
1469 assert env4['BUILDERS'] == {'z1' : 11, 'z2' : 12}, env4['BUILDERS']
1470 assert hasattr(env4, 'z1')
1471 assert hasattr(env4, 'z2')
1473 def test_PrependENVPath(self):
1474 """Test prepending to an ENV path."""
1475 env1 = Environment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
1476 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
1477 # have to include the pathsep here so that the test will work on UNIX too.
1478 env1.PrependENVPath('PATH',r'C:\dir\num\two',sep = ';')
1479 env1.PrependENVPath('PATH',r'C:\dir\num\three',sep = ';')
1480 env1.PrependENVPath('MYPATH',r'C:\mydir\num\three','MYENV',sep = ';')
1481 env1.PrependENVPath('MYPATH',r'C:\mydir\num\one','MYENV',sep = ';')
1482 assert(env1['ENV']['PATH'] == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
1483 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
1485 def test_PrependENVPath(self):
1486 """Test prepending to an ENV path."""
1487 env1 = Environment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
1488 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
1489 # have to include the pathsep here so that the test will work on UNIX too.
1490 env1.PrependENVPath('PATH',r'C:\dir\num\two',sep = ';')
1491 env1.PrependENVPath('PATH',r'C:\dir\num\three',sep = ';')
1492 env1.PrependENVPath('MYPATH',r'C:\mydir\num\three','MYENV',sep = ';')
1493 env1.PrependENVPath('MYPATH',r'C:\mydir\num\one','MYENV',sep = ';')
1494 assert(env1['ENV']['PATH'] == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
1495 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
1497 def test_PrependUnique(self):
1498 """Test prepending unique values to construction variables
1500 This strips values that are already present when lists are
1502 env = Environment(AAA1 = 'a1',
1508 env.PrependUnique(AAA1 = 'a1',
1510 AAA3 = ['a3', 'b', 'c', 'a3'],
1513 BBB3 = ['b3', 'b', 'c', 'b3'])
1514 assert env['AAA1'] == 'a1a1', env['AAA1']
1515 assert env['AAA2'] == ['a2'], env['AAA2']
1516 assert env['AAA3'] == ['b', 'c', 'a3'], env['AAA3']
1517 assert env['BBB1'] == ['b1'], env['BBB1']
1518 assert env['BBB2'] == ['b2'], env['BBB2']
1519 assert env['BBB3'] == ['b', 'c', 'b3'], env['BBB3']
1521 def test_Replace(self):
1522 """Test replacing construction variables in an Environment
1524 After creation of the Environment, of course.
1526 env1 = Environment(AAA = 'a', BBB = 'b')
1527 env1.Replace(BBB = 'bbb', CCC = 'ccc')
1529 env2 = Environment(AAA = 'a', BBB = 'bbb', CCC = 'ccc')
1530 assert env1 == env2, diff_env(env1, env2)
1532 env3 = Environment(BUILDERS = {'b1' : 1})
1533 assert hasattr(env3, 'b1'), "b1 was not set"
1534 env3.Replace(BUILDERS = {'b2' : 2})
1535 assert not hasattr(env3, 'b1'), "b1 was not cleared"
1536 assert hasattr(env3, 'b2'), "b2 was not set"
1538 def test_ReplaceIxes(self):
1539 "Test ReplaceIxes()"
1540 env = Environment(LIBPREFIX='lib',
1547 assert 'libfoo.a' == env.ReplaceIxes('libfoo.so',
1548 'SHLIBPREFIX', 'SHLIBSUFFIX',
1549 'LIBPREFIX', 'LIBSUFFIX')
1551 assert os.path.join('dir', 'libfoo.a') == env.ReplaceIxes(os.path.join('dir', 'libfoo.so'),
1552 'SHLIBPREFIX', 'SHLIBSUFFIX',
1553 'LIBPREFIX', 'LIBSUFFIX')
1555 assert 'libfoo.a' == env.ReplaceIxes('prefoopost',
1557 'LIBPREFIX', 'LIBSUFFIX')
1559 def test_Tool(self):
1560 """Test the Tool() method"""
1561 env = Environment(LINK='link', NONE='no-such-tool')
1565 env.Tool('does_not_exist')
1566 except SCons.Errors.UserError:
1568 assert exc_caught, "did not catch expected UserError"
1573 except SCons.Errors.UserError:
1575 assert exc_caught, "did not catch expected UserError"
1577 # Use a non-existent toolpath directory just to make sure we
1578 # can call Tool() with the keyword argument.
1579 env.Tool('cc', toolpath=['/no/such/directory'])
1580 assert env['CC'] == 'cc', env['CC']
1583 assert env['LINK'] == '$SMARTLINK', env['LINK']
1585 def test_WhereIs(self):
1586 """Test the WhereIs() method"""
1587 test = TestCmd.TestCmd(workdir = '')
1589 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
1590 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
1591 sub3_xxx_exe = test.workpath('sub3', 'xxx.exe')
1592 sub4_xxx_exe = test.workpath('sub4', 'xxx.exe')
1594 test.subdir('subdir', 'sub1', 'sub2', 'sub3', 'sub4')
1596 if sys.platform != 'win32':
1597 test.write(sub1_xxx_exe, "\n")
1599 os.mkdir(sub2_xxx_exe)
1601 test.write(sub3_xxx_exe, "\n")
1602 os.chmod(sub3_xxx_exe, 0777)
1604 test.write(sub4_xxx_exe, "\n")
1605 os.chmod(sub4_xxx_exe, 0777)
1607 env_path = os.environ['PATH']
1609 pathdirs_1234 = [ test.workpath('sub1'),
1610 test.workpath('sub2'),
1611 test.workpath('sub3'),
1612 test.workpath('sub4'),
1613 ] + string.split(env_path, os.pathsep)
1615 pathdirs_1243 = [ test.workpath('sub1'),
1616 test.workpath('sub2'),
1617 test.workpath('sub4'),
1618 test.workpath('sub3'),
1619 ] + string.split(env_path, os.pathsep)
1621 path = string.join(pathdirs_1234, os.pathsep)
1622 env = Environment(ENV = {'PATH' : path})
1623 wi = env.WhereIs('xxx.exe')
1624 assert wi == test.workpath(sub3_xxx_exe), wi
1625 wi = env.WhereIs('xxx.exe', pathdirs_1243)
1626 assert wi == test.workpath(sub4_xxx_exe), wi
1627 wi = env.WhereIs('xxx.exe', string.join(pathdirs_1243, os.pathsep))
1628 assert wi == test.workpath(sub4_xxx_exe), wi
1630 wi = env.WhereIs('xxx.exe', reject = sub3_xxx_exe)
1631 assert wi == test.workpath(sub4_xxx_exe), wi
1632 wi = env.WhereIs('xxx.exe', pathdirs_1243, reject = sub3_xxx_exe)
1633 assert wi == test.workpath(sub4_xxx_exe), wi
1635 path = string.join(pathdirs_1243, os.pathsep)
1636 env = Environment(ENV = {'PATH' : path})
1637 wi = env.WhereIs('xxx.exe')
1638 assert wi == test.workpath(sub4_xxx_exe), wi
1639 wi = env.WhereIs('xxx.exe', pathdirs_1234)
1640 assert wi == test.workpath(sub3_xxx_exe), wi
1641 wi = env.WhereIs('xxx.exe', string.join(pathdirs_1234, os.pathsep))
1642 assert wi == test.workpath(sub3_xxx_exe), wi
1644 if sys.platform == 'win32':
1645 wi = env.WhereIs('xxx', pathext = '')
1646 assert wi is None, wi
1648 wi = env.WhereIs('xxx', pathext = '.exe')
1649 assert wi == test.workpath(sub4_xxx_exe), wi
1651 wi = env.WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
1652 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
1654 # Test that we return a normalized path even when
1655 # the path contains forward slashes.
1656 forward_slash = test.workpath('') + '/sub3'
1657 wi = env.WhereIs('xxx', path = forward_slash, pathext = '.EXE')
1658 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
1662 def test_Action(self):
1663 """Test the Action() method"""
1666 env = Environment(FOO = 'xyzzy')
1668 a = env.Action('foo')
1670 assert a.__class__ is SCons.Action.CommandAction, a
1672 a = env.Action('$FOO')
1674 assert a.__class__ is SCons.Action.CommandGeneratorAction, a
1676 a = env.Action(['$FOO', 'foo'])
1678 assert a.__class__ is SCons.Action.ListAction, a
1682 a = env.Action(func)
1684 assert a.__class__ is SCons.Action.FunctionAction, a
1686 def test_AddPostAction(self):
1687 """Test the AddPostAction() method"""
1688 env = Environment(FOO='fff', BAR='bbb')
1690 n = env.AddPostAction('$FOO', lambda x: x)
1691 assert str(n[0]) == 'fff', n[0]
1693 n = env.AddPostAction(['ggg', '$BAR'], lambda x: x)
1694 assert str(n[0]) == 'ggg', n[0]
1695 assert str(n[1]) == 'bbb', n[1]
1697 def test_AddPreAction(self):
1698 """Test the AddPreAction() method"""
1699 env = Environment(FOO='fff', BAR='bbb')
1701 n = env.AddPreAction('$FOO', lambda x: x)
1702 assert str(n[0]) == 'fff', n[0]
1704 n = env.AddPreAction(['ggg', '$BAR'], lambda x: x)
1705 assert str(n[0]) == 'ggg', n[0]
1706 assert str(n[1]) == 'bbb', n[1]
1708 def test_Alias(self):
1709 """Test the Alias() method"""
1710 env = Environment(FOO='kkk', BAR='lll', EA='export_alias')
1712 tgt = env.Alias('new_alias')
1713 assert str(tgt) == 'new_alias', tgt
1714 assert tgt.sources == [], tgt.sources
1716 tgt = env.Alias('None_alias', None)
1717 assert str(tgt) == 'None_alias', tgt
1718 assert tgt.sources == [], tgt.sources
1720 tgt = env.Alias('empty_list', [])
1721 assert str(tgt) == 'empty_list', tgt
1722 assert tgt.sources == [], tgt.sources
1724 tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ])
1725 assert str(tgt) == 'export_alias', tgt
1726 assert len(tgt.sources) == 2, map(str, tgt.sources)
1727 assert str(tgt.sources[0]) == 'asrc1', map(str, tgt.sources)
1728 assert str(tgt.sources[1]) == 'kkk', map(str, tgt.sources)
1730 n = env.Alias(tgt, source = ['$BAR', 'asrc4'])
1732 assert len(tgt.sources) == 4, map(str, tgt.sources)
1733 assert str(tgt.sources[2]) == 'lll', map(str, tgt.sources)
1734 assert str(tgt.sources[3]) == 'asrc4', map(str, tgt.sources)
1736 n = env.Alias('$EA', 'asrc5')
1738 assert len(tgt.sources) == 5, map(str, tgt.sources)
1739 assert str(tgt.sources[4]) == 'asrc5', map(str, tgt.sources)
1741 t1, t2 = env.Alias(['t1', 't2'], ['asrc6', 'asrc7'])
1742 assert str(t1) == 't1', t1
1743 assert str(t2) == 't2', t2
1744 assert len(t1.sources) == 2, map(str, t1.sources)
1745 assert str(t1.sources[0]) == 'asrc6', map(str, t1.sources)
1746 assert str(t1.sources[1]) == 'asrc7', map(str, t1.sources)
1747 assert len(t2.sources) == 2, map(str, t2.sources)
1748 assert str(t2.sources[0]) == 'asrc6', map(str, t2.sources)
1749 assert str(t2.sources[1]) == 'asrc7', map(str, t2.sources)
1751 def test_AlwaysBuild(self):
1752 """Test the AlwaysBuild() method"""
1753 env = Environment(FOO='fff', BAR='bbb')
1754 t = env.AlwaysBuild('a', 'b$FOO', ['c', 'd'], '$BAR')
1755 assert t[0].__class__.__name__ == 'File'
1756 assert t[0].path == 'a'
1757 assert t[0].always_build
1758 assert t[1].__class__.__name__ == 'File'
1759 assert t[1].path == 'bfff'
1760 assert t[1].always_build
1761 assert t[2].__class__.__name__ == 'File'
1762 assert t[2].path == 'c'
1763 assert t[2].always_build
1764 assert t[3].__class__.__name__ == 'File'
1765 assert t[3].path == 'd'
1766 assert t[3].always_build
1767 assert t[4].__class__.__name__ == 'File'
1768 assert t[4].path == 'bbb'
1769 assert t[4].always_build
1771 def test_BuildDir(self):
1772 """Test the BuildDir() method"""
1774 def Dir(self, name):
1776 def BuildDir(self, build_dir, src_dir, duplicate):
1777 self.build_dir = build_dir
1778 self.src_dir = src_dir
1779 self.duplicate = duplicate
1781 env = Environment(FOO = 'fff', BAR = 'bbb')
1784 env.BuildDir('build', 'src')
1785 assert env.fs.build_dir == 'build', env.fs.build_dir
1786 assert env.fs.src_dir == 'src', env.fs.src_dir
1787 assert env.fs.duplicate == 1, env.fs.duplicate
1789 env.BuildDir('build${FOO}', '${BAR}src', 0)
1790 assert env.fs.build_dir == 'buildfff', env.fs.build_dir
1791 assert env.fs.src_dir == 'bbbsrc', env.fs.src_dir
1792 assert env.fs.duplicate == 0, env.fs.duplicate
1794 def test_Builder(self):
1795 """Test the Builder() method"""
1796 env = Environment(FOO = 'xyzzy')
1798 b = env.Builder(action = 'foo')
1799 assert not b is None, b
1801 b = env.Builder(action = '$FOO')
1802 assert not b is None, b
1804 b = env.Builder(action = ['$FOO', 'foo'])
1805 assert not b is None, b
1809 b = env.Builder(action = func)
1810 assert not b is None, b
1811 b = env.Builder(generator = func)
1812 assert not b is None, b
1814 def test_CacheDir(self):
1815 """Test the CacheDir() method"""
1817 def CacheDir(self, path):
1820 env = Environment(CD = 'CacheDir')
1824 assert env.fs.CD == 'foo', env.fs.CD
1827 assert env.fs.CD == 'CacheDir', env.fs.CD
1829 def test_Clean(self):
1830 """Test the Clean() method"""
1831 env = Environment(FOO = 'fff', BAR = 'bbb')
1833 CT = SCons.Environment.CleanTargets
1835 foo = env.arg2nodes('foo')[0]
1836 fff = env.arg2nodes('fff')[0]
1838 t = env.Clean('foo', 'aaa')
1839 l = map(str, CT[foo])
1840 assert l == ['aaa'], l
1842 t = env.Clean(foo, ['$BAR', 'ccc'])
1843 l = map(str, CT[foo])
1844 assert l == ['aaa', 'bbb', 'ccc'], l
1846 eee = env.arg2nodes('eee')[0]
1848 t = env.Clean('$FOO', 'ddd')
1849 l = map(str, CT[fff])
1850 assert l == ['ddd'], l
1851 t = env.Clean(fff, [eee, 'fff'])
1852 l = map(str, CT[fff])
1853 assert l == ['ddd', 'eee', 'fff'], l
1855 def test_Command(self):
1856 """Test the Command() method."""
1858 t = env.Command(target='foo.out', source=['foo1.in', 'foo2.in'],
1859 action='buildfoo $target $source')
1860 assert not t.builder is None
1861 assert t.builder.action.__class__.__name__ == 'CommandAction'
1862 assert t.builder.action.cmd_list == 'buildfoo $target $source'
1863 assert 'foo1.in' in map(lambda x: x.path, t.sources)
1864 assert 'foo2.in' in map(lambda x: x.path, t.sources)
1866 sub = SCons.Node.FS.default_fs.Dir('sub')
1867 t = env.Command(target='bar.out', source='sub',
1868 action='buildbar $target $source')
1869 assert 'sub' in map(lambda x: x.path, t.sources)
1871 def testFunc(env, target, source):
1872 assert str(target[0]) == 'foo.out'
1873 assert 'foo1.in' in map(str, source) and 'foo2.in' in map(str, source), map(str, source)
1875 t = env.Command(target='foo.out', source=['foo1.in','foo2.in'],
1877 assert not t.builder is None
1878 assert t.builder.action.__class__.__name__ == 'FunctionAction'
1880 assert 'foo1.in' in map(lambda x: x.path, t.sources)
1881 assert 'foo2.in' in map(lambda x: x.path, t.sources)
1884 def test2(baz, x=x):
1886 env = Environment(TEST2 = test2)
1887 t = env.Command(target='baz.out', source='baz.in',
1888 action='${TEST2(XYZ)}',
1890 assert not t.builder is None
1892 assert x[0] == 'magic word', x
1894 def test_Configure(self):
1895 """Test the Configure() method"""
1896 # Configure() will write to a local temporary file.
1897 test = TestCmd.TestCmd(workdir = '')
1899 # Configure() will test, if we are reading a SConscript file
1900 import SCons.Script.SConscript
1901 SCons.Script.SConscript.sconscript_reading = 1
1904 os.chdir(test.workpath())
1906 env = Environment(FOO = 'xyzzy')
1912 assert not c is None, c
1915 c = env.Configure(custom_tests = {'foo' : func, '$FOO' : func})
1916 assert not c is None, c
1917 assert hasattr(c, 'foo')
1918 assert hasattr(c, 'xyzzy')
1923 def test_Depends(self):
1924 """Test the explicit Depends method."""
1925 env = Environment(FOO = 'xxx', BAR='yyy')
1930 t = env.Depends(target='EnvironmentTest.py', dependency='Environment.py')
1931 assert t.__class__.__name__ == 'Entry', t.__class__.__name__
1932 assert t.path == 'EnvironmentTest.py'
1933 assert len(t.depends) == 1
1935 assert d.__class__.__name__ == 'Entry', d.__class__.__name__
1936 assert d.path == 'Environment.py'
1938 t = env.Depends(target='${FOO}.py', dependency='${BAR}.py')
1939 assert t.__class__.__name__ == 'File', t.__class__.__name__
1940 assert t.path == 'xxx.py'
1941 assert len(t.depends) == 1
1943 assert d.__class__.__name__ == 'File', d.__class__.__name__
1944 assert d.path == 'yyy.py'
1946 t = env.Depends(target='dir1', dependency='dir2')
1947 assert t.__class__.__name__ == 'Dir', t.__class__.__name__
1948 assert t.path == 'dir1'
1949 assert len(t.depends) == 1
1951 assert d.__class__.__name__ == 'Dir', d.__class__.__name__
1952 assert d.path == 'dir2'
1955 """Test the Dir() method"""
1957 def Dir(self, name):
1958 return 'Dir(%s)' % name
1960 env = Environment(FOO = 'foodir', BAR = 'bardir')
1964 assert d == 'Dir(d)', d
1967 assert d == 'Dir(foodir)', d
1969 d = env.Dir('${BAR}_$BAR')
1970 assert d == 'Dir(bardir_bardir)', d
1972 def test_Environment(self):
1973 """Test the Environment() method"""
1974 env = Environment(FOO = 'xxx', BAR = 'yyy')
1976 e2 = env.Environment(X = '$FOO', Y = '$BAR')
1977 assert e2['X'] == 'xxx', e2['X']
1978 assert e2['Y'] == 'yyy', e2['Y']
1980 def test_Execute(self):
1981 """Test the Execute() method"""
1984 def __init__(self, *args, **kw):
1986 def __call__(self, target, source, env):
1987 return "%s executed" % self.args
1990 env.Action = MyAction
1992 result = env.Execute("foo")
1993 assert result == "foo executed", result
1995 def test_File(self):
1996 """Test the File() method"""
1998 def File(self, name):
1999 return 'File(%s)' % name
2001 env = Environment(FOO = 'foofile', BAR = 'barfile')
2005 assert f == 'File(f)', f
2007 f = env.File('$FOO')
2008 assert f == 'File(foofile)', f
2010 f = env.File('${BAR}_$BAR')
2011 assert f == 'File(barfile_barfile)', f
2013 def test_FindFile(self):
2014 """Test the FindFile() method"""
2015 env = Environment(FOO = 'fff', BAR = 'bbb')
2017 r = env.FindFile('foo', ['no_such_directory'])
2022 def test_GetBuildPath(self):
2023 """Test the GetBuildPath() method."""
2024 env = Environment(MAGIC = 'xyzzy')
2026 p = env.GetBuildPath('foo')
2027 assert p == 'foo', p
2029 p = env.GetBuildPath('$MAGIC')
2030 assert p == 'xyzzy', p
2032 def test_Ignore(self):
2033 """Test the explicit Ignore method."""
2034 env = Environment(FOO='yyy', BAR='zzz')
2040 t = env.Ignore(target='targ.py', dependency='dep.py')
2041 assert t.__class__.__name__ == 'Entry', t.__class__.__name__
2042 assert t.path == 'targ.py'
2043 assert len(t.ignore) == 1
2045 assert i.__class__.__name__ == 'Entry', i.__class__.__name__
2046 assert i.path == 'dep.py'
2048 t = env.Ignore(target='$FOO$BAR', dependency='$BAR$FOO')
2049 assert t.__class__.__name__ == 'File', t.__class__.__name__
2050 assert t.path == 'yyyzzz'
2051 assert len(t.ignore) == 1
2053 assert i.__class__.__name__ == 'File', i.__class__.__name__
2054 assert i.path == 'zzzyyy'
2056 t = env.Ignore(target='dir1', dependency='dir2')
2057 assert t.__class__.__name__ == 'Dir', t.__class__.__name__
2058 assert t.path == 'dir1'
2059 assert len(t.ignore) == 1
2061 assert i.__class__.__name__ == 'Dir', i.__class__.__name__
2062 assert i.path == 'dir2'
2064 def test_Install(self):
2065 """Test the Install method"""
2066 env = Environment(FOO='iii', BAR='jjj')
2068 tgt = env.Install('export', [ 'build/foo1', 'build/foo2' ])
2069 paths = map(str, tgt)
2071 expect = map(os.path.normpath, [ 'export/foo1', 'export/foo2' ])
2072 assert paths == expect, paths
2074 assert tnode.builder == InstallBuilder
2076 tgt = env.Install('$FOO', [ 'build/${BAR}1', 'build/${BAR}2' ])
2077 paths = map(str, tgt)
2079 expect = map(os.path.normpath, [ 'iii/jjj1', 'iii/jjj2' ])
2080 assert paths == expect, paths
2082 assert tnode.builder == InstallBuilder
2086 tgt = env.Install('export', 'export')
2087 except SCons.Errors.UserError, e:
2089 assert exc_caught, "UserError should be thrown when Install() target is not a file."
2090 match = str(e) == "Source `export' of Install() is not a file. Install() source must be one or more files."
2095 tgt = env.Install('export', ['export', 'build/foo1'])
2096 except SCons.Errors.UserError, e:
2098 assert exc_caught, "UserError should be thrown when Install() target containins non-files."
2099 match = str(e) == "Source `['export', 'build/foo1']' of Install() contains one or more non-files. Install() source must be one or more files."
2104 tgt = env.Install('export/foo1', 'build/foo1')
2105 except SCons.Errors.UserError, e:
2107 assert exc_caught, "UserError should be thrown reversing the order of Install() targets."
2108 match = str(e) == "Target `export/foo1' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?"
2111 def test_InstallAs(self):
2112 """Test the InstallAs method"""
2113 env = Environment(FOO='iii', BAR='jjj')
2115 tgt = env.InstallAs(target=string.split('foo1 foo2'),
2116 source=string.split('bar1 bar2'))
2117 assert len(tgt) == 2, len(tgt)
2118 paths = map(lambda x: str(x.sources[0]), tgt)
2120 expect = map(os.path.normpath, [ 'bar1', 'bar2' ])
2121 assert paths == expect, paths
2123 assert tnode.builder == InstallBuilder
2125 tgt = env.InstallAs(target='${FOO}.t', source='${BAR}.s')
2126 assert tgt.path == 'iii.t'
2127 assert tgt.sources[0].path == 'jjj.s'
2128 assert tgt.builder == InstallBuilder
2130 def test_Literal(self):
2131 """Test the Literal() method"""
2132 env = Environment(FOO='fff', BAR='bbb')
2133 list = env.subst_list([env.Literal('$FOO'), '$BAR'])[0]
2134 assert list == ['$FOO', 'bbb'], list
2135 list = env.subst_list(['$FOO', env.Literal('$BAR')])[0]
2136 assert list == ['fff', '$BAR'], list
2138 def test_Local(self):
2139 """Test the Local() method."""
2140 env = Environment(FOO='lll')
2142 l = env.Local(env.fs.File('fff'))
2143 assert str(l[0]) == 'fff', l[0]
2145 l = env.Local('ggg', '$FOO')
2146 assert str(l[0]) == 'ggg', l[0]
2147 assert str(l[1]) == 'lll', l[1]
2149 def test_Precious(self):
2150 """Test the Precious() method"""
2151 env = Environment(FOO='ggg', BAR='hhh')
2154 t = env.Precious('p_a', 'p_${BAR}b', ['p_c', 'p_d'], 'p_$FOO')
2156 assert t[0].__class__.__name__ == 'Entry', t[0].__class__.__name__
2157 assert t[0].path == 'p_a'
2158 assert t[0].precious
2159 assert t[1].__class__.__name__ == 'Dir', t[1].__class__.__name__
2160 assert t[1].path == 'p_hhhb'
2161 assert t[1].precious
2162 assert t[2].__class__.__name__ == 'Entry', t[2].__class__.__name__
2163 assert t[2].path == 'p_c'
2164 assert t[2].precious
2165 assert t[3].__class__.__name__ == 'File', t[3].__class__.__name__
2166 assert t[3].path == 'p_d'
2167 assert t[3].precious
2168 assert t[4].__class__.__name__ == 'Entry', t[4].__class__.__name__
2169 assert t[4].path == 'p_ggg'
2170 assert t[4].precious
2172 def test_Repository(self):
2173 """Test the Repository() method."""
2177 def Repository(self, *dirs):
2178 self.list.extend(list(dirs))
2179 def Dir(self, name):
2181 env = Environment(FOO='rrr', BAR='sss')
2183 env.Repository('/tmp/foo')
2184 env.Repository('/tmp/$FOO', '/tmp/$BAR/foo')
2185 expect = ['/tmp/foo', '/tmp/rrr', '/tmp/sss/foo']
2186 assert env.fs.list == expect, env.fs.list
2188 def test_Scanner(self):
2189 """Test the Scanner() method"""
2190 def scan(node, env, target, arg):
2193 env = Environment(FOO = scan)
2195 s = env.Scanner('foo')
2196 assert not s is None, s
2198 s = env.Scanner(function = 'foo')
2199 assert not s is None, s
2202 s = env.Scanner('$FOO')
2203 assert not s is None, s
2205 s = env.Scanner(function = '$FOO')
2206 assert not s is None, s
2208 def test_SConsignFile(self):
2209 """Test the SConsignFile() method"""
2213 SConstruct_dir = os.sep + 'dir'
2215 env = Environment(FOO = 'SConsign',
2216 BAR = os.path.join(os.sep, 'File'))
2222 def capture(name, dbm_module, fnames=fnames, dbms=dbms):
2224 dbms.append(dbm_module)
2226 save_Sig_SConsignFile = SCons.Sig.SConsignFile
2227 SCons.Sig.SConsignFile = capture
2229 env.SConsignFile('foo')
2230 assert fnames[0] == os.path.join(os.sep, 'dir', 'foo'), fnames
2231 assert dbms[0] == None, dbms
2233 env.SConsignFile('$FOO')
2234 assert fnames[1] == os.path.join(os.sep, 'dir', 'SConsign'), fnames
2235 assert dbms[1] == None, dbms
2237 env.SConsignFile('/$FOO')
2238 assert fnames[2] == '/SConsign', fnames
2239 assert dbms[2] == None, dbms
2241 env.SConsignFile('$BAR', 'x')
2242 assert fnames[3] == os.path.join(os.sep, 'File'), fnames
2243 assert dbms[3] == 'x', dbms
2245 env.SConsignFile('__$BAR', 7)
2246 assert fnames[4] == os.path.join(os.sep, 'dir', '__', 'File'), fnames
2247 assert dbms[4] == 7, dbms
2249 SCons.Sig.SConsignFile = save_Sig_SConsignFile
2251 def test_SideEffect(self):
2252 """Test the SideEffect() method"""
2253 env = Environment(LIB='lll', FOO='fff', BAR='bbb')
2254 env.File('mylll.pdb')
2255 env.Dir('mymmm.pdb')
2257 foo = env.Object('foo.obj', 'foo.cpp')
2258 bar = env.Object('bar.obj', 'bar.cpp')
2259 s = env.SideEffect('mylib.pdb', ['foo.obj', 'bar.obj'])
2260 assert s.__class__.__name__ == 'Entry', s.__class__.__name__
2261 assert s.path == 'mylib.pdb'
2262 assert s.side_effect
2263 assert foo.side_effects == [s]
2264 assert bar.side_effects == [s]
2265 assert s.depends_on([bar])
2266 assert s.depends_on([foo])
2268 fff = env.Object('fff.obj', 'fff.cpp')
2269 bbb = env.Object('bbb.obj', 'bbb.cpp')
2270 s = env.SideEffect('my${LIB}.pdb', ['${FOO}.obj', '${BAR}.obj'])
2271 assert s.__class__.__name__ == 'File', s.__class__.__name__
2272 assert s.path == 'mylll.pdb'
2273 assert s.side_effect
2274 assert fff.side_effects == [s], fff.side_effects
2275 assert bbb.side_effects == [s], bbb.side_effects
2276 assert s.depends_on([bbb])
2277 assert s.depends_on([fff])
2279 ggg = env.Object('ggg.obj', 'ggg.cpp')
2280 ccc = env.Object('ccc.obj', 'ccc.cpp')
2281 s = env.SideEffect('mymmm.pdb', ['ggg.obj', 'ccc.obj'])
2282 assert s.__class__.__name__ == 'Dir', s.__class__.__name__
2283 assert s.path == 'mymmm.pdb'
2284 assert s.side_effect
2285 assert ggg.side_effects == [s], ggg.side_effects
2286 assert ccc.side_effects == [s], ccc.side_effects
2287 assert s.depends_on([ccc])
2288 assert s.depends_on([ggg])
2290 def test_SourceCode(self):
2291 """Test the SourceCode() method."""
2292 env = Environment(FOO='mmm', BAR='nnn')
2293 e = env.SourceCode('foo', None)
2294 assert e.path == 'foo'
2299 e = env.SourceCode(e, b)
2300 assert e.path == 'foo'
2304 e = env.SourceCode('$BAR$FOO', None)
2305 assert e.path == 'nnnmmm'
2309 def test_SourceSignatures(type):
2310 """Test the SourceSignatures() method"""
2311 env = Environment(M = 'MD5', T = 'timestamp')
2315 env.SourceSignatures('invalid_type')
2316 except SCons.Errors.UserError:
2318 assert exc_caught, "did not catch expected UserError"
2319 assert not hasattr(env, '_calc_module')
2321 env.SourceSignatures('MD5')
2322 m = env._calc_module
2324 env.SourceSignatures('$M')
2325 assert env._calc_module is m
2327 env.SourceSignatures('timestamp')
2328 t = env._calc_module
2330 env.SourceSignatures('$T')
2331 assert env._calc_module is t
2333 def test_Split(self):
2334 """Test the Split() method"""
2335 env = Environment(FOO='fff', BAR='bbb')
2336 s = env.Split("foo bar")
2337 assert s == ["foo", "bar"], s
2338 s = env.Split("$FOO bar")
2339 assert s == ["fff", "bar"], s
2340 s = env.Split(["foo", "bar"])
2341 assert s == ["foo", "bar"], s
2342 s = env.Split(["foo", "${BAR}-bbb"])
2343 assert s == ["foo", "bbb-bbb"], s
2344 s = env.Split("foo")
2345 assert s == ["foo"], s
2346 s = env.Split("$FOO$BAR")
2347 assert s == ["fffbbb"], s
2349 def test_TargetSignatures(type):
2350 """Test the TargetSignatures() method"""
2351 env = Environment(B = 'build', C = 'content')
2355 env.TargetSignatures('invalid_type')
2356 except SCons.Errors.UserError:
2358 assert exc_caught, "did not catch expected UserError"
2359 assert not hasattr(env, '_build_signature')
2361 env.TargetSignatures('build')
2362 assert env._build_signature == 1, env._build_signature
2364 env.TargetSignatures('content')
2365 assert env._build_signature == 0, env._build_signature
2367 env.TargetSignatures('$B')
2368 assert env._build_signature == 1, env._build_signature
2370 env.TargetSignatures('$C')
2371 assert env._build_signature == 0, env._build_signature
2373 def test_Value(self):
2374 """Test creating a Value() object
2378 assert v1.value == 'a', v1.value
2381 v2 = env.Value(value2)
2382 assert v2.value == value2, v2.value
2383 assert v2.value is value2, v2.value
2386 assert v1.value == v2.value
2390 def test_Environment_global_variable(type):
2391 """Test setting Environment variable to an Environment.Base subclass"""
2392 class MyEnv(SCons.Environment.Base):
2393 def xxx(self, string):
2394 return self.subst(string)
2396 SCons.Environment.Environment = MyEnv
2398 env = SCons.Environment.Environment(FOO = 'foo')
2400 f = env.subst('$FOO')
2401 assert f == 'foo', f
2404 assert f == 'foo', f
2406 def test_bad_keywords(type):
2407 """Test trying to use reserved keywords in an Environment"""
2408 reserved = ['TARGETS','SOURCES', 'SOURCE','TARGET']
2411 env = SCons.Environment.Environment(TARGETS = 'targets',
2412 SOURCES = 'sources',
2416 added.append('INIT')
2418 assert not env.has_key(x), env[x]
2420 assert env.has_key(x), \
2421 '%s is not reserved, but got omitted; see Environment.construction_var_name_ok'%x
2423 env.Append(TARGETS = 'targets',
2424 SOURCES = 'sources',
2428 added.append('APPEND')
2430 assert not env.has_key(x), env[x]
2432 assert env.has_key(x), \
2433 '%s is not reserved, but got omitted; see Environment.construction_var_name_ok'%x
2435 env.AppendUnique(TARGETS = 'targets',
2436 SOURCES = 'sources',
2439 APPENDUNIQUE = 'appendunique')
2440 added.append('APPENDUNIQUE')
2442 assert not env.has_key(x), env[x]
2444 assert env.has_key(x), \
2445 '%s is not reserved, but got omitted; see Environment.construction_var_name_ok'%x
2447 env.Prepend(TARGETS = 'targets',
2448 SOURCES = 'sources',
2451 PREPEND = 'prepend')
2452 added.append('PREPEND')
2454 assert not env.has_key(x), env[x]
2456 assert env.has_key(x), \
2457 '%s is not reserved, but got omitted; see Environment.construction_var_name_ok'%x
2459 env.Prepend(TARGETS = 'targets',
2460 SOURCES = 'sources',
2463 PREPENDUNIQUE = 'prependunique')
2464 added.append('PREPENDUNIQUE')
2466 assert not env.has_key(x), env[x]
2468 assert env.has_key(x), \
2469 '%s is not reserved, but got omitted; see Environment.construction_var_name_ok'%x
2471 env.Replace(TARGETS = 'targets',
2472 SOURCES = 'sources',
2475 REPLACE = 'replace')
2476 added.append('REPLACE')
2478 assert not env.has_key(x), env[x]
2480 assert env.has_key(x), \
2481 '%s is not reserved, but got omitted; see Environment.construction_var_name_ok'%x
2483 copy = env.Copy(TARGETS = 'targets',
2484 SOURCES = 'sources',
2489 assert not copy.has_key(x), env[x]
2490 for x in added + ['COPY']:
2491 assert copy.has_key(x), \
2492 '%s is not reserved, but got omitted; see Environment.construction_var_name_ok'%x
2494 over = env.Override({'TARGETS' : 'targets',
2495 'SOURCES' : 'sources',
2496 'SOURCE' : 'source',
2497 'TARGET' : 'target',
2498 'OVERRIDE' : 'override'})
2500 assert not over.has_key(x), over[x]
2501 for x in added + ['OVERRIDE']:
2502 assert over.has_key(x), \
2503 '%s is not reserved, but got omitted; see Environment.construction_var_name_ok'%x
2507 class NoSubstitutionProxyTestCase(unittest.TestCase):
2509 def test___init__(self):
2510 """Test NoSubstitutionProxy initialization"""
2511 env = Environment(XXX = 'x', YYY = 'y')
2512 assert env['XXX'] == 'x', env['XXX']
2513 assert env['YYY'] == 'y', env['YYY']
2515 proxy = NoSubstitutionProxy(env)
2516 assert proxy['XXX'] == 'x', proxy['XXX']
2517 assert proxy['YYY'] == 'y', proxy['YYY']
2519 def test_attributes(self):
2520 """Test getting and setting NoSubstitutionProxy attributes"""
2522 setattr(env, 'env_attr', 'value1')
2524 proxy = NoSubstitutionProxy(env)
2525 setattr(proxy, 'proxy_attr', 'value2')
2527 x = getattr(env, 'env_attr')
2528 assert x == 'value1', x
2529 x = getattr(proxy, 'env_attr')
2530 assert x == 'value1', x
2532 x = getattr(env, 'proxy_attr')
2533 assert x == 'value2', x
2534 x = getattr(proxy, 'proxy_attr')
2535 assert x == 'value2', x
2537 def test_subst(self):
2538 """Test the NoSubstitutionProxy.subst() method"""
2539 env = Environment(XXX = 'x', YYY = 'y')
2540 assert env['XXX'] == 'x', env['XXX']
2541 assert env['YYY'] == 'y', env['YYY']
2543 proxy = NoSubstitutionProxy(env)
2544 assert proxy['XXX'] == 'x', proxy['XXX']
2545 assert proxy['YYY'] == 'y', proxy['YYY']
2547 x = env.subst('$XXX')
2549 x = proxy.subst('$XXX')
2550 assert x == '$XXX', x
2552 x = proxy.subst('$YYY', raw=7, target=None, source=None,
2553 dict=None, conv=None,
2554 extra_meaningless_keyword_argument=None)
2555 assert x == '$YYY', x
2557 def test_subst_kw(self):
2558 """Test the NoSubstitutionProxy.subst_kw() method"""
2559 env = Environment(XXX = 'x', YYY = 'y')
2560 assert env['XXX'] == 'x', env['XXX']
2561 assert env['YYY'] == 'y', env['YYY']
2563 proxy = NoSubstitutionProxy(env)
2564 assert proxy['XXX'] == 'x', proxy['XXX']
2565 assert proxy['YYY'] == 'y', proxy['YYY']
2567 x = env.subst_kw({'$XXX':'$YYY'})
2568 assert x == {'x':'y'}, x
2569 x = proxy.subst_kw({'$XXX':'$YYY'})
2570 assert x == {'$XXX':'$YYY'}, x
2572 def test_subst_list(self):
2573 """Test the NoSubstitutionProxy.subst_list() method"""
2574 env = Environment(XXX = 'x', YYY = 'y')
2575 assert env['XXX'] == 'x', env['XXX']
2576 assert env['YYY'] == 'y', env['YYY']
2578 proxy = NoSubstitutionProxy(env)
2579 assert proxy['XXX'] == 'x', proxy['XXX']
2580 assert proxy['YYY'] == 'y', proxy['YYY']
2582 x = env.subst_list('$XXX')
2583 assert x == [['x']], x
2584 x = proxy.subst_list('$XXX')
2587 x = proxy.subst_list('$YYY', raw=0, target=None, source=None,
2588 dict=None, conv=None)
2591 def test_subst_target_source(self):
2592 """Test the NoSubstitutionProxy.subst_target_source() method"""
2593 env = Environment(XXX = 'x', YYY = 'y')
2594 assert env['XXX'] == 'x', env['XXX']
2595 assert env['YYY'] == 'y', env['YYY']
2597 proxy = NoSubstitutionProxy(env)
2598 assert proxy['XXX'] == 'x', proxy['XXX']
2599 assert proxy['YYY'] == 'y', proxy['YYY']
2601 args = ('$XXX $TARGET $SOURCE $YYY',)
2602 kw = {'target' : DummyNode('ttt'), 'source' : DummyNode('sss')}
2603 x = apply(env.subst_target_source, args, kw)
2604 assert x == 'x ttt sss y', x
2605 x = apply(proxy.subst_target_source, args, kw)
2606 assert x == ' ttt sss ', x
2610 if __name__ == "__main__":
2611 suite = unittest.TestSuite()
2612 tclasses = [ EnvironmentTestCase,
2613 NoSubstitutionProxyTestCase ]
2614 for tclass in tclasses:
2615 names = unittest.getTestCaseNames(tclass, 'test_')
2616 suite.addTests(map(tclass, names))
2617 if not unittest.TextTestRunner().run(suite).wasSuccessful():