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 Environments 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)
130 """Test the get() method."""
131 env = Environment(aaa = 'AAA')
135 x = env.get('aaa', 'XXX')
139 x = env.get('bbb', 'XXX')
142 def test_arg2nodes(self):
143 """Test the arg2nodes method
147 class X(SCons.Node.Node):
149 def Factory(name, directory = None, create = 1, dict=dict, X=X):
150 if not dict.has_key(name):
152 dict[name].name = name
155 nodes = env.arg2nodes("Util.py UtilTests.py", Factory)
156 assert len(nodes) == 1, nodes
157 assert isinstance(nodes[0], X)
158 assert nodes[0].name == "Util.py UtilTests.py"
161 if hasattr(types, 'UnicodeType'):
163 nodes = env.arg2nodes(u"Util.py UtilTests.py", Factory)
164 assert len(nodes) == 1, nodes
165 assert isinstance(nodes[0], X)
166 assert nodes[0].name == u"Util.py UtilTests.py"
168 exec code in globals(), locals()
170 nodes = env.arg2nodes(["Util.py", "UtilTests.py"], Factory)
171 assert len(nodes) == 2, nodes
172 assert isinstance(nodes[0], X)
173 assert isinstance(nodes[1], X)
174 assert nodes[0].name == "Util.py"
175 assert nodes[1].name == "UtilTests.py"
177 n1 = Factory("Util.py")
178 nodes = env.arg2nodes([n1, "UtilTests.py"], Factory)
179 assert len(nodes) == 2, nodes
180 assert isinstance(nodes[0], X)
181 assert isinstance(nodes[1], X)
182 assert nodes[0].name == "Util.py"
183 assert nodes[1].name == "UtilTests.py"
185 class SConsNode(SCons.Node.Node):
187 nodes = env.arg2nodes(SConsNode())
188 assert len(nodes) == 1, nodes
189 assert isinstance(nodes[0], SConsNode), node
193 nodes = env.arg2nodes(OtherNode())
194 assert len(nodes) == 1, nodes
195 assert isinstance(nodes[0], OtherNode), node
197 def lookup_a(str, F=Factory):
205 def lookup_b(str, F=Factory):
214 env_ll.lookup_list = [lookup_a, lookup_b]
216 nodes = env_ll.arg2nodes(['aaa', 'bbb', 'ccc'], Factory)
217 assert len(nodes) == 3, nodes
219 assert nodes[0].name == 'aaa', nodes[0]
220 assert nodes[0].a == 1, nodes[0]
221 assert not hasattr(nodes[0], 'b'), nodes[0]
223 assert nodes[1].name == 'bbb'
224 assert not hasattr(nodes[1], 'a'), nodes[1]
225 assert nodes[1].b == 1, nodes[1]
227 assert nodes[2].name == 'ccc'
228 assert not hasattr(nodes[2], 'a'), nodes[1]
229 assert not hasattr(nodes[2], 'b'), nodes[1]
231 def lookup_bbbb(str, F=Factory):
239 def lookup_c(str, F=Factory):
247 nodes = env.arg2nodes(['bbbb', 'ccc'], Factory,
248 [lookup_c, lookup_bbbb, lookup_b])
249 assert len(nodes) == 2, nodes
251 assert nodes[0].name == 'bbbb'
252 assert not hasattr(nodes[0], 'a'), nodes[1]
253 assert not hasattr(nodes[0], 'b'), nodes[1]
254 assert nodes[0].bbbb == 1, nodes[1]
255 assert not hasattr(nodes[0], 'c'), nodes[0]
257 assert nodes[1].name == 'ccc'
258 assert not hasattr(nodes[1], 'a'), nodes[1]
259 assert not hasattr(nodes[1], 'b'), nodes[1]
260 assert not hasattr(nodes[1], 'bbbb'), nodes[0]
261 assert nodes[1].c == 1, nodes[1]
263 def test_subst(self):
264 """Test substituting construction variables within strings
266 Check various combinations, including recursive expansion
267 of variables into other variables.
269 env = Environment(AAA = 'a', BBB = 'b')
270 mystr = env.subst("$AAA ${AAA}A $BBBB $BBB")
271 assert mystr == "a aA b", mystr
273 # Changed the tests below to reflect a bug fix in
275 env = Environment(AAA = '$BBB', BBB = 'b', BBBA = 'foo')
276 mystr = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
277 assert mystr == "b bA bB b", mystr
278 env = Environment(AAA = '$BBB', BBB = '$CCC', CCC = 'c')
279 mystr = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
280 assert mystr == "c cA cB c", mystr
282 env = Environment(AAA = '$BBB', BBB = '$CCC', CCC = [ 'a', 'b\nc' ])
283 lst = env.subst_list([ "$AAA", "B $CCC" ])
284 assert lst == [ [ "a", "b" ], [ "c", "B a", "b" ], [ "c" ] ], lst
287 def __init__(self, name):
293 def get_subst_proxy(self):
296 # Test callables in the Environment
297 def foo(target, source, env, for_signature):
298 assert str(target) == 't', target
299 assert str(source) == 's', source
302 env = Environment(BAR=foo, FOO='baz')
304 subst = env.subst('test $BAR', target=DummyNode('t'), source=DummyNode('s'))
305 assert subst == 'test baz', subst
307 lst = env.subst_list('test $BAR', target=DummyNode('t'), source=DummyNode('s'))
308 assert lst[0][0] == 'test', lst[0][0]
309 assert lst[0][1] == 'baz', lst[0][1]
311 # Test not calling callables in the Environment
313 # This will take some serious surgery to subst() and
314 # subst_list(), so just leave these tests out until we can
319 env = Environment(BAR=bar, FOO='$BAR')
321 subst = env.subst('$BAR', call=None)
322 assert subst is bar, subst
324 subst = env.subst('$FOO', call=None)
325 assert subst is bar, subst
327 subst = env.subst_list('$BAR', call=None)
328 assert subst is bar, subst
330 subst = env.subst_list('$FOO', call=None)
331 assert subst is bar, subst
333 def test_subst_kw(self):
334 """Test substituting construction variables within dictionaries"""
335 env = Environment(AAA = 'a', BBB = 'b')
336 kw = env.subst_kw({'$AAA' : 'aaa', 'bbb' : '$BBB'})
337 assert len(kw) == 2, kw
338 assert kw['a'] == 'aaa', kw['a']
339 assert kw['bbb'] == 'b', kw['bbb']
341 def test_Builder_calls(self):
342 """Test Builder calls through different environments
350 env.Replace(BUILDERS = { 'builder1' : b1,
353 env.builder1(target = 'out1')
354 assert called_it['target'] == 'out1', called_it
355 assert not called_it.has_key('source')
358 env.builder2(target = 'out2', xyzzy = 1)
359 assert called_it['target'] == 'out2', called_it
360 assert called_it['xyzzy'] == 1, called_it
361 assert not called_it.has_key('source')
364 env.builder1(foo = 'bar')
365 assert called_it['foo'] == 'bar', called_it
366 assert not called_it.has_key('target')
367 assert not called_it.has_key('source')
371 def test_Builder_execs(self):
372 """Test Builder execution through different environments
374 One environment is initialized with a single
375 Builder object, one with a list of a single Builder
376 object, and one with a list of two Builder objects.
385 env3.Replace(BUILDERS = { 'builder1' : b1,
387 env3.builder1.execute(target = 'out1')
388 env3.builder2.execute(target = 'out2')
389 env3.builder1.execute(target = 'out3')
390 assert built_it['out1']
391 assert built_it['out2']
392 assert built_it['out3']
395 assert env4.builder1.env is env4, "builder1.env (%s) == env3 (%s)?" % (env4.builder1.env, env3)
396 assert env4.builder2.env is env4, "builder2.env (%s) == env3 (%s)?" % (env4.builder1.env, env3)
398 # Now test BUILDERS as a dictionary.
400 env5 = Environment(BUILDERS={ 'foo' : b1 })
401 env5['BUILDERS']['bar'] = b2
402 env5.foo.execute(target='out1')
403 env5.bar.execute(target='out2')
404 assert built_it['out1']
405 assert built_it['out2']
409 env6['BUILDERS'] = { 'foo' : b1,
411 env6.foo.execute(target='out1')
412 env6.bar.execute(target='out2')
413 assert built_it['out1']
414 assert built_it['out2']
416 def test_Scanners(self):
417 """Test Scanner execution through different environments
419 One environment is initialized with a single
420 Scanner object, one with a list of a single Scanner
421 object, and one with a list of two Scanner objects.
425 # s1 = Scanner(name = 'scanner1', skeys = [".c", ".cc"])
426 # s2 = Scanner(name = 'scanner2', skeys = [".m4"])
429 # env1 = Environment(SCANNERS = s1)
430 # env1.scanner1(filename = 'out1')
431 # assert scanned_it['out1']
434 # env2 = Environment(SCANNERS = [s1])
435 # env1.scanner1(filename = 'out1')
436 # assert scanned_it['out1']
439 # env3 = Environment()
440 # env3.Replace(SCANNERS = [s1, s2])
441 # env3.scanner1(filename = 'out1')
442 # env3.scanner2(filename = 'out2')
443 # env3.scanner1(filename = 'out3')
444 # assert scanned_it['out1']
445 # assert scanned_it['out2']
446 # assert scanned_it['out3']
448 # s = env3.get_scanner(".c")
450 # s = env3.get_scanner(skey=".m4")
452 # s = env3.get_scanner(".cxx")
453 # assert s == None, s
456 """Test setting the external ENV in Environments
459 assert env.Dictionary().has_key('ENV')
461 env = Environment(ENV = { 'PATH' : '/foo:/bar' })
462 assert env.Dictionary('ENV')['PATH'] == '/foo:/bar'
464 def test_ReservedVariables(self):
465 """Test generation of warnings when reserved variable names
466 are set in an environment."""
468 SCons.Warnings.enableWarningClass(SCons.Warnings.ReservedVariableWarning)
469 old = SCons.Warnings.warningAsException(1)
473 for kw in ['TARGET', 'TARGETS', 'SOURCE', 'SOURCES']:
477 except SCons.Warnings.ReservedVariableWarning:
479 assert exc_caught, "Did not catch ReservedVariableWarning for `%s'" % kw
480 assert not env4.has_key(kw), "`%s' variable was incorrectly set" % kw
482 SCons.Warnings.warningAsException(old)
484 def test_IllegalVariables(self):
485 """Test that use of illegal variables raises an exception"""
487 def test_it(var, env=env):
491 except SCons.Errors.UserError:
493 assert exc_caught, "did not catch UserError for '%s'" % var
495 assert env['aaa'] == 1, env['aaa']
500 def test_autogenerate(dict):
501 """Test autogenerating variables in a dictionary."""
504 return SCons.Node.FS.default_fs.Rsearchall(pathlist,
505 clazz=SCons.Node.FS.Dir,
507 cwd=SCons.Node.FS.default_fs.Dir('xx'))
509 env = Environment(LIBS = [ 'foo', 'bar', 'baz' ],
510 LIBLINKPREFIX = 'foo',
511 LIBLINKSUFFIX = 'bar',
513 flags = env.subst_list('$_LIBFLAGS', 1)[0]
514 assert len(flags) == 3, flags
515 assert flags[0] == 'foofoobar', \
517 assert flags[1] == 'foobarbar', \
519 assert flags[2] == 'foobazbar', \
522 blat = SCons.Node.FS.default_fs.Dir('blat')
524 env = Environment(CPPPATH = [ 'foo', '$FOO/bar', blat ],
529 flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
530 assert len(flags) == 8, flags
531 assert flags[0] == '$(', \
533 assert flags[1] == os.path.normpath('foo'), \
535 assert flags[2] == os.path.normpath('xx/foobar'), \
537 assert flags[3] == os.path.normpath('foo'), \
539 assert flags[4] == os.path.normpath('xx/baz/barbar'), \
541 assert flags[5] == os.path.normpath('foo'), \
543 assert flags[6] == os.path.normpath('blatbar'), \
545 assert flags[7] == '$)', \
548 env = Environment(F77PATH = [ 'foo', '$FOO/bar', blat ],
553 flags = env.subst_list('$_F77INCFLAGS', 1)[0]
554 assert len(flags) == 8, flags
555 assert flags[0] == '$(', \
557 assert flags[1] == os.path.normpath('foo'), \
559 assert flags[2] == os.path.normpath('xx/foobar'), \
561 assert flags[3] == os.path.normpath('foo'), \
563 assert flags[4] == os.path.normpath('xx/baz/barbar'), \
565 assert flags[5] == os.path.normpath('foo'), \
567 assert flags[6] == os.path.normpath('blatbar'), \
569 assert flags[7] == '$)', \
572 env = Environment(CPPPATH = '', F77PATH = '', LIBPATH = '',
574 l = env.subst_list('$_CPPINCFLAGS')
575 assert len(l[0]) == 0, l[0]
576 l = env.subst_list('$_F77INCFLAGS')
577 assert len(l[0]) == 0, l[0]
578 l = env.subst_list('$_LIBDIRFLAGS')
579 assert len(l[0]) == 0, l[0]
581 SCons.Node.FS.default_fs.Repository('/rep1')
582 SCons.Node.FS.default_fs.Repository('/rep2')
583 env = Environment(CPPPATH = [ 'foo', '/a/b', '$FOO/bar', blat],
588 flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
589 assert flags[0] == '$(', \
591 assert flags[1] == '-I', \
593 assert flags[2] == os.path.normpath('xx/fooXXX'), \
595 assert flags[3] == '-I', \
597 assert flags[4] == os.path.normpath('/rep1/xx/fooXXX'), \
599 assert flags[5] == '-I', \
601 assert flags[6] == os.path.normpath('/rep2/xx/fooXXX'), \
603 assert flags[7] == '-I', \
605 assert flags[8] == os.path.normpath('/a/bXXX'), \
607 assert flags[9] == '-I', \
609 assert flags[10] == os.path.normpath('xx/baz/barXXX'), \
611 assert flags[11] == '-I', \
613 assert flags[12] == os.path.normpath('/rep1/xx/baz/barXXX'), \
615 assert flags[13] == '-I', \
617 assert flags[14] == os.path.normpath('/rep2/xx/baz/barXXX'), \
619 assert flags[15] == '-I', \
621 assert flags[16] == os.path.normpath('blatXXX'), \
623 assert flags[17] == '$)', \
626 def test_platform(self):
627 """Test specifying a platform callable when instantiating."""
629 def __str__(self): return "TestPlatform"
630 def __call__(self, env): env['XYZZY'] = 777
633 env['SET_TOOL'] = 'initialized'
634 assert env['PLATFORM'] == "TestPlatform"
636 env = Environment(platform = platform(), tools = [tool])
637 assert env['XYZZY'] == 777, env
638 assert env['PLATFORM'] == "TestPlatform"
639 assert env['SET_TOOL'] == "initialized"
641 def test_Default_PLATFORM(self):
642 """Test overriding the default PLATFORM variable"""
644 def __str__(self): return "DefaultTestPlatform"
645 def __call__(self, env): env['XYZZY'] = 888
648 env['SET_TOOL'] = 'abcde'
649 assert env['PLATFORM'] == "DefaultTestPlatform"
651 import SCons.Defaults
652 save = SCons.Defaults.ConstructionEnvironment.copy()
654 import SCons.Defaults
655 SCons.Defaults.ConstructionEnvironment.update({
656 'PLATFORM' : platform(),
658 env = Environment(tools = [tool])
659 assert env['XYZZY'] == 888, env
660 assert env['PLATFORM'] == "DefaultTestPlatform"
661 assert env['SET_TOOL'] == "abcde"
663 SCons.Defaults.ConstructionEnvironment = save
665 def test_tools(self):
666 """Test specifying a tool callable when instantiating."""
672 env['AAA'] = env['XYZ']
675 env = Environment(tools = [t1, t2, t3], XYZ = 'aaa')
676 assert env['TOOL1'] == 111, env['TOOL1']
677 assert env['TOOL2'] == 222, env
678 assert env['AAA'] == 'aaa', env
680 assert env['TOOL4'] == 444, env
682 def test_Default_TOOLS(self):
683 """Test overriding the default TOOLS variable"""
689 env['BBB'] = env['XYZ']
693 import SCons.Defaults
694 save = SCons.Defaults.ConstructionEnvironment.copy()
696 SCons.Defaults.ConstructionEnvironment.update({
697 'TOOLS' : [t5, t6, t7],
699 env = Environment(XYZ = 'bbb')
700 assert env['TOOL5'] == 555, env['TOOL5']
701 assert env['TOOL6'] == 666, env
702 assert env['BBB'] == 'bbb', env
704 assert env['TOOL8'] == 888, env
706 SCons.Defaults.ConstructionEnvironment = save
708 def test_concat(self):
710 e1 = Environment(PRE='pre', SUF='suf', STR='a b', LIST=['a', 'b'])
712 x = s("${_concat('', '', '', __env__)}")
714 x = s("${_concat('', [], '', __env__)}")
716 x = s("${_concat(PRE, '', SUF, __env__)}")
718 x = s("${_concat(PRE, STR, SUF, __env__)}")
719 assert x == 'prea bsuf', x
720 x = s("${_concat(PRE, LIST, SUF, __env__)}")
721 assert x == 'preasuf prebsuf', x
725 def test_Append(self):
726 """Test appending to construction variables in an Environment
729 b1 = Environment()['BUILDERS']
730 b2 = Environment()['BUILDERS']
731 assert b1 == b2, diff_dict(b1, b2)
734 UL = UserList.UserList
735 env1 = Environment(AAA = 'a',
736 AAA1 = 'a1', AAA2 = 'a2', AAA3 = 'a3',
738 EEE1 = ['e1'], EEE2 = ['e2'], EEE3 = ['e3'],
740 III1 = UL(['i1']), III2 = UL(['i2']), III3 = UL(['i3']),
742 MMM1 = '', MMM2 = '', MMM3 = '',
744 NNN1 = [], NNN2 = [], NNN3 = [],
746 OOO1 = UL([]), OOO2 = UL([]), OOO3 = UL([]),
748 PPP1 = [''], PPP2 = [''], PPP3 = [''],
750 QQQ1 = UL(['']), QQQ2 = UL(['']), QQQ3 = UL(['']))
751 env1.Append(AAA1 = 'A1', AAA2 = ['A2'], AAA3 = UL(['A3']),
752 EEE1 = 'E1', EEE2 = ['E2'], EEE3 = UL(['E3']),
753 III1 = 'I1', III2 = ['I2'], III3 = UL(['I3']),
754 MMM1 = 'M1', MMM2 = ['M2'], MMM3 = UL(['M3']),
755 NNN1 = 'N1', NNN2 = ['N2'], NNN3 = UL(['N3']),
756 OOO1 = 'O1', OOO2 = ['O2'], OOO3 = UL(['O3']),
757 PPP1 = 'P1', PPP2 = ['P2'], PPP3 = UL(['P3']),
758 QQQ1 = 'Q1', QQQ2 = ['Q2'], QQQ3 = UL(['Q3']))
759 assert env1['AAA'] == 'a', env1['AAA']
760 assert env1['AAA1'] == 'a1A1', env1['AAA1']
761 assert env1['AAA2'] == ['a2', 'A2'], env1['AAA2']
762 assert env1['AAA3'] == UL(['a3', 'A3']), env1['AAA3']
763 assert env1['EEE'] == ['e'], env1['EEE']
764 assert env1['EEE1'] == ['e1', 'E1'], env1['EEE1']
765 assert env1['EEE2'] == ['e2', 'E2'], env1['EEE2']
766 assert env1['EEE3'] == UL(['e3', 'E3']), env1['EEE3']
767 assert env1['III'] == UL(['i']), env1['III']
768 assert env1['III1'] == UL(['i1', 'I1']), env1['III1']
769 assert env1['III2'] == UL(['i2', 'I2']), env1['III2']
770 assert env1['III3'] == UL(['i3', 'I3']), env1['III3']
771 assert env1['MMM'] == '', env1['MMM']
772 assert env1['MMM1'] == 'M1', env1['MMM1']
773 assert env1['MMM2'] == ['M2'], env1['MMM2']
774 assert env1['MMM3'] == UL(['M3']), env1['MMM3']
775 assert env1['NNN1'] == ['N1'], env1['NNN1']
776 assert env1['NNN2'] == ['N2'], env1['NNN2']
777 assert env1['NNN3'] == UL(['N3']), env1['NNN3']
778 assert env1['OOO1'] == ['O1'], env1['OOO1']
779 assert env1['OOO2'] == ['O2'], env1['OOO2']
780 assert env1['OOO3'] == UL(['O3']), env1['OOO3']
781 assert env1['PPP1'] == ['', 'P1'], env1['PPP1']
782 assert env1['PPP2'] == ['', 'P2'], env1['PPP2']
783 assert env1['PPP3'] == UL(['', 'P3']), env1['PPP3']
784 assert env1['QQQ1'] == UL(['', 'Q1']), env1['QQQ1']
785 assert env1['QQQ2'] == UL(['', 'Q2']), env1['QQQ2']
786 assert env1['QQQ3'] == UL(['', 'Q3']), env1['QQQ3']
789 def __init__(self, name):
793 def __cmp__(self, other):
794 raise "should not compare"
798 env2 = Environment(CCC1 = ['c1'], CCC2 = ccc)
799 env2.Append(CCC1 = ccc, CCC2 = ['c2'])
800 assert env2['CCC1'][0] == 'c1', env2['CCC1']
801 assert env2['CCC1'][1] is ccc, env2['CCC1']
802 assert env2['CCC2'][0] is ccc, env2['CCC2']
803 assert env2['CCC2'][1] == 'c2', env2['CCC2']
805 env3 = Environment(X = {'x1' : 7})
806 env3.Append(X = {'x1' : 8, 'x2' : 9}, Y = {'y1' : 10})
807 assert env3['X'] == {'x1': 8, 'x2': 9}, env3['X']
808 assert env3['Y'] == {'y1': 10}, env3['Y']
810 env4 = Environment(BUILDERS = {'z1' : 11})
811 env4.Append(BUILDERS = {'z2' : 12})
812 assert env4['BUILDERS'] == {'z1' : 11, 'z2' : 12}, env4['BUILDERS']
813 assert hasattr(env4, 'z1')
814 assert hasattr(env4, 'z2')
816 def test_AppendENVPath(self):
817 """Test appending to an ENV path."""
818 env1 = Environment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
819 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
820 # have to include the pathsep here so that the test will work on UNIX too.
821 env1.AppendENVPath('PATH',r'C:\dir\num\two', sep = ';')
822 env1.AppendENVPath('PATH',r'C:\dir\num\three', sep = ';')
823 env1.AppendENVPath('MYPATH',r'C:\mydir\num\three','MYENV', sep = ';')
824 env1.AppendENVPath('MYPATH',r'C:\mydir\num\one','MYENV', sep = ';')
825 assert(env1['ENV']['PATH'] == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
826 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\two;C:\mydir\num\three;C:\mydir\num\one')
829 """Test construction Environment copying
831 Update the copy independently afterwards and check that
832 the original remains intact (that is, no dangling
833 references point to objects in the copied environment).
834 Copy the original with some construction variable
835 updates and check that the original remains intact
836 and the copy has the updated values.
838 env1 = Environment(XXX = 'x', YYY = 'y')
840 env1copy = env1.Copy()
841 env2.Replace(YYY = 'yyy')
843 assert env1 == env1copy
845 env3 = env1.Copy(XXX = 'x3', ZZZ = 'z3')
846 assert env3.Dictionary('XXX') == 'x3'
847 assert env3.Dictionary('YYY') == 'y'
848 assert env3.Dictionary('ZZZ') == 'z3'
849 assert env1 == env1copy
851 # Ensure that lists and dictionaries are
852 # deep copied, but not instances.
855 env1 = Environment(XXX=TestA(), YYY = [ 1, 2, 3 ],
858 env2.Dictionary('YYY').append(4)
859 env2.Dictionary('ZZZ')[5] = 6
860 assert env1.Dictionary('XXX') is env2.Dictionary('XXX')
861 assert 4 in env2.Dictionary('YYY')
862 assert not 4 in env1.Dictionary('YYY')
863 assert env2.Dictionary('ZZZ').has_key(5)
864 assert not env1.Dictionary('ZZZ').has_key(5)
867 env1 = Environment(BUILDERS = {'b1' : 1})
868 assert hasattr(env1, 'b1'), "env1.b1 was not set"
869 assert env1.b1.env == env1, "b1.env doesn't point to env1"
870 env2 = env1.Copy(BUILDERS = {'b2' : 2})
871 assert hasattr(env1, 'b1'), "b1 was mistakenly cleared from env1"
872 assert env1.b1.env == env1, "b1.env was changed"
873 assert not hasattr(env2, 'b1'), "b1 was not cleared from env2"
874 assert hasattr(env2, 'b2'), "env2.b2 was not set"
875 assert env2.b2.env == env2, "b2.env doesn't point to env2"
877 # Ensure that specifying new tools in a copied environment
879 def foo(env): env['FOO'] = 1
880 def bar(env): env['BAR'] = 2
881 def baz(env): env['BAZ'] = 3
882 env1 = Environment(tools=[foo])
884 env3 = env1.Copy(tools=[bar, baz])
886 assert env1.get('FOO') is 1
887 assert env1.get('BAR') is None
888 assert env1.get('BAZ') is None
889 assert env2.get('FOO') is 1
890 assert env2.get('BAR') is None
891 assert env2.get('BAZ') is None
892 assert env3.get('FOO') is 1
893 assert env3.get('BAR') is 2
894 assert env3.get('BAZ') is 3
896 def test_Detect(self):
897 """Test Detect()ing tools"""
898 test = TestCmd.TestCmd(workdir = '')
899 test.subdir('sub1', 'sub2')
900 sub1 = test.workpath('sub1')
901 sub2 = test.workpath('sub2')
903 if sys.platform == 'win32':
904 test.write(['sub1', 'xxx'], "sub1/xxx\n")
905 test.write(['sub2', 'xxx'], "sub2/xxx\n")
907 env = Environment(ENV = { 'PATH' : [sub1, sub2] })
909 x = env.Detect('xxx.exe')
912 test.write(['sub2', 'xxx.exe'], "sub2/xxx.exe\n")
914 env = Environment(ENV = { 'PATH' : [sub1, sub2] })
916 x = env.Detect('xxx.exe')
917 assert x == 'xxx.exe', x
919 test.write(['sub1', 'xxx.exe'], "sub1/xxx.exe\n")
921 x = env.Detect('xxx.exe')
922 assert x == 'xxx.exe', x
925 test.write(['sub1', 'xxx.exe'], "sub1/xxx.exe\n")
926 test.write(['sub2', 'xxx.exe'], "sub2/xxx.exe\n")
928 env = Environment(ENV = { 'PATH' : [sub1, sub2] })
930 x = env.Detect('xxx.exe')
933 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
934 os.chmod(sub2_xxx_exe, 0755)
936 env = Environment(ENV = { 'PATH' : [sub1, sub2] })
938 x = env.Detect('xxx.exe')
939 assert x == 'xxx.exe', x
941 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
942 os.chmod(sub1_xxx_exe, 0755)
944 x = env.Detect('xxx.exe')
945 assert x == 'xxx.exe', x
947 env = Environment(ENV = { 'PATH' : [] })
948 x = env.Detect('xxx.exe')
951 def test_Dictionary(self):
952 """Test retrieval of known construction variables
954 Fetch them from the Dictionary and check for well-known
955 defaults that get inserted.
957 env = Environment(XXX = 'x', YYY = 'y', ZZZ = 'z')
958 assert env.Dictionary('XXX') == 'x'
959 assert env.Dictionary('YYY') == 'y'
960 assert env.Dictionary('XXX', 'ZZZ') == ['x', 'z']
961 xxx, zzz = env.Dictionary('XXX', 'ZZZ')
964 assert env.Dictionary().has_key('BUILDERS')
965 assert env.Dictionary().has_key('CC')
966 assert env.Dictionary().has_key('CCFLAGS')
967 assert env.Dictionary().has_key('ENV')
969 assert env['XXX'] == 'x'
971 assert env.Dictionary('XXX') == 'foo'
973 assert not env.Dictionary().has_key('XXX')
975 def test_FindIxes(self):
977 env = Environment(LIBPREFIX='lib',
984 paths = [os.path.join('dir', 'libfoo.a'),
985 os.path.join('dir', 'libfoo.so')]
987 assert paths[0] == env.FindIxes(paths, 'LIBPREFIX', 'LIBSUFFIX')
988 assert paths[1] == env.FindIxes(paths, 'SHLIBPREFIX', 'SHLIBSUFFIX')
989 assert None == env.FindIxes(paths, 'PREFIX', 'POST')
991 paths = ['libfoo.a', 'prefoopost']
993 assert paths[0] == env.FindIxes(paths, 'LIBPREFIX', 'LIBSUFFIX')
994 assert None == env.FindIxes(paths, 'SHLIBPREFIX', 'SHLIBSUFFIX')
995 assert paths[1] == env.FindIxes(paths, 'PREFIX', 'SUFFIX')
997 def test_Override(self):
998 "Test overriding construction variables"
999 env = Environment(ONE=1, TWO=2)
1000 assert env['ONE'] == 1
1001 assert env['TWO'] == 2
1002 env2 = env.Override({'TWO':'10'})
1003 assert env2['ONE'] == 1
1004 assert env2['TWO'] == '10'
1005 assert env['TWO'] == 2
1006 env2.Replace(ONE = "won")
1007 assert env2['ONE'] == "won"
1008 assert env['ONE'] == 1
1010 def test_ParseConfig(self):
1011 """Test the ParseConfig() method"""
1012 env = Environment(COMMAND='command',
1018 orig_popen = os.popen
1019 def my_popen(command, save_command=save_command):
1020 save_command.append(command)
1023 return "-I/usr/include/fum -Ibar -X\n" + \
1024 "-L/usr/fax -Lfoo -lxxx abc"
1028 libs = env.ParseConfig("fake $COMMAND")
1029 assert save_command == ['fake command'], save_command
1030 assert libs == ['abc'], libs
1031 assert env['CPPPATH'] == ['string', '/usr/include/fum', 'bar'], env['CPPPATH']
1032 assert env['LIBPATH'] == ['list', '/usr/fax', 'foo'], env['LIBPATH']
1033 assert env['LIBS'] == ['xxx'], env['LIBS']
1034 assert env['CCFLAGS'] == ['', '-X'], env['CCFLAGS']
1036 os.popen = orig_popen
1038 def test_Platform(self):
1039 """Test the Platform() method"""
1040 env = Environment(WIN32='win32', NONE='no-such-platform')
1044 env.Platform('does_not_exist')
1045 except SCons.Errors.UserError:
1047 assert exc_caught, "did not catch expected UserError"
1051 env.Platform('$NONE')
1052 except SCons.Errors.UserError:
1054 assert exc_caught, "did not catch expected UserError"
1056 env.Platform('posix')
1057 assert env['OBJSUFFIX'] == '.o', env['OBJSUFFIX']
1059 env.Platform('$WIN32')
1060 assert env['OBJSUFFIX'] == '.obj', env['OBJSUFFIX']
1062 def test_Prepend(self):
1063 """Test prepending to construction variables in an Environment
1066 UL = UserList.UserList
1067 env1 = Environment(AAA = 'a', BBB = 'b', CCC = 'c', DDD = 'd',
1068 EEE = ['e'], FFF = ['f'], GGG = ['g'], HHH = ['h'],
1069 III = UL(['i']), JJJ = UL(['j']),
1070 KKK = UL(['k']), LLL = UL(['l']))
1071 env1.Prepend(BBB = 'B', CCC = ['C'], DDD = UL(['D']),
1072 FFF = 'F', GGG = ['G'], HHH = UL(['H']),
1073 JJJ = 'J', KKK = ['K'], LLL = UL(['L']))
1074 env2 = Environment(AAA = 'a', BBB = 'Bb',
1075 CCC = ['C', 'c'], DDD = UL(['D', 'd']),
1076 EEE = ['e'], FFF = ['F', 'f'],
1077 GGG = ['G', 'g'], HHH = UL(['H', 'h']),
1078 III = UL(['i']), JJJ = UL(['J', 'j']),
1079 KKK = UL(['K', 'k']), LLL = UL(['L', 'l']))
1080 assert env1 == env2, diff_env(env1, env2)
1082 env3 = Environment(X = {'x1' : 7})
1083 env3.Prepend(X = {'x1' : 8, 'x2' : 9}, Y = {'y1' : 10})
1084 assert env3['X'] == {'x1': 8, 'x2' : 9}, env3['X']
1085 assert env3['Y'] == {'y1': 10}, env3['Y']
1087 env4 = Environment(BUILDERS = {'z1' : 11})
1088 env4.Prepend(BUILDERS = {'z2' : 12})
1089 assert env4['BUILDERS'] == {'z1' : 11, 'z2' : 12}, env4['BUILDERS']
1090 assert hasattr(env4, 'z1')
1091 assert hasattr(env4, 'z2')
1093 def test_PrependENVPath(self):
1094 """Test prepending to an ENV path."""
1095 env1 = Environment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
1096 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
1097 # have to include the pathsep here so that the test will work on UNIX too.
1098 env1.PrependENVPath('PATH',r'C:\dir\num\two',sep = ';')
1099 env1.PrependENVPath('PATH',r'C:\dir\num\three',sep = ';')
1100 env1.PrependENVPath('MYPATH',r'C:\mydir\num\three','MYENV',sep = ';')
1101 env1.PrependENVPath('MYPATH',r'C:\mydir\num\one','MYENV',sep = ';')
1102 assert(env1['ENV']['PATH'] == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
1103 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
1105 def test_PrependENVPath(self):
1106 """Test prepending to an ENV path."""
1107 env1 = Environment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
1108 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
1109 # have to include the pathsep here so that the test will work on UNIX too.
1110 env1.PrependENVPath('PATH',r'C:\dir\num\two',sep = ';')
1111 env1.PrependENVPath('PATH',r'C:\dir\num\three',sep = ';')
1112 env1.PrependENVPath('MYPATH',r'C:\mydir\num\three','MYENV',sep = ';')
1113 env1.PrependENVPath('MYPATH',r'C:\mydir\num\one','MYENV',sep = ';')
1114 assert(env1['ENV']['PATH'] == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
1115 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
1117 def test_Replace(self):
1118 """Test replacing construction variables in an Environment
1120 After creation of the Environment, of course.
1122 env1 = Environment(AAA = 'a', BBB = 'b')
1123 env1.Replace(BBB = 'bbb', CCC = 'ccc')
1125 env2 = Environment(AAA = 'a', BBB = 'bbb', CCC = 'ccc')
1126 assert env1 == env2, diff_env(env1, env2)
1128 env3 = Environment(BUILDERS = {'b1' : 1})
1129 assert hasattr(env3, 'b1'), "b1 was not set"
1130 env3.Replace(BUILDERS = {'b2' : 2})
1131 assert not hasattr(env3, 'b1'), "b1 was not cleared"
1132 assert hasattr(env3, 'b2'), "b2 was not set"
1134 def test_ReplaceIxes(self):
1135 "Test ReplaceIxes()"
1136 env = Environment(LIBPREFIX='lib',
1143 assert 'libfoo.a' == env.ReplaceIxes('libfoo.so',
1144 'SHLIBPREFIX', 'SHLIBSUFFIX',
1145 'LIBPREFIX', 'LIBSUFFIX')
1147 assert os.path.join('dir', 'libfoo.a') == env.ReplaceIxes(os.path.join('dir', 'libfoo.so'),
1148 'SHLIBPREFIX', 'SHLIBSUFFIX',
1149 'LIBPREFIX', 'LIBSUFFIX')
1151 assert 'libfoo.a' == env.ReplaceIxes('prefoopost',
1153 'LIBPREFIX', 'LIBSUFFIX')
1155 def test_Tool(self):
1156 """Test the Tool() method"""
1157 env = Environment(LINK='link', NONE='no-such-tool')
1161 env.Tool('does_not_exist')
1162 except SCons.Errors.UserError:
1164 assert exc_caught, "did not catch expected UserError"
1169 except SCons.Errors.UserError:
1171 assert exc_caught, "did not catch expected UserError"
1173 # Use a non-existent toolpath directory just to make sure we
1174 # can call Tool() with the keyword argument.
1175 env.Tool('cc', toolpath=['/no/such/directory'])
1176 assert env['CC'] == 'cc', env['CC']
1179 assert env['LINK'] == '$SMARTLINK', env['LINK']
1181 def test_WhereIs(self):
1182 """Test the WhereIs() method"""
1183 test = TestCmd.TestCmd(workdir = '')
1185 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
1186 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
1187 sub3_xxx_exe = test.workpath('sub3', 'xxx.exe')
1188 sub4_xxx_exe = test.workpath('sub4', 'xxx.exe')
1190 test.subdir('subdir', 'sub1', 'sub2', 'sub3', 'sub4')
1192 if sys.platform != 'win32':
1193 test.write(sub1_xxx_exe, "\n")
1195 os.mkdir(sub2_xxx_exe)
1197 test.write(sub3_xxx_exe, "\n")
1198 os.chmod(sub3_xxx_exe, 0777)
1200 test.write(sub4_xxx_exe, "\n")
1201 os.chmod(sub4_xxx_exe, 0777)
1203 env_path = os.environ['PATH']
1205 pathdirs_1234 = [ test.workpath('sub1'),
1206 test.workpath('sub2'),
1207 test.workpath('sub3'),
1208 test.workpath('sub4'),
1209 ] + string.split(env_path, os.pathsep)
1211 pathdirs_1243 = [ test.workpath('sub1'),
1212 test.workpath('sub2'),
1213 test.workpath('sub4'),
1214 test.workpath('sub3'),
1215 ] + string.split(env_path, os.pathsep)
1217 path = string.join(pathdirs_1234, os.pathsep)
1218 env = Environment(ENV = {'PATH' : path})
1219 wi = env.WhereIs('xxx.exe')
1220 assert wi == test.workpath(sub3_xxx_exe), wi
1221 wi = env.WhereIs('xxx.exe', pathdirs_1243)
1222 assert wi == test.workpath(sub4_xxx_exe), wi
1223 wi = env.WhereIs('xxx.exe', string.join(pathdirs_1243, os.pathsep))
1224 assert wi == test.workpath(sub4_xxx_exe), wi
1226 path = string.join(pathdirs_1243, os.pathsep)
1227 env = Environment(ENV = {'PATH' : path})
1228 wi = env.WhereIs('xxx.exe')
1229 assert wi == test.workpath(sub4_xxx_exe), wi
1230 wi = env.WhereIs('xxx.exe', pathdirs_1234)
1231 assert wi == test.workpath(sub3_xxx_exe), wi
1232 wi = env.WhereIs('xxx.exe', string.join(pathdirs_1234, os.pathsep))
1233 assert wi == test.workpath(sub3_xxx_exe), wi
1235 if sys.platform == 'win32':
1236 wi = env.WhereIs('xxx', pathext = '')
1237 assert wi is None, wi
1239 wi = env.WhereIs('xxx', pathext = '.exe')
1240 assert wi == test.workpath(sub4_xxx_exe), wi
1242 wi = env.WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
1243 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
1245 # Test that we return a normalized path even when
1246 # the path contains forward slashes.
1247 forward_slash = test.workpath('') + '/sub3'
1248 wi = env.WhereIs('xxx', path = forward_slash, pathext = '.EXE')
1249 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
1253 def test_Action(self):
1254 """Test the Action() method"""
1257 env = Environment(FOO = 'xyzzy')
1259 a = env.Action('foo')
1261 assert a.__class__ is SCons.Action.CommandAction, a
1263 a = env.Action('$FOO')
1265 assert a.__class__ is SCons.Action.CommandGeneratorAction, a
1267 a = env.Action(['$FOO', 'foo'])
1269 assert a.__class__ is SCons.Action.ListAction, a
1273 a = env.Action(func)
1275 assert a.__class__ is SCons.Action.FunctionAction, a
1277 def test_AddPostAction(self):
1278 """Test the AddPostAction() method"""
1279 env = Environment(FOO='fff', BAR='bbb')
1281 n = env.AddPostAction('$FOO', lambda x: x)
1282 assert str(n[0]) == 'fff', n[0]
1284 n = env.AddPostAction(['ggg', '$BAR'], lambda x: x)
1285 assert str(n[0]) == 'ggg', n[0]
1286 assert str(n[1]) == 'bbb', n[1]
1288 def test_AddPreAction(self):
1289 """Test the AddPreAction() method"""
1290 env = Environment(FOO='fff', BAR='bbb')
1292 n = env.AddPreAction('$FOO', lambda x: x)
1293 assert str(n[0]) == 'fff', n[0]
1295 n = env.AddPreAction(['ggg', '$BAR'], lambda x: x)
1296 assert str(n[0]) == 'ggg', n[0]
1297 assert str(n[1]) == 'bbb', n[1]
1299 def test_Alias(self):
1300 """Test the Alias() method"""
1301 env = Environment(FOO='kkk', BAR='lll', EA='export_alias')
1303 tgt = env.Alias('new_alias')
1304 assert str(tgt) == 'new_alias', tgt
1305 assert tgt.sources == [], tgt.sources
1307 tgt = env.Alias('None_alias', None)
1308 assert str(tgt) == 'None_alias', tgt
1309 assert tgt.sources == [], tgt.sources
1311 tgt = env.Alias('empty_list', [])
1312 assert str(tgt) == 'empty_list', tgt
1313 assert tgt.sources == [], tgt.sources
1315 tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ])
1316 assert str(tgt) == 'export_alias', tgt
1317 assert len(tgt.sources) == 2, map(str, tgt.sources)
1318 assert str(tgt.sources[0]) == 'asrc1', map(str, tgt.sources)
1319 assert str(tgt.sources[1]) == 'kkk', map(str, tgt.sources)
1321 n = env.Alias(tgt, source = ['$BAR', 'asrc4'])
1323 assert len(tgt.sources) == 4, map(str, tgt.sources)
1324 assert str(tgt.sources[2]) == 'lll', map(str, tgt.sources)
1325 assert str(tgt.sources[3]) == 'asrc4', map(str, tgt.sources)
1327 n = env.Alias('$EA', 'asrc5')
1329 assert len(tgt.sources) == 5, map(str, tgt.sources)
1330 assert str(tgt.sources[4]) == 'asrc5', map(str, tgt.sources)
1332 t1, t2 = env.Alias(['t1', 't2'], ['asrc6', 'asrc7'])
1333 assert str(t1) == 't1', t1
1334 assert str(t2) == 't2', t2
1335 assert len(t1.sources) == 2, map(str, t1.sources)
1336 assert str(t1.sources[0]) == 'asrc6', map(str, t1.sources)
1337 assert str(t1.sources[1]) == 'asrc7', map(str, t1.sources)
1338 assert len(t2.sources) == 2, map(str, t2.sources)
1339 assert str(t2.sources[0]) == 'asrc6', map(str, t2.sources)
1340 assert str(t2.sources[1]) == 'asrc7', map(str, t2.sources)
1342 def test_AlwaysBuild(self):
1343 """Test the AlwaysBuild() method"""
1344 env = Environment(FOO='fff', BAR='bbb')
1345 t = env.AlwaysBuild('a', 'b$FOO', ['c', 'd'], '$BAR')
1346 assert t[0].__class__.__name__ == 'File'
1347 assert t[0].path == 'a'
1348 assert t[0].always_build
1349 assert t[1].__class__.__name__ == 'File'
1350 assert t[1].path == 'bfff'
1351 assert t[1].always_build
1352 assert t[2].__class__.__name__ == 'File'
1353 assert t[2].path == 'c'
1354 assert t[2].always_build
1355 assert t[3].__class__.__name__ == 'File'
1356 assert t[3].path == 'd'
1357 assert t[3].always_build
1358 assert t[4].__class__.__name__ == 'File'
1359 assert t[4].path == 'bbb'
1360 assert t[4].always_build
1362 def test_BuildDir(self):
1363 """Test the BuildDir() method"""
1365 def Dir(self, name):
1367 def BuildDir(self, build_dir, src_dir, duplicate):
1368 self.build_dir = build_dir
1369 self.src_dir = src_dir
1370 self.duplicate = duplicate
1372 env = Environment(FOO = 'fff', BAR = 'bbb')
1375 env.BuildDir('build', 'src')
1376 assert env.fs.build_dir == 'build', env.fs.build_dir
1377 assert env.fs.src_dir == 'src', env.fs.src_dir
1378 assert env.fs.duplicate == 1, env.fs.duplicate
1380 env.BuildDir('build${FOO}', '${BAR}src', 0)
1381 assert env.fs.build_dir == 'buildfff', env.fs.build_dir
1382 assert env.fs.src_dir == 'bbbsrc', env.fs.src_dir
1383 assert env.fs.duplicate == 0, env.fs.duplicate
1385 def test_Builder(self):
1386 """Test the Builder() method"""
1387 env = Environment(FOO = 'xyzzy')
1389 b = env.Builder(action = 'foo')
1390 assert not b is None, b
1392 b = env.Builder(action = '$FOO')
1393 assert not b is None, b
1395 b = env.Builder(action = ['$FOO', 'foo'])
1396 assert not b is None, b
1400 b = env.Builder(action = func)
1401 assert not b is None, b
1402 b = env.Builder(generator = func)
1403 assert not b is None, b
1405 def test_CacheDir(self):
1406 """Test the CacheDir() method"""
1408 def CacheDir(self, path):
1411 env = Environment(CD = 'CacheDir')
1415 assert env.fs.CD == 'foo', env.fs.CD
1418 assert env.fs.CD == 'CacheDir', env.fs.CD
1420 def test_Clean(self):
1421 """Test the Clean() method"""
1422 env = Environment(FOO = 'fff', BAR = 'bbb')
1424 CT = SCons.Environment.CleanTargets
1426 foo = env.arg2nodes('foo')[0]
1427 fff = env.arg2nodes('fff')[0]
1429 t = env.Clean('foo', 'aaa')
1430 l = map(str, CT[foo])
1431 assert l == ['aaa'], l
1433 t = env.Clean(foo, ['$BAR', 'ccc'])
1434 l = map(str, CT[foo])
1435 assert l == ['aaa', 'bbb', 'ccc'], l
1437 eee = env.arg2nodes('eee')[0]
1439 t = env.Clean('$FOO', 'ddd')
1440 l = map(str, CT[fff])
1441 assert l == ['ddd'], l
1442 t = env.Clean(fff, [eee, 'fff'])
1443 l = map(str, CT[fff])
1444 assert l == ['ddd', 'eee', 'fff'], l
1446 def test_Command(self):
1447 """Test the Command() method."""
1449 t = env.Command(target='foo.out', source=['foo1.in', 'foo2.in'],
1450 action='buildfoo $target $source')
1451 assert not t.builder is None
1452 assert t.builder.action.__class__.__name__ == 'CommandAction'
1453 assert t.builder.action.cmd_list == 'buildfoo $target $source'
1454 assert 'foo1.in' in map(lambda x: x.path, t.sources)
1455 assert 'foo2.in' in map(lambda x: x.path, t.sources)
1457 sub = SCons.Node.FS.default_fs.Dir('sub')
1458 t = env.Command(target='bar.out', source='sub',
1459 action='buildbar $target $source')
1460 assert 'sub' in map(lambda x: x.path, t.sources)
1462 def testFunc(env, target, source):
1463 assert str(target[0]) == 'foo.out'
1464 assert 'foo1.in' in map(str, source) and 'foo2.in' in map(str, source), map(str, source)
1466 t = env.Command(target='foo.out', source=['foo1.in','foo2.in'],
1468 assert not t.builder is None
1469 assert t.builder.action.__class__.__name__ == 'FunctionAction'
1471 assert 'foo1.in' in map(lambda x: x.path, t.sources)
1472 assert 'foo2.in' in map(lambda x: x.path, t.sources)
1474 def test_Configure(self):
1475 """Test the Configure() method"""
1476 # Configure() will write to a local temporary file.
1477 test = TestCmd.TestCmd(workdir = '')
1479 # Configure() will test, if we are reading a SConscript file
1480 import SCons.Script.SConscript
1481 SCons.Script.SConscript.sconscript_reading = 1
1484 os.chdir(test.workpath())
1486 env = Environment(FOO = 'xyzzy')
1492 assert not c is None, c
1495 c = env.Configure(custom_tests = {'foo' : func, '$FOO' : func})
1496 assert not c is None, c
1497 assert hasattr(c, 'foo')
1498 assert hasattr(c, 'xyzzy')
1503 def test_Depends(self):
1504 """Test the explicit Depends method."""
1505 env = Environment(FOO = 'xxx', BAR='yyy')
1510 t = env.Depends(target='EnvironmentTest.py', dependency='Environment.py')
1511 assert t.__class__.__name__ == 'Entry', t.__class__.__name__
1512 assert t.path == 'EnvironmentTest.py'
1513 assert len(t.depends) == 1
1515 assert d.__class__.__name__ == 'Entry', d.__class__.__name__
1516 assert d.path == 'Environment.py'
1518 t = env.Depends(target='${FOO}.py', dependency='${BAR}.py')
1519 assert t.__class__.__name__ == 'File', t.__class__.__name__
1520 assert t.path == 'xxx.py'
1521 assert len(t.depends) == 1
1523 assert d.__class__.__name__ == 'File', d.__class__.__name__
1524 assert d.path == 'yyy.py'
1526 t = env.Depends(target='dir1', dependency='dir2')
1527 assert t.__class__.__name__ == 'Dir', t.__class__.__name__
1528 assert t.path == 'dir1'
1529 assert len(t.depends) == 1
1531 assert d.__class__.__name__ == 'Dir', d.__class__.__name__
1532 assert d.path == 'dir2'
1535 """Test the Dir() method"""
1537 def Dir(self, name):
1538 return 'Dir(%s)' % name
1540 env = Environment(FOO = 'foodir', BAR = 'bardir')
1544 assert d == 'Dir(d)', d
1547 assert d == 'Dir(foodir)', d
1549 d = env.Dir('${BAR}_$BAR')
1550 assert d == 'Dir(bardir_bardir)', d
1552 def test_Environment(self):
1553 """Test the Environment() method"""
1554 env = Environment(FOO = 'xxx', BAR = 'yyy')
1556 e2 = env.Environment(X = '$FOO', Y = '$BAR')
1557 assert e2['X'] == 'xxx', e2['X']
1558 assert e2['Y'] == 'yyy', e2['Y']
1560 def test_File(self):
1561 """Test the File() method"""
1563 def File(self, name):
1564 return 'File(%s)' % name
1566 env = Environment(FOO = 'foofile', BAR = 'barfile')
1570 assert f == 'File(f)', f
1572 f = env.File('$FOO')
1573 assert f == 'File(foofile)', f
1575 f = env.File('${BAR}_$BAR')
1576 assert f == 'File(barfile_barfile)', f
1578 def test_FindFile(self):
1579 """Test the FindFile() method"""
1580 env = Environment(FOO = 'fff', BAR = 'bbb')
1582 r = env.FindFile('foo', ['no_such_directory'])
1587 def test_GetBuildPath(self):
1588 """Test the GetBuildPath() method."""
1589 env = Environment(MAGIC = 'xyzzy')
1591 p = env.GetBuildPath('foo')
1592 assert p == 'foo', p
1594 p = env.GetBuildPath('$MAGIC')
1595 assert p == 'xyzzy', p
1597 def test_Ignore(self):
1598 """Test the explicit Ignore method."""
1599 env = Environment(FOO='yyy', BAR='zzz')
1605 t = env.Ignore(target='targ.py', dependency='dep.py')
1606 assert t.__class__.__name__ == 'Entry', t.__class__.__name__
1607 assert t.path == 'targ.py'
1608 assert len(t.ignore) == 1
1610 assert i.__class__.__name__ == 'Entry', i.__class__.__name__
1611 assert i.path == 'dep.py'
1613 t = env.Ignore(target='$FOO$BAR', dependency='$BAR$FOO')
1614 assert t.__class__.__name__ == 'File', t.__class__.__name__
1615 assert t.path == 'yyyzzz'
1616 assert len(t.ignore) == 1
1618 assert i.__class__.__name__ == 'File', i.__class__.__name__
1619 assert i.path == 'zzzyyy'
1621 t = env.Ignore(target='dir1', dependency='dir2')
1622 assert t.__class__.__name__ == 'Dir', t.__class__.__name__
1623 assert t.path == 'dir1'
1624 assert len(t.ignore) == 1
1626 assert i.__class__.__name__ == 'Dir', i.__class__.__name__
1627 assert i.path == 'dir2'
1629 def test_Install(self):
1630 """Test the Install method"""
1631 env = Environment(FOO='iii', BAR='jjj')
1633 tgt = env.Install('export', [ 'build/foo1', 'build/foo2' ])
1634 paths = map(str, tgt)
1636 expect = map(os.path.normpath, [ 'export/foo1', 'export/foo2' ])
1637 assert paths == expect, paths
1639 assert tnode.builder == InstallBuilder
1641 tgt = env.Install('$FOO', [ 'build/${BAR}1', 'build/${BAR}2' ])
1642 paths = map(str, tgt)
1644 expect = map(os.path.normpath, [ 'iii/jjj1', 'iii/jjj2' ])
1645 assert paths == expect, paths
1647 assert tnode.builder == InstallBuilder
1651 tgt = env.Install('export', 'export')
1652 except SCons.Errors.UserError, e:
1654 assert exc_caught, "UserError should be thrown when Install() target is not a file."
1655 match = str(e) == "Source `export' of Install() is not a file. Install() source must be one or more files."
1660 tgt = env.Install('export', ['export', 'build/foo1'])
1661 except SCons.Errors.UserError, e:
1663 assert exc_caught, "UserError should be thrown when Install() target containins non-files."
1664 match = str(e) == "Source `['export', 'build/foo1']' of Install() contains one or more non-files. Install() source must be one or more files."
1669 tgt = env.Install('export/foo1', 'build/foo1')
1670 except SCons.Errors.UserError, e:
1672 assert exc_caught, "UserError should be thrown reversing the order of Install() targets."
1673 match = str(e) == "Target `export/foo1' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?"
1676 def test_InstallAs(self):
1677 """Test the InstallAs method"""
1678 env = Environment(FOO='iii', BAR='jjj')
1680 tgt = env.InstallAs(target=string.split('foo1 foo2'),
1681 source=string.split('bar1 bar2'))
1682 assert len(tgt) == 2, len(tgt)
1683 paths = map(lambda x: str(x.sources[0]), tgt)
1685 expect = map(os.path.normpath, [ 'bar1', 'bar2' ])
1686 assert paths == expect, paths
1688 assert tnode.builder == InstallBuilder
1690 tgt = env.InstallAs(target='${FOO}.t', source='${BAR}.s')
1691 assert tgt.path == 'iii.t'
1692 assert tgt.sources[0].path == 'jjj.s'
1693 assert tgt.builder == InstallBuilder
1695 def test_Literal(self):
1696 """Test the Literal() method"""
1697 env = Environment(FOO='fff', BAR='bbb')
1698 list = env.subst_list([env.Literal('$FOO'), '$BAR'])[0]
1699 assert list == ['$FOO', 'bbb'], list
1700 list = env.subst_list(['$FOO', env.Literal('$BAR')])[0]
1701 assert list == ['fff', '$BAR'], list
1703 def test_Local(self):
1704 """Test the Local() method."""
1705 env = Environment(FOO='lll')
1707 l = env.Local(env.fs.File('fff'))
1708 assert str(l[0]) == 'fff', l[0]
1710 l = env.Local('ggg', '$FOO')
1711 assert str(l[0]) == 'ggg', l[0]
1712 assert str(l[1]) == 'lll', l[1]
1714 def test_Precious(self):
1715 """Test the Precious() method"""
1716 env = Environment(FOO='ggg', BAR='hhh')
1719 t = env.Precious('p_a', 'p_${BAR}b', ['p_c', 'p_d'], 'p_$FOO')
1721 assert t[0].__class__.__name__ == 'Entry', t[0].__class__.__name__
1722 assert t[0].path == 'p_a'
1723 assert t[0].precious
1724 assert t[1].__class__.__name__ == 'Dir', t[1].__class__.__name__
1725 assert t[1].path == 'p_hhhb'
1726 assert t[1].precious
1727 assert t[2].__class__.__name__ == 'Entry', t[2].__class__.__name__
1728 assert t[2].path == 'p_c'
1729 assert t[2].precious
1730 assert t[3].__class__.__name__ == 'File', t[3].__class__.__name__
1731 assert t[3].path == 'p_d'
1732 assert t[3].precious
1733 assert t[4].__class__.__name__ == 'Entry', t[4].__class__.__name__
1734 assert t[4].path == 'p_ggg'
1735 assert t[4].precious
1737 def test_Repository(self):
1738 """Test the Repository() method."""
1742 def Repository(self, *dirs):
1743 self.list.extend(list(dirs))
1744 def Dir(self, name):
1746 env = Environment(FOO='rrr', BAR='sss')
1748 env.Repository('/tmp/foo')
1749 env.Repository('/tmp/$FOO', '/tmp/$BAR/foo')
1750 expect = ['/tmp/foo', '/tmp/rrr', '/tmp/sss/foo']
1751 assert env.fs.list == expect, env.fs.list
1753 def test_Scanner(self):
1754 """Test the Scanner() method"""
1755 def scan(node, env, target, arg):
1758 env = Environment(FOO = scan)
1760 s = env.Scanner('foo')
1761 assert not s is None, s
1763 s = env.Scanner(function = 'foo')
1764 assert not s is None, s
1767 s = env.Scanner('$FOO')
1768 assert not s is None, s
1770 s = env.Scanner(function = '$FOO')
1771 assert not s is None, s
1773 def test_SConsignFile(self):
1774 """Test the SConsignFile() method"""
1778 SConstruct_dir = os.sep + 'dir'
1780 env = Environment(FOO = 'SConsign',
1781 BAR = os.path.join(os.sep, 'File'))
1787 def capture(name, dbm_module, fnames=fnames, dbms=dbms):
1789 dbms.append(dbm_module)
1791 save_Sig_SConsignFile = SCons.Sig.SConsignFile
1792 SCons.Sig.SConsignFile = capture
1794 env.SConsignFile('foo')
1795 assert fnames[0] == os.path.join(os.sep, 'dir', 'foo'), fnames
1796 assert dbms[0] == None, dbms
1798 env.SConsignFile('$FOO')
1799 assert fnames[1] == os.path.join(os.sep, 'dir', 'SConsign'), fnames
1800 assert dbms[1] == None, dbms
1802 env.SConsignFile('/$FOO')
1803 assert fnames[2] == '/SConsign', fnames
1804 assert dbms[2] == None, dbms
1806 env.SConsignFile('$BAR', 'x')
1807 assert fnames[3] == os.path.join(os.sep, 'File'), fnames
1808 assert dbms[3] == 'x', dbms
1810 env.SConsignFile('__$BAR', 7)
1811 assert fnames[4] == os.path.join(os.sep, 'dir', '__', 'File'), fnames
1812 assert dbms[4] == 7, dbms
1814 SCons.Sig.SConsignFile = save_Sig_SConsignFile
1816 def test_SideEffect(self):
1817 """Test the SideEffect() method"""
1818 env = Environment(LIB='lll', FOO='fff', BAR='bbb')
1819 env.File('mylll.pdb')
1820 env.Dir('mymmm.pdb')
1822 foo = env.Object('foo.obj', 'foo.cpp')
1823 bar = env.Object('bar.obj', 'bar.cpp')
1824 s = env.SideEffect('mylib.pdb', ['foo.obj', 'bar.obj'])
1825 assert s.__class__.__name__ == 'Entry', s.__class__.__name__
1826 assert s.path == 'mylib.pdb'
1827 assert s.side_effect
1828 assert foo.side_effects == [s]
1829 assert bar.side_effects == [s]
1830 assert s.depends_on([bar])
1831 assert s.depends_on([foo])
1833 fff = env.Object('fff.obj', 'fff.cpp')
1834 bbb = env.Object('bbb.obj', 'bbb.cpp')
1835 s = env.SideEffect('my${LIB}.pdb', ['${FOO}.obj', '${BAR}.obj'])
1836 assert s.__class__.__name__ == 'File', s.__class__.__name__
1837 assert s.path == 'mylll.pdb'
1838 assert s.side_effect
1839 assert fff.side_effects == [s], fff.side_effects
1840 assert bbb.side_effects == [s], bbb.side_effects
1841 assert s.depends_on([bbb])
1842 assert s.depends_on([fff])
1844 ggg = env.Object('ggg.obj', 'ggg.cpp')
1845 ccc = env.Object('ccc.obj', 'ccc.cpp')
1846 s = env.SideEffect('mymmm.pdb', ['ggg.obj', 'ccc.obj'])
1847 assert s.__class__.__name__ == 'Dir', s.__class__.__name__
1848 assert s.path == 'mymmm.pdb'
1849 assert s.side_effect
1850 assert ggg.side_effects == [s], ggg.side_effects
1851 assert ccc.side_effects == [s], ccc.side_effects
1852 assert s.depends_on([ccc])
1853 assert s.depends_on([ggg])
1855 def test_SourceCode(self):
1856 """Test the SourceCode() method."""
1857 env = Environment(FOO='mmm', BAR='nnn')
1858 e = env.SourceCode('foo', None)
1859 assert e.path == 'foo'
1864 e = env.SourceCode(e, b)
1865 assert e.path == 'foo'
1869 e = env.SourceCode('$BAR$FOO', None)
1870 assert e.path == 'nnnmmm'
1874 def test_SourceSignatures(type):
1875 """Test the SourceSignatures() method"""
1876 env = Environment(M = 'MD5', T = 'timestamp')
1880 env.SourceSignatures('invalid_type')
1881 except SCons.Errors.UserError:
1883 assert exc_caught, "did not catch expected UserError"
1884 assert not hasattr(env, '_calc_module')
1886 env.SourceSignatures('MD5')
1887 m = env._calc_module
1889 env.SourceSignatures('$M')
1890 assert env._calc_module is m
1892 env.SourceSignatures('timestamp')
1893 t = env._calc_module
1895 env.SourceSignatures('$T')
1896 assert env._calc_module is t
1898 def test_Split(self):
1899 """Test the Split() method"""
1900 env = Environment(FOO='fff', BAR='bbb')
1901 s = env.Split("foo bar")
1902 assert s == ["foo", "bar"], s
1903 s = env.Split("$FOO bar")
1904 assert s == ["fff", "bar"], s
1905 s = env.Split(["foo", "bar"])
1906 assert s == ["foo", "bar"], s
1907 s = env.Split(["foo", "${BAR}-bbb"])
1908 assert s == ["foo", "bbb-bbb"], s
1909 s = env.Split("foo")
1910 assert s == ["foo"], s
1911 s = env.Split("$FOO$BAR")
1912 assert s == ["fffbbb"], s
1914 def test_TargetSignatures(type):
1915 """Test the TargetSignatures() method"""
1916 env = Environment(B = 'build', C = 'content')
1920 env.TargetSignatures('invalid_type')
1921 except SCons.Errors.UserError:
1923 assert exc_caught, "did not catch expected UserError"
1924 assert not hasattr(env, '_build_signature')
1926 env.TargetSignatures('build')
1927 assert env._build_signature == 1, env._build_signature
1929 env.TargetSignatures('content')
1930 assert env._build_signature == 0, env._build_signature
1932 env.TargetSignatures('$B')
1933 assert env._build_signature == 1, env._build_signature
1935 env.TargetSignatures('$C')
1936 assert env._build_signature == 0, env._build_signature
1938 def test_Value(self):
1939 """Test creating a Value() object
1943 assert v1.value == 'a', v1.value
1946 v2 = env.Value(value2)
1947 assert v2.value == value2, v2.value
1948 assert v2.value is value2, v2.value
1951 assert v1.value == v2.value
1955 def test_Environment_global_variable(type):
1956 """Test setting Environment variable to an Environment.Base subclass"""
1957 class MyEnv(SCons.Environment.Base):
1958 def xxx(self, string):
1959 return self.subst(string)
1961 SCons.Environment.Environment = MyEnv
1963 env = SCons.Environment.Environment(FOO = 'foo')
1965 f = env.subst('$FOO')
1966 assert f == 'foo', f
1969 assert f == 'foo', f
1972 if __name__ == "__main__":
1973 suite = unittest.makeSuite(EnvironmentTestCase, 'test_')
1974 if not unittest.TextTestRunner().run(suite).wasSuccessful():