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.Environment import *
35 def diff_env(env1, env2):
39 for k in env1._dict.keys() + env2._dict.keys():
46 if env1[k] != env2[k]:
47 s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n"
48 s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n"
50 s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n"
52 s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n"
57 def diff_dict(d1, d2):
61 for k in d1.keys() + d2.keys():
69 s1 = s1 + " " + repr(k) + " : " + repr(d1[k]) + "\n"
70 s2 = s2 + " " + repr(k) + " : " + repr(d2[k]) + "\n"
72 s1 = s1 + " " + repr(k) + " : " + repr(d1[k]) + "\n"
74 s2 = s2 + " " + repr(k) + " : " + repr(d2[k]) + "\n"
83 """A dummy Builder class for testing purposes. "Building"
84 a target is simply setting a value in the dictionary.
86 def __init__(self, name = None):
89 def __call__(self, env, **kw):
93 def execute(self, target = None, **kw):
102 """A dummy Scanner class for testing purposes. "Scanning"
103 a target is simply setting a value in the dictionary.
105 def __init__(self, name, skeys=[]):
109 def __call__(self, filename):
110 scanned_it[filename] = 1
112 def __cmp__(self, other):
113 return cmp(self.__dict__, other.__dict__)
117 class EnvironmentTestCase(unittest.TestCase):
119 def test___init__(self):
120 """Test construction Environment creation
122 Create two with identical arguments and check that
123 they compare the same.
125 env1 = Environment(XXX = 'x', YYY = 'y')
126 env2 = Environment(XXX = 'x', YYY = 'y')
127 assert env1 == env2, diff_env(env1, env2)
129 assert env1['__env__'] is env1, env1['__env__']
130 assert env2['__env__'] is env2, env2['__env__']
133 """Test the get() method."""
134 env = Environment(aaa = 'AAA')
138 x = env.get('aaa', 'XXX')
142 x = env.get('bbb', 'XXX')
145 def test_arg2nodes(self):
146 """Test the arg2nodes method
150 class X(SCons.Node.Node):
152 def Factory(name, directory = None, create = 1, dict=dict, X=X):
153 if not dict.has_key(name):
155 dict[name].name = name
158 nodes = env.arg2nodes("Util.py UtilTests.py", Factory)
159 assert len(nodes) == 1, nodes
160 assert isinstance(nodes[0], X)
161 assert nodes[0].name == "Util.py UtilTests.py"
164 if hasattr(types, 'UnicodeType'):
166 nodes = env.arg2nodes(u"Util.py UtilTests.py", Factory)
167 assert len(nodes) == 1, nodes
168 assert isinstance(nodes[0], X)
169 assert nodes[0].name == u"Util.py UtilTests.py"
171 exec code in globals(), locals()
173 nodes = env.arg2nodes(["Util.py", "UtilTests.py"], Factory)
174 assert len(nodes) == 2, nodes
175 assert isinstance(nodes[0], X)
176 assert isinstance(nodes[1], X)
177 assert nodes[0].name == "Util.py"
178 assert nodes[1].name == "UtilTests.py"
180 n1 = Factory("Util.py")
181 nodes = env.arg2nodes([n1, "UtilTests.py"], Factory)
182 assert len(nodes) == 2, nodes
183 assert isinstance(nodes[0], X)
184 assert isinstance(nodes[1], X)
185 assert nodes[0].name == "Util.py"
186 assert nodes[1].name == "UtilTests.py"
188 class SConsNode(SCons.Node.Node):
190 nodes = env.arg2nodes(SConsNode())
191 assert len(nodes) == 1, nodes
192 assert isinstance(nodes[0], SConsNode), node
196 nodes = env.arg2nodes(OtherNode())
197 assert len(nodes) == 1, nodes
198 assert isinstance(nodes[0], OtherNode), node
200 def lookup_a(str, F=Factory):
208 def lookup_b(str, F=Factory):
217 env_ll.lookup_list = [lookup_a, lookup_b]
219 nodes = env_ll.arg2nodes(['aaa', 'bbb', 'ccc'], Factory)
220 assert len(nodes) == 3, nodes
222 assert nodes[0].name == 'aaa', nodes[0]
223 assert nodes[0].a == 1, nodes[0]
224 assert not hasattr(nodes[0], 'b'), nodes[0]
226 assert nodes[1].name == 'bbb'
227 assert not hasattr(nodes[1], 'a'), nodes[1]
228 assert nodes[1].b == 1, nodes[1]
230 assert nodes[2].name == 'ccc'
231 assert not hasattr(nodes[2], 'a'), nodes[1]
232 assert not hasattr(nodes[2], 'b'), nodes[1]
234 def lookup_bbbb(str, F=Factory):
242 def lookup_c(str, F=Factory):
250 nodes = env.arg2nodes(['bbbb', 'ccc'], Factory,
251 [lookup_c, lookup_bbbb, lookup_b])
252 assert len(nodes) == 2, nodes
254 assert nodes[0].name == 'bbbb'
255 assert not hasattr(nodes[0], 'a'), nodes[1]
256 assert not hasattr(nodes[0], 'b'), nodes[1]
257 assert nodes[0].bbbb == 1, nodes[1]
258 assert not hasattr(nodes[0], 'c'), nodes[0]
260 assert nodes[1].name == 'ccc'
261 assert not hasattr(nodes[1], 'a'), nodes[1]
262 assert not hasattr(nodes[1], 'b'), nodes[1]
263 assert not hasattr(nodes[1], 'bbbb'), nodes[0]
264 assert nodes[1].c == 1, nodes[1]
266 def test_subst(self):
267 """Test substituting construction variables within strings
269 Check various combinations, including recursive expansion
270 of variables into other variables.
272 env = Environment(AAA = 'a', BBB = 'b')
273 mystr = env.subst("$AAA ${AAA}A $BBBB $BBB")
274 assert mystr == "a aA b", mystr
276 # Changed the tests below to reflect a bug fix in
278 env = Environment(AAA = '$BBB', BBB = 'b', BBBA = 'foo')
279 mystr = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
280 assert mystr == "b bA bB b", mystr
282 env = Environment(AAA = '$BBB', BBB = '$CCC', CCC = 'c')
283 mystr = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
284 assert mystr == "c cA cB c", mystr
287 def __init__(self, name):
293 def get_subst_proxy(self):
301 env = Environment(AAA = 'aaa')
302 s = env.subst('$AAA $TARGET $SOURCES', target=[t1, t2], source=[s1, s2])
303 assert s == "aaa t1 s1 s2", s
304 s = env.subst('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2])
305 assert s == "aaa t1 t2 s1", s
306 s = env.subst('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2], dict={})
309 # Test callables in the Environment
310 def foo(target, source, env, for_signature):
311 assert str(target) == 't', target
312 assert str(source) == 's', source
315 env = Environment(BAR=foo, FOO='baz')
319 subst = env.subst('test $BAR', target=t, source=s)
320 assert subst == 'test baz', subst
322 # Test not calling callables in the Environment
324 # This will take some serious surgery to subst() and
325 # subst_list(), so just leave these tests out until we can
330 env = Environment(BAR=bar, FOO='$BAR')
332 subst = env.subst('$BAR', call=None)
333 assert subst is bar, subst
335 subst = env.subst('$FOO', call=None)
336 assert subst is bar, subst
338 def test_subst_kw(self):
339 """Test substituting construction variables within dictionaries"""
340 env = Environment(AAA = 'a', BBB = 'b')
341 kw = env.subst_kw({'$AAA' : 'aaa', 'bbb' : '$BBB'})
342 assert len(kw) == 2, kw
343 assert kw['a'] == 'aaa', kw['a']
344 assert kw['bbb'] == 'b', kw['bbb']
346 def test_subst_list(self):
347 """Test substituting construction variables in command lists
349 env = Environment(AAA = 'a', BBB = 'b')
350 l = env.subst_list("$AAA ${AAA}A $BBBB $BBB")
351 assert l == [["a", "aA", "b"]], l
353 # Changed the tests below to reflect a bug fix in
355 env = Environment(AAA = '$BBB', BBB = 'b', BBBA = 'foo')
356 l = env.subst_list("$AAA ${AAA}A ${AAA}B $BBB")
357 assert l == [["b", "bA", "bB", "b"]], l
359 env = Environment(AAA = '$BBB', BBB = '$CCC', CCC = 'c')
360 l = env.subst_list("$AAA ${AAA}A ${AAA}B $BBB")
361 assert l == [["c", "cA", "cB", "c"]], mystr
363 env = Environment(AAA = '$BBB', BBB = '$CCC', CCC = [ 'a', 'b\nc' ])
364 lst = env.subst_list([ "$AAA", "B $CCC" ])
365 assert lst == [[ "a", "b"], ["c", "B a", "b"], ["c"]], lst
368 def __init__(self, name):
374 def get_subst_proxy(self):
382 env = Environment(AAA = 'aaa')
383 s = env.subst_list('$AAA $TARGET $SOURCES', target=[t1, t2], source=[s1, s2])
384 assert s == [["aaa", "t1", "s1", "s2"]], s
385 s = env.subst_list('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2])
386 assert s == [["aaa", "t1", "t2", "s1"]], s
387 s = env.subst_list('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2], dict={})
388 assert s == [["aaa"]], s
390 # Test callables in the Environment
391 def foo(target, source, env, for_signature):
392 assert str(target) == 't', target
393 assert str(source) == 's', source
396 env = Environment(BAR=foo, FOO='baz')
400 lst = env.subst_list('test $BAR', target=t, source=s)
401 assert lst == [['test', 'baz']], lst
403 # Test not calling callables in the Environment
405 # This will take some serious surgery to subst() and
406 # subst_list(), so just leave these tests out until we can
411 env = Environment(BAR=bar, FOO='$BAR')
413 subst = env.subst_list('$BAR', call=None)
414 assert subst is bar, subst
416 subst = env.subst_list('$FOO', call=None)
417 assert subst is bar, subst
419 def test_subst_path(self):
420 """Test substituting a path list
423 def __init__(self, val):
426 return self.val + '-proxy'
431 env = Environment(FOO='foo', BAR='bar', PROXY=MyProxy('my1'))
433 r = env.subst_path('$FOO')
434 assert r == ['foo'], r
436 r = env.subst_path(['$FOO', 'xxx', '$BAR'])
437 assert r == ['foo', 'xxx', 'bar'], r
441 r = env.subst_path(['$PROXY', MyProxy('my2'), n])
442 assert r == ['my1-proxy', 'my2-proxy', n], r
444 def test_Builder_calls(self):
445 """Test Builder calls through different environments
453 env.Replace(BUILDERS = { 'builder1' : b1,
456 env.builder1(target = 'out1')
457 assert called_it['target'] == 'out1', called_it
458 assert not called_it.has_key('source')
461 env.builder2(target = 'out2', xyzzy = 1)
462 assert called_it['target'] == 'out2', called_it
463 assert called_it['xyzzy'] == 1, called_it
464 assert not called_it.has_key('source')
467 env.builder1(foo = 'bar')
468 assert called_it['foo'] == 'bar', called_it
469 assert not called_it.has_key('target')
470 assert not called_it.has_key('source')
474 def test_Builder_execs(self):
475 """Test Builder execution through different environments
477 One environment is initialized with a single
478 Builder object, one with a list of a single Builder
479 object, and one with a list of two Builder objects.
488 env3.Replace(BUILDERS = { 'builder1' : b1,
490 env3.builder1.execute(target = 'out1')
491 env3.builder2.execute(target = 'out2')
492 env3.builder1.execute(target = 'out3')
493 assert built_it['out1']
494 assert built_it['out2']
495 assert built_it['out3']
498 assert env4.builder1.env is env4, "builder1.env (%s) == env3 (%s)?" % (env4.builder1.env, env3)
499 assert env4.builder2.env is env4, "builder2.env (%s) == env3 (%s)?" % (env4.builder1.env, env3)
501 # Now test BUILDERS as a dictionary.
503 env5 = Environment(BUILDERS={ 'foo' : b1 })
504 env5['BUILDERS']['bar'] = b2
505 env5.foo.execute(target='out1')
506 env5.bar.execute(target='out2')
507 assert built_it['out1']
508 assert built_it['out2']
512 env6['BUILDERS'] = { 'foo' : b1,
514 env6.foo.execute(target='out1')
515 env6.bar.execute(target='out2')
516 assert built_it['out1']
517 assert built_it['out2']
519 def test_Scanners(self):
520 """Test Scanner execution through different environments
522 One environment is initialized with a single
523 Scanner object, one with a list of a single Scanner
524 object, and one with a list of two Scanner objects.
528 # s1 = Scanner(name = 'scanner1', skeys = [".c", ".cc"])
529 # s2 = Scanner(name = 'scanner2', skeys = [".m4"])
532 # env1 = Environment(SCANNERS = s1)
533 # env1.scanner1(filename = 'out1')
534 # assert scanned_it['out1']
537 # env2 = Environment(SCANNERS = [s1])
538 # env1.scanner1(filename = 'out1')
539 # assert scanned_it['out1']
542 # env3 = Environment()
543 # env3.Replace(SCANNERS = [s1, s2])
544 # env3.scanner1(filename = 'out1')
545 # env3.scanner2(filename = 'out2')
546 # env3.scanner1(filename = 'out3')
547 # assert scanned_it['out1']
548 # assert scanned_it['out2']
549 # assert scanned_it['out3']
551 # s = env3.get_scanner(".c")
553 # s = env3.get_scanner(skey=".m4")
555 # s = env3.get_scanner(".cxx")
556 # assert s == None, s
559 """Test setting the external ENV in Environments
562 assert env.Dictionary().has_key('ENV')
564 env = Environment(ENV = { 'PATH' : '/foo:/bar' })
565 assert env.Dictionary('ENV')['PATH'] == '/foo:/bar'
567 def test_ReservedVariables(self):
568 """Test generation of warnings when reserved variable names
569 are set in an environment."""
571 SCons.Warnings.enableWarningClass(SCons.Warnings.ReservedVariableWarning)
572 old = SCons.Warnings.warningAsException(1)
576 for kw in ['TARGET', 'TARGETS', 'SOURCE', 'SOURCES']:
580 except SCons.Warnings.ReservedVariableWarning:
582 assert exc_caught, "Did not catch ReservedVariableWarning for `%s'" % kw
583 assert not env4.has_key(kw), "`%s' variable was incorrectly set" % kw
585 SCons.Warnings.warningAsException(old)
587 def test_IllegalVariables(self):
588 """Test that use of illegal variables raises an exception"""
590 def test_it(var, env=env):
594 except SCons.Errors.UserError:
596 assert exc_caught, "did not catch UserError for '%s'" % var
598 assert env['aaa'] == 1, env['aaa']
603 def test_autogenerate(dict):
604 """Test autogenerating variables in a dictionary."""
607 return SCons.Node.FS.default_fs.Rsearchall(pathlist,
608 clazz=SCons.Node.FS.Dir,
610 cwd=SCons.Node.FS.default_fs.Dir('xx'))
612 env = Environment(LIBS = [ 'foo', 'bar', 'baz' ],
613 LIBLINKPREFIX = 'foo',
614 LIBLINKSUFFIX = 'bar',
616 flags = env.subst_list('$_LIBFLAGS', 1)[0]
617 assert len(flags) == 3, flags
618 assert flags[0] == 'foobar', \
620 assert flags[1] == 'foobar', \
622 assert flags[2] == 'foobazbar', \
625 blat = SCons.Node.FS.default_fs.Dir('blat')
627 env = Environment(CPPPATH = [ 'foo', '$FOO/bar', blat ],
632 flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
633 assert len(flags) == 8, flags
634 assert flags[0] == '$(', \
636 assert flags[1] == os.path.normpath('foo'), \
638 assert flags[2] == os.path.normpath('xx/foobar'), \
640 assert flags[3] == os.path.normpath('foo'), \
642 assert flags[4] == os.path.normpath('xx/baz/bar'), \
644 assert flags[5] == os.path.normpath('foo'), \
646 assert flags[6] == os.path.normpath('blatbar'), \
648 assert flags[7] == '$)', \
651 env = Environment(F77PATH = [ 'foo', '$FOO/bar', blat ],
656 flags = env.subst_list('$_F77INCFLAGS', 1)[0]
657 assert len(flags) == 8, flags
658 assert flags[0] == '$(', \
660 assert flags[1] == os.path.normpath('foo'), \
662 assert flags[2] == os.path.normpath('xx/foobar'), \
664 assert flags[3] == os.path.normpath('foo'), \
666 assert flags[4] == os.path.normpath('xx/baz/bar'), \
668 assert flags[5] == os.path.normpath('foo'), \
670 assert flags[6] == os.path.normpath('blatbar'), \
672 assert flags[7] == '$)', \
675 env = Environment(CPPPATH = '', F77PATH = '', LIBPATH = '',
677 l = env.subst_list('$_CPPINCFLAGS')
678 assert len(l[0]) == 0, l[0]
679 l = env.subst_list('$_F77INCFLAGS')
680 assert len(l[0]) == 0, l[0]
681 l = env.subst_list('$_LIBDIRFLAGS')
682 assert len(l[0]) == 0, l[0]
684 SCons.Node.FS.default_fs.Repository('/rep1')
685 SCons.Node.FS.default_fs.Repository('/rep2')
686 env = Environment(CPPPATH = [ 'foo', '/a/b', '$FOO/bar', blat],
691 flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
692 assert flags[0] == '$(', \
694 assert flags[1] == '-I', \
696 assert flags[2] == os.path.normpath('xx/fooXXX'), \
698 assert flags[3] == '-I', \
700 assert flags[4] == os.path.normpath('/rep1/xx/fooXXX'), \
702 assert flags[5] == '-I', \
704 assert flags[6] == os.path.normpath('/rep2/xx/fooXXX'), \
706 assert flags[7] == '-I', \
708 assert flags[8] == os.path.normpath('/a/bXXX'), \
710 assert flags[9] == '-I', \
712 assert flags[10] == os.path.normpath('xx/baz/barXXX'), \
714 assert flags[11] == '-I', \
716 assert flags[12] == os.path.normpath('/rep1/xx/baz/barXXX'), \
718 assert flags[13] == '-I', \
720 assert flags[14] == os.path.normpath('/rep2/xx/baz/barXXX'), \
722 assert flags[15] == '-I', \
724 assert flags[16] == os.path.normpath('blatXXX'), \
726 assert flags[17] == '$)', \
729 def test_platform(self):
730 """Test specifying a platform callable when instantiating."""
732 def __str__(self): return "TestPlatform"
733 def __call__(self, env): env['XYZZY'] = 777
736 env['SET_TOOL'] = 'initialized'
737 assert env['PLATFORM'] == "TestPlatform"
739 env = Environment(platform = platform(), tools = [tool])
740 assert env['XYZZY'] == 777, env
741 assert env['PLATFORM'] == "TestPlatform"
742 assert env['SET_TOOL'] == "initialized"
744 def test_Default_PLATFORM(self):
745 """Test overriding the default PLATFORM variable"""
747 def __str__(self): return "DefaultTestPlatform"
748 def __call__(self, env): env['XYZZY'] = 888
751 env['SET_TOOL'] = 'abcde'
752 assert env['PLATFORM'] == "DefaultTestPlatform"
754 import SCons.Defaults
755 save = SCons.Defaults.ConstructionEnvironment.copy()
757 import SCons.Defaults
758 SCons.Defaults.ConstructionEnvironment.update({
759 'PLATFORM' : platform(),
761 env = Environment(tools = [tool])
762 assert env['XYZZY'] == 888, env
763 assert env['PLATFORM'] == "DefaultTestPlatform"
764 assert env['SET_TOOL'] == "abcde"
766 SCons.Defaults.ConstructionEnvironment = save
768 def test_tools(self):
769 """Test specifying a tool callable when instantiating."""
775 env['AAA'] = env['XYZ']
778 env = Environment(tools = [t1, t2, t3], XYZ = 'aaa')
779 assert env['TOOL1'] == 111, env['TOOL1']
780 assert env['TOOL2'] == 222, env
781 assert env['AAA'] == 'aaa', env
783 assert env['TOOL4'] == 444, env
785 def test_Default_TOOLS(self):
786 """Test overriding the default TOOLS variable"""
792 env['BBB'] = env['XYZ']
796 import SCons.Defaults
797 save = SCons.Defaults.ConstructionEnvironment.copy()
799 SCons.Defaults.ConstructionEnvironment.update({
800 'TOOLS' : [t5, t6, t7],
802 env = Environment(XYZ = 'bbb')
803 assert env['TOOL5'] == 555, env['TOOL5']
804 assert env['TOOL6'] == 666, env
805 assert env['BBB'] == 'bbb', env
807 assert env['TOOL8'] == 888, env
809 SCons.Defaults.ConstructionEnvironment = save
811 def test_concat(self):
813 e1 = Environment(PRE='pre', SUF='suf', STR='a b', LIST=['a', 'b'])
815 x = s("${_concat('', '', '', __env__)}")
817 x = s("${_concat('', [], '', __env__)}")
819 x = s("${_concat(PRE, '', SUF, __env__)}")
821 x = s("${_concat(PRE, STR, SUF, __env__)}")
822 assert x == 'prea bsuf', x
823 x = s("${_concat(PRE, LIST, SUF, __env__)}")
824 assert x == 'preasuf prebsuf', x
826 def test__update(self):
827 """Test the _update() method"""
828 env = Environment(X = 'x', Y = 'y', Z = 'z')
829 assert env['X'] == 'x', env['X']
830 assert env['Y'] == 'y', env['Y']
831 assert env['Z'] == 'z', env['Z']
832 env._update({'X' : 'xxx',
838 assert env['X'] == 'xxx', env['X']
839 assert env['Y'] == 'y', env['Y']
840 assert env['Z'] == 'zzz', env['Z']
841 assert env['TARGET'] == 't', env['TARGET']
842 assert env['TARGETS'] == 'ttt', env['TARGETS']
843 assert env['SOURCE'] == 's', env['SOURCE']
844 assert env['SOURCES'] == 'sss', env['SOURCES']
848 def test_Append(self):
849 """Test appending to construction variables in an Environment
852 b1 = Environment()['BUILDERS']
853 b2 = Environment()['BUILDERS']
854 assert b1 == b2, diff_dict(b1, b2)
857 UL = UserList.UserList
861 'a2', ['A2'], ['a2', 'A2'],
862 'a3', UL(['A3']), UL(['a3', 'A3']),
865 'a6', UL([]), UL(['a6']),
866 'a7', [''], ['a7', ''],
867 'a8', UL(['']), UL(['a8', '']),
869 ['e1'], 'E1', ['e1', 'E1'],
870 ['e2'], ['E2'], ['e2', 'E2'],
871 ['e3'], UL(['E3']), UL(['e3', 'E3']),
874 ['e6'], UL([]), UL(['e6']),
875 ['e7'], [''], ['e7', ''],
876 ['e8'], UL(['']), UL(['e8', '']),
878 UL(['i1']), 'I1', UL(['i1', 'I', '1']),
879 UL(['i2']), ['I2'], UL(['i2', 'I2']),
880 UL(['i3']), UL(['I3']), UL(['i3', 'I3']),
881 UL(['i4']), '', UL(['i4']),
882 UL(['i5']), [], UL(['i5']),
883 UL(['i6']), UL([]), UL(['i6']),
884 UL(['i7']), [''], UL(['i7', '']),
885 UL(['i8']), UL(['']), UL(['i8', '']),
889 '', UL(['M3']), UL(['M3']),
894 '', UL(['']), UL(['']),
898 [], UL(['N3']), UL(['N3']),
903 [], UL(['']), UL(['']),
905 UL([]), 'O1', ['O', '1'],
906 UL([]), ['O2'], ['O2'],
907 UL([]), UL(['O3']), UL(['O3']),
910 UL([]), UL([]), UL([]),
911 UL([]), [''], UL(['']),
912 UL([]), UL(['']), UL(['']),
914 [''], 'P1', ['', 'P1'],
915 [''], ['P2'], ['', 'P2'],
916 [''], UL(['P3']), UL(['', 'P3']),
919 [''], UL([]), UL(['']),
920 [''], [''], ['', ''],
921 [''], UL(['']), UL(['', '']),
923 UL(['']), 'Q1', ['', 'Q', '1'],
924 UL(['']), ['Q2'], ['', 'Q2'],
925 UL(['']), UL(['Q3']), UL(['', 'Q3']),
926 UL(['']), '', UL(['']),
927 UL(['']), [], UL(['']),
928 UL(['']), UL([]), UL(['']),
929 UL(['']), [''], UL(['', '']),
930 UL(['']), UL(['']), UL(['', '']),
936 input, append, expect = cases[:3]
938 env.Append(XXX = append)
941 if failed == 0: print
942 print " %s Append %s => %s did not match %s" % \
943 (repr(input), repr(append), repr(result), repr(expect))
946 assert failed == 0, "%d Append() cases failed" % failed
949 def __init__(self, name):
953 def __cmp__(self, other):
954 raise "should not compare"
958 env2 = Environment(CCC1 = ['c1'], CCC2 = ccc)
959 env2.Append(CCC1 = ccc, CCC2 = ['c2'])
960 assert env2['CCC1'][0] == 'c1', env2['CCC1']
961 assert env2['CCC1'][1] is ccc, env2['CCC1']
962 assert env2['CCC2'][0] is ccc, env2['CCC2']
963 assert env2['CCC2'][1] == 'c2', env2['CCC2']
965 env3 = Environment(X = {'x1' : 7})
966 env3.Append(X = {'x1' : 8, 'x2' : 9}, Y = {'y1' : 10})
967 assert env3['X'] == {'x1': 8, 'x2': 9}, env3['X']
968 assert env3['Y'] == {'y1': 10}, env3['Y']
970 env4 = Environment(BUILDERS = {'z1' : 11})
971 env4.Append(BUILDERS = {'z2' : 12})
972 assert env4['BUILDERS'] == {'z1' : 11, 'z2' : 12}, env4['BUILDERS']
973 assert hasattr(env4, 'z1')
974 assert hasattr(env4, 'z2')
976 def test_AppendENVPath(self):
977 """Test appending to an ENV path."""
978 env1 = Environment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
979 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
980 # have to include the pathsep here so that the test will work on UNIX too.
981 env1.AppendENVPath('PATH',r'C:\dir\num\two', sep = ';')
982 env1.AppendENVPath('PATH',r'C:\dir\num\three', sep = ';')
983 env1.AppendENVPath('MYPATH',r'C:\mydir\num\three','MYENV', sep = ';')
984 env1.AppendENVPath('MYPATH',r'C:\mydir\num\one','MYENV', sep = ';')
985 assert(env1['ENV']['PATH'] == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
986 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\two;C:\mydir\num\three;C:\mydir\num\one')
988 def test_AppendUnique(self):
989 """Test appending to unique values to construction variables
991 This strips values that are already present when lists are
993 env = Environment(AAA1 = 'a1',
999 env.AppendUnique(AAA1 = 'a1',
1001 AAA3 = ['a3', 'b', 'c', 'a3'],
1004 BBB3 = ['b3', 'c', 'd', 'b3'])
1005 assert env['AAA1'] == 'a1a1', env['AAA1']
1006 assert env['AAA2'] == ['a2'], env['AAA2']
1007 assert env['AAA3'] == ['a3', 'b', 'c'], env['AAA3']
1008 assert env['BBB1'] == ['b1'], env['BBB1']
1009 assert env['BBB2'] == ['b2'], env['BBB2']
1010 assert env['BBB3'] == ['b3', 'c', 'd'], env['BBB3']
1012 def test_Copy(self):
1013 """Test construction Environment copying
1015 Update the copy independently afterwards and check that
1016 the original remains intact (that is, no dangling
1017 references point to objects in the copied environment).
1018 Copy the original with some construction variable
1019 updates and check that the original remains intact
1020 and the copy has the updated values.
1022 env1 = Environment(XXX = 'x', YYY = 'y')
1024 env1copy = env1.Copy()
1025 env2.Replace(YYY = 'yyy')
1027 assert env1 == env1copy
1029 env3 = env1.Copy(XXX = 'x3', ZZZ = 'z3')
1030 assert env3.Dictionary('XXX') == 'x3'
1031 assert env3.Dictionary('YYY') == 'y'
1032 assert env3.Dictionary('ZZZ') == 'z3'
1033 assert env1 == env1copy
1035 assert env1['__env__'] is env1, env1['__env__']
1036 assert env2['__env__'] is env2, env2['__env__']
1037 assert env3['__env__'] is env3, env3['__env__']
1039 # Ensure that lists and dictionaries are
1040 # deep copied, but not instances.
1043 env1 = Environment(XXX=TestA(), YYY = [ 1, 2, 3 ],
1046 env2.Dictionary('YYY').append(4)
1047 env2.Dictionary('ZZZ')[5] = 6
1048 assert env1.Dictionary('XXX') is env2.Dictionary('XXX')
1049 assert 4 in env2.Dictionary('YYY')
1050 assert not 4 in env1.Dictionary('YYY')
1051 assert env2.Dictionary('ZZZ').has_key(5)
1052 assert not env1.Dictionary('ZZZ').has_key(5)
1055 env1 = Environment(BUILDERS = {'b1' : 1})
1056 assert hasattr(env1, 'b1'), "env1.b1 was not set"
1057 assert env1.b1.env == env1, "b1.env doesn't point to env1"
1058 env2 = env1.Copy(BUILDERS = {'b2' : 2})
1059 assert hasattr(env1, 'b1'), "b1 was mistakenly cleared from env1"
1060 assert env1.b1.env == env1, "b1.env was changed"
1061 assert not hasattr(env2, 'b1'), "b1 was not cleared from env2"
1062 assert hasattr(env2, 'b2'), "env2.b2 was not set"
1063 assert env2.b2.env == env2, "b2.env doesn't point to env2"
1065 # Ensure that specifying new tools in a copied environment
1067 def foo(env): env['FOO'] = 1
1068 def bar(env): env['BAR'] = 2
1069 def baz(env): env['BAZ'] = 3
1070 env1 = Environment(tools=[foo])
1072 env3 = env1.Copy(tools=[bar, baz])
1074 assert env1.get('FOO') is 1
1075 assert env1.get('BAR') is None
1076 assert env1.get('BAZ') is None
1077 assert env2.get('FOO') is 1
1078 assert env2.get('BAR') is None
1079 assert env2.get('BAZ') is None
1080 assert env3.get('FOO') is 1
1081 assert env3.get('BAR') is 2
1082 assert env3.get('BAZ') is 3
1084 # Ensure that recursive variable substitution when copying
1085 # environments works properly.
1086 env1 = Environment(CCFLAGS = '-DFOO', XYZ = '-DXYZ')
1087 env2 = env1.Copy(CCFLAGS = '$CCFLAGS -DBAR',
1088 XYZ = ['-DABC', 'x $XYZ y', '-DDEF'])
1089 x = env2.get('CCFLAGS')
1090 assert x == '-DFOO -DBAR', x
1092 assert x == ['-DABC', 'x -DXYZ y', '-DDEF'], x
1094 def test_Detect(self):
1095 """Test Detect()ing tools"""
1096 test = TestCmd.TestCmd(workdir = '')
1097 test.subdir('sub1', 'sub2')
1098 sub1 = test.workpath('sub1')
1099 sub2 = test.workpath('sub2')
1101 if sys.platform == 'win32':
1102 test.write(['sub1', 'xxx'], "sub1/xxx\n")
1103 test.write(['sub2', 'xxx'], "sub2/xxx\n")
1105 env = Environment(ENV = { 'PATH' : [sub1, sub2] })
1107 x = env.Detect('xxx.exe')
1110 test.write(['sub2', 'xxx.exe'], "sub2/xxx.exe\n")
1112 env = Environment(ENV = { 'PATH' : [sub1, sub2] })
1114 x = env.Detect('xxx.exe')
1115 assert x == 'xxx.exe', x
1117 test.write(['sub1', 'xxx.exe'], "sub1/xxx.exe\n")
1119 x = env.Detect('xxx.exe')
1120 assert x == 'xxx.exe', x
1123 test.write(['sub1', 'xxx.exe'], "sub1/xxx.exe\n")
1124 test.write(['sub2', 'xxx.exe'], "sub2/xxx.exe\n")
1126 env = Environment(ENV = { 'PATH' : [sub1, sub2] })
1128 x = env.Detect('xxx.exe')
1131 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
1132 os.chmod(sub2_xxx_exe, 0755)
1134 env = Environment(ENV = { 'PATH' : [sub1, sub2] })
1136 x = env.Detect('xxx.exe')
1137 assert x == 'xxx.exe', x
1139 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
1140 os.chmod(sub1_xxx_exe, 0755)
1142 x = env.Detect('xxx.exe')
1143 assert x == 'xxx.exe', x
1145 env = Environment(ENV = { 'PATH' : [] })
1146 x = env.Detect('xxx.exe')
1149 def test_Dictionary(self):
1150 """Test retrieval of known construction variables
1152 Fetch them from the Dictionary and check for well-known
1153 defaults that get inserted.
1155 env = Environment(XXX = 'x', YYY = 'y', ZZZ = 'z')
1156 assert env.Dictionary('XXX') == 'x'
1157 assert env.Dictionary('YYY') == 'y'
1158 assert env.Dictionary('XXX', 'ZZZ') == ['x', 'z']
1159 xxx, zzz = env.Dictionary('XXX', 'ZZZ')
1162 assert env.Dictionary().has_key('BUILDERS')
1163 assert env.Dictionary().has_key('CC')
1164 assert env.Dictionary().has_key('CCFLAGS')
1165 assert env.Dictionary().has_key('ENV')
1167 assert env['XXX'] == 'x'
1169 assert env.Dictionary('XXX') == 'foo'
1171 assert not env.Dictionary().has_key('XXX')
1173 def test_FindIxes(self):
1175 env = Environment(LIBPREFIX='lib',
1182 paths = [os.path.join('dir', 'libfoo.a'),
1183 os.path.join('dir', 'libfoo.so')]
1185 assert paths[0] == env.FindIxes(paths, 'LIBPREFIX', 'LIBSUFFIX')
1186 assert paths[1] == env.FindIxes(paths, 'SHLIBPREFIX', 'SHLIBSUFFIX')
1187 assert None == env.FindIxes(paths, 'PREFIX', 'POST')
1189 paths = ['libfoo.a', 'prefoopost']
1191 assert paths[0] == env.FindIxes(paths, 'LIBPREFIX', 'LIBSUFFIX')
1192 assert None == env.FindIxes(paths, 'SHLIBPREFIX', 'SHLIBSUFFIX')
1193 assert paths[1] == env.FindIxes(paths, 'PREFIX', 'SUFFIX')
1195 def test_Override(self):
1196 "Test overriding construction variables"
1197 env = Environment(ONE=1, TWO=2, THREE=3, FOUR=4)
1198 assert env['ONE'] == 1, env['ONE']
1199 assert env['TWO'] == 2, env['TWO']
1200 assert env['THREE'] == 3, env['THREE']
1201 assert env['FOUR'] == 4, env['FOUR']
1203 env2 = env.Override({'TWO' : '10',
1204 'THREE' :'x $THREE y',
1205 'FOUR' : ['x', '$FOUR', 'y']})
1206 assert env2['ONE'] == 1, env2['ONE']
1207 assert env2['TWO'] == '10', env2['TWO']
1208 assert env2['THREE'] == 'x 3 y', env2['THREE']
1209 assert env2['FOUR'] == ['x', 4, 'y'], env2['FOUR']
1211 assert env['ONE'] == 1, env['ONE']
1212 assert env['TWO'] == 2, env['TWO']
1213 assert env['THREE'] == 3, env['THREE']
1214 assert env['FOUR'] == 4, env['FOUR']
1216 env2.Replace(ONE = "won")
1217 assert env2['ONE'] == "won", env2['ONE']
1218 assert env['ONE'] == 1, env['ONE']
1220 assert env['__env__'] is env, env['__env__']
1221 assert env2['__env__'] is env2, env2['__env__']
1223 def test_ParseConfig(self):
1224 """Test the ParseConfig() method"""
1225 env = Environment(COMMAND='command',
1231 orig_popen = os.popen
1232 def my_popen(command, save_command=save_command):
1233 save_command.append(command)
1236 return "-I/usr/include/fum -Ibar -X\n" + \
1237 "-L/usr/fax -Lfoo -lxxx abc"
1241 libs = env.ParseConfig("fake $COMMAND")
1242 assert save_command == ['fake command'], save_command
1243 assert libs == ['abc'], libs
1244 assert env['CPPPATH'] == ['string', '/usr/include/fum', 'bar'], env['CPPPATH']
1245 assert env['LIBPATH'] == ['list', '/usr/fax', 'foo'], env['LIBPATH']
1246 assert env['LIBS'] == ['xxx'], env['LIBS']
1247 assert env['CCFLAGS'] == ['', '-X'], env['CCFLAGS']
1249 os.popen = orig_popen
1251 def test_Platform(self):
1252 """Test the Platform() method"""
1253 env = Environment(WIN32='win32', NONE='no-such-platform')
1257 env.Platform('does_not_exist')
1258 except SCons.Errors.UserError:
1260 assert exc_caught, "did not catch expected UserError"
1264 env.Platform('$NONE')
1265 except SCons.Errors.UserError:
1267 assert exc_caught, "did not catch expected UserError"
1269 env.Platform('posix')
1270 assert env['OBJSUFFIX'] == '.o', env['OBJSUFFIX']
1272 env.Platform('$WIN32')
1273 assert env['OBJSUFFIX'] == '.obj', env['OBJSUFFIX']
1275 def test_Prepend(self):
1276 """Test prepending to construction variables in an Environment
1279 UL = UserList.UserList
1283 'a2', ['A2'], ['A2', 'a2'],
1284 'a3', UL(['A3']), UL(['A3', 'a3']),
1287 'a6', UL([]), UL(['a6']),
1288 'a7', [''], ['', 'a7'],
1289 'a8', UL(['']), UL(['', 'a8']),
1291 ['e1'], 'E1', ['E1', 'e1'],
1292 ['e2'], ['E2'], ['E2', 'e2'],
1293 ['e3'], UL(['E3']), UL(['E3', 'e3']),
1296 ['e6'], UL([]), UL(['e6']),
1297 ['e7'], [''], ['', 'e7'],
1298 ['e8'], UL(['']), UL(['', 'e8']),
1300 UL(['i1']), 'I1', UL(['I', '1', 'i1']),
1301 UL(['i2']), ['I2'], UL(['I2', 'i2']),
1302 UL(['i3']), UL(['I3']), UL(['I3', 'i3']),
1303 UL(['i4']), '', UL(['i4']),
1304 UL(['i5']), [], UL(['i5']),
1305 UL(['i6']), UL([]), UL(['i6']),
1306 UL(['i7']), [''], UL(['', 'i7']),
1307 UL(['i8']), UL(['']), UL(['', 'i8']),
1311 '', UL(['M3']), UL(['M3']),
1316 '', UL(['']), UL(['']),
1320 [], UL(['N3']), UL(['N3']),
1325 [], UL(['']), UL(['']),
1327 UL([]), 'O1', UL(['O', '1']),
1328 UL([]), ['O2'], UL(['O2']),
1329 UL([]), UL(['O3']), UL(['O3']),
1332 UL([]), UL([]), UL([]),
1333 UL([]), [''], UL(['']),
1334 UL([]), UL(['']), UL(['']),
1336 [''], 'P1', ['P1', ''],
1337 [''], ['P2'], ['P2', ''],
1338 [''], UL(['P3']), UL(['P3', '']),
1341 [''], UL([]), UL(['']),
1342 [''], [''], ['', ''],
1343 [''], UL(['']), UL(['', '']),
1345 UL(['']), 'Q1', UL(['Q', '1', '']),
1346 UL(['']), ['Q2'], UL(['Q2', '']),
1347 UL(['']), UL(['Q3']), UL(['Q3', '']),
1348 UL(['']), '', UL(['']),
1349 UL(['']), [], UL(['']),
1350 UL(['']), UL([]), UL(['']),
1351 UL(['']), [''], UL(['', '']),
1352 UL(['']), UL(['']), UL(['', '']),
1358 input, prepend, expect = cases[:3]
1360 env.Prepend(XXX = prepend)
1362 if result != expect:
1363 if failed == 0: print
1364 print " %s Prepend %s => %s did not match %s" % \
1365 (repr(input), repr(prepend), repr(result), repr(expect))
1368 assert failed == 0, "%d subst() cases failed" % failed
1370 env3 = Environment(X = {'x1' : 7})
1371 env3.Prepend(X = {'x1' : 8, 'x2' : 9}, Y = {'y1' : 10})
1372 assert env3['X'] == {'x1': 8, 'x2' : 9}, env3['X']
1373 assert env3['Y'] == {'y1': 10}, env3['Y']
1375 env4 = Environment(BUILDERS = {'z1' : 11})
1376 env4.Prepend(BUILDERS = {'z2' : 12})
1377 assert env4['BUILDERS'] == {'z1' : 11, 'z2' : 12}, env4['BUILDERS']
1378 assert hasattr(env4, 'z1')
1379 assert hasattr(env4, 'z2')
1381 def test_PrependENVPath(self):
1382 """Test prepending to an ENV path."""
1383 env1 = Environment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
1384 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
1385 # have to include the pathsep here so that the test will work on UNIX too.
1386 env1.PrependENVPath('PATH',r'C:\dir\num\two',sep = ';')
1387 env1.PrependENVPath('PATH',r'C:\dir\num\three',sep = ';')
1388 env1.PrependENVPath('MYPATH',r'C:\mydir\num\three','MYENV',sep = ';')
1389 env1.PrependENVPath('MYPATH',r'C:\mydir\num\one','MYENV',sep = ';')
1390 assert(env1['ENV']['PATH'] == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
1391 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
1393 def test_PrependENVPath(self):
1394 """Test prepending to an ENV path."""
1395 env1 = Environment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
1396 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
1397 # have to include the pathsep here so that the test will work on UNIX too.
1398 env1.PrependENVPath('PATH',r'C:\dir\num\two',sep = ';')
1399 env1.PrependENVPath('PATH',r'C:\dir\num\three',sep = ';')
1400 env1.PrependENVPath('MYPATH',r'C:\mydir\num\three','MYENV',sep = ';')
1401 env1.PrependENVPath('MYPATH',r'C:\mydir\num\one','MYENV',sep = ';')
1402 assert(env1['ENV']['PATH'] == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
1403 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
1405 def test_PrependUnique(self):
1406 """Test prepending unique values to construction variables
1408 This strips values that are already present when lists are
1410 env = Environment(AAA1 = 'a1',
1416 env.PrependUnique(AAA1 = 'a1',
1418 AAA3 = ['a3', 'b', 'c', 'a3'],
1421 BBB3 = ['b3', 'b', 'c', 'b3'])
1422 assert env['AAA1'] == 'a1a1', env['AAA1']
1423 assert env['AAA2'] == ['a2'], env['AAA2']
1424 assert env['AAA3'] == ['b', 'c', 'a3'], env['AAA3']
1425 assert env['BBB1'] == ['b1'], env['BBB1']
1426 assert env['BBB2'] == ['b2'], env['BBB2']
1427 assert env['BBB3'] == ['b', 'c', 'b3'], env['BBB3']
1429 def test_Replace(self):
1430 """Test replacing construction variables in an Environment
1432 After creation of the Environment, of course.
1434 env1 = Environment(AAA = 'a', BBB = 'b')
1435 env1.Replace(BBB = 'bbb', CCC = 'ccc')
1437 env2 = Environment(AAA = 'a', BBB = 'bbb', CCC = 'ccc')
1438 assert env1 == env2, diff_env(env1, env2)
1440 env3 = Environment(BUILDERS = {'b1' : 1})
1441 assert hasattr(env3, 'b1'), "b1 was not set"
1442 env3.Replace(BUILDERS = {'b2' : 2})
1443 assert not hasattr(env3, 'b1'), "b1 was not cleared"
1444 assert hasattr(env3, 'b2'), "b2 was not set"
1446 def test_ReplaceIxes(self):
1447 "Test ReplaceIxes()"
1448 env = Environment(LIBPREFIX='lib',
1455 assert 'libfoo.a' == env.ReplaceIxes('libfoo.so',
1456 'SHLIBPREFIX', 'SHLIBSUFFIX',
1457 'LIBPREFIX', 'LIBSUFFIX')
1459 assert os.path.join('dir', 'libfoo.a') == env.ReplaceIxes(os.path.join('dir', 'libfoo.so'),
1460 'SHLIBPREFIX', 'SHLIBSUFFIX',
1461 'LIBPREFIX', 'LIBSUFFIX')
1463 assert 'libfoo.a' == env.ReplaceIxes('prefoopost',
1465 'LIBPREFIX', 'LIBSUFFIX')
1467 def test_Tool(self):
1468 """Test the Tool() method"""
1469 env = Environment(LINK='link', NONE='no-such-tool')
1473 env.Tool('does_not_exist')
1474 except SCons.Errors.UserError:
1476 assert exc_caught, "did not catch expected UserError"
1481 except SCons.Errors.UserError:
1483 assert exc_caught, "did not catch expected UserError"
1485 # Use a non-existent toolpath directory just to make sure we
1486 # can call Tool() with the keyword argument.
1487 env.Tool('cc', toolpath=['/no/such/directory'])
1488 assert env['CC'] == 'cc', env['CC']
1491 assert env['LINK'] == '$SMARTLINK', env['LINK']
1493 def test_WhereIs(self):
1494 """Test the WhereIs() method"""
1495 test = TestCmd.TestCmd(workdir = '')
1497 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
1498 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
1499 sub3_xxx_exe = test.workpath('sub3', 'xxx.exe')
1500 sub4_xxx_exe = test.workpath('sub4', 'xxx.exe')
1502 test.subdir('subdir', 'sub1', 'sub2', 'sub3', 'sub4')
1504 if sys.platform != 'win32':
1505 test.write(sub1_xxx_exe, "\n")
1507 os.mkdir(sub2_xxx_exe)
1509 test.write(sub3_xxx_exe, "\n")
1510 os.chmod(sub3_xxx_exe, 0777)
1512 test.write(sub4_xxx_exe, "\n")
1513 os.chmod(sub4_xxx_exe, 0777)
1515 env_path = os.environ['PATH']
1517 pathdirs_1234 = [ test.workpath('sub1'),
1518 test.workpath('sub2'),
1519 test.workpath('sub3'),
1520 test.workpath('sub4'),
1521 ] + string.split(env_path, os.pathsep)
1523 pathdirs_1243 = [ test.workpath('sub1'),
1524 test.workpath('sub2'),
1525 test.workpath('sub4'),
1526 test.workpath('sub3'),
1527 ] + string.split(env_path, os.pathsep)
1529 path = string.join(pathdirs_1234, os.pathsep)
1530 env = Environment(ENV = {'PATH' : path})
1531 wi = env.WhereIs('xxx.exe')
1532 assert wi == test.workpath(sub3_xxx_exe), wi
1533 wi = env.WhereIs('xxx.exe', pathdirs_1243)
1534 assert wi == test.workpath(sub4_xxx_exe), wi
1535 wi = env.WhereIs('xxx.exe', string.join(pathdirs_1243, os.pathsep))
1536 assert wi == test.workpath(sub4_xxx_exe), wi
1538 path = string.join(pathdirs_1243, os.pathsep)
1539 env = Environment(ENV = {'PATH' : path})
1540 wi = env.WhereIs('xxx.exe')
1541 assert wi == test.workpath(sub4_xxx_exe), wi
1542 wi = env.WhereIs('xxx.exe', pathdirs_1234)
1543 assert wi == test.workpath(sub3_xxx_exe), wi
1544 wi = env.WhereIs('xxx.exe', string.join(pathdirs_1234, os.pathsep))
1545 assert wi == test.workpath(sub3_xxx_exe), wi
1547 if sys.platform == 'win32':
1548 wi = env.WhereIs('xxx', pathext = '')
1549 assert wi is None, wi
1551 wi = env.WhereIs('xxx', pathext = '.exe')
1552 assert wi == test.workpath(sub4_xxx_exe), wi
1554 wi = env.WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
1555 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
1557 # Test that we return a normalized path even when
1558 # the path contains forward slashes.
1559 forward_slash = test.workpath('') + '/sub3'
1560 wi = env.WhereIs('xxx', path = forward_slash, pathext = '.EXE')
1561 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
1565 def test_Action(self):
1566 """Test the Action() method"""
1569 env = Environment(FOO = 'xyzzy')
1571 a = env.Action('foo')
1573 assert a.__class__ is SCons.Action.CommandAction, a
1575 a = env.Action('$FOO')
1577 assert a.__class__ is SCons.Action.CommandGeneratorAction, a
1579 a = env.Action(['$FOO', 'foo'])
1581 assert a.__class__ is SCons.Action.ListAction, a
1585 a = env.Action(func)
1587 assert a.__class__ is SCons.Action.FunctionAction, a
1589 def test_AddPostAction(self):
1590 """Test the AddPostAction() method"""
1591 env = Environment(FOO='fff', BAR='bbb')
1593 n = env.AddPostAction('$FOO', lambda x: x)
1594 assert str(n[0]) == 'fff', n[0]
1596 n = env.AddPostAction(['ggg', '$BAR'], lambda x: x)
1597 assert str(n[0]) == 'ggg', n[0]
1598 assert str(n[1]) == 'bbb', n[1]
1600 def test_AddPreAction(self):
1601 """Test the AddPreAction() method"""
1602 env = Environment(FOO='fff', BAR='bbb')
1604 n = env.AddPreAction('$FOO', lambda x: x)
1605 assert str(n[0]) == 'fff', n[0]
1607 n = env.AddPreAction(['ggg', '$BAR'], lambda x: x)
1608 assert str(n[0]) == 'ggg', n[0]
1609 assert str(n[1]) == 'bbb', n[1]
1611 def test_Alias(self):
1612 """Test the Alias() method"""
1613 env = Environment(FOO='kkk', BAR='lll', EA='export_alias')
1615 tgt = env.Alias('new_alias')
1616 assert str(tgt) == 'new_alias', tgt
1617 assert tgt.sources == [], tgt.sources
1619 tgt = env.Alias('None_alias', None)
1620 assert str(tgt) == 'None_alias', tgt
1621 assert tgt.sources == [], tgt.sources
1623 tgt = env.Alias('empty_list', [])
1624 assert str(tgt) == 'empty_list', tgt
1625 assert tgt.sources == [], tgt.sources
1627 tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ])
1628 assert str(tgt) == 'export_alias', tgt
1629 assert len(tgt.sources) == 2, map(str, tgt.sources)
1630 assert str(tgt.sources[0]) == 'asrc1', map(str, tgt.sources)
1631 assert str(tgt.sources[1]) == 'kkk', map(str, tgt.sources)
1633 n = env.Alias(tgt, source = ['$BAR', 'asrc4'])
1635 assert len(tgt.sources) == 4, map(str, tgt.sources)
1636 assert str(tgt.sources[2]) == 'lll', map(str, tgt.sources)
1637 assert str(tgt.sources[3]) == 'asrc4', map(str, tgt.sources)
1639 n = env.Alias('$EA', 'asrc5')
1641 assert len(tgt.sources) == 5, map(str, tgt.sources)
1642 assert str(tgt.sources[4]) == 'asrc5', map(str, tgt.sources)
1644 t1, t2 = env.Alias(['t1', 't2'], ['asrc6', 'asrc7'])
1645 assert str(t1) == 't1', t1
1646 assert str(t2) == 't2', t2
1647 assert len(t1.sources) == 2, map(str, t1.sources)
1648 assert str(t1.sources[0]) == 'asrc6', map(str, t1.sources)
1649 assert str(t1.sources[1]) == 'asrc7', map(str, t1.sources)
1650 assert len(t2.sources) == 2, map(str, t2.sources)
1651 assert str(t2.sources[0]) == 'asrc6', map(str, t2.sources)
1652 assert str(t2.sources[1]) == 'asrc7', map(str, t2.sources)
1654 def test_AlwaysBuild(self):
1655 """Test the AlwaysBuild() method"""
1656 env = Environment(FOO='fff', BAR='bbb')
1657 t = env.AlwaysBuild('a', 'b$FOO', ['c', 'd'], '$BAR')
1658 assert t[0].__class__.__name__ == 'File'
1659 assert t[0].path == 'a'
1660 assert t[0].always_build
1661 assert t[1].__class__.__name__ == 'File'
1662 assert t[1].path == 'bfff'
1663 assert t[1].always_build
1664 assert t[2].__class__.__name__ == 'File'
1665 assert t[2].path == 'c'
1666 assert t[2].always_build
1667 assert t[3].__class__.__name__ == 'File'
1668 assert t[3].path == 'd'
1669 assert t[3].always_build
1670 assert t[4].__class__.__name__ == 'File'
1671 assert t[4].path == 'bbb'
1672 assert t[4].always_build
1674 def test_BuildDir(self):
1675 """Test the BuildDir() method"""
1677 def Dir(self, name):
1679 def BuildDir(self, build_dir, src_dir, duplicate):
1680 self.build_dir = build_dir
1681 self.src_dir = src_dir
1682 self.duplicate = duplicate
1684 env = Environment(FOO = 'fff', BAR = 'bbb')
1687 env.BuildDir('build', 'src')
1688 assert env.fs.build_dir == 'build', env.fs.build_dir
1689 assert env.fs.src_dir == 'src', env.fs.src_dir
1690 assert env.fs.duplicate == 1, env.fs.duplicate
1692 env.BuildDir('build${FOO}', '${BAR}src', 0)
1693 assert env.fs.build_dir == 'buildfff', env.fs.build_dir
1694 assert env.fs.src_dir == 'bbbsrc', env.fs.src_dir
1695 assert env.fs.duplicate == 0, env.fs.duplicate
1697 def test_Builder(self):
1698 """Test the Builder() method"""
1699 env = Environment(FOO = 'xyzzy')
1701 b = env.Builder(action = 'foo')
1702 assert not b is None, b
1704 b = env.Builder(action = '$FOO')
1705 assert not b is None, b
1707 b = env.Builder(action = ['$FOO', 'foo'])
1708 assert not b is None, b
1712 b = env.Builder(action = func)
1713 assert not b is None, b
1714 b = env.Builder(generator = func)
1715 assert not b is None, b
1717 def test_CacheDir(self):
1718 """Test the CacheDir() method"""
1720 def CacheDir(self, path):
1723 env = Environment(CD = 'CacheDir')
1727 assert env.fs.CD == 'foo', env.fs.CD
1730 assert env.fs.CD == 'CacheDir', env.fs.CD
1732 def test_Clean(self):
1733 """Test the Clean() method"""
1734 env = Environment(FOO = 'fff', BAR = 'bbb')
1736 CT = SCons.Environment.CleanTargets
1738 foo = env.arg2nodes('foo')[0]
1739 fff = env.arg2nodes('fff')[0]
1741 t = env.Clean('foo', 'aaa')
1742 l = map(str, CT[foo])
1743 assert l == ['aaa'], l
1745 t = env.Clean(foo, ['$BAR', 'ccc'])
1746 l = map(str, CT[foo])
1747 assert l == ['aaa', 'bbb', 'ccc'], l
1749 eee = env.arg2nodes('eee')[0]
1751 t = env.Clean('$FOO', 'ddd')
1752 l = map(str, CT[fff])
1753 assert l == ['ddd'], l
1754 t = env.Clean(fff, [eee, 'fff'])
1755 l = map(str, CT[fff])
1756 assert l == ['ddd', 'eee', 'fff'], l
1758 def test_Command(self):
1759 """Test the Command() method."""
1761 t = env.Command(target='foo.out', source=['foo1.in', 'foo2.in'],
1762 action='buildfoo $target $source')
1763 assert not t.builder is None
1764 assert t.builder.action.__class__.__name__ == 'CommandAction'
1765 assert t.builder.action.cmd_list == 'buildfoo $target $source'
1766 assert 'foo1.in' in map(lambda x: x.path, t.sources)
1767 assert 'foo2.in' in map(lambda x: x.path, t.sources)
1769 sub = SCons.Node.FS.default_fs.Dir('sub')
1770 t = env.Command(target='bar.out', source='sub',
1771 action='buildbar $target $source')
1772 assert 'sub' in map(lambda x: x.path, t.sources)
1774 def testFunc(env, target, source):
1775 assert str(target[0]) == 'foo.out'
1776 assert 'foo1.in' in map(str, source) and 'foo2.in' in map(str, source), map(str, source)
1778 t = env.Command(target='foo.out', source=['foo1.in','foo2.in'],
1780 assert not t.builder is None
1781 assert t.builder.action.__class__.__name__ == 'FunctionAction'
1783 assert 'foo1.in' in map(lambda x: x.path, t.sources)
1784 assert 'foo2.in' in map(lambda x: x.path, t.sources)
1787 def test2(baz, x=x):
1789 env = Environment(TEST2 = test2)
1790 t = env.Command(target='baz.out', source='baz.in',
1791 action='${TEST2(XYZ)}',
1793 assert not t.builder is None
1795 assert x[0] == 'magic word', x
1797 def test_Configure(self):
1798 """Test the Configure() method"""
1799 # Configure() will write to a local temporary file.
1800 test = TestCmd.TestCmd(workdir = '')
1802 # Configure() will test, if we are reading a SConscript file
1803 import SCons.Script.SConscript
1804 SCons.Script.SConscript.sconscript_reading = 1
1807 os.chdir(test.workpath())
1809 env = Environment(FOO = 'xyzzy')
1815 assert not c is None, c
1818 c = env.Configure(custom_tests = {'foo' : func, '$FOO' : func})
1819 assert not c is None, c
1820 assert hasattr(c, 'foo')
1821 assert hasattr(c, 'xyzzy')
1826 def test_Depends(self):
1827 """Test the explicit Depends method."""
1828 env = Environment(FOO = 'xxx', BAR='yyy')
1833 t = env.Depends(target='EnvironmentTest.py', dependency='Environment.py')
1834 assert t.__class__.__name__ == 'Entry', t.__class__.__name__
1835 assert t.path == 'EnvironmentTest.py'
1836 assert len(t.depends) == 1
1838 assert d.__class__.__name__ == 'Entry', d.__class__.__name__
1839 assert d.path == 'Environment.py'
1841 t = env.Depends(target='${FOO}.py', dependency='${BAR}.py')
1842 assert t.__class__.__name__ == 'File', t.__class__.__name__
1843 assert t.path == 'xxx.py'
1844 assert len(t.depends) == 1
1846 assert d.__class__.__name__ == 'File', d.__class__.__name__
1847 assert d.path == 'yyy.py'
1849 t = env.Depends(target='dir1', dependency='dir2')
1850 assert t.__class__.__name__ == 'Dir', t.__class__.__name__
1851 assert t.path == 'dir1'
1852 assert len(t.depends) == 1
1854 assert d.__class__.__name__ == 'Dir', d.__class__.__name__
1855 assert d.path == 'dir2'
1858 """Test the Dir() method"""
1860 def Dir(self, name):
1861 return 'Dir(%s)' % name
1863 env = Environment(FOO = 'foodir', BAR = 'bardir')
1867 assert d == 'Dir(d)', d
1870 assert d == 'Dir(foodir)', d
1872 d = env.Dir('${BAR}_$BAR')
1873 assert d == 'Dir(bardir_bardir)', d
1875 def test_Environment(self):
1876 """Test the Environment() method"""
1877 env = Environment(FOO = 'xxx', BAR = 'yyy')
1879 e2 = env.Environment(X = '$FOO', Y = '$BAR')
1880 assert e2['X'] == 'xxx', e2['X']
1881 assert e2['Y'] == 'yyy', e2['Y']
1883 def test_Execute(self):
1884 """Test the Execute() method"""
1887 def __init__(self, *args, **kw):
1889 def __call__(self, target, source, env):
1890 return "%s executed" % self.args
1893 env.Action = MyAction
1895 result = env.Execute("foo")
1896 assert result == "foo executed", result
1898 def test_File(self):
1899 """Test the File() method"""
1901 def File(self, name):
1902 return 'File(%s)' % name
1904 env = Environment(FOO = 'foofile', BAR = 'barfile')
1908 assert f == 'File(f)', f
1910 f = env.File('$FOO')
1911 assert f == 'File(foofile)', f
1913 f = env.File('${BAR}_$BAR')
1914 assert f == 'File(barfile_barfile)', f
1916 def test_FindFile(self):
1917 """Test the FindFile() method"""
1918 env = Environment(FOO = 'fff', BAR = 'bbb')
1920 r = env.FindFile('foo', ['no_such_directory'])
1925 def test_GetBuildPath(self):
1926 """Test the GetBuildPath() method."""
1927 env = Environment(MAGIC = 'xyzzy')
1929 p = env.GetBuildPath('foo')
1930 assert p == 'foo', p
1932 p = env.GetBuildPath('$MAGIC')
1933 assert p == 'xyzzy', p
1935 def test_Ignore(self):
1936 """Test the explicit Ignore method."""
1937 env = Environment(FOO='yyy', BAR='zzz')
1943 t = env.Ignore(target='targ.py', dependency='dep.py')
1944 assert t.__class__.__name__ == 'Entry', t.__class__.__name__
1945 assert t.path == 'targ.py'
1946 assert len(t.ignore) == 1
1948 assert i.__class__.__name__ == 'Entry', i.__class__.__name__
1949 assert i.path == 'dep.py'
1951 t = env.Ignore(target='$FOO$BAR', dependency='$BAR$FOO')
1952 assert t.__class__.__name__ == 'File', t.__class__.__name__
1953 assert t.path == 'yyyzzz'
1954 assert len(t.ignore) == 1
1956 assert i.__class__.__name__ == 'File', i.__class__.__name__
1957 assert i.path == 'zzzyyy'
1959 t = env.Ignore(target='dir1', dependency='dir2')
1960 assert t.__class__.__name__ == 'Dir', t.__class__.__name__
1961 assert t.path == 'dir1'
1962 assert len(t.ignore) == 1
1964 assert i.__class__.__name__ == 'Dir', i.__class__.__name__
1965 assert i.path == 'dir2'
1967 def test_Install(self):
1968 """Test the Install method"""
1969 env = Environment(FOO='iii', BAR='jjj')
1971 tgt = env.Install('export', [ 'build/foo1', 'build/foo2' ])
1972 paths = map(str, tgt)
1974 expect = map(os.path.normpath, [ 'export/foo1', 'export/foo2' ])
1975 assert paths == expect, paths
1977 assert tnode.builder == InstallBuilder
1979 tgt = env.Install('$FOO', [ 'build/${BAR}1', 'build/${BAR}2' ])
1980 paths = map(str, tgt)
1982 expect = map(os.path.normpath, [ 'iii/jjj1', 'iii/jjj2' ])
1983 assert paths == expect, paths
1985 assert tnode.builder == InstallBuilder
1989 tgt = env.Install('export', 'export')
1990 except SCons.Errors.UserError, e:
1992 assert exc_caught, "UserError should be thrown when Install() target is not a file."
1993 match = str(e) == "Source `export' of Install() is not a file. Install() source must be one or more files."
1998 tgt = env.Install('export', ['export', 'build/foo1'])
1999 except SCons.Errors.UserError, e:
2001 assert exc_caught, "UserError should be thrown when Install() target containins non-files."
2002 match = str(e) == "Source `['export', 'build/foo1']' of Install() contains one or more non-files. Install() source must be one or more files."
2007 tgt = env.Install('export/foo1', 'build/foo1')
2008 except SCons.Errors.UserError, e:
2010 assert exc_caught, "UserError should be thrown reversing the order of Install() targets."
2011 match = str(e) == "Target `export/foo1' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?"
2014 def test_InstallAs(self):
2015 """Test the InstallAs method"""
2016 env = Environment(FOO='iii', BAR='jjj')
2018 tgt = env.InstallAs(target=string.split('foo1 foo2'),
2019 source=string.split('bar1 bar2'))
2020 assert len(tgt) == 2, len(tgt)
2021 paths = map(lambda x: str(x.sources[0]), tgt)
2023 expect = map(os.path.normpath, [ 'bar1', 'bar2' ])
2024 assert paths == expect, paths
2026 assert tnode.builder == InstallBuilder
2028 tgt = env.InstallAs(target='${FOO}.t', source='${BAR}.s')
2029 assert tgt.path == 'iii.t'
2030 assert tgt.sources[0].path == 'jjj.s'
2031 assert tgt.builder == InstallBuilder
2033 def test_Literal(self):
2034 """Test the Literal() method"""
2035 env = Environment(FOO='fff', BAR='bbb')
2036 list = env.subst_list([env.Literal('$FOO'), '$BAR'])[0]
2037 assert list == ['$FOO', 'bbb'], list
2038 list = env.subst_list(['$FOO', env.Literal('$BAR')])[0]
2039 assert list == ['fff', '$BAR'], list
2041 def test_Local(self):
2042 """Test the Local() method."""
2043 env = Environment(FOO='lll')
2045 l = env.Local(env.fs.File('fff'))
2046 assert str(l[0]) == 'fff', l[0]
2048 l = env.Local('ggg', '$FOO')
2049 assert str(l[0]) == 'ggg', l[0]
2050 assert str(l[1]) == 'lll', l[1]
2052 def test_Precious(self):
2053 """Test the Precious() method"""
2054 env = Environment(FOO='ggg', BAR='hhh')
2057 t = env.Precious('p_a', 'p_${BAR}b', ['p_c', 'p_d'], 'p_$FOO')
2059 assert t[0].__class__.__name__ == 'Entry', t[0].__class__.__name__
2060 assert t[0].path == 'p_a'
2061 assert t[0].precious
2062 assert t[1].__class__.__name__ == 'Dir', t[1].__class__.__name__
2063 assert t[1].path == 'p_hhhb'
2064 assert t[1].precious
2065 assert t[2].__class__.__name__ == 'Entry', t[2].__class__.__name__
2066 assert t[2].path == 'p_c'
2067 assert t[2].precious
2068 assert t[3].__class__.__name__ == 'File', t[3].__class__.__name__
2069 assert t[3].path == 'p_d'
2070 assert t[3].precious
2071 assert t[4].__class__.__name__ == 'Entry', t[4].__class__.__name__
2072 assert t[4].path == 'p_ggg'
2073 assert t[4].precious
2075 def test_Repository(self):
2076 """Test the Repository() method."""
2080 def Repository(self, *dirs):
2081 self.list.extend(list(dirs))
2082 def Dir(self, name):
2084 env = Environment(FOO='rrr', BAR='sss')
2086 env.Repository('/tmp/foo')
2087 env.Repository('/tmp/$FOO', '/tmp/$BAR/foo')
2088 expect = ['/tmp/foo', '/tmp/rrr', '/tmp/sss/foo']
2089 assert env.fs.list == expect, env.fs.list
2091 def test_Scanner(self):
2092 """Test the Scanner() method"""
2093 def scan(node, env, target, arg):
2096 env = Environment(FOO = scan)
2098 s = env.Scanner('foo')
2099 assert not s is None, s
2101 s = env.Scanner(function = 'foo')
2102 assert not s is None, s
2105 s = env.Scanner('$FOO')
2106 assert not s is None, s
2108 s = env.Scanner(function = '$FOO')
2109 assert not s is None, s
2111 def test_SConsignFile(self):
2112 """Test the SConsignFile() method"""
2116 SConstruct_dir = os.sep + 'dir'
2118 env = Environment(FOO = 'SConsign',
2119 BAR = os.path.join(os.sep, 'File'))
2125 def capture(name, dbm_module, fnames=fnames, dbms=dbms):
2127 dbms.append(dbm_module)
2129 save_Sig_SConsignFile = SCons.Sig.SConsignFile
2130 SCons.Sig.SConsignFile = capture
2132 env.SConsignFile('foo')
2133 assert fnames[0] == os.path.join(os.sep, 'dir', 'foo'), fnames
2134 assert dbms[0] == None, dbms
2136 env.SConsignFile('$FOO')
2137 assert fnames[1] == os.path.join(os.sep, 'dir', 'SConsign'), fnames
2138 assert dbms[1] == None, dbms
2140 env.SConsignFile('/$FOO')
2141 assert fnames[2] == '/SConsign', fnames
2142 assert dbms[2] == None, dbms
2144 env.SConsignFile('$BAR', 'x')
2145 assert fnames[3] == os.path.join(os.sep, 'File'), fnames
2146 assert dbms[3] == 'x', dbms
2148 env.SConsignFile('__$BAR', 7)
2149 assert fnames[4] == os.path.join(os.sep, 'dir', '__', 'File'), fnames
2150 assert dbms[4] == 7, dbms
2152 SCons.Sig.SConsignFile = save_Sig_SConsignFile
2154 def test_SideEffect(self):
2155 """Test the SideEffect() method"""
2156 env = Environment(LIB='lll', FOO='fff', BAR='bbb')
2157 env.File('mylll.pdb')
2158 env.Dir('mymmm.pdb')
2160 foo = env.Object('foo.obj', 'foo.cpp')
2161 bar = env.Object('bar.obj', 'bar.cpp')
2162 s = env.SideEffect('mylib.pdb', ['foo.obj', 'bar.obj'])
2163 assert s.__class__.__name__ == 'Entry', s.__class__.__name__
2164 assert s.path == 'mylib.pdb'
2165 assert s.side_effect
2166 assert foo.side_effects == [s]
2167 assert bar.side_effects == [s]
2168 assert s.depends_on([bar])
2169 assert s.depends_on([foo])
2171 fff = env.Object('fff.obj', 'fff.cpp')
2172 bbb = env.Object('bbb.obj', 'bbb.cpp')
2173 s = env.SideEffect('my${LIB}.pdb', ['${FOO}.obj', '${BAR}.obj'])
2174 assert s.__class__.__name__ == 'File', s.__class__.__name__
2175 assert s.path == 'mylll.pdb'
2176 assert s.side_effect
2177 assert fff.side_effects == [s], fff.side_effects
2178 assert bbb.side_effects == [s], bbb.side_effects
2179 assert s.depends_on([bbb])
2180 assert s.depends_on([fff])
2182 ggg = env.Object('ggg.obj', 'ggg.cpp')
2183 ccc = env.Object('ccc.obj', 'ccc.cpp')
2184 s = env.SideEffect('mymmm.pdb', ['ggg.obj', 'ccc.obj'])
2185 assert s.__class__.__name__ == 'Dir', s.__class__.__name__
2186 assert s.path == 'mymmm.pdb'
2187 assert s.side_effect
2188 assert ggg.side_effects == [s], ggg.side_effects
2189 assert ccc.side_effects == [s], ccc.side_effects
2190 assert s.depends_on([ccc])
2191 assert s.depends_on([ggg])
2193 def test_SourceCode(self):
2194 """Test the SourceCode() method."""
2195 env = Environment(FOO='mmm', BAR='nnn')
2196 e = env.SourceCode('foo', None)
2197 assert e.path == 'foo'
2202 e = env.SourceCode(e, b)
2203 assert e.path == 'foo'
2207 e = env.SourceCode('$BAR$FOO', None)
2208 assert e.path == 'nnnmmm'
2212 def test_SourceSignatures(type):
2213 """Test the SourceSignatures() method"""
2214 env = Environment(M = 'MD5', T = 'timestamp')
2218 env.SourceSignatures('invalid_type')
2219 except SCons.Errors.UserError:
2221 assert exc_caught, "did not catch expected UserError"
2222 assert not hasattr(env, '_calc_module')
2224 env.SourceSignatures('MD5')
2225 m = env._calc_module
2227 env.SourceSignatures('$M')
2228 assert env._calc_module is m
2230 env.SourceSignatures('timestamp')
2231 t = env._calc_module
2233 env.SourceSignatures('$T')
2234 assert env._calc_module is t
2236 def test_Split(self):
2237 """Test the Split() method"""
2238 env = Environment(FOO='fff', BAR='bbb')
2239 s = env.Split("foo bar")
2240 assert s == ["foo", "bar"], s
2241 s = env.Split("$FOO bar")
2242 assert s == ["fff", "bar"], s
2243 s = env.Split(["foo", "bar"])
2244 assert s == ["foo", "bar"], s
2245 s = env.Split(["foo", "${BAR}-bbb"])
2246 assert s == ["foo", "bbb-bbb"], s
2247 s = env.Split("foo")
2248 assert s == ["foo"], s
2249 s = env.Split("$FOO$BAR")
2250 assert s == ["fffbbb"], s
2252 def test_TargetSignatures(type):
2253 """Test the TargetSignatures() method"""
2254 env = Environment(B = 'build', C = 'content')
2258 env.TargetSignatures('invalid_type')
2259 except SCons.Errors.UserError:
2261 assert exc_caught, "did not catch expected UserError"
2262 assert not hasattr(env, '_build_signature')
2264 env.TargetSignatures('build')
2265 assert env._build_signature == 1, env._build_signature
2267 env.TargetSignatures('content')
2268 assert env._build_signature == 0, env._build_signature
2270 env.TargetSignatures('$B')
2271 assert env._build_signature == 1, env._build_signature
2273 env.TargetSignatures('$C')
2274 assert env._build_signature == 0, env._build_signature
2276 def test_Value(self):
2277 """Test creating a Value() object
2281 assert v1.value == 'a', v1.value
2284 v2 = env.Value(value2)
2285 assert v2.value == value2, v2.value
2286 assert v2.value is value2, v2.value
2289 assert v1.value == v2.value
2293 def test_Environment_global_variable(type):
2294 """Test setting Environment variable to an Environment.Base subclass"""
2295 class MyEnv(SCons.Environment.Base):
2296 def xxx(self, string):
2297 return self.subst(string)
2299 SCons.Environment.Environment = MyEnv
2301 env = SCons.Environment.Environment(FOO = 'foo')
2303 f = env.subst('$FOO')
2304 assert f == 'foo', f
2307 assert f == 'foo', f
2310 if __name__ == "__main__":
2311 suite = unittest.makeSuite(EnvironmentTestCase, 'test_')
2312 if not unittest.TextTestRunner().run(suite).wasSuccessful():