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__"
36 from SCons.Environment import *
39 def diff_env(env1, env2):
43 for k in env1._dict.keys() + env2._dict.keys():
45 for k in sorted(d.keys()):
48 if env1[k] != env2[k]:
49 s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n"
50 s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n"
52 s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n"
54 s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n"
59 def diff_dict(d1, d2):
63 for k in d1.keys() + d2.keys():
65 for k in sorted(d.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"
82 class Builder(SCons.Builder.BuilderBase):
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, target=None, source=None, **kw):
91 called_it['target'] = target
92 called_it['source'] = source
95 def execute(self, target = None, **kw):
104 """A dummy Scanner class for testing purposes. "Scanning"
105 a target is simply setting a value in the dictionary.
107 def __init__(self, name, skeys=[]):
111 def __call__(self, filename):
113 scanned_it[filename] = 1
115 def __cmp__(self, other):
117 return cmp(self.__dict__, other.__dict__)
118 except AttributeError:
121 def get_skeys(self, env):
129 class CLVar(UserList.UserList):
130 def __init__(self, seq):
131 if type(seq) == type(''):
133 UserList.UserList.__init__(self, seq)
134 def __add__(self, other):
135 return UserList.UserList.__add__(self, CLVar(other))
136 def __radd__(self, other):
137 return UserList.UserList.__radd__(self, CLVar(other))
138 def __coerce__(self, other):
139 return (self, CLVar(other))
144 def __init__(self, name):
150 def get_subst_proxy(self):
153 def test_tool( env ):
154 env['_F77INCFLAGS'] = '$( ${_concat(INCPREFIX, F77PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
156 class TestEnvironmentFixture:
157 def TestEnvironment(self, *args, **kw):
158 if not kw or 'tools' not in kw:
159 kw['tools'] = [test_tool]
160 default_keys = { 'CC' : 'cc',
161 'CCFLAGS' : '-DNDEBUG',
162 'ENV' : { 'TMP' : '/tmp' } }
163 for key, value in default_keys.items():
166 if 'BUILDERS' not in kw:
167 static_obj = SCons.Builder.Builder(action = {},
171 kw['BUILDERS'] = {'Object' : static_obj}
172 static_obj.add_action('.cpp', 'fake action')
174 env = Environment(*args, **kw)
177 class SubstitutionTestCase(unittest.TestCase):
179 def test___init__(self):
180 """Test initializing a SubstitutionEnvironment
182 env = SubstitutionEnvironment()
183 assert '__env__' not in env
185 def test___cmp__(self):
186 """Test comparing SubstitutionEnvironments
189 env1 = SubstitutionEnvironment(XXX = 'x')
190 env2 = SubstitutionEnvironment(XXX = 'x')
191 env3 = SubstitutionEnvironment(XXX = 'xxx')
192 env4 = SubstitutionEnvironment(XXX = 'x', YYY = 'x')
198 def test___delitem__(self):
199 """Test deleting a variable from a SubstitutionEnvironment
201 env1 = SubstitutionEnvironment(XXX = 'x', YYY = 'y')
202 env2 = SubstitutionEnvironment(XXX = 'x')
206 def test___getitem__(self):
207 """Test fetching a variable from a SubstitutionEnvironment
209 env = SubstitutionEnvironment(XXX = 'x')
210 assert env['XXX'] == 'x', env['XXX']
212 def test___setitem__(self):
213 """Test setting a variable in a SubstitutionEnvironment
215 env1 = SubstitutionEnvironment(XXX = 'x')
216 env2 = SubstitutionEnvironment(XXX = 'x', YYY = 'y')
221 """Test the SubstitutionEnvironment get() method
223 env = SubstitutionEnvironment(XXX = 'x')
224 assert env.get('XXX') == 'x', env.get('XXX')
225 assert env.get('YYY') is None, env.get('YYY')
227 def test_has_key(self):
228 """Test the SubstitutionEnvironment has_key() method
230 env = SubstitutionEnvironment(XXX = 'x')
232 assert 'YYY' not in env
234 def test_contains(self):
235 """Test the SubstitutionEnvironment __contains__() method
241 # An early version of Python that doesn't support "in"
242 # on dictionaries. Just pass the test.
245 env = SubstitutionEnvironment(XXX = 'x')
247 assert not 'YYY' in env
249 def test_items(self):
250 """Test the SubstitutionEnvironment items() method
252 env = SubstitutionEnvironment(XXX = 'x', YYY = 'y')
254 assert items == [('XXX','x'), ('YYY','y')], items
256 def test_arg2nodes(self):
257 """Test the arg2nodes method
259 env = SubstitutionEnvironment()
261 class X(SCons.Node.Node):
263 def Factory(name, directory = None, create = 1, dict=dict, X=X):
266 dict[name].name = name
269 nodes = env.arg2nodes("Util.py UtilTests.py", Factory)
270 assert len(nodes) == 1, nodes
271 assert isinstance(nodes[0], X)
272 assert nodes[0].name == "Util.py UtilTests.py"
275 if hasattr(types, 'UnicodeType'):
277 nodes = env.arg2nodes(u"Util.py UtilTests.py", Factory)
278 assert len(nodes) == 1, nodes
279 assert isinstance(nodes[0], X)
280 assert nodes[0].name == u"Util.py UtilTests.py"
282 exec code in globals(), locals()
284 nodes = env.arg2nodes(["Util.py", "UtilTests.py"], Factory)
285 assert len(nodes) == 2, nodes
286 assert isinstance(nodes[0], X)
287 assert isinstance(nodes[1], X)
288 assert nodes[0].name == "Util.py"
289 assert nodes[1].name == "UtilTests.py"
291 n1 = Factory("Util.py")
292 nodes = env.arg2nodes([n1, "UtilTests.py"], Factory)
293 assert len(nodes) == 2, nodes
294 assert isinstance(nodes[0], X)
295 assert isinstance(nodes[1], X)
296 assert nodes[0].name == "Util.py"
297 assert nodes[1].name == "UtilTests.py"
299 class SConsNode(SCons.Node.Node):
301 nodes = env.arg2nodes(SConsNode())
302 assert len(nodes) == 1, nodes
303 assert isinstance(nodes[0], SConsNode), node
307 nodes = env.arg2nodes(OtherNode())
308 assert len(nodes) == 1, nodes
309 assert isinstance(nodes[0], OtherNode), node
311 def lookup_a(str, F=Factory):
319 def lookup_b(str, F=Factory):
327 env_ll = SubstitutionEnvironment()
328 env_ll.lookup_list = [lookup_a, lookup_b]
330 nodes = env_ll.arg2nodes(['aaa', 'bbb', 'ccc'], Factory)
331 assert len(nodes) == 3, nodes
333 assert nodes[0].name == 'aaa', nodes[0]
334 assert nodes[0].a == 1, nodes[0]
335 assert not hasattr(nodes[0], 'b'), nodes[0]
337 assert nodes[1].name == 'bbb'
338 assert not hasattr(nodes[1], 'a'), nodes[1]
339 assert nodes[1].b == 1, nodes[1]
341 assert nodes[2].name == 'ccc'
342 assert not hasattr(nodes[2], 'a'), nodes[1]
343 assert not hasattr(nodes[2], 'b'), nodes[1]
345 def lookup_bbbb(str, F=Factory):
353 def lookup_c(str, F=Factory):
361 nodes = env.arg2nodes(['bbbb', 'ccc'], Factory,
362 [lookup_c, lookup_bbbb, lookup_b])
363 assert len(nodes) == 2, nodes
365 assert nodes[0].name == 'bbbb'
366 assert not hasattr(nodes[0], 'a'), nodes[1]
367 assert not hasattr(nodes[0], 'b'), nodes[1]
368 assert nodes[0].bbbb == 1, nodes[1]
369 assert not hasattr(nodes[0], 'c'), nodes[0]
371 assert nodes[1].name == 'ccc'
372 assert not hasattr(nodes[1], 'a'), nodes[1]
373 assert not hasattr(nodes[1], 'b'), nodes[1]
374 assert not hasattr(nodes[1], 'bbbb'), nodes[0]
375 assert nodes[1].c == 1, nodes[1]
377 def test_arg2nodes_target_source(self):
378 """Test the arg2nodes method with target= and source= keywords
380 targets = [DummyNode('t1'), DummyNode('t2')]
381 sources = [DummyNode('s1'), DummyNode('s2')]
382 env = SubstitutionEnvironment()
383 nodes = env.arg2nodes(['${TARGET}-a',
390 names = [n.name for n in nodes]
391 assert names == ['t1-a', 's1-b', 't2-c', 's2-d'], names
393 def test_gvars(self):
394 """Test the base class gvars() method"""
395 env = SubstitutionEnvironment()
397 assert gvars == {}, gvars
399 def test_lvars(self):
400 """Test the base class lvars() method"""
401 env = SubstitutionEnvironment()
403 assert lvars == {}, lvars
405 def test_subst(self):
406 """Test substituting construction variables within strings
408 Check various combinations, including recursive expansion
409 of variables into other variables.
411 env = SubstitutionEnvironment(AAA = 'a', BBB = 'b')
412 mystr = env.subst("$AAA ${AAA}A $BBBB $BBB")
413 assert mystr == "a aA b", mystr
415 # Changed the tests below to reflect a bug fix in
417 env = SubstitutionEnvironment(AAA = '$BBB', BBB = 'b', BBBA = 'foo')
418 mystr = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
419 assert mystr == "b bA bB b", mystr
421 env = SubstitutionEnvironment(AAA = '$BBB', BBB = '$CCC', CCC = 'c')
422 mystr = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
423 assert mystr == "c cA cB c", mystr
426 env = SubstitutionEnvironment(AAA = ['a', 'aa', 'aaa'])
427 mystr = env.subst("$AAA")
428 assert mystr == "a aa aaa", mystr
431 env = SubstitutionEnvironment(AAA = ('a', 'aa', 'aaa'))
432 mystr = env.subst("$AAA")
433 assert mystr == "a aa aaa", mystr
440 env = SubstitutionEnvironment(AAA = 'aaa')
441 s = env.subst('$AAA $TARGET $SOURCES', target=[t1, t2], source=[s1, s2])
442 assert s == "aaa t1 s1 s2", s
443 s = env.subst('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2])
444 assert s == "aaa t1 t2 s1", s
446 # Test callables in the SubstitutionEnvironment
447 def foo(target, source, env, for_signature):
448 assert str(target) == 't', target
449 assert str(source) == 's', source
452 env = SubstitutionEnvironment(BAR=foo, FOO='baz')
456 subst = env.subst('test $BAR', target=t, source=s)
457 assert subst == 'test baz', subst
459 # Test not calling callables in the SubstitutionEnvironment
461 # This will take some serious surgery to subst() and
462 # subst_list(), so just leave these tests out until we can
467 env = SubstitutionEnvironment(BAR=bar, FOO='$BAR')
469 subst = env.subst('$BAR', call=None)
470 assert subst is bar, subst
472 subst = env.subst('$FOO', call=None)
473 assert subst is bar, subst
475 def test_subst_kw(self):
476 """Test substituting construction variables within dictionaries"""
477 env = SubstitutionEnvironment(AAA = 'a', BBB = 'b')
478 kw = env.subst_kw({'$AAA' : 'aaa', 'bbb' : '$BBB'})
479 assert len(kw) == 2, kw
480 assert kw['a'] == 'aaa', kw['a']
481 assert kw['bbb'] == 'b', kw['bbb']
483 def test_subst_list(self):
484 """Test substituting construction variables in command lists
486 env = SubstitutionEnvironment(AAA = 'a', BBB = 'b')
487 l = env.subst_list("$AAA ${AAA}A $BBBB $BBB")
488 assert l == [["a", "aA", "b"]], l
490 # Changed the tests below to reflect a bug fix in
492 env = SubstitutionEnvironment(AAA = '$BBB', BBB = 'b', BBBA = 'foo')
493 l = env.subst_list("$AAA ${AAA}A ${AAA}B $BBB")
494 assert l == [["b", "bA", "bB", "b"]], l
496 env = SubstitutionEnvironment(AAA = '$BBB', BBB = '$CCC', CCC = 'c')
497 l = env.subst_list("$AAA ${AAA}A ${AAA}B $BBB")
498 assert l == [["c", "cA", "cB", "c"]], mystr
500 env = SubstitutionEnvironment(AAA = '$BBB', BBB = '$CCC', CCC = [ 'a', 'b\nc' ])
501 lst = env.subst_list([ "$AAA", "B $CCC" ])
502 assert lst == [[ "a", "b"], ["c", "B a", "b"], ["c"]], lst
509 env = SubstitutionEnvironment(AAA = 'aaa')
510 s = env.subst_list('$AAA $TARGET $SOURCES', target=[t1, t2], source=[s1, s2])
511 assert s == [["aaa", "t1", "s1", "s2"]], s
512 s = env.subst_list('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2])
513 assert s == [["aaa", "t1", "t2", "s1"]], s
515 # Test callables in the SubstitutionEnvironment
516 def foo(target, source, env, for_signature):
517 assert str(target) == 't', target
518 assert str(source) == 's', source
521 env = SubstitutionEnvironment(BAR=foo, FOO='baz')
525 lst = env.subst_list('test $BAR', target=t, source=s)
526 assert lst == [['test', 'baz']], lst
528 # Test not calling callables in the SubstitutionEnvironment
530 # This will take some serious surgery to subst() and
531 # subst_list(), so just leave these tests out until we can
536 env = SubstitutionEnvironment(BAR=bar, FOO='$BAR')
538 subst = env.subst_list('$BAR', call=None)
539 assert subst is bar, subst
541 subst = env.subst_list('$FOO', call=None)
542 assert subst is bar, subst
544 def test_subst_path(self):
545 """Test substituting a path list
548 def __init__(self, val):
551 return self.val + '-proxy'
554 def __init__(self, val):
556 def get_subst_proxy(self):
565 env = SubstitutionEnvironment(FOO='foo',
568 PROXY=MyProxy('my1'))
570 r = env.subst_path('$FOO')
571 assert r == ['foo'], r
573 r = env.subst_path(['$FOO', 'xxx', '$BAR'])
574 assert r == ['foo', 'xxx', 'bar'], r
576 r = env.subst_path(['$FOO', '$LIST', '$BAR'])
577 assert list(map(str, r)) == ['foo', 'one two', 'bar'], r
579 r = env.subst_path(['$FOO', '$TARGET', '$SOURCE', '$BAR'])
580 assert r == ['foo', '', '', 'bar'], r
582 r = env.subst_path(['$FOO', '$TARGET', '$BAR'], target=MyNode('ttt'))
583 assert list(map(str, r)) == ['foo', 'ttt', 'bar'], r
585 r = env.subst_path(['$FOO', '$SOURCE', '$BAR'], source=MyNode('sss'))
586 assert list(map(str, r)) == ['foo', 'sss', 'bar'], r
590 r = env.subst_path(['$PROXY', MyProxy('my2'), n])
591 assert r == ['my1-proxy', 'my2-proxy', n], r
594 def __init__(self, s):
599 env = SubstitutionEnvironment(FOO=StringableObj("foo"),
600 BAR=StringableObj("bar"))
602 r = env.subst_path([ "${FOO}/bar", "${BAR}/baz" ])
603 assert r == [ "foo/bar", "bar/baz" ], r
605 r = env.subst_path([ "bar/${FOO}", "baz/${BAR}" ])
606 assert r == [ "bar/foo", "baz/bar" ], r
608 r = env.subst_path([ "bar/${FOO}/bar", "baz/${BAR}/baz" ])
609 assert r == [ "bar/foo/bar", "baz/bar/baz" ], r
611 def test_subst_target_source(self):
612 """Test the base environment subst_target_source() method"""
613 env = SubstitutionEnvironment(AAA = 'a', BBB = 'b')
614 mystr = env.subst_target_source("$AAA ${AAA}A $BBBB $BBB")
615 assert mystr == "a aA b", mystr
617 def test_backtick(self):
618 """Test the backtick() method for capturing command output"""
619 env = SubstitutionEnvironment()
621 test = TestCmd.TestCmd(workdir = '')
622 test.write('stdout.py', """\
624 sys.stdout.write('this came from stdout.py\\n')
627 test.write('stderr.py', """\
629 sys.stderr.write('this came from stderr.py\\n')
632 test.write('fail.py', """\
636 test.write('echo.py', """\
638 sys.stdout.write(os.environ['ECHO'] + '\\n')
642 save_stderr = sys.stderr
644 python = '"' + sys.executable + '"'
647 sys.stderr = StringIO.StringIO()
648 cmd = '%s %s' % (python, test.workpath('stdout.py'))
649 output = env.backtick(cmd)
650 errout = sys.stderr.getvalue()
651 assert output == 'this came from stdout.py\n', output
652 assert errout == '', errout
654 sys.stderr = StringIO.StringIO()
655 cmd = '%s %s' % (python, test.workpath('stderr.py'))
656 output = env.backtick(cmd)
657 errout = sys.stderr.getvalue()
658 assert output == '', output
659 assert errout == 'this came from stderr.py\n', errout
661 sys.stderr = StringIO.StringIO()
662 cmd = '%s %s' % (python, test.workpath('fail.py'))
666 assert str(e) == "'%s' exited 1" % cmd, str(e)
668 self.fail("did not catch expected OSError")
670 sys.stderr = StringIO.StringIO()
671 cmd = '%s %s' % (python, test.workpath('echo.py'))
672 env['ENV'] = os.environ.copy()
673 env['ENV']['ECHO'] = 'this came from ECHO'
674 output = env.backtick(cmd)
675 errout = sys.stderr.getvalue()
676 assert output == 'this came from ECHO\n', output
677 assert errout == '', errout
680 sys.stderr = save_stderr
682 def test_AddMethod(self):
683 """Test the AddMethod() method"""
684 env = SubstitutionEnvironment(FOO = 'foo')
687 return 'func-' + self['FOO']
689 assert not hasattr(env, 'func')
692 assert r == 'func-foo', r
694 assert not hasattr(env, 'bar')
695 env.AddMethod(func, 'bar')
697 assert r == 'func-foo', r
699 def func2(self, arg=''):
700 return 'func2-' + self['FOO'] + arg
704 assert r == 'func2-foo', r
705 r = env.func2('-xxx')
706 assert r == 'func2-foo-xxx', r
708 env.AddMethod(func2, 'func')
710 assert r == 'func2-foo', r
712 assert r == 'func2-foo-yyy', r
714 # Test that clones of clones correctly re-bind added methods.
715 env1 = Environment(FOO = '1')
716 env1.AddMethod(func2)
717 env2 = env1.Clone(FOO = '2')
718 env3 = env2.Clone(FOO = '3')
719 env4 = env3.Clone(FOO = '4')
721 assert r == 'func2-1', r
723 assert r == 'func2-2', r
725 assert r == 'func2-3', r
727 assert r == 'func2-4', r
729 # Test that clones don't re-bind an attribute that the user
730 env1 = Environment(FOO = '1')
731 env1.AddMethod(func2)
733 return 'replace_func2'
734 env1.func2 = replace_func2
735 env2 = env1.Clone(FOO = '2')
737 assert r == 'replace_func2', r
739 def test_Override(self):
740 "Test overriding construction variables"
741 env = SubstitutionEnvironment(ONE=1, TWO=2, THREE=3, FOUR=4)
742 assert env['ONE'] == 1, env['ONE']
743 assert env['TWO'] == 2, env['TWO']
744 assert env['THREE'] == 3, env['THREE']
745 assert env['FOUR'] == 4, env['FOUR']
747 env2 = env.Override({'TWO' : '10',
748 'THREE' :'x $THREE y',
749 'FOUR' : ['x', '$FOUR', 'y']})
750 assert env2['ONE'] == 1, env2['ONE']
751 assert env2['TWO'] == '10', env2['TWO']
752 assert env2['THREE'] == 'x 3 y', env2['THREE']
753 assert env2['FOUR'] == ['x', 4, 'y'], env2['FOUR']
755 assert env['ONE'] == 1, env['ONE']
756 assert env['TWO'] == 2, env['TWO']
757 assert env['THREE'] == 3, env['THREE']
758 assert env['FOUR'] == 4, env['FOUR']
760 env2.Replace(ONE = "won")
761 assert env2['ONE'] == "won", env2['ONE']
762 assert env['ONE'] == 1, env['ONE']
764 def test_ParseFlags(self):
765 """Test the ParseFlags() method
767 env = SubstitutionEnvironment()
776 'FRAMEWORKPATH' : [],
784 d = env.ParseFlags(None)
787 d = env.ParseFlags('')
790 d = env.ParseFlags([])
793 s = "-I/usr/include/fum -I bar -X\n" + \
794 '-I"C:\\Program Files\\ASCEND\\include" ' + \
795 "-L/usr/fax -L foo -lxxx -l yyy " + \
796 '-L"C:\\Program Files\\ASCEND" -lascend ' + \
797 "-Wa,-as -Wl,-link " + \
798 "-Wl,-rpath=rpath1 " + \
803 "-framework Carbon " + \
804 "-frameworkdir=fwd1 " + \
808 "-mno-cygwin -mwindows " + \
809 "-arch i386 -isysroot /tmp +DD64 " + \
810 "-DFOO -DBAR=value -D BAZ "
812 d = env.ParseFlags(s)
814 assert d['ASFLAGS'] == ['-as'], d['ASFLAGS']
815 assert d['CFLAGS'] == ['-std=c99']
816 assert d['CCFLAGS'] == ['-X', '-Wa,-as',
817 '-pthread', '-mno-cygwin',
818 ('-arch', 'i386'), ('-isysroot', '/tmp'),
819 '+DD64'], d['CCFLAGS']
820 assert d['CPPDEFINES'] == ['FOO', ['BAR', 'value'], 'BAZ'], d['CPPDEFINES']
821 assert d['CPPFLAGS'] == ['-Wp,-cpp'], d['CPPFLAGS']
822 assert d['CPPPATH'] == ['/usr/include/fum',
824 'C:\\Program Files\\ASCEND\\include'], d['CPPPATH']
825 assert d['FRAMEWORKPATH'] == ['fwd1', 'fwd2', 'fwd3'], d['FRAMEWORKPATH']
826 assert d['FRAMEWORKS'] == ['Carbon'], d['FRAMEWORKS']
827 assert d['LIBPATH'] == ['/usr/fax',
829 'C:\\Program Files\\ASCEND'], d['LIBPATH']
830 LIBS = list(map(str, d['LIBS']))
831 assert LIBS == ['xxx', 'yyy', 'ascend'], (d['LIBS'], LIBS)
832 assert d['LINKFLAGS'] == ['-Wl,-link', '-pthread',
833 '-mno-cygwin', '-mwindows',
835 ('-isysroot', '/tmp'),
836 '+DD64'], d['LINKFLAGS']
837 assert d['RPATH'] == ['rpath1', 'rpath2', 'rpath3'], d['RPATH']
840 def test_MergeFlags(self):
841 """Test the MergeFlags() method
843 env = SubstitutionEnvironment()
845 assert 'CCFLAGS' not in env, env['CCFLAGS']
847 assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
849 assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
851 env = SubstitutionEnvironment(CCFLAGS=None)
853 assert env['CCFLAGS'] == ['-Y'], env['CCFLAGS']
855 env = SubstitutionEnvironment()
856 env.MergeFlags({'A':['aaa'], 'B':['bbb']})
857 assert env['A'] == ['aaa'], env['A']
858 assert env['B'] == ['bbb'], env['B']
860 # def test_MergeShellPaths(self):
861 # """Test the MergeShellPaths() method
863 # env = Environment()
864 # env.MergeShellPaths({})
865 # assert not env['ENV'].has_key('INCLUDE'), env['INCLUDE']
866 # env.MergeShellPaths({'INCLUDE': r'c:\Program Files\Stuff'})
867 # assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff', env['ENV']['INCLUDE']
868 # env.MergeShellPaths({'INCLUDE': r'c:\Program Files\Stuff'})
869 # assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff', env['ENV']['INCLUDE']
870 # env.MergeShellPaths({'INCLUDE': r'xyz'})
871 # assert env['ENV']['INCLUDE'] == r'xyz%sc:\Program Files\Stuff'%os.pathsep, env['ENV']['INCLUDE']
873 # env = Environment()
874 # env['ENV']['INCLUDE'] = 'xyz'
875 # env.MergeShellPaths({'INCLUDE':['c:/inc1', 'c:/inc2']} )
876 # assert env['ENV']['INCLUDE'] == r'c:/inc1%sc:/inc2%sxyz'%(os.pathsep, os.pathsep), env['ENV']['INCLUDE']
879 # env = Environment()
880 # env.MergeShellPaths({'INCLUDE': r'c:\Program Files\Stuff'}, prepend=0)
881 # assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff', env['ENV']['INCLUDE']
882 # env.MergeShellPaths({'INCLUDE': r'xyz'}, prepend=0)
883 # assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff%sxyz'%os.pathsep, env['ENV']['INCLUDE']
886 class BaseTestCase(unittest.TestCase,TestEnvironmentFixture):
888 reserved_variables = [
899 def test___init__(self):
900 """Test construction Environment creation
902 Create two with identical arguments and check that
903 they compare the same.
905 env1 = self.TestEnvironment(XXX = 'x', YYY = 'y')
906 env2 = self.TestEnvironment(XXX = 'x', YYY = 'y')
907 assert env1 == env2, diff_env(env1, env2)
909 assert '__env__' not in env1
910 assert '__env__' not in env2
912 def test_variables(self):
913 """Test that variables only get applied once."""
915 def __init__(self, key, val):
921 def Update(self, env):
922 env[self.key] = self.val
923 self.calls = self.calls + 1
925 o = FakeOptions('AAA', 'fake_opt')
926 env = Environment(variables=o, AAA='keyword_arg')
927 assert o.calls == 1, o.calls
928 assert env['AAA'] == 'fake_opt', env['AAA']
931 """Test the get() method."""
932 env = self.TestEnvironment(aaa = 'AAA')
936 x = env.get('aaa', 'XXX')
940 x = env.get('bbb', 'XXX')
943 def test_Builder_calls(self):
944 """Test Builder calls through different environments
952 env.Replace(BUILDERS = { 'builder1' : b1,
956 assert called_it['target'] is None, called_it
957 assert called_it['source'] == ['in1'], called_it
960 env.builder2(source = 'in2', xyzzy = 1)
961 assert called_it['target'] is None, called_it
962 assert called_it['source'] == ['in2'], called_it
963 assert called_it['xyzzy'] == 1, called_it
966 env.builder1(foo = 'bar')
967 assert called_it['foo'] == 'bar', called_it
968 assert called_it['target'] is None, called_it
969 assert called_it['source'] is None, called_it
971 def test_BuilderWrapper_attributes(self):
972 """Test getting and setting of BuilderWrapper attributes
979 e1.Replace(BUILDERS = {'b' : b1})
986 assert bw.builder is b1
988 assert bw.builder is b2
990 self.assertRaises(AttributeError, getattr, bw, 'foobar')
992 assert bw.foobar is 42
994 # This unit test is currently disabled because we don't think the
995 # underlying method it tests (Environment.BuilderWrapper.execute())
996 # is necessary, but we're leaving the code here for now in case
998 def _DO_NOT_test_Builder_execs(self):
999 """Test Builder execution through different environments
1001 One environment is initialized with a single
1002 Builder object, one with a list of a single Builder
1003 object, and one with a list of two Builder objects.
1011 env3 = Environment()
1012 env3.Replace(BUILDERS = { 'builder1' : b1,
1014 env3.builder1.execute(target = 'out1')
1015 env3.builder2.execute(target = 'out2')
1016 env3.builder1.execute(target = 'out3')
1017 assert built_it['out1']
1018 assert built_it['out2']
1019 assert built_it['out3']
1022 assert env4.builder1.env is env4, "builder1.env (%s) == env3 (%s)?" % (
1023 env4.builder1.env, env3)
1024 assert env4.builder2.env is env4, "builder2.env (%s) == env3 (%s)?" % (
1025 env4.builder1.env, env3)
1027 # Now test BUILDERS as a dictionary.
1029 env5 = self.TestEnvironment(BUILDERS={ 'foo' : b1 })
1030 env5['BUILDERS']['bar'] = b2
1031 env5.foo.execute(target='out1')
1032 env5.bar.execute(target='out2')
1033 assert built_it['out1']
1034 assert built_it['out2']
1037 env6 = Environment()
1038 env6['BUILDERS'] = { 'foo' : b1,
1040 env6.foo.execute(target='out1')
1041 env6.bar.execute(target='out2')
1042 assert built_it['out1']
1043 assert built_it['out2']
1047 def test_Scanners(self):
1048 """Test setting SCANNERS in various ways
1050 One environment is initialized with a single
1051 Scanner object, one with a list of a single Scanner
1052 object, and one with a list of two Scanner objects.
1056 s1 = Scanner(name = 'scanner1', skeys = [".c", ".cc"])
1057 s2 = Scanner(name = 'scanner2', skeys = [".m4"])
1058 s3 = Scanner(name = 'scanner3', skeys = [".m4", ".m5"])
1059 s4 = Scanner(name = 'scanner4', skeys = [None])
1061 # XXX Tests for scanner execution through different environments,
1062 # XXX if we ever want to do that some day
1064 # env1 = self.TestEnvironment(SCANNERS = s1)
1065 # env1.scanner1(filename = 'out1')
1066 # assert scanned_it['out1']
1069 # env2 = self.TestEnvironment(SCANNERS = [s1])
1070 # env1.scanner1(filename = 'out1')
1071 # assert scanned_it['out1']
1074 # env3 = Environment()
1075 # env3.Replace(SCANNERS = [s1])
1076 # env3.scanner1(filename = 'out1')
1077 # env3.scanner2(filename = 'out2')
1078 # env3.scanner1(filename = 'out3')
1079 # assert scanned_it['out1']
1080 # assert scanned_it['out2']
1081 # assert scanned_it['out3']
1083 suffixes = [".c", ".cc", ".cxx", ".m4", ".m5"]
1086 try: del env['SCANNERS']
1087 except KeyError: pass
1088 s = list(map(env.get_scanner, suffixes))
1089 assert s == [None, None, None, None, None], s
1091 env = self.TestEnvironment(SCANNERS = [])
1092 s = list(map(env.get_scanner, suffixes))
1093 assert s == [None, None, None, None, None], s
1095 env.Replace(SCANNERS = [s1])
1096 s = list(map(env.get_scanner, suffixes))
1097 assert s == [s1, s1, None, None, None], s
1099 env.Append(SCANNERS = [s2])
1100 s = list(map(env.get_scanner, suffixes))
1101 assert s == [s1, s1, None, s2, None], s
1103 env.AppendUnique(SCANNERS = [s3])
1104 s = list(map(env.get_scanner, suffixes))
1105 assert s == [s1, s1, None, s2, s3], s
1107 env = env.Clone(SCANNERS = [s2])
1108 s = list(map(env.get_scanner, suffixes))
1109 assert s == [None, None, None, s2, None], s
1111 env['SCANNERS'] = [s1]
1112 s = list(map(env.get_scanner, suffixes))
1113 assert s == [s1, s1, None, None, None], s
1115 env.PrependUnique(SCANNERS = [s2, s1])
1116 s = list(map(env.get_scanner, suffixes))
1117 assert s == [s1, s1, None, s2, None], s
1119 env.Prepend(SCANNERS = [s3])
1120 s = list(map(env.get_scanner, suffixes))
1121 assert s == [s1, s1, None, s3, s3], s
1123 # Verify behavior of case-insensitive suffix matches on Windows.
1124 uc_suffixes = [_.upper() for _ in suffixes]
1126 env = Environment(SCANNERS = [s1, s2, s3],
1129 s = list(map(env.get_scanner, suffixes))
1130 assert s == [s1, s1, None, s2, s3], s
1132 s = list(map(env.get_scanner, uc_suffixes))
1133 assert s == [None, None, None, None, None], s
1135 env['PLATFORM'] = 'win32'
1137 s = list(map(env.get_scanner, uc_suffixes))
1138 assert s == [s1, s1, None, s2, s3], s
1140 # Verify behavior for a scanner returning None (on Windows
1141 # where we might try to perform case manipulation on None).
1142 env.Replace(SCANNERS = [s4])
1143 s = list(map(env.get_scanner, suffixes))
1144 assert s == [None, None, None, None, None], s
1147 """Test setting the external ENV in Environments
1150 assert 'ENV' in env.Dictionary()
1152 env = self.TestEnvironment(ENV = { 'PATH' : '/foo:/bar' })
1153 assert env.Dictionary('ENV')['PATH'] == '/foo:/bar'
1155 def test_ReservedVariables(self):
1156 """Test warning generation when reserved variable names are set"""
1158 reserved_variables = [
1165 'UNCHANGED_SOURCES',
1166 'UNCHANGED_TARGETS',
1169 warning = SCons.Warnings.ReservedVariableWarning
1170 SCons.Warnings.enableWarningClass(warning)
1171 old = SCons.Warnings.warningAsException(1)
1174 env4 = Environment()
1175 for kw in self.reserved_variables:
1181 assert exc_caught, "Did not catch ReservedVariableWarning for `%s'" % kw
1182 assert kw not in env4, "`%s' variable was incorrectly set" % kw
1184 SCons.Warnings.warningAsException(old)
1186 def test_FutureReservedVariables(self):
1187 """Test warning generation when future reserved variable names are set"""
1189 future_reserved_variables = []
1191 warning = SCons.Warnings.FutureReservedVariableWarning
1192 SCons.Warnings.enableWarningClass(warning)
1193 old = SCons.Warnings.warningAsException(1)
1196 env4 = Environment()
1197 for kw in future_reserved_variables:
1203 assert exc_caught, "Did not catch FutureReservedVariableWarning for `%s'" % kw
1204 assert kw in env4, "`%s' variable was not set" % kw
1206 SCons.Warnings.warningAsException(old)
1208 def test_IllegalVariables(self):
1209 """Test that use of illegal variables raises an exception"""
1211 def test_it(var, env=env):
1215 except SCons.Errors.UserError:
1217 assert exc_caught, "did not catch UserError for '%s'" % var
1219 assert env['aaa'] == 1, env['aaa']
1224 def test_autogenerate(dict):
1225 """Test autogenerating variables in a dictionary."""
1227 drive, p = os.path.splitdrive(os.getcwd())
1228 def normalize_path(path, drive=drive):
1229 if path[0] in '\\/':
1231 path = os.path.normpath(path)
1232 drive, path = os.path.splitdrive(path)
1233 return drive.lower() + path
1235 env = dict.TestEnvironment(LIBS = [ 'foo', 'bar', 'baz' ],
1236 LIBLINKPREFIX = 'foo',
1237 LIBLINKSUFFIX = 'bar')
1239 def RDirs(pathlist, fs=env.fs):
1240 return fs.Dir('xx').Rfindalldirs(pathlist)
1242 env['RDirs'] = RDirs
1243 flags = env.subst_list('$_LIBFLAGS', 1)[0]
1244 assert flags == ['foobar', 'foobar', 'foobazbar'], flags
1246 blat = env.fs.Dir('blat')
1248 env.Replace(CPPPATH = [ 'foo', '$FOO/bar', blat ],
1252 flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
1254 normalize_path('foo'),
1255 normalize_path('xx/foobar'),
1256 normalize_path('foo'),
1257 normalize_path('xx/baz/bar'),
1258 normalize_path('foo'),
1259 normalize_path('blatbar'),
1262 assert flags == expect, flags
1264 env.Replace(F77PATH = [ 'foo', '$FOO/bar', blat ],
1268 flags = env.subst_list('$_F77INCFLAGS', 1)[0]
1270 normalize_path('foo'),
1271 normalize_path('xx/foobar'),
1272 normalize_path('foo'),
1273 normalize_path('xx/baz/bar'),
1274 normalize_path('foo'),
1275 normalize_path('blatbar'),
1278 assert flags == expect, flags
1280 env.Replace(CPPPATH = '', F77PATH = '', LIBPATH = '')
1281 l = env.subst_list('$_CPPINCFLAGS')
1283 l = env.subst_list('$_F77INCFLAGS')
1285 l = env.subst_list('$_LIBDIRFLAGS')
1288 env.fs.Repository('/rep1')
1289 env.fs.Repository('/rep2')
1290 env.Replace(CPPPATH = [ 'foo', '/a/b', '$FOO/bar', blat],
1294 flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
1296 '-I', normalize_path('xx/fooXXX'),
1297 '-I', normalize_path('/rep1/xx/fooXXX'),
1298 '-I', normalize_path('/rep2/xx/fooXXX'),
1299 '-I', normalize_path('/a/bXXX'),
1300 '-I', normalize_path('xx/baz/barXXX'),
1301 '-I', normalize_path('/rep1/xx/baz/barXXX'),
1302 '-I', normalize_path('/rep2/xx/baz/barXXX'),
1303 '-I', normalize_path('blatXXX'),
1306 def normalize_if_path(arg, np=normalize_path):
1307 if arg not in ('$(','$)','-I'):
1310 flags = list(map(normalize_if_path, flags))
1311 assert flags == expect, flags
1313 def test_platform(self):
1314 """Test specifying a platform callable when instantiating."""
1316 def __str__(self): return "TestPlatform"
1317 def __call__(self, env): env['XYZZY'] = 777
1320 env['SET_TOOL'] = 'initialized'
1321 assert env['PLATFORM'] == "TestPlatform"
1323 env = self.TestEnvironment(platform = platform(), tools = [tool])
1324 assert env['XYZZY'] == 777, env
1325 assert env['PLATFORM'] == "TestPlatform"
1326 assert env['SET_TOOL'] == "initialized"
1328 def test_Default_PLATFORM(self):
1329 """Test overriding the default PLATFORM variable"""
1331 def __str__(self): return "DefaultTestPlatform"
1332 def __call__(self, env): env['XYZZY'] = 888
1335 env['SET_TOOL'] = 'abcde'
1336 assert env['PLATFORM'] == "DefaultTestPlatform"
1338 import SCons.Defaults
1339 save = SCons.Defaults.ConstructionEnvironment.copy()
1341 import SCons.Defaults
1342 SCons.Defaults.ConstructionEnvironment.update({
1343 'PLATFORM' : platform(),
1345 env = self.TestEnvironment(tools = [tool])
1346 assert env['XYZZY'] == 888, env
1347 assert env['PLATFORM'] == "DefaultTestPlatform"
1348 assert env['SET_TOOL'] == "abcde"
1350 SCons.Defaults.ConstructionEnvironment = save
1352 def test_tools(self):
1353 """Test specifying a tool callable when instantiating."""
1359 env['AAA'] = env['XYZ']
1362 env = self.TestEnvironment(tools = [t1, t2, t3], XYZ = 'aaa')
1363 assert env['TOOL1'] == 111, env['TOOL1']
1364 assert env['TOOL2'] == 222, env
1365 assert env['AAA'] == 'aaa', env
1367 assert env['TOOL4'] == 444, env
1369 test = TestCmd.TestCmd(workdir = '')
1370 test.write('faketool.py', """\
1371 def generate(env, **kw):
1372 for k, v in kw.items():
1379 env = self.TestEnvironment(tools = [('faketool', {'a':1, 'b':2, 'c':3})],
1380 toolpath = [test.workpath('')])
1381 assert env['a'] == 1, env['a']
1382 assert env['b'] == 2, env['b']
1383 assert env['c'] == 3, env['c']
1385 def test_Default_TOOLS(self):
1386 """Test overriding the default TOOLS variable"""
1392 env['BBB'] = env['XYZ']
1396 import SCons.Defaults
1397 save = SCons.Defaults.ConstructionEnvironment.copy()
1399 SCons.Defaults.ConstructionEnvironment.update({
1400 'TOOLS' : [t5, t6, t7],
1402 env = Environment(XYZ = 'bbb')
1403 assert env['TOOL5'] == 555, env['TOOL5']
1404 assert env['TOOL6'] == 666, env
1405 assert env['BBB'] == 'bbb', env
1407 assert env['TOOL8'] == 888, env
1409 SCons.Defaults.ConstructionEnvironment = save
1411 def test_null_tools(self):
1412 """Test specifying a tool of None is OK."""
1417 env = self.TestEnvironment(tools = [t1, None, t2], XYZ = 'aaa')
1418 assert env['TOOL1'] == 111, env['TOOL1']
1419 assert env['TOOL2'] == 222, env
1420 assert env['XYZ'] == 'aaa', env
1421 env = self.TestEnvironment(tools = [None], XYZ = 'xyz')
1422 assert env['XYZ'] == 'xyz', env
1423 env = self.TestEnvironment(tools = [t1, '', t2], XYZ = 'ddd')
1424 assert env['TOOL1'] == 111, env['TOOL1']
1425 assert env['TOOL2'] == 222, env
1426 assert env['XYZ'] == 'ddd', env
1428 def test_concat(self):
1430 e1 = self.TestEnvironment(PRE='pre', SUF='suf', STR='a b', LIST=['a', 'b'])
1432 x = s("${_concat('', '', '', __env__)}")
1434 x = s("${_concat('', [], '', __env__)}")
1436 x = s("${_concat(PRE, '', SUF, __env__)}")
1438 x = s("${_concat(PRE, STR, SUF, __env__)}")
1439 assert x == 'prea bsuf', x
1440 x = s("${_concat(PRE, LIST, SUF, __env__)}")
1441 assert x == 'preasuf prebsuf', x
1443 def test_gvars(self):
1444 """Test the Environment gvars() method"""
1445 env = self.TestEnvironment(XXX = 'x', YYY = 'y', ZZZ = 'z')
1447 assert gvars['XXX'] == 'x', gvars['XXX']
1448 assert gvars['YYY'] == 'y', gvars['YYY']
1449 assert gvars['ZZZ'] == 'z', gvars['ZZZ']
1451 def test__update(self):
1452 """Test the _update() method"""
1453 env = self.TestEnvironment(X = 'x', Y = 'y', Z = 'z')
1454 assert env['X'] == 'x', env['X']
1455 assert env['Y'] == 'y', env['Y']
1456 assert env['Z'] == 'z', env['Z']
1457 env._update({'X' : 'xxx',
1463 assert env['X'] == 'xxx', env['X']
1464 assert env['Y'] == 'y', env['Y']
1465 assert env['Z'] == 'zzz', env['Z']
1466 assert env['TARGET'] == 't', env['TARGET']
1467 assert env['TARGETS'] == 'ttt', env['TARGETS']
1468 assert env['SOURCE'] == 's', env['SOURCE']
1469 assert env['SOURCES'] == 'sss', env['SOURCES']
1473 def test_Append(self):
1474 """Test appending to construction variables in an Environment
1477 b1 = Environment()['BUILDERS']
1478 b2 = Environment()['BUILDERS']
1479 assert b1 == b2, diff_dict(b1, b2)
1482 UD = UserDict.UserDict
1484 UL = UserList.UserList
1488 'a2', ['A2'], ['a2', 'A2'],
1489 'a3', UL(['A3']), UL(['a', '3', 'A3']),
1492 'a6', UL([]), UL(['a', '6']),
1493 'a7', [''], ['a7', ''],
1494 'a8', UL(['']), UL(['a', '8', '']),
1496 ['e1'], 'E1', ['e1', 'E1'],
1497 ['e2'], ['E2'], ['e2', 'E2'],
1498 ['e3'], UL(['E3']), UL(['e3', 'E3']),
1501 ['e6'], UL([]), UL(['e6']),
1502 ['e7'], [''], ['e7', ''],
1503 ['e8'], UL(['']), UL(['e8', '']),
1505 UL(['i1']), 'I1', UL(['i1', 'I', '1']),
1506 UL(['i2']), ['I2'], UL(['i2', 'I2']),
1507 UL(['i3']), UL(['I3']), UL(['i3', 'I3']),
1508 UL(['i4']), '', UL(['i4']),
1509 UL(['i5']), [], UL(['i5']),
1510 UL(['i6']), UL([]), UL(['i6']),
1511 UL(['i7']), [''], UL(['i7', '']),
1512 UL(['i8']), UL(['']), UL(['i8', '']),
1514 {'d1':1}, 'D1', {'d1':1, 'D1':None},
1515 {'d2':1}, ['D2'], {'d2':1, 'D2':None},
1516 {'d3':1}, UL(['D3']), {'d3':1, 'D3':None},
1517 {'d4':1}, {'D4':1}, {'d4':1, 'D4':1},
1518 {'d5':1}, UD({'D5':1}), UD({'d5':1, 'D5':1}),
1520 UD({'u1':1}), 'U1', UD({'u1':1, 'U1':None}),
1521 UD({'u2':1}), ['U2'], UD({'u2':1, 'U2':None}),
1522 UD({'u3':1}), UL(['U3']), UD({'u3':1, 'U3':None}),
1523 UD({'u4':1}), {'U4':1}, UD({'u4':1, 'U4':1}),
1524 UD({'u5':1}), UD({'U5':1}), UD({'u5':1, 'U5':1}),
1528 '', UL(['M3']), UL(['M3']),
1533 '', UL(['']), UL(['']),
1537 [], UL(['N3']), UL(['N3']),
1542 [], UL(['']), UL(['']),
1544 UL([]), 'O1', ['O', '1'],
1545 UL([]), ['O2'], ['O2'],
1546 UL([]), UL(['O3']), UL(['O3']),
1549 UL([]), UL([]), UL([]),
1550 UL([]), [''], UL(['']),
1551 UL([]), UL(['']), UL(['']),
1553 [''], 'P1', ['', 'P1'],
1554 [''], ['P2'], ['', 'P2'],
1555 [''], UL(['P3']), UL(['', 'P3']),
1558 [''], UL([]), UL(['']),
1559 [''], [''], ['', ''],
1560 [''], UL(['']), UL(['', '']),
1562 UL(['']), 'Q1', ['', 'Q', '1'],
1563 UL(['']), ['Q2'], ['', 'Q2'],
1564 UL(['']), UL(['Q3']), UL(['', 'Q3']),
1565 UL(['']), '', UL(['']),
1566 UL(['']), [], UL(['']),
1567 UL(['']), UL([]), UL(['']),
1568 UL(['']), [''], UL(['', '']),
1569 UL(['']), UL(['']), UL(['', '']),
1575 input, append, expect = cases[:3]
1576 env['XXX'] = copy.copy(input)
1578 env.Append(XXX = append)
1579 except Exception, e:
1580 if failed == 0: print
1581 print " %s Append %s exception: %s" % \
1582 (repr(input), repr(append), e)
1586 if result != expect:
1587 if failed == 0: print
1588 print " %s Append %s => %s did not match %s" % \
1589 (repr(input), repr(append), repr(result), repr(expect))
1592 assert failed == 0, "%d Append() cases failed" % failed
1594 env['UL'] = UL(['foo'])
1595 env.Append(UL = 'bar')
1597 assert isinstance(result, UL), repr(result)
1598 assert result == ['foo', 'b', 'a', 'r'], result
1600 env['CLVar'] = CLVar(['foo'])
1601 env.Append(CLVar = 'bar')
1602 result = env['CLVar']
1603 assert isinstance(result, CLVar), repr(result)
1604 assert result == ['foo', 'bar'], result
1607 def __init__(self, name):
1611 def __cmp__(self, other):
1612 raise "should not compare"
1616 env2 = self.TestEnvironment(CCC1 = ['c1'], CCC2 = ccc)
1617 env2.Append(CCC1 = ccc, CCC2 = ['c2'])
1618 assert env2['CCC1'][0] == 'c1', env2['CCC1']
1619 assert env2['CCC1'][1] is ccc, env2['CCC1']
1620 assert env2['CCC2'][0] is ccc, env2['CCC2']
1621 assert env2['CCC2'][1] == 'c2', env2['CCC2']
1623 env3 = self.TestEnvironment(X = {'x1' : 7})
1624 env3.Append(X = {'x1' : 8, 'x2' : 9}, Y = {'y1' : 10})
1625 assert env3['X'] == {'x1': 8, 'x2': 9}, env3['X']
1626 assert env3['Y'] == {'y1': 10}, env3['Y']
1630 env4 = self.TestEnvironment(BUILDERS = {'z1' : z1})
1631 env4.Append(BUILDERS = {'z2' : z2})
1632 assert env4['BUILDERS'] == {'z1' : z1, 'z2' : z2}, env4['BUILDERS']
1633 assert hasattr(env4, 'z1')
1634 assert hasattr(env4, 'z2')
1636 def test_AppendENVPath(self):
1637 """Test appending to an ENV path."""
1638 env1 = self.TestEnvironment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
1639 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
1640 # have to include the pathsep here so that the test will work on UNIX too.
1641 env1.AppendENVPath('PATH',r'C:\dir\num\two', sep = ';')
1642 env1.AppendENVPath('PATH',r'C:\dir\num\three', sep = ';')
1643 env1.AppendENVPath('MYPATH',r'C:\mydir\num\three','MYENV', sep = ';')
1644 env1.AppendENVPath('MYPATH',r'C:\mydir\num\one','MYENV', sep = ';')
1645 # this should do nothing since delete_existing is 0
1646 env1.AppendENVPath('MYPATH',r'C:\mydir\num\three','MYENV', sep = ';', delete_existing=0)
1647 assert(env1['ENV']['PATH'] == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
1648 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\two;C:\mydir\num\three;C:\mydir\num\one')
1650 test = TestCmd.TestCmd(workdir = '')
1651 test.subdir('sub1', 'sub2')
1652 p=env1['ENV']['PATH']
1653 env1.AppendENVPath('PATH','#sub1', sep = ';')
1654 env1.AppendENVPath('PATH',env1.fs.Dir('sub2'), sep = ';')
1655 assert env1['ENV']['PATH'] == p + ';sub1;sub2', env1['ENV']['PATH']
1657 def test_AppendUnique(self):
1658 """Test appending to unique values to construction variables
1660 This strips values that are already present when lists are
1662 env = self.TestEnvironment(AAA1 = 'a1',
1674 DDD1 = ['a', 'b', 'c'])
1675 env.AppendUnique(AAA1 = 'a1',
1677 AAA3 = ['a3', 'b', 'c', 'c', 'b', 'a3'], # ignore dups
1682 BBB3 = ['b3', 'c', 'd', 'c', 'b3'],
1689 assert env['AAA1'] == 'a1a1', env['AAA1']
1690 assert env['AAA2'] == ['a2'], env['AAA2']
1691 assert env['AAA3'] == ['a3', 'b', 'c'], env['AAA3']
1692 assert env['AAA4'] == 'a4a4.new', env['AAA4']
1693 assert env['AAA5'] == ['a5', 'a5.new'], env['AAA5']
1694 assert env['BBB1'] == ['b1'], env['BBB1']
1695 assert env['BBB2'] == ['b2'], env['BBB2']
1696 assert env['BBB3'] == ['b3', 'c', 'd'], env['BBB3']
1697 assert env['BBB4'] == ['b4', 'b4.new'], env['BBB4']
1698 assert env['BBB5'] == ['b5', 'b5.new'], env['BBB5']
1699 assert env['CCC1'] == 'c1', env['CCC1']
1700 assert env['CCC2'] == ['c2'], env['CCC2']
1701 assert env['DDD1'] == ['a', 'b', 'c'], env['DDD1']
1703 env.AppendUnique(DDD1 = 'b', delete_existing=1)
1704 assert env['DDD1'] == ['a', 'c', 'b'], env['DDD1'] # b moves to end
1705 env.AppendUnique(DDD1 = ['a','b'], delete_existing=1)
1706 assert env['DDD1'] == ['c', 'a', 'b'], env['DDD1'] # a & b move to end
1707 env.AppendUnique(DDD1 = ['e','f', 'e'], delete_existing=1)
1708 assert env['DDD1'] == ['c', 'a', 'b', 'f', 'e'], env['DDD1'] # add last
1710 env['CLVar'] = CLVar([])
1711 env.AppendUnique(CLVar = 'bar')
1712 result = env['CLVar']
1713 if sys.version[0] == '1' or sys.version[:3] == '2.0':
1714 # Python 2.0 and before have a quirky behavior where CLVar([])
1715 # actually matches '' and [] due to different __coerce__()
1716 # semantics in the UserList implementation. It isn't worth a
1717 # lot of effort to get this corner case to work identically
1718 # (support for Python 1.5 support will die soon anyway),
1719 # so just treat it separately for now.
1720 assert result == 'bar', result
1722 assert isinstance(result, CLVar), repr(result)
1723 assert result == ['bar'], result
1725 env['CLVar'] = CLVar(['abc'])
1726 env.AppendUnique(CLVar = 'bar')
1727 result = env['CLVar']
1728 assert isinstance(result, CLVar), repr(result)
1729 assert result == ['abc', 'bar'], result
1731 env['CLVar'] = CLVar(['bar'])
1732 env.AppendUnique(CLVar = 'bar')
1733 result = env['CLVar']
1734 assert isinstance(result, CLVar), repr(result)
1735 assert result == ['bar'], result
1737 def test_Clone(self):
1738 """Test construction environment copying
1740 Update the copy independently afterwards and check that
1741 the original remains intact (that is, no dangling
1742 references point to objects in the copied environment).
1743 Clone the original with some construction variable
1744 updates and check that the original remains intact
1745 and the copy has the updated values.
1747 env1 = self.TestEnvironment(XXX = 'x', YYY = 'y')
1749 env1copy = env1.Clone()
1750 assert env1copy == env1copy
1752 env2.Replace(YYY = 'yyy')
1755 assert env1 == env1copy
1757 env3 = env1.Clone(XXX = 'x3', ZZZ = 'z3')
1759 assert env3.Dictionary('XXX') == 'x3'
1760 assert env3.Dictionary('YYY') == 'y'
1761 assert env3.Dictionary('ZZZ') == 'z3'
1762 assert env1 == env1copy
1764 # Ensure that lists and dictionaries are
1765 # deep copied, but not instances.
1768 env1 = self.TestEnvironment(XXX=TestA(), YYY = [ 1, 2, 3 ],
1771 env2.Dictionary('YYY').append(4)
1772 env2.Dictionary('ZZZ')[5] = 6
1773 assert env1.Dictionary('XXX') is env2.Dictionary('XXX')
1774 assert 4 in env2.Dictionary('YYY')
1775 assert not 4 in env1.Dictionary('YYY')
1776 assert 5 in env2.Dictionary('ZZZ')
1777 assert 5 not in env1.Dictionary('ZZZ')
1780 env1 = self.TestEnvironment(BUILDERS = {'b1' : Builder()})
1781 assert hasattr(env1, 'b1'), "env1.b1 was not set"
1782 assert env1.b1.object == env1, "b1.object doesn't point to env1"
1783 env2 = env1.Clone(BUILDERS = {'b2' : Builder()})
1786 assert hasattr(env1, 'b1'), "b1 was mistakenly cleared from env1"
1787 assert env1.b1.object == env1, "b1.object was changed"
1788 assert not hasattr(env2, 'b1'), "b1 was not cleared from env2"
1789 assert hasattr(env2, 'b2'), "env2.b2 was not set"
1790 assert env2.b2.object == env2, "b2.object doesn't point to env2"
1792 # Ensure that specifying new tools in a copied environment
1794 def foo(env): env['FOO'] = 1
1795 def bar(env): env['BAR'] = 2
1796 def baz(env): env['BAZ'] = 3
1797 env1 = self.TestEnvironment(tools=[foo])
1799 env3 = env1.Clone(tools=[bar, baz])
1801 assert env1.get('FOO') is 1
1802 assert env1.get('BAR') is None
1803 assert env1.get('BAZ') is None
1804 assert env2.get('FOO') is 1
1805 assert env2.get('BAR') is None
1806 assert env2.get('BAZ') is None
1807 assert env3.get('FOO') is 1
1808 assert env3.get('BAR') is 2
1809 assert env3.get('BAZ') is 3
1811 # Ensure that recursive variable substitution when copying
1812 # environments works properly.
1813 env1 = self.TestEnvironment(CCFLAGS = '-DFOO', XYZ = '-DXYZ')
1814 env2 = env1.Clone(CCFLAGS = '$CCFLAGS -DBAR',
1815 XYZ = ['-DABC', 'x $XYZ y', '-DDEF'])
1816 x = env2.get('CCFLAGS')
1817 assert x == '-DFOO -DBAR', x
1819 assert x == ['-DABC', 'x -DXYZ y', '-DDEF'], x
1821 # Ensure that special properties of a class don't get
1823 env1 = self.TestEnvironment(FLAGS = CLVar('flag1 flag2'))
1824 x = env1.get('FLAGS')
1825 assert x == ['flag1', 'flag2'], x
1827 env2.Append(FLAGS = 'flag3 flag4')
1828 x = env2.get('FLAGS')
1829 assert x == ['flag1', 'flag2', 'flag3', 'flag4'], x
1831 # Test that the environment stores the toolpath and
1832 # re-uses it for copies.
1833 test = TestCmd.TestCmd(workdir = '')
1835 test.write('xxx.py', """\
1842 test.write('yyy.py', """\
1849 env = self.TestEnvironment(tools=['xxx'], toolpath=[test.workpath('')])
1850 assert env['XXX'] == 'one', env['XXX']
1851 env = env.Clone(tools=['yyy'])
1852 assert env['YYY'] == 'two', env['YYY']
1858 def my_tool(env, rv=real_value):
1859 assert env['KEY_THAT_I_WANT'] == rv[0]
1860 env['KEY_THAT_I_WANT'] = rv[0] + 1
1862 env = self.TestEnvironment()
1865 env = env.Clone(KEY_THAT_I_WANT=5, tools=[my_tool])
1866 assert env['KEY_THAT_I_WANT'] == real_value[0], env['KEY_THAT_I_WANT']
1869 env = env.Clone(KEY_THAT_I_WANT=6, tools=[my_tool])
1870 assert env['KEY_THAT_I_WANT'] == real_value[0], env['KEY_THAT_I_WANT']
1873 def test_Copy(self):
1874 """Test copying using the old env.Copy() method"""
1875 env1 = self.TestEnvironment(XXX = 'x', YYY = 'y')
1877 env1copy = env1.Copy()
1878 assert env1copy == env1copy
1880 env2.Replace(YYY = 'yyy')
1883 assert env1 == env1copy
1885 def test_Detect(self):
1886 """Test Detect()ing tools"""
1887 test = TestCmd.TestCmd(workdir = '')
1888 test.subdir('sub1', 'sub2')
1889 sub1 = test.workpath('sub1')
1890 sub2 = test.workpath('sub2')
1892 if sys.platform == 'win32':
1893 test.write(['sub1', 'xxx'], "sub1/xxx\n")
1894 test.write(['sub2', 'xxx'], "sub2/xxx\n")
1896 env = self.TestEnvironment(ENV = { 'PATH' : [sub1, sub2] })
1898 x = env.Detect('xxx.exe')
1901 test.write(['sub2', 'xxx.exe'], "sub2/xxx.exe\n")
1903 env = self.TestEnvironment(ENV = { 'PATH' : [sub1, sub2] })
1905 x = env.Detect('xxx.exe')
1906 assert x == 'xxx.exe', x
1908 test.write(['sub1', 'xxx.exe'], "sub1/xxx.exe\n")
1910 x = env.Detect('xxx.exe')
1911 assert x == 'xxx.exe', x
1914 test.write(['sub1', 'xxx.exe'], "sub1/xxx.exe\n")
1915 test.write(['sub2', 'xxx.exe'], "sub2/xxx.exe\n")
1917 env = self.TestEnvironment(ENV = { 'PATH' : [sub1, sub2] })
1919 x = env.Detect('xxx.exe')
1922 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
1923 os.chmod(sub2_xxx_exe, 0755)
1925 env = self.TestEnvironment(ENV = { 'PATH' : [sub1, sub2] })
1927 x = env.Detect('xxx.exe')
1928 assert x == 'xxx.exe', x
1930 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
1931 os.chmod(sub1_xxx_exe, 0755)
1933 x = env.Detect('xxx.exe')
1934 assert x == 'xxx.exe', x
1936 env = self.TestEnvironment(ENV = { 'PATH' : [] })
1937 x = env.Detect('xxx.exe')
1940 def test_Dictionary(self):
1941 """Test retrieval of known construction variables
1943 Fetch them from the Dictionary and check for well-known
1944 defaults that get inserted.
1946 env = self.TestEnvironment(XXX = 'x', YYY = 'y', ZZZ = 'z')
1947 assert env.Dictionary('XXX') == 'x'
1948 assert env.Dictionary('YYY') == 'y'
1949 assert env.Dictionary('XXX', 'ZZZ') == ['x', 'z']
1950 xxx, zzz = env.Dictionary('XXX', 'ZZZ')
1953 assert 'BUILDERS' in env.Dictionary()
1954 assert 'CC' in env.Dictionary()
1955 assert 'CCFLAGS' in env.Dictionary()
1956 assert 'ENV' in env.Dictionary()
1958 assert env['XXX'] == 'x'
1960 assert env.Dictionary('XXX') == 'foo'
1962 assert 'XXX' not in env.Dictionary()
1964 def test_FindIxes(self):
1966 env = self.TestEnvironment(LIBPREFIX='lib',
1973 paths = [os.path.join('dir', 'libfoo.a'),
1974 os.path.join('dir', 'libfoo.so')]
1976 assert paths[0] == env.FindIxes(paths, 'LIBPREFIX', 'LIBSUFFIX')
1977 assert paths[1] == env.FindIxes(paths, 'SHLIBPREFIX', 'SHLIBSUFFIX')
1978 assert None is env.FindIxes(paths, 'PREFIX', 'POST')
1980 paths = ['libfoo.a', 'prefoopost']
1982 assert paths[0] == env.FindIxes(paths, 'LIBPREFIX', 'LIBSUFFIX')
1983 assert None is env.FindIxes(paths, 'SHLIBPREFIX', 'SHLIBSUFFIX')
1984 assert paths[1] == env.FindIxes(paths, 'PREFIX', 'SUFFIX')
1986 def test_ParseConfig(self):
1987 """Test the ParseConfig() method"""
1988 env = self.TestEnvironment(COMMAND='command',
1989 ASFLAGS='assembler',
2001 orig_backtick = env.backtick
2003 def __init__(self, save_command, output):
2004 self.save_command = save_command
2005 self.output = output
2006 def __call__(self, command):
2007 self.save_command.append(command)
2012 env.backtick = my_backtick(save_command,
2013 "-I/usr/include/fum -I bar -X\n" + \
2014 "-L/usr/fax -L foo -lxxx -l yyy " + \
2015 "-Wa,-as -Wl,-link " + \
2016 "-Wl,-rpath=rpath1 " + \
2017 "-Wl,-R,rpath2 " + \
2020 "-framework Carbon " + \
2021 "-frameworkdir=fwd1 " + \
2025 "-mno-cygwin -mwindows " + \
2026 "-arch i386 -isysroot /tmp +DD64 " + \
2027 "-DFOO -DBAR=value")
2028 env.ParseConfig("fake $COMMAND")
2029 assert save_command == ['fake command'], save_command
2030 assert env['ASFLAGS'] == ['assembler', '-as'], env['ASFLAGS']
2031 assert env['CCFLAGS'] == ['', '-X', '-Wa,-as',
2032 '-pthread', '-mno-cygwin',
2033 ('-arch', 'i386'), ('-isysroot', '/tmp'),
2034 '+DD64'], env['CCFLAGS']
2035 assert env['CPPDEFINES'] == ['FOO', ['BAR', 'value']], env['CPPDEFINES']
2036 assert env['CPPFLAGS'] == ['', '-Wp,-cpp'], env['CPPFLAGS']
2037 assert env['CPPPATH'] == ['string', '/usr/include/fum', 'bar'], env['CPPPATH']
2038 assert env['FRAMEWORKPATH'] == ['fwd1', 'fwd2', 'fwd3'], env['FRAMEWORKPATH']
2039 assert env['FRAMEWORKS'] == ['Carbon'], env['FRAMEWORKS']
2040 assert env['LIBPATH'] == ['list', '/usr/fax', 'foo'], env['LIBPATH']
2041 assert env['LIBS'] == ['xxx', 'yyy', env.File('abc')], env['LIBS']
2042 assert env['LINKFLAGS'] == ['', '-Wl,-link', '-pthread',
2043 '-mno-cygwin', '-mwindows',
2045 ('-isysroot', '/tmp'),
2046 '+DD64'], env['LINKFLAGS']
2047 assert env['RPATH'] == ['rpath1', 'rpath2', 'rpath3'], env['RPATH']
2049 env.backtick = my_backtick([], "-Ibar")
2050 env.ParseConfig("fake2")
2051 assert env['CPPPATH'] == ['string', '/usr/include/fum', 'bar'], env['CPPPATH']
2052 env.ParseConfig("fake2", unique=0)
2053 assert env['CPPPATH'] == ['string', '/usr/include/fum', 'bar', 'bar'], env['CPPPATH']
2055 env.backtick = orig_backtick
2057 def test_ParseDepends(self):
2058 """Test the ParseDepends() method"""
2059 test = TestCmd.TestCmd(workdir = '')
2061 test.write('single', """
2071 test.write('multiple', """
2082 env = self.TestEnvironment(SINGLE = test.workpath('single'))
2086 def my_depends(target, dependency, tlist=tlist, dlist=dlist):
2087 tlist.extend(target)
2088 dlist.extend(dependency)
2090 env.Depends = my_depends
2092 env.ParseDepends(test.workpath('does_not_exist'))
2096 env.ParseDepends(test.workpath('does_not_exist'), must_exist=1)
2099 assert exc_caught, "did not catch expected IOError"
2104 env.ParseDepends('$SINGLE', only_one=1)
2105 t = list(map(str, tlist))
2106 d = list(map(str, dlist))
2107 assert t == ['f0'], t
2108 assert d == ['d1', 'd2', 'd3'], d
2113 env.ParseDepends(test.workpath('multiple'))
2114 t = list(map(str, tlist))
2115 d = list(map(str, dlist))
2116 assert t == ['f1', 'f2', 'f3', 'f4', 'f5'], t
2117 assert d == ['foo', 'bar', 'abc', 'def', 'ghi', 'jkl', 'mno'], d
2121 env.ParseDepends(test.workpath('multiple'), only_one=1)
2122 except SCons.Errors.UserError:
2124 assert exc_caught, "did not catch expected UserError"
2126 def test_Platform(self):
2127 """Test the Platform() method"""
2128 env = self.TestEnvironment(WIN32='win32', NONE='no-such-platform')
2132 env.Platform('does_not_exist')
2133 except SCons.Errors.UserError:
2135 assert exc_caught, "did not catch expected UserError"
2139 env.Platform('$NONE')
2140 except SCons.Errors.UserError:
2142 assert exc_caught, "did not catch expected UserError"
2144 env.Platform('posix')
2145 assert env['OBJSUFFIX'] == '.o', env['OBJSUFFIX']
2147 env.Platform('$WIN32')
2148 assert env['OBJSUFFIX'] == '.obj', env['OBJSUFFIX']
2150 def test_Prepend(self):
2151 """Test prepending to construction variables in an Environment
2154 UD = UserDict.UserDict
2156 UL = UserList.UserList
2160 'a2', ['A2'], ['A2', 'a2'],
2161 'a3', UL(['A3']), UL(['A3', 'a', '3']),
2164 'a6', UL([]), UL(['a', '6']),
2165 'a7', [''], ['', 'a7'],
2166 'a8', UL(['']), UL(['', 'a', '8']),
2168 ['e1'], 'E1', ['E1', 'e1'],
2169 ['e2'], ['E2'], ['E2', 'e2'],
2170 ['e3'], UL(['E3']), UL(['E3', 'e3']),
2173 ['e6'], UL([]), UL(['e6']),
2174 ['e7'], [''], ['', 'e7'],
2175 ['e8'], UL(['']), UL(['', 'e8']),
2177 UL(['i1']), 'I1', UL(['I', '1', 'i1']),
2178 UL(['i2']), ['I2'], UL(['I2', 'i2']),
2179 UL(['i3']), UL(['I3']), UL(['I3', 'i3']),
2180 UL(['i4']), '', UL(['i4']),
2181 UL(['i5']), [], UL(['i5']),
2182 UL(['i6']), UL([]), UL(['i6']),
2183 UL(['i7']), [''], UL(['', 'i7']),
2184 UL(['i8']), UL(['']), UL(['', 'i8']),
2186 {'d1':1}, 'D1', {'d1':1, 'D1':None},
2187 {'d2':1}, ['D2'], {'d2':1, 'D2':None},
2188 {'d3':1}, UL(['D3']), {'d3':1, 'D3':None},
2189 {'d4':1}, {'D4':1}, {'d4':1, 'D4':1},
2190 {'d5':1}, UD({'D5':1}), UD({'d5':1, 'D5':1}),
2192 UD({'u1':1}), 'U1', UD({'u1':1, 'U1':None}),
2193 UD({'u2':1}), ['U2'], UD({'u2':1, 'U2':None}),
2194 UD({'u3':1}), UL(['U3']), UD({'u3':1, 'U3':None}),
2195 UD({'u4':1}), {'U4':1}, UD({'u4':1, 'U4':1}),
2196 UD({'u5':1}), UD({'U5':1}), UD({'u5':1, 'U5':1}),
2200 '', UL(['M3']), UL(['M3']),
2205 '', UL(['']), UL(['']),
2209 [], UL(['N3']), UL(['N3']),
2214 [], UL(['']), UL(['']),
2216 UL([]), 'O1', UL(['O', '1']),
2217 UL([]), ['O2'], UL(['O2']),
2218 UL([]), UL(['O3']), UL(['O3']),
2221 UL([]), UL([]), UL([]),
2222 UL([]), [''], UL(['']),
2223 UL([]), UL(['']), UL(['']),
2225 [''], 'P1', ['P1', ''],
2226 [''], ['P2'], ['P2', ''],
2227 [''], UL(['P3']), UL(['P3', '']),
2230 [''], UL([]), UL(['']),
2231 [''], [''], ['', ''],
2232 [''], UL(['']), UL(['', '']),
2234 UL(['']), 'Q1', UL(['Q', '1', '']),
2235 UL(['']), ['Q2'], UL(['Q2', '']),
2236 UL(['']), UL(['Q3']), UL(['Q3', '']),
2237 UL(['']), '', UL(['']),
2238 UL(['']), [], UL(['']),
2239 UL(['']), UL([]), UL(['']),
2240 UL(['']), [''], UL(['', '']),
2241 UL(['']), UL(['']), UL(['', '']),
2247 input, prepend, expect = cases[:3]
2248 env['XXX'] = copy.copy(input)
2250 env.Prepend(XXX = prepend)
2251 except Exception, e:
2252 if failed == 0: print
2253 print " %s Prepend %s exception: %s" % \
2254 (repr(input), repr(prepend), e)
2258 if result != expect:
2259 if failed == 0: print
2260 print " %s Prepend %s => %s did not match %s" % \
2261 (repr(input), repr(prepend), repr(result), repr(expect))
2264 assert failed == 0, "%d Prepend() cases failed" % failed
2266 env['UL'] = UL(['foo'])
2267 env.Prepend(UL = 'bar')
2269 assert isinstance(result, UL), repr(result)
2270 assert result == ['b', 'a', 'r', 'foo'], result
2272 env['CLVar'] = CLVar(['foo'])
2273 env.Prepend(CLVar = 'bar')
2274 result = env['CLVar']
2275 assert isinstance(result, CLVar), repr(result)
2276 assert result == ['bar', 'foo'], result
2278 env3 = self.TestEnvironment(X = {'x1' : 7})
2279 env3.Prepend(X = {'x1' : 8, 'x2' : 9}, Y = {'y1' : 10})
2280 assert env3['X'] == {'x1': 8, 'x2' : 9}, env3['X']
2281 assert env3['Y'] == {'y1': 10}, env3['Y']
2285 env4 = self.TestEnvironment(BUILDERS = {'z1' : z1})
2286 env4.Prepend(BUILDERS = {'z2' : z2})
2287 assert env4['BUILDERS'] == {'z1' : z1, 'z2' : z2}, env4['BUILDERS']
2288 assert hasattr(env4, 'z1')
2289 assert hasattr(env4, 'z2')
2291 def test_PrependENVPath(self):
2292 """Test prepending to an ENV path."""
2293 env1 = self.TestEnvironment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
2294 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
2295 # have to include the pathsep here so that the test will work on UNIX too.
2296 env1.PrependENVPath('PATH',r'C:\dir\num\two',sep = ';')
2297 env1.PrependENVPath('PATH',r'C:\dir\num\three',sep = ';')
2298 env1.PrependENVPath('MYPATH',r'C:\mydir\num\three','MYENV',sep = ';')
2299 env1.PrependENVPath('MYPATH',r'C:\mydir\num\one','MYENV',sep = ';')
2300 # this should do nothing since delete_existing is 0
2301 env1.PrependENVPath('MYPATH',r'C:\mydir\num\three','MYENV', sep = ';', delete_existing=0)
2302 assert(env1['ENV']['PATH'] == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
2303 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
2305 test = TestCmd.TestCmd(workdir = '')
2306 test.subdir('sub1', 'sub2')
2307 p=env1['ENV']['PATH']
2308 env1.PrependENVPath('PATH','#sub1', sep = ';')
2309 env1.PrependENVPath('PATH',env1.fs.Dir('sub2'), sep = ';')
2310 assert env1['ENV']['PATH'] == 'sub2;sub1;' + p, env1['ENV']['PATH']
2312 def test_PrependUnique(self):
2313 """Test prepending unique values to construction variables
2315 This strips values that are already present when lists are
2317 env = self.TestEnvironment(AAA1 = 'a1',
2329 DDD1 = ['a', 'b', 'c'])
2330 env.PrependUnique(AAA1 = 'a1',
2332 AAA3 = ['a3', 'b', 'c', 'b', 'a3'], # ignore dups
2337 BBB3 = ['b3', 'b', 'c', 'b3'],
2343 assert env['AAA1'] == 'a1a1', env['AAA1']
2344 assert env['AAA2'] == ['a2'], env['AAA2']
2345 assert env['AAA3'] == ['c', 'b', 'a3'], env['AAA3']
2346 assert env['AAA4'] == 'a4.newa4', env['AAA4']
2347 assert env['AAA5'] == ['a5.new', 'a5'], env['AAA5']
2348 assert env['BBB1'] == ['b1'], env['BBB1']
2349 assert env['BBB2'] == ['b2'], env['BBB2']
2350 assert env['BBB3'] == ['b', 'c', 'b3'], env['BBB3']
2351 assert env['BBB4'] == ['b4.new', 'b4'], env['BBB4']
2352 assert env['BBB5'] == ['b5.new', 'b5'], env['BBB5']
2353 assert env['CCC1'] == 'c1', env['CCC1']
2354 assert env['CCC2'] == ['c2'], env['CCC2']
2355 assert env['DDD1'] == ['a', 'b', 'c'], env['DDD1']
2357 env.PrependUnique(DDD1 = 'b', delete_existing=1)
2358 assert env['DDD1'] == ['b', 'a', 'c'], env['DDD1'] # b moves to front
2359 env.PrependUnique(DDD1 = ['a','c'], delete_existing=1)
2360 assert env['DDD1'] == ['a', 'c', 'b'], env['DDD1'] # a & c move to front
2361 env.PrependUnique(DDD1 = ['d','e','d'], delete_existing=1)
2362 assert env['DDD1'] == ['d', 'e', 'a', 'c', 'b'], env['DDD1']
2365 env['CLVar'] = CLVar([])
2366 env.PrependUnique(CLVar = 'bar')
2367 result = env['CLVar']
2368 if sys.version[0] == '1' or sys.version[:3] == '2.0':
2369 # Python 2.0 and before have a quirky behavior where CLVar([])
2370 # actually matches '' and [] due to different __coerce__()
2371 # semantics in the UserList implementation. It isn't worth a
2372 # lot of effort to get this corner case to work identically
2373 # (support for Python 1.5 support will die soon anyway),
2374 # so just treat it separately for now.
2375 assert result == 'bar', result
2377 assert isinstance(result, CLVar), repr(result)
2378 assert result == ['bar'], result
2380 env['CLVar'] = CLVar(['abc'])
2381 env.PrependUnique(CLVar = 'bar')
2382 result = env['CLVar']
2383 assert isinstance(result, CLVar), repr(result)
2384 assert result == ['bar', 'abc'], result
2386 env['CLVar'] = CLVar(['bar'])
2387 env.PrependUnique(CLVar = 'bar')
2388 result = env['CLVar']
2389 assert isinstance(result, CLVar), repr(result)
2390 assert result == ['bar'], result
2392 def test_Replace(self):
2393 """Test replacing construction variables in an Environment
2395 After creation of the Environment, of course.
2397 env1 = self.TestEnvironment(AAA = 'a', BBB = 'b')
2398 env1.Replace(BBB = 'bbb', CCC = 'ccc')
2400 env2 = self.TestEnvironment(AAA = 'a', BBB = 'bbb', CCC = 'ccc')
2401 assert env1 == env2, diff_env(env1, env2)
2405 env3 = self.TestEnvironment(BUILDERS = {'b1' : b1})
2406 assert hasattr(env3, 'b1'), "b1 was not set"
2407 env3.Replace(BUILDERS = {'b2' : b2})
2408 assert not hasattr(env3, 'b1'), "b1 was not cleared"
2409 assert hasattr(env3, 'b2'), "b2 was not set"
2411 def test_ReplaceIxes(self):
2412 "Test ReplaceIxes()"
2413 env = self.TestEnvironment(LIBPREFIX='lib',
2420 assert 'libfoo.a' == env.ReplaceIxes('libfoo.so',
2421 'SHLIBPREFIX', 'SHLIBSUFFIX',
2422 'LIBPREFIX', 'LIBSUFFIX')
2424 assert os.path.join('dir', 'libfoo.a') == env.ReplaceIxes(os.path.join('dir', 'libfoo.so'),
2425 'SHLIBPREFIX', 'SHLIBSUFFIX',
2426 'LIBPREFIX', 'LIBSUFFIX')
2428 assert 'libfoo.a' == env.ReplaceIxes('prefoopost',
2430 'LIBPREFIX', 'LIBSUFFIX')
2432 def test_SetDefault(self):
2433 """Test the SetDefault method"""
2434 env = self.TestEnvironment(tools = [])
2435 env.SetDefault(V1 = 1)
2436 env.SetDefault(V1 = 2)
2437 assert env['V1'] == 1
2439 env.SetDefault(V2 = 1)
2440 assert env['V2'] == 2
2442 def test_Tool(self):
2443 """Test the Tool() method"""
2444 env = self.TestEnvironment(LINK='link', NONE='no-such-tool')
2448 env.Tool('does_not_exist')
2449 except SCons.Errors.EnvironmentError:
2451 assert exc_caught, "did not catch expected EnvironmentError"
2456 except SCons.Errors.EnvironmentError:
2458 assert exc_caught, "did not catch expected EnvironmentError"
2460 # Use a non-existent toolpath directory just to make sure we
2461 # can call Tool() with the keyword argument.
2462 env.Tool('cc', toolpath=['/no/such/directory'])
2463 assert env['CC'] == 'cc', env['CC']
2466 assert env['LINK'] == '$SMARTLINK', env['LINK']
2468 # Test that the environment stores the toolpath and
2469 # re-uses it for later calls.
2470 test = TestCmd.TestCmd(workdir = '')
2472 test.write('xxx.py', """\
2479 test.write('yyy.py', """\
2486 env = self.TestEnvironment(tools=['xxx'], toolpath=[test.workpath('')])
2487 assert env['XXX'] == 'one', env['XXX']
2489 assert env['YYY'] == 'two', env['YYY']
2491 def test_WhereIs(self):
2492 """Test the WhereIs() method"""
2493 test = TestCmd.TestCmd(workdir = '')
2495 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
2496 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
2497 sub3_xxx_exe = test.workpath('sub3', 'xxx.exe')
2498 sub4_xxx_exe = test.workpath('sub4', 'xxx.exe')
2500 test.subdir('subdir', 'sub1', 'sub2', 'sub3', 'sub4')
2502 if sys.platform != 'win32':
2503 test.write(sub1_xxx_exe, "\n")
2505 os.mkdir(sub2_xxx_exe)
2507 test.write(sub3_xxx_exe, "\n")
2508 os.chmod(sub3_xxx_exe, 0777)
2510 test.write(sub4_xxx_exe, "\n")
2511 os.chmod(sub4_xxx_exe, 0777)
2513 env_path = os.environ['PATH']
2515 pathdirs_1234 = [ test.workpath('sub1'),
2516 test.workpath('sub2'),
2517 test.workpath('sub3'),
2518 test.workpath('sub4'),
2519 ] + env_path.split(os.pathsep)
2521 pathdirs_1243 = [ test.workpath('sub1'),
2522 test.workpath('sub2'),
2523 test.workpath('sub4'),
2524 test.workpath('sub3'),
2525 ] + env_path.split(os.pathsep)
2527 path = os.pathsep.join(pathdirs_1234)
2528 env = self.TestEnvironment(ENV = {'PATH' : path})
2529 wi = env.WhereIs('xxx.exe')
2530 assert wi == test.workpath(sub3_xxx_exe), wi
2531 wi = env.WhereIs('xxx.exe', pathdirs_1243)
2532 assert wi == test.workpath(sub4_xxx_exe), wi
2533 wi = env.WhereIs('xxx.exe', os.pathsep.join(pathdirs_1243))
2534 assert wi == test.workpath(sub4_xxx_exe), wi
2536 wi = env.WhereIs('xxx.exe', reject = sub3_xxx_exe)
2537 assert wi == test.workpath(sub4_xxx_exe), wi
2538 wi = env.WhereIs('xxx.exe', pathdirs_1243, reject = sub3_xxx_exe)
2539 assert wi == test.workpath(sub4_xxx_exe), wi
2541 path = os.pathsep.join(pathdirs_1243)
2542 env = self.TestEnvironment(ENV = {'PATH' : path})
2543 wi = env.WhereIs('xxx.exe')
2544 assert wi == test.workpath(sub4_xxx_exe), wi
2545 wi = env.WhereIs('xxx.exe', pathdirs_1234)
2546 assert wi == test.workpath(sub3_xxx_exe), wi
2547 wi = env.WhereIs('xxx.exe', os.pathsep.join(pathdirs_1234))
2548 assert wi == test.workpath(sub3_xxx_exe), wi
2550 if sys.platform == 'win32':
2551 wi = env.WhereIs('xxx', pathext = '')
2552 assert wi is None, wi
2554 wi = env.WhereIs('xxx', pathext = '.exe')
2555 assert wi == test.workpath(sub4_xxx_exe), wi
2557 wi = env.WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
2558 assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
2560 # Test that we return a normalized path even when
2561 # the path contains forward slashes.
2562 forward_slash = test.workpath('') + '/sub3'
2563 wi = env.WhereIs('xxx', path = forward_slash, pathext = '.EXE')
2564 assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
2568 def test_Action(self):
2569 """Test the Action() method"""
2572 env = self.TestEnvironment(FOO = 'xyzzy')
2574 a = env.Action('foo')
2576 assert a.__class__ is SCons.Action.CommandAction, a.__class__
2578 a = env.Action('$FOO')
2580 assert a.__class__ is SCons.Action.CommandAction, a.__class__
2582 a = env.Action('$$FOO')
2584 assert a.__class__ is SCons.Action.LazyAction, a.__class__
2586 a = env.Action(['$FOO', 'foo'])
2588 assert a.__class__ is SCons.Action.ListAction, a.__class__
2592 a = env.Action(func)
2594 assert a.__class__ is SCons.Action.FunctionAction, a.__class__
2596 def test_AddPostAction(self):
2597 """Test the AddPostAction() method"""
2598 env = self.TestEnvironment(FOO='fff', BAR='bbb')
2600 n = env.AddPostAction('$FOO', lambda x: x)
2601 assert str(n[0]) == 'fff', n[0]
2603 n = env.AddPostAction(['ggg', '$BAR'], lambda x: x)
2604 assert str(n[0]) == 'ggg', n[0]
2605 assert str(n[1]) == 'bbb', n[1]
2607 def test_AddPreAction(self):
2608 """Test the AddPreAction() method"""
2609 env = self.TestEnvironment(FOO='fff', BAR='bbb')
2611 n = env.AddPreAction('$FOO', lambda x: x)
2612 assert str(n[0]) == 'fff', n[0]
2614 n = env.AddPreAction(['ggg', '$BAR'], lambda x: x)
2615 assert str(n[0]) == 'ggg', n[0]
2616 assert str(n[1]) == 'bbb', n[1]
2618 def test_Alias(self):
2619 """Test the Alias() method"""
2620 env = self.TestEnvironment(FOO='kkk', BAR='lll', EA='export_alias')
2622 tgt = env.Alias('new_alias')[0]
2623 assert str(tgt) == 'new_alias', tgt
2624 assert tgt.sources == [], tgt.sources
2625 assert not hasattr(tgt, 'builder'), tgt.builder
2627 tgt = env.Alias('None_alias', None)[0]
2628 assert str(tgt) == 'None_alias', tgt
2629 assert tgt.sources == [], tgt.sources
2631 tgt = env.Alias('empty_list', [])[0]
2632 assert str(tgt) == 'empty_list', tgt
2633 assert tgt.sources == [], tgt.sources
2635 tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ])[0]
2636 assert str(tgt) == 'export_alias', tgt
2637 assert len(tgt.sources) == 2, list(map(str, tgt.sources))
2638 assert str(tgt.sources[0]) == 'asrc1', list(map(str, tgt.sources))
2639 assert str(tgt.sources[1]) == 'kkk', list(map(str, tgt.sources))
2641 n = env.Alias(tgt, source = ['$BAR', 'asrc4'])[0]
2643 assert len(tgt.sources) == 4, list(map(str, tgt.sources))
2644 assert str(tgt.sources[2]) == 'lll', list(map(str, tgt.sources))
2645 assert str(tgt.sources[3]) == 'asrc4', list(map(str, tgt.sources))
2647 n = env.Alias('$EA', 'asrc5')[0]
2649 assert len(tgt.sources) == 5, list(map(str, tgt.sources))
2650 assert str(tgt.sources[4]) == 'asrc5', list(map(str, tgt.sources))
2652 t1, t2 = env.Alias(['t1', 't2'], ['asrc6', 'asrc7'])
2653 assert str(t1) == 't1', t1
2654 assert str(t2) == 't2', t2
2655 assert len(t1.sources) == 2, list(map(str, t1.sources))
2656 assert str(t1.sources[0]) == 'asrc6', list(map(str, t1.sources))
2657 assert str(t1.sources[1]) == 'asrc7', list(map(str, t1.sources))
2658 assert len(t2.sources) == 2, list(map(str, t2.sources))
2659 assert str(t2.sources[0]) == 'asrc6', list(map(str, t2.sources))
2660 assert str(t2.sources[1]) == 'asrc7', list(map(str, t2.sources))
2662 tgt = env.Alias('add', 's1')
2663 tgt = env.Alias('add', 's2')[0]
2664 s = list(map(str, tgt.sources))
2665 assert s == ['s1', 's2'], s
2666 tgt = env.Alias(tgt, 's3')[0]
2667 s = list(map(str, tgt.sources))
2668 assert s == ['s1', 's2', 's3'], s
2670 tgt = env.Alias('act', None, "action1")[0]
2671 s = str(tgt.builder.action)
2672 assert s == "action1", s
2673 tgt = env.Alias('act', None, "action2")[0]
2674 s = str(tgt.builder.action)
2675 assert s == "action1\naction2", s
2676 tgt = env.Alias(tgt, None, "action3")[0]
2677 s = str(tgt.builder.action)
2678 assert s == "action1\naction2\naction3", s
2680 def test_AlwaysBuild(self):
2681 """Test the AlwaysBuild() method"""
2682 env = self.TestEnvironment(FOO='fff', BAR='bbb')
2683 t = env.AlwaysBuild('a', 'b$FOO', ['c', 'd'], '$BAR',
2684 env.fs.Dir('dir'), env.fs.File('file'))
2685 assert t[0].__class__.__name__ == 'Entry'
2686 assert t[0].path == 'a'
2687 assert t[0].always_build
2688 assert t[1].__class__.__name__ == 'Entry'
2689 assert t[1].path == 'bfff'
2690 assert t[1].always_build
2691 assert t[2].__class__.__name__ == 'Entry'
2692 assert t[2].path == 'c'
2693 assert t[2].always_build
2694 assert t[3].__class__.__name__ == 'Entry'
2695 assert t[3].path == 'd'
2696 assert t[3].always_build
2697 assert t[4].__class__.__name__ == 'Entry'
2698 assert t[4].path == 'bbb'
2699 assert t[4].always_build
2700 assert t[5].__class__.__name__ == 'Dir'
2701 assert t[5].path == 'dir'
2702 assert t[5].always_build
2703 assert t[6].__class__.__name__ == 'File'
2704 assert t[6].path == 'file'
2705 assert t[6].always_build
2707 def test_VariantDir(self):
2708 """Test the VariantDir() method"""
2710 def Dir(self, name):
2712 def VariantDir(self, variant_dir, src_dir, duplicate):
2713 self.variant_dir = variant_dir
2714 self.src_dir = src_dir
2715 self.duplicate = duplicate
2717 env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb')
2720 env.VariantDir('build', 'src')
2721 assert env.fs.variant_dir == 'build', env.fs.variant_dir
2722 assert env.fs.src_dir == 'src', env.fs.src_dir
2723 assert env.fs.duplicate == 1, env.fs.duplicate
2725 env.VariantDir('build${FOO}', '${BAR}src', 0)
2726 assert env.fs.variant_dir == 'buildfff', env.fs.variant_dir
2727 assert env.fs.src_dir == 'bbbsrc', env.fs.src_dir
2728 assert env.fs.duplicate == 0, env.fs.duplicate
2730 def test_Builder(self):
2731 """Test the Builder() method"""
2732 env = self.TestEnvironment(FOO = 'xyzzy')
2734 b = env.Builder(action = 'foo')
2735 assert b is not None, b
2737 b = env.Builder(action = '$FOO')
2738 assert b is not None, b
2740 b = env.Builder(action = ['$FOO', 'foo'])
2741 assert b is not None, b
2745 b = env.Builder(action = func)
2746 assert b is not None, b
2747 b = env.Builder(generator = func)
2748 assert b is not None, b
2750 def test_CacheDir(self):
2751 """Test the CacheDir() method"""
2752 env = self.TestEnvironment(CD = 'CacheDir')
2755 assert env._CacheDir_path == 'foo', env._CacheDir_path
2758 assert env._CacheDir_path == 'CacheDir', env._CacheDir_path
2760 def test_Clean(self):
2761 """Test the Clean() method"""
2762 env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb')
2764 CT = SCons.Environment.CleanTargets
2766 foo = env.arg2nodes('foo')[0]
2767 fff = env.arg2nodes('fff')[0]
2769 t = env.Clean('foo', 'aaa')
2770 l = list(map(str, CT[foo]))
2771 assert l == ['aaa'], l
2773 t = env.Clean(foo, ['$BAR', 'ccc'])
2774 l = list(map(str, CT[foo]))
2775 assert l == ['aaa', 'bbb', 'ccc'], l
2777 eee = env.arg2nodes('eee')[0]
2779 t = env.Clean('$FOO', 'ddd')
2780 l = list(map(str, CT[fff]))
2781 assert l == ['ddd'], l
2782 t = env.Clean(fff, [eee, 'fff'])
2783 l = list(map(str, CT[fff]))
2784 assert l == ['ddd', 'eee', 'fff'], l
2786 def test_Command(self):
2787 """Test the Command() method."""
2789 t = env.Command(target='foo.out', source=['foo1.in', 'foo2.in'],
2790 action='buildfoo $target $source')[0]
2791 assert t.builder is not None
2792 assert t.builder.action.__class__.__name__ == 'CommandAction'
2793 assert t.builder.action.cmd_list == 'buildfoo $target $source'
2794 assert 'foo1.in' in [x.path for x in t.sources]
2795 assert 'foo2.in' in [x.path for x in t.sources]
2797 sub = env.fs.Dir('sub')
2798 t = env.Command(target='bar.out', source='sub',
2799 action='buildbar $target $source')[0]
2800 assert 'sub' in [x.path for x in t.sources]
2802 def testFunc(env, target, source):
2803 assert str(target[0]) == 'foo.out'
2804 assert 'foo1.in' in list(map(str, source)) and 'foo2.in' in list(map(str, source)), list(map(str, source))
2806 t = env.Command(target='foo.out', source=['foo1.in','foo2.in'],
2808 assert t.builder is not None
2809 assert t.builder.action.__class__.__name__ == 'FunctionAction'
2811 assert 'foo1.in' in [x.path for x in t.sources]
2812 assert 'foo2.in' in [x.path for x in t.sources]
2815 def test2(baz, x=x):
2817 env = self.TestEnvironment(TEST2 = test2)
2818 t = env.Command(target='baz.out', source='baz.in',
2819 action='${TEST2(XYZ)}',
2820 XYZ='magic word')[0]
2821 assert t.builder is not None
2823 assert x[0] == 'magic word', x
2825 t = env.Command(target='${X}.out', source='${X}.in',
2828 assert str(t) == 'xxx.out', str(t)
2829 assert 'xxx.in' in [x.path for x in t.sources]
2831 env = self.TestEnvironment(source_scanner = 'should_not_find_this')
2832 t = env.Command(target='file.out', source='file.in',
2834 source_scanner = 'fake')[0]
2835 assert t.builder.source_scanner == 'fake', t.builder.source_scanner
2837 def test_Configure(self):
2838 """Test the Configure() method"""
2839 # Configure() will write to a local temporary file.
2840 test = TestCmd.TestCmd(workdir = '')
2844 os.chdir(test.workpath())
2846 env = self.TestEnvironment(FOO = 'xyzzy')
2852 assert c is not None, c
2855 c = env.Configure(custom_tests = {'foo' : func, '$FOO' : func})
2856 assert c is not None, c
2857 assert hasattr(c, 'foo')
2858 assert hasattr(c, 'xyzzy')
2863 def test_Depends(self):
2864 """Test the explicit Depends method."""
2865 env = self.TestEnvironment(FOO = 'xxx', BAR='yyy')
2870 t = env.Depends(target='EnvironmentTest.py',
2871 dependency='Environment.py')[0]
2872 assert t.__class__.__name__ == 'Entry', t.__class__.__name__
2873 assert t.path == 'EnvironmentTest.py'
2874 assert len(t.depends) == 1
2876 assert d.__class__.__name__ == 'Entry', d.__class__.__name__
2877 assert d.path == 'Environment.py'
2879 t = env.Depends(target='${FOO}.py', dependency='${BAR}.py')[0]
2880 assert t.__class__.__name__ == 'File', t.__class__.__name__
2881 assert t.path == 'xxx.py'
2882 assert len(t.depends) == 1
2884 assert d.__class__.__name__ == 'File', d.__class__.__name__
2885 assert d.path == 'yyy.py'
2887 t = env.Depends(target='dir1', dependency='dir2')[0]
2888 assert t.__class__.__name__ == 'Dir', t.__class__.__name__
2889 assert t.path == 'dir1'
2890 assert len(t.depends) == 1
2892 assert d.__class__.__name__ == 'Dir', d.__class__.__name__
2893 assert d.path == 'dir2'
2896 """Test the Dir() method"""
2898 def Dir(self, name):
2899 return 'Dir(%s)' % name
2901 env = self.TestEnvironment(FOO = 'foodir', BAR = 'bardir')
2905 assert d == 'Dir(d)', d
2908 assert d == 'Dir(foodir)', d
2910 d = env.Dir('${BAR}_$BAR')
2911 assert d == 'Dir(bardir_bardir)', d
2913 d = env.Dir(['dir1'])
2914 assert d == ['Dir(dir1)'], d
2916 d = env.Dir(['dir1', 'dir2'])
2917 assert d == ['Dir(dir1)', 'Dir(dir2)'], d
2919 def test_NoClean(self):
2920 """Test the NoClean() method"""
2921 env = self.TestEnvironment(FOO='ggg', BAR='hhh')
2924 t = env.NoClean('p_a', 'p_${BAR}b', ['p_c', 'p_d'], 'p_$FOO')
2926 assert t[0].__class__.__name__ == 'Entry', t[0].__class__.__name__
2927 assert t[0].path == 'p_a'
2929 assert t[1].__class__.__name__ == 'Dir', t[1].__class__.__name__
2930 assert t[1].path == 'p_hhhb'
2932 assert t[2].__class__.__name__ == 'Entry', t[2].__class__.__name__
2933 assert t[2].path == 'p_c'
2935 assert t[3].__class__.__name__ == 'File', t[3].__class__.__name__
2936 assert t[3].path == 'p_d'
2938 assert t[4].__class__.__name__ == 'Entry', t[4].__class__.__name__
2939 assert t[4].path == 'p_ggg'
2942 def test_Dump(self):
2943 """Test the Dump() method"""
2945 env = self.TestEnvironment(FOO = 'foo')
2946 assert env.Dump('FOO') == "'foo'", env.Dump('FOO')
2947 assert len(env.Dump()) > 200, env.Dump() # no args version
2949 def test_Environment(self):
2950 """Test the Environment() method"""
2951 env = self.TestEnvironment(FOO = 'xxx', BAR = 'yyy')
2953 e2 = env.Environment(X = '$FOO', Y = '$BAR')
2954 assert e2['X'] == 'xxx', e2['X']
2955 assert e2['Y'] == 'yyy', e2['Y']
2957 def test_Execute(self):
2958 """Test the Execute() method"""
2961 def __init__(self, *args, **kw):
2963 def __call__(self, target, source, env):
2964 return "%s executed" % self.args
2967 env.Action = MyAction
2969 result = env.Execute("foo")
2970 assert result == "foo executed", result
2972 def test_Entry(self):
2973 """Test the Entry() method"""
2975 def Entry(self, name):
2976 return 'Entry(%s)' % name
2978 env = self.TestEnvironment(FOO = 'fooentry', BAR = 'barentry')
2982 assert e == 'Entry(e)', e
2984 e = env.Entry('$FOO')
2985 assert e == 'Entry(fooentry)', e
2987 e = env.Entry('${BAR}_$BAR')
2988 assert e == 'Entry(barentry_barentry)', e
2990 e = env.Entry(['entry1'])
2991 assert e == ['Entry(entry1)'], e
2993 e = env.Entry(['entry1', 'entry2'])
2994 assert e == ['Entry(entry1)', 'Entry(entry2)'], e
2996 def test_File(self):
2997 """Test the File() method"""
2999 def File(self, name):
3000 return 'File(%s)' % name
3002 env = self.TestEnvironment(FOO = 'foofile', BAR = 'barfile')
3006 assert f == 'File(f)', f
3008 f = env.File('$FOO')
3009 assert f == 'File(foofile)', f
3011 f = env.File('${BAR}_$BAR')
3012 assert f == 'File(barfile_barfile)', f
3014 f = env.File(['file1'])
3015 assert f == ['File(file1)'], f
3017 f = env.File(['file1', 'file2'])
3018 assert f == ['File(file1)', 'File(file2)'], f
3020 def test_FindFile(self):
3021 """Test the FindFile() method"""
3022 env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb')
3024 r = env.FindFile('foo', ['no_such_directory'])
3029 def test_Flatten(self):
3030 """Test the Flatten() method"""
3032 l = env.Flatten([1])
3034 l = env.Flatten([1, [2, [3, [4]]]])
3035 assert l == [1, 2, 3, 4], l
3037 def test_GetBuildPath(self):
3038 """Test the GetBuildPath() method."""
3039 env = self.TestEnvironment(MAGIC = 'xyzzy')
3041 p = env.GetBuildPath('foo')
3042 assert p == 'foo', p
3044 p = env.GetBuildPath('$MAGIC')
3045 assert p == 'xyzzy', p
3047 def test_Ignore(self):
3048 """Test the explicit Ignore method."""
3049 env = self.TestEnvironment(FOO='yyy', BAR='zzz')
3055 t = env.Ignore(target='targ.py', dependency='dep.py')[0]
3056 assert t.__class__.__name__ == 'Entry', t.__class__.__name__
3057 assert t.path == 'targ.py'
3058 assert len(t.ignore) == 1
3060 assert i.__class__.__name__ == 'Entry', i.__class__.__name__
3061 assert i.path == 'dep.py'
3063 t = env.Ignore(target='$FOO$BAR', dependency='$BAR$FOO')[0]
3064 assert t.__class__.__name__ == 'File', t.__class__.__name__
3065 assert t.path == 'yyyzzz'
3066 assert len(t.ignore) == 1
3068 assert i.__class__.__name__ == 'File', i.__class__.__name__
3069 assert i.path == 'zzzyyy'
3071 t = env.Ignore(target='dir1', dependency='dir2')[0]
3072 assert t.__class__.__name__ == 'Dir', t.__class__.__name__
3073 assert t.path == 'dir1'
3074 assert len(t.ignore) == 1
3076 assert i.__class__.__name__ == 'Dir', i.__class__.__name__
3077 assert i.path == 'dir2'
3079 def test_Literal(self):
3080 """Test the Literal() method"""
3081 env = self.TestEnvironment(FOO='fff', BAR='bbb')
3082 list = env.subst_list([env.Literal('$FOO'), '$BAR'])[0]
3083 assert list == ['$FOO', 'bbb'], list
3084 list = env.subst_list(['$FOO', env.Literal('$BAR')])[0]
3085 assert list == ['fff', '$BAR'], list
3087 def test_Local(self):
3088 """Test the Local() method."""
3089 env = self.TestEnvironment(FOO='lll')
3091 l = env.Local(env.fs.File('fff'))
3092 assert str(l[0]) == 'fff', l[0]
3094 l = env.Local('ggg', '$FOO')
3095 assert str(l[0]) == 'ggg', l[0]
3096 assert str(l[1]) == 'lll', l[1]
3098 def test_Precious(self):
3099 """Test the Precious() method"""
3100 env = self.TestEnvironment(FOO='ggg', BAR='hhh')
3103 t = env.Precious('p_a', 'p_${BAR}b', ['p_c', 'p_d'], 'p_$FOO')
3105 assert t[0].__class__.__name__ == 'Entry', t[0].__class__.__name__
3106 assert t[0].path == 'p_a'
3107 assert t[0].precious
3108 assert t[1].__class__.__name__ == 'Dir', t[1].__class__.__name__
3109 assert t[1].path == 'p_hhhb'
3110 assert t[1].precious
3111 assert t[2].__class__.__name__ == 'Entry', t[2].__class__.__name__
3112 assert t[2].path == 'p_c'
3113 assert t[2].precious
3114 assert t[3].__class__.__name__ == 'File', t[3].__class__.__name__
3115 assert t[3].path == 'p_d'
3116 assert t[3].precious
3117 assert t[4].__class__.__name__ == 'Entry', t[4].__class__.__name__
3118 assert t[4].path == 'p_ggg'
3119 assert t[4].precious
3121 def test_Repository(self):
3122 """Test the Repository() method."""
3126 def Repository(self, *dirs):
3127 self.list.extend(list(dirs))
3128 def Dir(self, name):
3130 env = self.TestEnvironment(FOO='rrr', BAR='sss')
3132 env.Repository('/tmp/foo')
3133 env.Repository('/tmp/$FOO', '/tmp/$BAR/foo')
3134 expect = ['/tmp/foo', '/tmp/rrr', '/tmp/sss/foo']
3135 assert env.fs.list == expect, env.fs.list
3137 def test_Scanner(self):
3138 """Test the Scanner() method"""
3139 def scan(node, env, target, arg):
3142 env = self.TestEnvironment(FOO = scan)
3144 s = env.Scanner('foo')
3145 assert s is not None, s
3147 s = env.Scanner(function = 'foo')
3148 assert s is not None, s
3151 s = env.Scanner('$FOO')
3152 assert s is not None, s
3154 s = env.Scanner(function = '$FOO')
3155 assert s is not None, s
3157 def test_SConsignFile(self):
3158 """Test the SConsignFile() method"""
3159 import SCons.SConsign
3162 SConstruct_dir = os.sep + 'dir'
3164 env = self.TestEnvironment(FOO = 'SConsign',
3165 BAR = os.path.join(os.sep, 'File'))
3167 env.Execute = lambda action: None
3172 def capture(name, dbm_module, fnames=fnames, dbms=dbms):
3174 dbms.append(dbm_module)
3176 save_SConsign_File = SCons.SConsign.File
3177 SCons.SConsign.File = capture
3179 env.SConsignFile('foo')
3180 assert fnames[-1] == os.path.join(os.sep, 'dir', 'foo'), fnames
3181 assert dbms[-1] is None, dbms
3183 env.SConsignFile('$FOO')
3184 assert fnames[-1] == os.path.join(os.sep, 'dir', 'SConsign'), fnames
3185 assert dbms[-1] is None, dbms
3187 env.SConsignFile('/$FOO')
3188 assert fnames[-1] == os.sep + 'SConsign', fnames
3189 assert dbms[-1] is None, dbms
3191 env.SConsignFile(os.sep + '$FOO')
3192 assert fnames[-1] == os.sep + 'SConsign', fnames
3193 assert dbms[-1] is None, dbms
3195 env.SConsignFile('$BAR', 'x')
3196 assert fnames[-1] == os.path.join(os.sep, 'File'), fnames
3197 assert dbms[-1] == 'x', dbms
3199 env.SConsignFile('__$BAR', 7)
3200 assert fnames[-1] == os.path.join(os.sep, 'dir', '__', 'File'), fnames
3201 assert dbms[-1] == 7, dbms
3204 assert fnames[-1] == os.path.join(os.sep, 'dir', '.sconsign'), fnames
3205 assert dbms[-1] is None, dbms
3207 env.SConsignFile(None)
3208 assert fnames[-1] is None, fnames
3209 assert dbms[-1] is None, dbms
3211 SCons.SConsign.File = save_SConsign_File
3213 def test_SideEffect(self):
3214 """Test the SideEffect() method"""
3215 env = self.TestEnvironment(LIB='lll', FOO='fff', BAR='bbb')
3216 env.File('mylll.pdb')
3217 env.Dir('mymmm.pdb')
3219 foo = env.Object('foo.obj', 'foo.cpp')[0]
3220 bar = env.Object('bar.obj', 'bar.cpp')[0]
3221 s = env.SideEffect('mylib.pdb', ['foo.obj', 'bar.obj'])[0]
3222 assert s.__class__.__name__ == 'Entry', s.__class__.__name__
3223 assert s.path == 'mylib.pdb'
3224 assert s.side_effect
3225 assert foo.side_effects == [s]
3226 assert bar.side_effects == [s]
3228 fff = env.Object('fff.obj', 'fff.cpp')[0]
3229 bbb = env.Object('bbb.obj', 'bbb.cpp')[0]
3230 s = env.SideEffect('my${LIB}.pdb', ['${FOO}.obj', '${BAR}.obj'])[0]
3231 assert s.__class__.__name__ == 'File', s.__class__.__name__
3232 assert s.path == 'mylll.pdb'
3233 assert s.side_effect
3234 assert fff.side_effects == [s], fff.side_effects
3235 assert bbb.side_effects == [s], bbb.side_effects
3237 ggg = env.Object('ggg.obj', 'ggg.cpp')[0]
3238 ccc = env.Object('ccc.obj', 'ccc.cpp')[0]
3239 s = env.SideEffect('mymmm.pdb', ['ggg.obj', 'ccc.obj'])[0]
3240 assert s.__class__.__name__ == 'Dir', s.__class__.__name__
3241 assert s.path == 'mymmm.pdb'
3242 assert s.side_effect
3243 assert ggg.side_effects == [s], ggg.side_effects
3244 assert ccc.side_effects == [s], ccc.side_effects
3246 def test_SourceCode(self):
3247 """Test the SourceCode() method."""
3248 env = self.TestEnvironment(FOO='mmm', BAR='nnn')
3249 e = env.SourceCode('foo', None)[0]
3250 assert e.path == 'foo'
3255 e = env.SourceCode(e, b)[0]
3256 assert e.path == 'foo'
3260 e = env.SourceCode('$BAR$FOO', None)[0]
3261 assert e.path == 'nnnmmm'
3265 def test_SourceSignatures(type):
3266 """Test the SourceSignatures() method"""
3269 env = type.TestEnvironment(M = 'MD5', T = 'timestamp')
3273 env.SourceSignatures('invalid_type')
3274 except SCons.Errors.UserError:
3276 assert exc_caught, "did not catch expected UserError"
3278 env.SourceSignatures('MD5')
3279 assert env.src_sig_type == 'MD5', env.src_sig_type
3281 env.SourceSignatures('$M')
3282 assert env.src_sig_type == 'MD5', env.src_sig_type
3284 env.SourceSignatures('timestamp')
3285 assert env.src_sig_type == 'timestamp', env.src_sig_type
3287 env.SourceSignatures('$T')
3288 assert env.src_sig_type == 'timestamp', env.src_sig_type
3292 save_md5 = SCons.Util.md5
3293 SCons.Util.md5 = None
3295 env.SourceSignatures('MD5')
3296 except SCons.Errors.UserError:
3299 self.fail('Did not catch expected UserError')
3301 SCons.Util.md5 = save_md5
3303 def test_Split(self):
3304 """Test the Split() method"""
3305 env = self.TestEnvironment(FOO='fff', BAR='bbb')
3306 s = env.Split("foo bar")
3307 assert s == ["foo", "bar"], s
3308 s = env.Split("$FOO bar")
3309 assert s == ["fff", "bar"], s
3310 s = env.Split(["foo", "bar"])
3311 assert s == ["foo", "bar"], s
3312 s = env.Split(["foo", "${BAR}-bbb"])
3313 assert s == ["foo", "bbb-bbb"], s
3314 s = env.Split("foo")
3315 assert s == ["foo"], s
3316 s = env.Split("$FOO$BAR")
3317 assert s == ["fffbbb"], s
3319 def test_TargetSignatures(type):
3320 """Test the TargetSignatures() method"""
3323 env = type.TestEnvironment(B = 'build', C = 'content')
3327 env.TargetSignatures('invalid_type')
3328 except SCons.Errors.UserError:
3330 assert exc_caught, "did not catch expected UserError"
3331 assert not hasattr(env, '_build_signature')
3333 env.TargetSignatures('build')
3334 assert env.tgt_sig_type == 'build', env.tgt_sig_type
3336 env.TargetSignatures('$B')
3337 assert env.tgt_sig_type == 'build', env.tgt_sig_type
3339 env.TargetSignatures('content')
3340 assert env.tgt_sig_type == 'content', env.tgt_sig_type
3342 env.TargetSignatures('$C')
3343 assert env.tgt_sig_type == 'content', env.tgt_sig_type
3345 env.TargetSignatures('MD5')
3346 assert env.tgt_sig_type == 'MD5', env.tgt_sig_type
3348 env.TargetSignatures('timestamp')
3349 assert env.tgt_sig_type == 'timestamp', env.tgt_sig_type
3353 save_md5 = SCons.Util.md5
3354 SCons.Util.md5 = None
3356 env.TargetSignatures('MD5')
3357 except SCons.Errors.UserError:
3360 self.fail('Did not catch expected UserError')
3362 env.TargetSignatures('content')
3363 except SCons.Errors.UserError:
3366 self.fail('Did not catch expected UserError')
3368 SCons.Util.md5 = save_md5
3370 def test_Value(self):
3371 """Test creating a Value() object
3375 assert v1.value == 'a', v1.value
3378 v2 = env.Value(value2)
3379 assert v2.value == value2, v2.value
3380 assert v2.value is value2, v2.value
3383 assert v1.value == v2.value
3385 v3 = env.Value('c', 'build-c')
3386 assert v3.value == 'c', v3.value
3390 def test_Environment_global_variable(type):
3391 """Test setting Environment variable to an Environment.Base subclass"""
3392 class MyEnv(SCons.Environment.Base):
3393 def xxx(self, string):
3394 return self.subst(string)
3396 SCons.Environment.Environment = MyEnv
3398 env = SCons.Environment.Environment(FOO = 'foo')
3400 f = env.subst('$FOO')
3401 assert f == 'foo', f
3404 assert f == 'foo', f
3406 def test_bad_keywords(self):
3407 """Test trying to use reserved keywords in an Environment"""
3410 env = self.TestEnvironment(TARGETS = 'targets',
3411 SOURCES = 'sources',
3414 CHANGED_SOURCES = 'changed_sources',
3415 CHANGED_TARGETS = 'changed_targets',
3416 UNCHANGED_SOURCES = 'unchanged_sources',
3417 UNCHANGED_TARGETS = 'unchanged_targets',
3419 bad_msg = '%s is not reserved, but got omitted; see Environment.construction_var_name_ok'
3420 added.append('INIT')
3421 for x in self.reserved_variables:
3422 assert x not in env, env[x]
3424 assert x in env, bad_msg % x
3426 env.Append(TARGETS = 'targets',
3427 SOURCES = 'sources',
3430 CHANGED_SOURCES = 'changed_sources',
3431 CHANGED_TARGETS = 'changed_targets',
3432 UNCHANGED_SOURCES = 'unchanged_sources',
3433 UNCHANGED_TARGETS = 'unchanged_targets',
3435 added.append('APPEND')
3436 for x in self.reserved_variables:
3437 assert x not in env, env[x]
3439 assert x in env, bad_msg % x
3441 env.AppendUnique(TARGETS = 'targets',
3442 SOURCES = 'sources',
3445 CHANGED_SOURCES = 'changed_sources',
3446 CHANGED_TARGETS = 'changed_targets',
3447 UNCHANGED_SOURCES = 'unchanged_sources',
3448 UNCHANGED_TARGETS = 'unchanged_targets',
3449 APPENDUNIQUE = 'appendunique')
3450 added.append('APPENDUNIQUE')
3451 for x in self.reserved_variables:
3452 assert x not in env, env[x]
3454 assert x in env, bad_msg % x
3456 env.Prepend(TARGETS = 'targets',
3457 SOURCES = 'sources',
3460 CHANGED_SOURCES = 'changed_sources',
3461 CHANGED_TARGETS = 'changed_targets',
3462 UNCHANGED_SOURCES = 'unchanged_sources',
3463 UNCHANGED_TARGETS = 'unchanged_targets',
3464 PREPEND = 'prepend')
3465 added.append('PREPEND')
3466 for x in self.reserved_variables:
3467 assert x not in env, env[x]
3469 assert x in env, bad_msg % x
3471 env.Prepend(TARGETS = 'targets',
3472 SOURCES = 'sources',
3475 CHANGED_SOURCES = 'changed_sources',
3476 CHANGED_TARGETS = 'changed_targets',
3477 UNCHANGED_SOURCES = 'unchanged_sources',
3478 UNCHANGED_TARGETS = 'unchanged_targets',
3479 PREPENDUNIQUE = 'prependunique')
3480 added.append('PREPENDUNIQUE')
3481 for x in self.reserved_variables:
3482 assert x not in env, env[x]
3484 assert x in env, bad_msg % x
3486 env.Replace(TARGETS = 'targets',
3487 SOURCES = 'sources',
3490 CHANGED_SOURCES = 'changed_sources',
3491 CHANGED_TARGETS = 'changed_targets',
3492 UNCHANGED_SOURCES = 'unchanged_sources',
3493 UNCHANGED_TARGETS = 'unchanged_targets',
3494 REPLACE = 'replace')
3495 added.append('REPLACE')
3496 for x in self.reserved_variables:
3497 assert x not in env, env[x]
3499 assert x in env, bad_msg % x
3501 copy = env.Clone(TARGETS = 'targets',
3502 SOURCES = 'sources',
3505 CHANGED_SOURCES = 'changed_sources',
3506 CHANGED_TARGETS = 'changed_targets',
3507 UNCHANGED_SOURCES = 'unchanged_sources',
3508 UNCHANGED_TARGETS = 'unchanged_targets',
3510 for x in self.reserved_variables:
3511 assert x not in copy, env[x]
3512 for x in added + ['COPY']:
3513 assert x in copy, bad_msg % x
3515 over = env.Override({'TARGETS' : 'targets',
3516 'SOURCES' : 'sources',
3517 'SOURCE' : 'source',
3518 'TARGET' : 'target',
3519 'CHANGED_SOURCES' : 'changed_sources',
3520 'CHANGED_TARGETS' : 'changed_targets',
3521 'UNCHANGED_SOURCES' : 'unchanged_sources',
3522 'UNCHANGED_TARGETS' : 'unchanged_targets',
3523 'OVERRIDE' : 'override'})
3524 for x in self.reserved_variables:
3525 assert x not in over, over[x]
3526 for x in added + ['OVERRIDE']:
3527 assert x in over, bad_msg % x
3529 def test_parse_flags(self):
3530 '''Test the Base class parse_flags argument'''
3531 # all we have to show is that it gets to MergeFlags internally
3532 env = Environment(tools=[], parse_flags = '-X')
3533 assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
3535 env = Environment(tools=[], CCFLAGS=None, parse_flags = '-Y')
3536 assert env['CCFLAGS'] == ['-Y'], env['CCFLAGS']
3538 env = Environment(tools=[], CPPDEFINES = 'FOO', parse_flags = '-std=c99 -X -DBAR')
3539 assert env['CFLAGS'] == ['-std=c99'], env['CFLAGS']
3540 assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
3541 assert env['CPPDEFINES'] == ['FOO', 'BAR'], env['CPPDEFINES']
3543 def test_clone_parse_flags(self):
3544 '''Test the env.Clone() parse_flags argument'''
3545 # all we have to show is that it gets to MergeFlags internally
3546 env = Environment(tools = [])
3547 env2 = env.Clone(parse_flags = '-X')
3548 assert 'CCFLAGS' not in env
3549 assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
3551 env = Environment(tools = [], CCFLAGS=None)
3552 env2 = env.Clone(parse_flags = '-Y')
3553 assert env['CCFLAGS'] is None, env['CCFLAGS']
3554 assert env2['CCFLAGS'] == ['-Y'], env2['CCFLAGS']
3556 env = Environment(tools = [], CPPDEFINES = 'FOO')
3557 env2 = env.Clone(parse_flags = '-std=c99 -X -DBAR')
3558 assert 'CFLAGS' not in env
3559 assert env2['CFLAGS'] == ['-std=c99'], env2['CFLAGS']
3560 assert 'CCFLAGS' not in env
3561 assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
3562 assert env['CPPDEFINES'] == 'FOO', env['CPPDEFINES']
3563 assert env2['CPPDEFINES'] == ['FOO','BAR'], env2['CPPDEFINES']
3567 class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture):
3571 env._dict = {'XXX' : 'x', 'YYY' : 'y'}
3572 env2 = OverrideEnvironment(env, {'XXX' : 'x2'})
3573 env3 = OverrideEnvironment(env2, {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'})
3574 self.envs = [ env, env2, env3 ]
3576 def checkpath(self, node, expect):
3577 return str(node) == os.path.normpath(expect)
3579 def test___init__(self):
3580 """Test OverrideEnvironment initialization"""
3581 env, env2, env3 = self.envs
3582 assert env['XXX'] == 'x', env['XXX']
3583 assert env2['XXX'] == 'x2', env2['XXX']
3584 assert env3['XXX'] == 'x3', env3['XXX']
3585 assert env['YYY'] == 'y', env['YYY']
3586 assert env2['YYY'] == 'y', env2['YYY']
3587 assert env3['YYY'] == 'y3', env3['YYY']
3589 def test___delitem__(self):
3590 """Test deleting variables from an OverrideEnvironment"""
3591 env, env2, env3 = self.envs
3594 assert 'XXX' not in env, "env has XXX?"
3595 assert 'XXX' not in env2, "env2 has XXX?"
3596 assert 'XXX' not in env3, "env3 has XXX?"
3599 assert 'YYY' not in env, "env has YYY?"
3600 assert 'YYY' not in env2, "env2 has YYY?"
3601 assert 'YYY' not in env3, "env3 has YYY?"
3604 assert 'ZZZ' not in env, "env has ZZZ?"
3605 assert 'ZZZ' not in env2, "env2 has ZZZ?"
3606 assert 'ZZZ' not in env3, "env3 has ZZZ?"
3609 """Test the OverrideEnvironment get() method"""
3610 env, env2, env3 = self.envs
3611 assert env.get('XXX') == 'x', env.get('XXX')
3612 assert env2.get('XXX') == 'x2', env2.get('XXX')
3613 assert env3.get('XXX') == 'x3', env3.get('XXX')
3614 assert env.get('YYY') == 'y', env.get('YYY')
3615 assert env2.get('YYY') == 'y', env2.get('YYY')
3616 assert env3.get('YYY') == 'y3', env3.get('YYY')
3617 assert env.get('ZZZ') is None, env.get('ZZZ')
3618 assert env2.get('ZZZ') is None, env2.get('ZZZ')
3619 assert env3.get('ZZZ') == 'z3', env3.get('ZZZ')
3621 def test_has_key(self):
3622 """Test the OverrideEnvironment has_key() method"""
3623 env, env2, env3 = self.envs
3624 assert 'XXX' in env, 'XXX' in env
3625 assert 'XXX' in env2, 'XXX' in env2
3626 assert 'XXX' in env3, 'XXX' in env3
3627 assert 'YYY' in env, 'YYY' in env
3628 assert 'YYY' in env2, 'YYY' in env2
3629 assert 'YYY' in env3, 'YYY' in env3
3630 assert 'ZZZ' not in env, 'ZZZ' in env
3631 assert 'ZZZ' not in env2, 'ZZZ' in env2
3632 assert 'ZZZ' in env3, 'ZZZ' in env3
3634 def test_contains(self):
3635 """Test the OverrideEnvironment __contains__() method"""
3640 # An early version of Python that doesn't support "in"
3641 # on dictionaries. Just pass the test.
3644 env, env2, env3 = self.envs
3646 assert 'XXX' in env2
3647 assert 'XXX' in env3
3649 assert 'YYY' in env2
3650 assert 'YYY' in env3
3651 assert not 'ZZZ' in env
3652 assert not 'ZZZ' in env2
3653 assert 'ZZZ' in env3
3655 def test_items(self):
3656 """Test the OverrideEnvironment Dictionary() method"""
3657 env, env2, env3 = self.envs
3658 items = env.Dictionary()
3659 assert items == {'XXX' : 'x', 'YYY' : 'y'}, items
3660 items = env2.Dictionary()
3661 assert items == {'XXX' : 'x2', 'YYY' : 'y'}, items
3662 items = env3.Dictionary()
3663 assert items == {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}, items
3665 def test_items(self):
3666 """Test the OverrideEnvironment items() method"""
3667 env, env2, env3 = self.envs
3668 items = sorted(env.items())
3669 assert items == [('XXX', 'x'), ('YYY', 'y')], items
3670 items = sorted(env2.items())
3671 assert items == [('XXX', 'x2'), ('YYY', 'y')], items
3672 items = sorted(env3.items())
3673 assert items == [('XXX', 'x3'), ('YYY', 'y3'), ('ZZZ', 'z3')], items
3675 def test_gvars(self):
3676 """Test the OverrideEnvironment gvars() method"""
3677 env, env2, env3 = self.envs
3679 assert gvars == {'XXX' : 'x', 'YYY' : 'y'}, gvars
3680 gvars = env2.gvars()
3681 assert gvars == {'XXX' : 'x', 'YYY' : 'y'}, gvars
3682 gvars = env3.gvars()
3683 assert gvars == {'XXX' : 'x', 'YYY' : 'y'}, gvars
3685 def test_lvars(self):
3686 """Test the OverrideEnvironment lvars() method"""
3687 env, env2, env3 = self.envs
3689 assert lvars == {}, lvars
3690 lvars = env2.lvars()
3691 assert lvars == {'XXX' : 'x2'}, lvars
3692 lvars = env3.lvars()
3693 assert lvars == {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}, lvars
3695 def test_Replace(self):
3696 """Test the OverrideEnvironment Replace() method"""
3697 env, env2, env3 = self.envs
3698 assert env['XXX'] == 'x', env['XXX']
3699 assert env2['XXX'] == 'x2', env2['XXX']
3700 assert env3['XXX'] == 'x3', env3['XXX']
3701 assert env['YYY'] == 'y', env['YYY']
3702 assert env2['YYY'] == 'y', env2['YYY']
3703 assert env3['YYY'] == 'y3', env3['YYY']
3705 env.Replace(YYY = 'y4')
3707 assert env['XXX'] == 'x', env['XXX']
3708 assert env2['XXX'] == 'x2', env2['XXX']
3709 assert env3['XXX'] == 'x3', env3['XXX']
3710 assert env['YYY'] == 'y4', env['YYY']
3711 assert env2['YYY'] == 'y4', env2['YYY']
3712 assert env3['YYY'] == 'y3', env3['YYY']
3714 # Tests a number of Base methods through an OverrideEnvironment to
3715 # make sure they handle overridden constructionv variables properly.
3717 # The following Base methods also call self.subst(), and so could
3718 # theoretically be subject to problems with evaluating overridden
3719 # variables, but they're never really called that way in the rest
3720 # of our code, so we won't worry about them (at least for now):
3735 # SourceSignatures()
3736 # TargetSignatures()
3738 # It's unlikely Clone() will ever be called this way, so let the
3739 # other methods test that handling overridden values works.
3740 #def test_Clone(self):
3741 # """Test the OverrideEnvironment Clone() method"""
3744 def test_FindIxes(self):
3745 """Test the OverrideEnvironment FindIxes() method"""
3746 env, env2, env3 = self.envs
3747 x = env.FindIxes(['xaaay'], 'XXX', 'YYY')
3748 assert x == 'xaaay', x
3749 x = env2.FindIxes(['x2aaay'], 'XXX', 'YYY')
3750 assert x == 'x2aaay', x
3751 x = env3.FindIxes(['x3aaay3'], 'XXX', 'YYY')
3752 assert x == 'x3aaay3', x
3754 def test_ReplaceIxes(self):
3755 """Test the OverrideEnvironment ReplaceIxes() method"""
3756 env, env2, env3 = self.envs
3757 x = env.ReplaceIxes('xaaay', 'XXX', 'YYY', 'YYY', 'XXX')
3758 assert x == 'yaaax', x
3759 x = env2.ReplaceIxes('x2aaay', 'XXX', 'YYY', 'YYY', 'XXX')
3760 assert x == 'yaaax2', x
3761 x = env3.ReplaceIxes('x3aaay3', 'XXX', 'YYY', 'YYY', 'XXX')
3762 assert x == 'y3aaax3', x
3764 # It's unlikely WhereIs() will ever be called this way, so let the
3765 # other methods test that handling overridden values works.
3766 #def test_WhereIs(self):
3767 # """Test the OverrideEnvironment WhereIs() method"""
3771 """Test the OverrideEnvironment Dir() method"""
3772 env, env2, env3 = self.envs
3773 x = env.Dir('ddir/$XXX')
3774 assert self.checkpath(x, 'ddir/x'), str(x)
3775 x = env2.Dir('ddir/$XXX')
3776 assert self.checkpath(x, 'ddir/x2'), str(x)
3777 x = env3.Dir('ddir/$XXX')
3778 assert self.checkpath(x, 'ddir/x3'), str(x)
3780 def test_Entry(self):
3781 """Test the OverrideEnvironment Entry() method"""
3782 env, env2, env3 = self.envs
3783 x = env.Entry('edir/$XXX')
3784 assert self.checkpath(x, 'edir/x'), str(x)
3785 x = env2.Entry('edir/$XXX')
3786 assert self.checkpath(x, 'edir/x2'), str(x)
3787 x = env3.Entry('edir/$XXX')
3788 assert self.checkpath(x, 'edir/x3'), str(x)
3790 def test_File(self):
3791 """Test the OverrideEnvironment File() method"""
3792 env, env2, env3 = self.envs
3793 x = env.File('fdir/$XXX')
3794 assert self.checkpath(x, 'fdir/x'), str(x)
3795 x = env2.File('fdir/$XXX')
3796 assert self.checkpath(x, 'fdir/x2'), str(x)
3797 x = env3.File('fdir/$XXX')
3798 assert self.checkpath(x, 'fdir/x3'), str(x)
3800 def test_Split(self):
3801 """Test the OverrideEnvironment Split() method"""
3802 env, env2, env3 = self.envs
3803 env['AAA'] = '$XXX $YYY $ZZZ'
3804 x = env.Split('$AAA')
3805 assert x == ['x', 'y'], x
3806 x = env2.Split('$AAA')
3807 assert x == ['x2', 'y'], x
3808 x = env3.Split('$AAA')
3809 assert x == ['x3', 'y3', 'z3'], x
3811 def test_parse_flags(self):
3812 '''Test the OverrideEnvironment parse_flags argument'''
3813 # all we have to show is that it gets to MergeFlags internally
3814 env = SubstitutionEnvironment()
3815 env2 = env.Override({'parse_flags' : '-X'})
3816 assert 'CCFLAGS' not in env
3817 assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
3819 env = SubstitutionEnvironment(CCFLAGS=None)
3820 env2 = env.Override({'parse_flags' : '-Y'})
3821 assert env['CCFLAGS'] is None, env['CCFLAGS']
3822 assert env2['CCFLAGS'] == ['-Y'], env2['CCFLAGS']
3824 env = SubstitutionEnvironment(CPPDEFINES = 'FOO')
3825 env2 = env.Override({'parse_flags' : '-std=c99 -X -DBAR'})
3826 assert 'CFLAGS' not in env
3827 assert env2['CFLAGS'] == ['-std=c99'], env2['CFLAGS']
3828 assert 'CCFLAGS' not in env
3829 assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
3830 assert env['CPPDEFINES'] == 'FOO', env['CPPDEFINES']
3831 assert env2['CPPDEFINES'] == ['FOO','BAR'], env2['CPPDEFINES']
3835 class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture):
3837 def test___init__(self):
3838 """Test NoSubstitutionProxy initialization"""
3839 env = self.TestEnvironment(XXX = 'x', YYY = 'y')
3840 assert env['XXX'] == 'x', env['XXX']
3841 assert env['YYY'] == 'y', env['YYY']
3843 proxy = NoSubstitutionProxy(env)
3844 assert proxy['XXX'] == 'x', proxy['XXX']
3845 assert proxy['YYY'] == 'y', proxy['YYY']
3847 def test_attributes(self):
3848 """Test getting and setting NoSubstitutionProxy attributes"""
3850 setattr(env, 'env_attr', 'value1')
3852 proxy = NoSubstitutionProxy(env)
3853 setattr(proxy, 'proxy_attr', 'value2')
3855 x = getattr(env, 'env_attr')
3856 assert x == 'value1', x
3857 x = getattr(proxy, 'env_attr')
3858 assert x == 'value1', x
3860 x = getattr(env, 'proxy_attr')
3861 assert x == 'value2', x
3862 x = getattr(proxy, 'proxy_attr')
3863 assert x == 'value2', x
3865 def test_subst(self):
3866 """Test the NoSubstitutionProxy.subst() method"""
3867 env = self.TestEnvironment(XXX = 'x', YYY = 'y')
3868 assert env['XXX'] == 'x', env['XXX']
3869 assert env['YYY'] == 'y', env['YYY']
3871 proxy = NoSubstitutionProxy(env)
3872 assert proxy['XXX'] == 'x', proxy['XXX']
3873 assert proxy['YYY'] == 'y', proxy['YYY']
3875 x = env.subst('$XXX')
3877 x = proxy.subst('$XXX')
3878 assert x == '$XXX', x
3880 x = proxy.subst('$YYY', raw=7, target=None, source=None,
3882 extra_meaningless_keyword_argument=None)
3883 assert x == '$YYY', x
3885 def test_subst_kw(self):
3886 """Test the NoSubstitutionProxy.subst_kw() method"""
3887 env = self.TestEnvironment(XXX = 'x', YYY = 'y')
3888 assert env['XXX'] == 'x', env['XXX']
3889 assert env['YYY'] == 'y', env['YYY']
3891 proxy = NoSubstitutionProxy(env)
3892 assert proxy['XXX'] == 'x', proxy['XXX']
3893 assert proxy['YYY'] == 'y', proxy['YYY']
3895 x = env.subst_kw({'$XXX':'$YYY'})
3896 assert x == {'x':'y'}, x
3897 x = proxy.subst_kw({'$XXX':'$YYY'})
3898 assert x == {'$XXX':'$YYY'}, x
3900 def test_subst_list(self):
3901 """Test the NoSubstitutionProxy.subst_list() method"""
3902 env = self.TestEnvironment(XXX = 'x', YYY = 'y')
3903 assert env['XXX'] == 'x', env['XXX']
3904 assert env['YYY'] == 'y', env['YYY']
3906 proxy = NoSubstitutionProxy(env)
3907 assert proxy['XXX'] == 'x', proxy['XXX']
3908 assert proxy['YYY'] == 'y', proxy['YYY']
3910 x = env.subst_list('$XXX')
3911 assert x == [['x']], x
3912 x = proxy.subst_list('$XXX')
3915 x = proxy.subst_list('$YYY', raw=0, target=None, source=None, conv=None)
3918 def test_subst_target_source(self):
3919 """Test the NoSubstitutionProxy.subst_target_source() method"""
3920 env = self.TestEnvironment(XXX = 'x', YYY = 'y')
3921 assert env['XXX'] == 'x', env['XXX']
3922 assert env['YYY'] == 'y', env['YYY']
3924 proxy = NoSubstitutionProxy(env)
3925 assert proxy['XXX'] == 'x', proxy['XXX']
3926 assert proxy['YYY'] == 'y', proxy['YYY']
3928 args = ('$XXX $TARGET $SOURCE $YYY',)
3929 kw = {'target' : DummyNode('ttt'), 'source' : DummyNode('sss')}
3930 x = env.subst_target_source(*args, **kw)
3931 assert x == 'x ttt sss y', x
3932 x = proxy.subst_target_source(*args, **kw)
3933 assert x == ' ttt sss ', x
3935 class EnvironmentVariableTestCase(unittest.TestCase):
3937 def test_is_valid_construction_var(self):
3938 """Testing is_valid_construction_var()"""
3939 r = is_valid_construction_var("_a")
3940 assert r is not None, r
3941 r = is_valid_construction_var("z_")
3942 assert r is not None, r
3943 r = is_valid_construction_var("X_")
3944 assert r is not None, r
3945 r = is_valid_construction_var("2a")
3947 r = is_valid_construction_var("a2_")
3948 assert r is not None, r
3949 r = is_valid_construction_var("/")
3951 r = is_valid_construction_var("_/")
3953 r = is_valid_construction_var("a/")
3955 r = is_valid_construction_var(".b")
3957 r = is_valid_construction_var("_.b")
3959 r = is_valid_construction_var("b1._")
3961 r = is_valid_construction_var("-b")
3963 r = is_valid_construction_var("_-b")
3965 r = is_valid_construction_var("b1-_")
3970 if __name__ == "__main__":
3971 suite = unittest.TestSuite()
3972 tclasses = [ SubstitutionTestCase,
3974 OverrideEnvironmentTestCase,
3975 NoSubstitutionProxyTestCase,
3976 EnvironmentVariableTestCase ]
3977 for tclass in tclasses:
3978 names = unittest.getTestCaseNames(tclass, 'test_')
3979 suite.addTests(list(map(tclass, names)))
3980 if not unittest.TextTestRunner().run(suite).wasSuccessful():
3985 # indent-tabs-mode:nil
3987 # vim: set expandtab tabstop=4 shiftwidth=4: