4 # Permission is hereby granted, free of charge, to any person obtaining
5 # a copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including
7 # without limitation the rights to use, copy, modify, merge, publish,
8 # distribute, sublicense, and/or sell copies of the Software, and to
9 # permit persons to whom the Software is furnished to do so, subject to
10 # the following conditions:
12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
16 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
17 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
35 from SCons.Environment import *
38 def diff_env(env1, env2):
42 for k in env1._dict.keys() + env2._dict.keys():
49 if env1[k] != env2[k]:
50 s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n"
51 s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n"
53 s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n"
55 s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n"
60 def diff_dict(d1, d2):
64 for k in d1.keys() + d2.keys():
72 s1 = s1 + " " + repr(k) + " : " + repr(d1[k]) + "\n"
73 s2 = s2 + " " + repr(k) + " : " + repr(d2[k]) + "\n"
75 s1 = s1 + " " + repr(k) + " : " + repr(d1[k]) + "\n"
77 s2 = s2 + " " + repr(k) + " : " + repr(d2[k]) + "\n"
86 """A dummy Builder class for testing purposes. "Building"
87 a target is simply setting a value in the dictionary.
89 def __init__(self, name = None):
92 def __call__(self, env, target=None, source=None, **kw):
94 called_it['target'] = target
95 called_it['source'] = source
98 def execute(self, target = None, **kw):
107 """A dummy Scanner class for testing purposes. "Scanning"
108 a target is simply setting a value in the dictionary.
110 def __init__(self, name, skeys=[]):
114 def __call__(self, filename):
116 scanned_it[filename] = 1
118 def __cmp__(self, other):
120 return cmp(self.__dict__, other.__dict__)
121 except AttributeError:
124 def get_skeys(self, env):
132 class CLVar(UserList.UserList):
133 def __init__(self, seq):
134 if type(seq) == type(''):
135 seq = string.split(seq)
136 UserList.UserList.__init__(self, seq)
137 def __add__(self, other):
138 return UserList.UserList.__add__(self, CLVar(other))
139 def __radd__(self, other):
140 return UserList.UserList.__radd__(self, CLVar(other))
141 def __coerce__(self, other):
142 return (self, CLVar(other))
147 def __init__(self, name):
153 def get_subst_proxy(self):
156 def test_tool( env ):
157 env['_F77INCFLAGS'] = '$( ${_concat(INCPREFIX, F77PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
159 class TestEnvironmentFixture:
160 def TestEnvironment(self, *args, **kw):
161 if not kw or not kw.has_key('tools'):
162 kw['tools'] = [test_tool]
163 default_keys = { 'CC' : 'cc',
164 'CCFLAGS' : '-DNDEBUG',
165 'ENV' : { 'TMP' : '/tmp' } }
166 for key, value in default_keys.items():
167 if not kw.has_key(key):
169 if not kw.has_key('BUILDERS'):
170 static_obj = SCons.Builder.Builder(action = {},
174 kw['BUILDERS'] = {'Object' : static_obj}
175 static_obj.add_action('.cpp', 'fake action')
177 env = apply(Environment, args, kw)
180 class SubstitutionTestCase(unittest.TestCase):
182 def test___init__(self):
183 """Test initializing a SubstitutionEnvironment
185 env = SubstitutionEnvironment()
186 assert not env.has_key('__env__')
188 def test___cmp__(self):
189 """Test comparing SubstitutionEnvironments
192 env1 = SubstitutionEnvironment(XXX = 'x')
193 env2 = SubstitutionEnvironment(XXX = 'x')
194 env3 = SubstitutionEnvironment(XXX = 'xxx')
195 env4 = SubstitutionEnvironment(XXX = 'x', YYY = 'x')
201 def test___delitem__(self):
202 """Test deleting a variable from a SubstitutionEnvironment
204 env1 = SubstitutionEnvironment(XXX = 'x', YYY = 'y')
205 env2 = SubstitutionEnvironment(XXX = 'x')
209 def test___getitem__(self):
210 """Test fetching a variable from a SubstitutionEnvironment
212 env = SubstitutionEnvironment(XXX = 'x')
213 assert env['XXX'] == 'x', env['XXX']
215 def test___setitem__(self):
216 """Test setting a variable in a SubstitutionEnvironment
218 env1 = SubstitutionEnvironment(XXX = 'x')
219 env2 = SubstitutionEnvironment(XXX = 'x', YYY = 'y')
224 """Test the SubstitutionEnvironment get() method
226 env = SubstitutionEnvironment(XXX = 'x')
227 assert env.get('XXX') == 'x', env.get('XXX')
228 assert env.get('YYY') is None, env.get('YYY')
230 def test_has_key(self):
231 """Test the SubstitutionEnvironment has_key() method
233 env = SubstitutionEnvironment(XXX = 'x')
234 assert env.has_key('XXX')
235 assert not env.has_key('YYY')
237 def test_contains(self):
238 """Test the SubstitutionEnvironment __contains__() method
244 # An early version of Python that doesn't support "in"
245 # on dictionaries. Just pass the test.
248 env = SubstitutionEnvironment(XXX = 'x')
250 assert not 'YYY' in env
252 def test_items(self):
253 """Test the SubstitutionEnvironment items() method
255 env = SubstitutionEnvironment(XXX = 'x', YYY = 'y')
257 assert items == [('XXX','x'), ('YYY','y')], items
259 def test_arg2nodes(self):
260 """Test the arg2nodes method
262 env = SubstitutionEnvironment()
264 class X(SCons.Node.Node):
266 def Factory(name, directory = None, create = 1, dict=dict, X=X):
267 if not dict.has_key(name):
269 dict[name].name = name
272 nodes = env.arg2nodes("Util.py UtilTests.py", Factory)
273 assert len(nodes) == 1, nodes
274 assert isinstance(nodes[0], X)
275 assert nodes[0].name == "Util.py UtilTests.py"
278 if hasattr(types, 'UnicodeType'):
280 nodes = env.arg2nodes(u"Util.py UtilTests.py", Factory)
281 assert len(nodes) == 1, nodes
282 assert isinstance(nodes[0], X)
283 assert nodes[0].name == u"Util.py UtilTests.py"
285 exec code in globals(), locals()
287 nodes = env.arg2nodes(["Util.py", "UtilTests.py"], Factory)
288 assert len(nodes) == 2, nodes
289 assert isinstance(nodes[0], X)
290 assert isinstance(nodes[1], X)
291 assert nodes[0].name == "Util.py"
292 assert nodes[1].name == "UtilTests.py"
294 n1 = Factory("Util.py")
295 nodes = env.arg2nodes([n1, "UtilTests.py"], Factory)
296 assert len(nodes) == 2, nodes
297 assert isinstance(nodes[0], X)
298 assert isinstance(nodes[1], X)
299 assert nodes[0].name == "Util.py"
300 assert nodes[1].name == "UtilTests.py"
302 class SConsNode(SCons.Node.Node):
304 nodes = env.arg2nodes(SConsNode())
305 assert len(nodes) == 1, nodes
306 assert isinstance(nodes[0], SConsNode), node
310 nodes = env.arg2nodes(OtherNode())
311 assert len(nodes) == 1, nodes
312 assert isinstance(nodes[0], OtherNode), node
314 def lookup_a(str, F=Factory):
322 def lookup_b(str, F=Factory):
330 env_ll = SubstitutionEnvironment()
331 env_ll.lookup_list = [lookup_a, lookup_b]
333 nodes = env_ll.arg2nodes(['aaa', 'bbb', 'ccc'], Factory)
334 assert len(nodes) == 3, nodes
336 assert nodes[0].name == 'aaa', nodes[0]
337 assert nodes[0].a == 1, nodes[0]
338 assert not hasattr(nodes[0], 'b'), nodes[0]
340 assert nodes[1].name == 'bbb'
341 assert not hasattr(nodes[1], 'a'), nodes[1]
342 assert nodes[1].b == 1, nodes[1]
344 assert nodes[2].name == 'ccc'
345 assert not hasattr(nodes[2], 'a'), nodes[1]
346 assert not hasattr(nodes[2], 'b'), nodes[1]
348 def lookup_bbbb(str, F=Factory):
356 def lookup_c(str, F=Factory):
364 nodes = env.arg2nodes(['bbbb', 'ccc'], Factory,
365 [lookup_c, lookup_bbbb, lookup_b])
366 assert len(nodes) == 2, nodes
368 assert nodes[0].name == 'bbbb'
369 assert not hasattr(nodes[0], 'a'), nodes[1]
370 assert not hasattr(nodes[0], 'b'), nodes[1]
371 assert nodes[0].bbbb == 1, nodes[1]
372 assert not hasattr(nodes[0], 'c'), nodes[0]
374 assert nodes[1].name == 'ccc'
375 assert not hasattr(nodes[1], 'a'), nodes[1]
376 assert not hasattr(nodes[1], 'b'), nodes[1]
377 assert not hasattr(nodes[1], 'bbbb'), nodes[0]
378 assert nodes[1].c == 1, nodes[1]
380 def test_arg2nodes_target_source(self):
381 """Test the arg2nodes method with target= and source= keywords
383 targets = [DummyNode('t1'), DummyNode('t2')]
384 sources = [DummyNode('s1'), DummyNode('s2')]
385 env = SubstitutionEnvironment()
386 nodes = env.arg2nodes(['${TARGET}-a',
393 names = map(lambda n: n.name, nodes)
394 assert names == ['t1-a', 's1-b', 't2-c', 's2-d'], names
396 def test_gvars(self):
397 """Test the base class gvars() method"""
398 env = SubstitutionEnvironment()
400 assert gvars == {}, gvars
402 def test_lvars(self):
403 """Test the base class lvars() method"""
404 env = SubstitutionEnvironment()
406 assert lvars == {}, lvars
408 def test_subst(self):
409 """Test substituting construction variables within strings
411 Check various combinations, including recursive expansion
412 of variables into other variables.
414 env = SubstitutionEnvironment(AAA = 'a', BBB = 'b')
415 mystr = env.subst("$AAA ${AAA}A $BBBB $BBB")
416 assert mystr == "a aA b", mystr
418 # Changed the tests below to reflect a bug fix in
420 env = SubstitutionEnvironment(AAA = '$BBB', BBB = 'b', BBBA = 'foo')
421 mystr = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
422 assert mystr == "b bA bB b", mystr
424 env = SubstitutionEnvironment(AAA = '$BBB', BBB = '$CCC', CCC = 'c')
425 mystr = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
426 assert mystr == "c cA cB c", mystr
429 env = SubstitutionEnvironment(AAA = ['a', 'aa', 'aaa'])
430 mystr = env.subst("$AAA")
431 assert mystr == "a aa aaa", mystr
434 env = SubstitutionEnvironment(AAA = ('a', 'aa', 'aaa'))
435 mystr = env.subst("$AAA")
436 assert mystr == "a aa aaa", mystr
443 env = SubstitutionEnvironment(AAA = 'aaa')
444 s = env.subst('$AAA $TARGET $SOURCES', target=[t1, t2], source=[s1, s2])
445 assert s == "aaa t1 s1 s2", s
446 s = env.subst('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2])
447 assert s == "aaa t1 t2 s1", s
449 # Test callables in the SubstitutionEnvironment
450 def foo(target, source, env, for_signature):
451 assert str(target) == 't', target
452 assert str(source) == 's', source
455 env = SubstitutionEnvironment(BAR=foo, FOO='baz')
459 subst = env.subst('test $BAR', target=t, source=s)
460 assert subst == 'test baz', subst
462 # Test not calling callables in the SubstitutionEnvironment
464 # This will take some serious surgery to subst() and
465 # subst_list(), so just leave these tests out until we can
470 env = SubstitutionEnvironment(BAR=bar, FOO='$BAR')
472 subst = env.subst('$BAR', call=None)
473 assert subst is bar, subst
475 subst = env.subst('$FOO', call=None)
476 assert subst is bar, subst
478 def test_subst_kw(self):
479 """Test substituting construction variables within dictionaries"""
480 env = SubstitutionEnvironment(AAA = 'a', BBB = 'b')
481 kw = env.subst_kw({'$AAA' : 'aaa', 'bbb' : '$BBB'})
482 assert len(kw) == 2, kw
483 assert kw['a'] == 'aaa', kw['a']
484 assert kw['bbb'] == 'b', kw['bbb']
486 def test_subst_list(self):
487 """Test substituting construction variables in command lists
489 env = SubstitutionEnvironment(AAA = 'a', BBB = 'b')
490 l = env.subst_list("$AAA ${AAA}A $BBBB $BBB")
491 assert l == [["a", "aA", "b"]], l
493 # Changed the tests below to reflect a bug fix in
495 env = SubstitutionEnvironment(AAA = '$BBB', BBB = 'b', BBBA = 'foo')
496 l = env.subst_list("$AAA ${AAA}A ${AAA}B $BBB")
497 assert l == [["b", "bA", "bB", "b"]], l
499 env = SubstitutionEnvironment(AAA = '$BBB', BBB = '$CCC', CCC = 'c')
500 l = env.subst_list("$AAA ${AAA}A ${AAA}B $BBB")
501 assert l == [["c", "cA", "cB", "c"]], mystr
503 env = SubstitutionEnvironment(AAA = '$BBB', BBB = '$CCC', CCC = [ 'a', 'b\nc' ])
504 lst = env.subst_list([ "$AAA", "B $CCC" ])
505 assert lst == [[ "a", "b"], ["c", "B a", "b"], ["c"]], lst
512 env = SubstitutionEnvironment(AAA = 'aaa')
513 s = env.subst_list('$AAA $TARGET $SOURCES', target=[t1, t2], source=[s1, s2])
514 assert s == [["aaa", "t1", "s1", "s2"]], s
515 s = env.subst_list('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2])
516 assert s == [["aaa", "t1", "t2", "s1"]], s
518 # Test callables in the SubstitutionEnvironment
519 def foo(target, source, env, for_signature):
520 assert str(target) == 't', target
521 assert str(source) == 's', source
524 env = SubstitutionEnvironment(BAR=foo, FOO='baz')
528 lst = env.subst_list('test $BAR', target=t, source=s)
529 assert lst == [['test', 'baz']], lst
531 # Test not calling callables in the SubstitutionEnvironment
533 # This will take some serious surgery to subst() and
534 # subst_list(), so just leave these tests out until we can
539 env = SubstitutionEnvironment(BAR=bar, FOO='$BAR')
541 subst = env.subst_list('$BAR', call=None)
542 assert subst is bar, subst
544 subst = env.subst_list('$FOO', call=None)
545 assert subst is bar, subst
547 def test_subst_path(self):
548 """Test substituting a path list
551 def __init__(self, val):
554 return self.val + '-proxy'
557 def __init__(self, val):
559 def get_subst_proxy(self):
568 env = SubstitutionEnvironment(FOO='foo',
571 PROXY=MyProxy('my1'))
573 r = env.subst_path('$FOO')
574 assert r == ['foo'], r
576 r = env.subst_path(['$FOO', 'xxx', '$BAR'])
577 assert r == ['foo', 'xxx', 'bar'], r
579 r = env.subst_path(['$FOO', '$LIST', '$BAR'])
580 assert map(str, r) == ['foo', 'one two', 'bar'], r
582 r = env.subst_path(['$FOO', '$TARGET', '$SOURCE', '$BAR'])
583 assert r == ['foo', '', '', 'bar'], r
585 r = env.subst_path(['$FOO', '$TARGET', '$BAR'], target=MyNode('ttt'))
586 assert map(str, r) == ['foo', 'ttt', 'bar'], r
588 r = env.subst_path(['$FOO', '$SOURCE', '$BAR'], source=MyNode('sss'))
589 assert map(str, r) == ['foo', 'sss', 'bar'], r
593 r = env.subst_path(['$PROXY', MyProxy('my2'), n])
594 assert r == ['my1-proxy', 'my2-proxy', n], r
597 def __init__(self, s):
602 env = SubstitutionEnvironment(FOO=StringableObj("foo"),
603 BAR=StringableObj("bar"))
605 r = env.subst_path([ "${FOO}/bar", "${BAR}/baz" ])
606 assert r == [ "foo/bar", "bar/baz" ], r
608 r = env.subst_path([ "bar/${FOO}", "baz/${BAR}" ])
609 assert r == [ "bar/foo", "baz/bar" ], r
611 r = env.subst_path([ "bar/${FOO}/bar", "baz/${BAR}/baz" ])
612 assert r == [ "bar/foo/bar", "baz/bar/baz" ], r
614 def test_subst_target_source(self):
615 """Test the base environment subst_target_source() method"""
616 env = SubstitutionEnvironment(AAA = 'a', BBB = 'b')
617 mystr = env.subst_target_source("$AAA ${AAA}A $BBBB $BBB")
618 assert mystr == "a aA b", mystr
620 def test_backtick(self):
621 """Test the backtick() method for capturing command output"""
622 env = SubstitutionEnvironment()
624 test = TestCmd.TestCmd(workdir = '')
625 test.write('stdout.py', """\
627 sys.stdout.write('this came from stdout.py\\n')
630 test.write('stderr.py', """\
632 sys.stderr.write('this came from stderr.py\\n')
635 test.write('fail.py', """\
639 test.write('echo.py', """\
641 sys.stdout.write(os.environ['ECHO'] + '\\n')
645 save_stderr = sys.stderr
647 python = '"' + sys.executable + '"'
650 sys.stderr = StringIO.StringIO()
651 cmd = '%s %s' % (python, test.workpath('stdout.py'))
652 output = env.backtick(cmd)
653 errout = sys.stderr.getvalue()
654 assert output == 'this came from stdout.py\n', output
655 assert errout == '', errout
657 sys.stderr = StringIO.StringIO()
658 cmd = '%s %s' % (python, test.workpath('stderr.py'))
659 output = env.backtick(cmd)
660 errout = sys.stderr.getvalue()
661 assert output == '', output
662 assert errout == 'this came from stderr.py\n', errout
664 sys.stderr = StringIO.StringIO()
665 cmd = '%s %s' % (python, test.workpath('fail.py'))
669 assert str(e) == "'%s' exited 1" % cmd, str(e)
671 self.fail("did not catch expected OSError")
673 sys.stderr = StringIO.StringIO()
674 cmd = '%s %s' % (python, test.workpath('echo.py'))
675 env['ENV'] = os.environ.copy()
676 env['ENV']['ECHO'] = 'this came from ECHO'
677 output = env.backtick(cmd)
678 errout = sys.stderr.getvalue()
679 assert output == 'this came from ECHO\n', output
680 assert errout == '', errout
683 sys.stderr = save_stderr
685 def test_AddMethod(self):
686 """Test the AddMethod() method"""
687 env = SubstitutionEnvironment(FOO = 'foo')
690 return 'func-' + self['FOO']
692 assert not hasattr(env, 'func')
695 assert r == 'func-foo', r
697 assert not hasattr(env, 'bar')
698 env.AddMethod(func, 'bar')
700 assert r == 'func-foo', r
702 def func2(self, arg=''):
703 return 'func2-' + self['FOO'] + arg
707 assert r == 'func2-foo', r
708 r = env.func2('-xxx')
709 assert r == 'func2-foo-xxx', r
711 env.AddMethod(func2, 'func')
713 assert r == 'func2-foo', r
715 assert r == 'func2-foo-yyy', r
717 # Test that clones of clones correctly re-bind added methods.
718 env1 = Environment(FOO = '1')
719 env1.AddMethod(func2)
720 env2 = env1.Clone(FOO = '2')
721 env3 = env2.Clone(FOO = '3')
722 env4 = env3.Clone(FOO = '4')
724 assert r == 'func2-1', r
726 assert r == 'func2-2', r
728 assert r == 'func2-3', r
730 assert r == 'func2-4', r
732 # Test that clones don't re-bind an attribute that the user
733 env1 = Environment(FOO = '1')
734 env1.AddMethod(func2)
736 return 'replace_func2'
737 env1.func2 = replace_func2
738 env2 = env1.Clone(FOO = '2')
740 assert r == 'replace_func2', r
742 def test_Override(self):
743 "Test overriding construction variables"
744 env = SubstitutionEnvironment(ONE=1, TWO=2, THREE=3, FOUR=4)
745 assert env['ONE'] == 1, env['ONE']
746 assert env['TWO'] == 2, env['TWO']
747 assert env['THREE'] == 3, env['THREE']
748 assert env['FOUR'] == 4, env['FOUR']
750 env2 = env.Override({'TWO' : '10',
751 'THREE' :'x $THREE y',
752 'FOUR' : ['x', '$FOUR', 'y']})
753 assert env2['ONE'] == 1, env2['ONE']
754 assert env2['TWO'] == '10', env2['TWO']
755 assert env2['THREE'] == 'x 3 y', env2['THREE']
756 assert env2['FOUR'] == ['x', 4, 'y'], env2['FOUR']
758 assert env['ONE'] == 1, env['ONE']
759 assert env['TWO'] == 2, env['TWO']
760 assert env['THREE'] == 3, env['THREE']
761 assert env['FOUR'] == 4, env['FOUR']
763 env2.Replace(ONE = "won")
764 assert env2['ONE'] == "won", env2['ONE']
765 assert env['ONE'] == 1, env['ONE']
767 def test_ParseFlags(self):
768 """Test the ParseFlags() method
770 env = SubstitutionEnvironment()
779 'FRAMEWORKPATH' : [],
787 d = env.ParseFlags(None)
790 d = env.ParseFlags('')
793 d = env.ParseFlags([])
796 s = "-I/usr/include/fum -I bar -X\n" + \
797 '-I"C:\\Program Files\\ASCEND\\include" ' + \
798 "-L/usr/fax -L foo -lxxx -l yyy " + \
799 '-L"C:\\Program Files\\ASCEND" -lascend ' + \
800 "-Wa,-as -Wl,-link " + \
801 "-Wl,-rpath=rpath1 " + \
806 "-framework Carbon " + \
807 "-frameworkdir=fwd1 " + \
811 "-mno-cygwin -mwindows " + \
812 "-arch i386 -isysroot /tmp +DD64 " + \
813 "-DFOO -DBAR=value -D BAZ "
815 d = env.ParseFlags(s)
817 assert d['ASFLAGS'] == ['-as'], d['ASFLAGS']
818 assert d['CFLAGS'] == ['-std=c99']
819 assert d['CCFLAGS'] == ['-X', '-Wa,-as',
820 '-pthread', '-mno-cygwin',
821 ('-arch', 'i386'), ('-isysroot', '/tmp'),
822 '+DD64'], d['CCFLAGS']
823 assert d['CPPDEFINES'] == ['FOO', ['BAR', 'value'], 'BAZ'], d['CPPDEFINES']
824 assert d['CPPFLAGS'] == ['-Wp,-cpp'], d['CPPFLAGS']
825 assert d['CPPPATH'] == ['/usr/include/fum',
827 'C:\\Program Files\\ASCEND\\include'], d['CPPPATH']
828 assert d['FRAMEWORKPATH'] == ['fwd1', 'fwd2', 'fwd3'], d['FRAMEWORKPATH']
829 assert d['FRAMEWORKS'] == ['Carbon'], d['FRAMEWORKS']
830 assert d['LIBPATH'] == ['/usr/fax',
832 'C:\\Program Files\\ASCEND'], d['LIBPATH']
833 LIBS = map(str, d['LIBS'])
834 assert LIBS == ['xxx', 'yyy', 'ascend'], (d['LIBS'], LIBS)
835 assert d['LINKFLAGS'] == ['-Wl,-link', '-pthread',
836 '-mno-cygwin', '-mwindows',
838 ('-isysroot', '/tmp'),
839 '+DD64'], d['LINKFLAGS']
840 assert d['RPATH'] == ['rpath1', 'rpath2', 'rpath3'], d['RPATH']
843 def test_MergeFlags(self):
844 """Test the MergeFlags() method
846 env = SubstitutionEnvironment()
848 assert not env.has_key('CCFLAGS'), env['CCFLAGS']
850 assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
852 assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
854 env = SubstitutionEnvironment(CCFLAGS=None)
856 assert env['CCFLAGS'] == ['-Y'], env['CCFLAGS']
858 env = SubstitutionEnvironment()
859 env.MergeFlags({'A':['aaa'], 'B':['bbb']})
860 assert env['A'] == ['aaa'], env['A']
861 assert env['B'] == ['bbb'], env['B']
863 # def test_MergeShellPaths(self):
864 # """Test the MergeShellPaths() method
866 # env = Environment()
867 # env.MergeShellPaths({})
868 # assert not env['ENV'].has_key('INCLUDE'), env['INCLUDE']
869 # env.MergeShellPaths({'INCLUDE': r'c:\Program Files\Stuff'})
870 # assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff', env['ENV']['INCLUDE']
871 # env.MergeShellPaths({'INCLUDE': r'c:\Program Files\Stuff'})
872 # assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff', env['ENV']['INCLUDE']
873 # env.MergeShellPaths({'INCLUDE': r'xyz'})
874 # assert env['ENV']['INCLUDE'] == r'xyz%sc:\Program Files\Stuff'%os.pathsep, env['ENV']['INCLUDE']
876 # env = Environment()
877 # env['ENV']['INCLUDE'] = 'xyz'
878 # env.MergeShellPaths({'INCLUDE':['c:/inc1', 'c:/inc2']} )
879 # assert env['ENV']['INCLUDE'] == r'c:/inc1%sc:/inc2%sxyz'%(os.pathsep, os.pathsep), env['ENV']['INCLUDE']
882 # env = Environment()
883 # env.MergeShellPaths({'INCLUDE': r'c:\Program Files\Stuff'}, prepend=0)
884 # assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff', env['ENV']['INCLUDE']
885 # env.MergeShellPaths({'INCLUDE': r'xyz'}, prepend=0)
886 # assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff%sxyz'%os.pathsep, env['ENV']['INCLUDE']
889 class BaseTestCase(unittest.TestCase,TestEnvironmentFixture):
891 reserved_variables = [
902 def test___init__(self):
903 """Test construction Environment creation
905 Create two with identical arguments and check that
906 they compare the same.
908 env1 = self.TestEnvironment(XXX = 'x', YYY = 'y')
909 env2 = self.TestEnvironment(XXX = 'x', YYY = 'y')
910 assert env1 == env2, diff_env(env1, env2)
912 assert not env1.has_key('__env__')
913 assert not env2.has_key('__env__')
915 def test_variables(self):
916 """Test that variables only get applied once."""
918 def __init__(self, key, val):
924 def Update(self, env):
925 env[self.key] = self.val
926 self.calls = self.calls + 1
928 o = FakeOptions('AAA', 'fake_opt')
929 env = Environment(variables=o, AAA='keyword_arg')
930 assert o.calls == 1, o.calls
931 assert env['AAA'] == 'fake_opt', env['AAA']
934 """Test the get() method."""
935 env = self.TestEnvironment(aaa = 'AAA')
939 x = env.get('aaa', 'XXX')
943 x = env.get('bbb', 'XXX')
946 def test_Builder_calls(self):
947 """Test Builder calls through different environments
955 env.Replace(BUILDERS = { 'builder1' : b1,
959 assert called_it['target'] is None, called_it
960 assert called_it['source'] == ['in1'], called_it
963 env.builder2(source = 'in2', xyzzy = 1)
964 assert called_it['target'] is None, called_it
965 assert called_it['source'] == ['in2'], called_it
966 assert called_it['xyzzy'] == 1, called_it
969 env.builder1(foo = 'bar')
970 assert called_it['foo'] == 'bar', called_it
971 assert called_it['target'] is None, called_it
972 assert called_it['source'] is None, called_it
974 def test_BuilderWrapper_attributes(self):
975 """Test getting and setting of BuilderWrapper attributes
982 e1.Replace(BUILDERS = {'b' : b1})
989 assert bw.builder is b1
991 assert bw.builder is b2
993 self.assertRaises(AttributeError, getattr, bw, 'foobar')
995 assert bw.foobar is 42
997 # This unit test is currently disabled because we don't think the
998 # underlying method it tests (Environment.BuilderWrapper.execute())
999 # is necessary, but we're leaving the code here for now in case
1001 def _DO_NOT_test_Builder_execs(self):
1002 """Test Builder execution through different environments
1004 One environment is initialized with a single
1005 Builder object, one with a list of a single Builder
1006 object, and one with a list of two Builder objects.
1014 env3 = Environment()
1015 env3.Replace(BUILDERS = { 'builder1' : b1,
1017 env3.builder1.execute(target = 'out1')
1018 env3.builder2.execute(target = 'out2')
1019 env3.builder1.execute(target = 'out3')
1020 assert built_it['out1']
1021 assert built_it['out2']
1022 assert built_it['out3']
1025 assert env4.builder1.env is env4, "builder1.env (%s) == env3 (%s)?" % (
1026 env4.builder1.env, env3)
1027 assert env4.builder2.env is env4, "builder2.env (%s) == env3 (%s)?" % (
1028 env4.builder1.env, env3)
1030 # Now test BUILDERS as a dictionary.
1032 env5 = self.TestEnvironment(BUILDERS={ 'foo' : b1 })
1033 env5['BUILDERS']['bar'] = b2
1034 env5.foo.execute(target='out1')
1035 env5.bar.execute(target='out2')
1036 assert built_it['out1']
1037 assert built_it['out2']
1040 env6 = Environment()
1041 env6['BUILDERS'] = { 'foo' : b1,
1043 env6.foo.execute(target='out1')
1044 env6.bar.execute(target='out2')
1045 assert built_it['out1']
1046 assert built_it['out2']
1050 def test_Scanners(self):
1051 """Test setting SCANNERS in various ways
1053 One environment is initialized with a single
1054 Scanner object, one with a list of a single Scanner
1055 object, and one with a list of two Scanner objects.
1059 s1 = Scanner(name = 'scanner1', skeys = [".c", ".cc"])
1060 s2 = Scanner(name = 'scanner2', skeys = [".m4"])
1061 s3 = Scanner(name = 'scanner3', skeys = [".m4", ".m5"])
1062 s4 = Scanner(name = 'scanner4', skeys = [None])
1064 # XXX Tests for scanner execution through different environments,
1065 # XXX if we ever want to do that some day
1067 # env1 = self.TestEnvironment(SCANNERS = s1)
1068 # env1.scanner1(filename = 'out1')
1069 # assert scanned_it['out1']
1072 # env2 = self.TestEnvironment(SCANNERS = [s1])
1073 # env1.scanner1(filename = 'out1')
1074 # assert scanned_it['out1']
1077 # env3 = Environment()
1078 # env3.Replace(SCANNERS = [s1])
1079 # env3.scanner1(filename = 'out1')
1080 # env3.scanner2(filename = 'out2')
1081 # env3.scanner1(filename = 'out3')
1082 # assert scanned_it['out1']
1083 # assert scanned_it['out2']
1084 # assert scanned_it['out3']
1086 suffixes = [".c", ".cc", ".cxx", ".m4", ".m5"]
1089 try: del env['SCANNERS']
1090 except KeyError: pass
1091 s = map(env.get_scanner, suffixes)
1092 assert s == [None, None, None, None, None], s
1094 env = self.TestEnvironment(SCANNERS = [])
1095 s = map(env.get_scanner, suffixes)
1096 assert s == [None, None, None, None, None], s
1098 env.Replace(SCANNERS = [s1])
1099 s = map(env.get_scanner, suffixes)
1100 assert s == [s1, s1, None, None, None], s
1102 env.Append(SCANNERS = [s2])
1103 s = map(env.get_scanner, suffixes)
1104 assert s == [s1, s1, None, s2, None], s
1106 env.AppendUnique(SCANNERS = [s3])
1107 s = map(env.get_scanner, suffixes)
1108 assert s == [s1, s1, None, s2, s3], s
1110 env = env.Clone(SCANNERS = [s2])
1111 s = map(env.get_scanner, suffixes)
1112 assert s == [None, None, None, s2, None], s
1114 env['SCANNERS'] = [s1]
1115 s = map(env.get_scanner, suffixes)
1116 assert s == [s1, s1, None, None, None], s
1118 env.PrependUnique(SCANNERS = [s2, s1])
1119 s = map(env.get_scanner, suffixes)
1120 assert s == [s1, s1, None, s2, None], s
1122 env.Prepend(SCANNERS = [s3])
1123 s = map(env.get_scanner, suffixes)
1124 assert s == [s1, s1, None, s3, s3], s
1126 # Verify behavior of case-insensitive suffix matches on Windows.
1127 uc_suffixes = map(string.upper, suffixes)
1129 env = Environment(SCANNERS = [s1, s2, s3],
1132 s = map(env.get_scanner, suffixes)
1133 assert s == [s1, s1, None, s2, s3], s
1135 s = map(env.get_scanner, uc_suffixes)
1136 assert s == [None, None, None, None, None], s
1138 env['PLATFORM'] = 'win32'
1140 s = map(env.get_scanner, uc_suffixes)
1141 assert s == [s1, s1, None, s2, s3], s
1143 # Verify behavior for a scanner returning None (on Windows
1144 # where we might try to perform case manipulation on None).
1145 env.Replace(SCANNERS = [s4])
1146 s = map(env.get_scanner, suffixes)
1147 assert s == [None, None, None, None, None], s
1150 """Test setting the external ENV in Environments
1153 assert env.Dictionary().has_key('ENV')
1155 env = self.TestEnvironment(ENV = { 'PATH' : '/foo:/bar' })
1156 assert env.Dictionary('ENV')['PATH'] == '/foo:/bar'
1158 def test_ReservedVariables(self):
1159 """Test warning generation when reserved variable names are set"""
1161 reserved_variables = [
1168 'UNCHANGED_SOURCES',
1169 'UNCHANGED_TARGETS',
1172 warning = SCons.Warnings.ReservedVariableWarning
1173 SCons.Warnings.enableWarningClass(warning)
1174 old = SCons.Warnings.warningAsException(1)
1177 env4 = Environment()
1178 for kw in self.reserved_variables:
1184 assert exc_caught, "Did not catch ReservedVariableWarning for `%s'" % kw
1185 assert not env4.has_key(kw), "`%s' variable was incorrectly set" % kw
1187 SCons.Warnings.warningAsException(old)
1189 def test_FutureReservedVariables(self):
1190 """Test warning generation when future reserved variable names are set"""
1192 future_reserved_variables = []
1194 warning = SCons.Warnings.FutureReservedVariableWarning
1195 SCons.Warnings.enableWarningClass(warning)
1196 old = SCons.Warnings.warningAsException(1)
1199 env4 = Environment()
1200 for kw in future_reserved_variables:
1206 assert exc_caught, "Did not catch FutureReservedVariableWarning for `%s'" % kw
1207 assert env4.has_key(kw), "`%s' variable was not set" % kw
1209 SCons.Warnings.warningAsException(old)
1211 def test_IllegalVariables(self):
1212 """Test that use of illegal variables raises an exception"""
1214 def test_it(var, env=env):
1218 except SCons.Errors.UserError:
1220 assert exc_caught, "did not catch UserError for '%s'" % var
1222 assert env['aaa'] == 1, env['aaa']
1227 def test_autogenerate(dict):
1228 """Test autogenerating variables in a dictionary."""
1230 drive, p = os.path.splitdrive(os.getcwd())
1231 def normalize_path(path, drive=drive):
1232 if path[0] in '\\/':
1234 path = os.path.normpath(path)
1235 drive, path = os.path.splitdrive(path)
1236 return string.lower(drive) + path
1238 env = dict.TestEnvironment(LIBS = [ 'foo', 'bar', 'baz' ],
1239 LIBLINKPREFIX = 'foo',
1240 LIBLINKSUFFIX = 'bar')
1242 def RDirs(pathlist, fs=env.fs):
1243 return fs.Dir('xx').Rfindalldirs(pathlist)
1245 env['RDirs'] = RDirs
1246 flags = env.subst_list('$_LIBFLAGS', 1)[0]
1247 assert flags == ['foobar', 'foobar', 'foobazbar'], flags
1249 blat = env.fs.Dir('blat')
1251 env.Replace(CPPPATH = [ 'foo', '$FOO/bar', blat ],
1255 flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
1257 normalize_path('foo'),
1258 normalize_path('xx/foobar'),
1259 normalize_path('foo'),
1260 normalize_path('xx/baz/bar'),
1261 normalize_path('foo'),
1262 normalize_path('blatbar'),
1265 assert flags == expect, flags
1267 env.Replace(F77PATH = [ 'foo', '$FOO/bar', blat ],
1271 flags = env.subst_list('$_F77INCFLAGS', 1)[0]
1273 normalize_path('foo'),
1274 normalize_path('xx/foobar'),
1275 normalize_path('foo'),
1276 normalize_path('xx/baz/bar'),
1277 normalize_path('foo'),
1278 normalize_path('blatbar'),
1281 assert flags == expect, flags
1283 env.Replace(CPPPATH = '', F77PATH = '', LIBPATH = '')
1284 l = env.subst_list('$_CPPINCFLAGS')
1286 l = env.subst_list('$_F77INCFLAGS')
1288 l = env.subst_list('$_LIBDIRFLAGS')
1291 env.fs.Repository('/rep1')
1292 env.fs.Repository('/rep2')
1293 env.Replace(CPPPATH = [ 'foo', '/a/b', '$FOO/bar', blat],
1297 flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
1299 '-I', normalize_path('xx/fooXXX'),
1300 '-I', normalize_path('/rep1/xx/fooXXX'),
1301 '-I', normalize_path('/rep2/xx/fooXXX'),
1302 '-I', normalize_path('/a/bXXX'),
1303 '-I', normalize_path('xx/baz/barXXX'),
1304 '-I', normalize_path('/rep1/xx/baz/barXXX'),
1305 '-I', normalize_path('/rep2/xx/baz/barXXX'),
1306 '-I', normalize_path('blatXXX'),
1309 def normalize_if_path(arg, np=normalize_path):
1310 if arg not in ('$(','$)','-I'):
1313 flags = map(normalize_if_path, flags)
1314 assert flags == expect, flags
1316 def test_platform(self):
1317 """Test specifying a platform callable when instantiating."""
1319 def __str__(self): return "TestPlatform"
1320 def __call__(self, env): env['XYZZY'] = 777
1323 env['SET_TOOL'] = 'initialized'
1324 assert env['PLATFORM'] == "TestPlatform"
1326 env = self.TestEnvironment(platform = platform(), tools = [tool])
1327 assert env['XYZZY'] == 777, env
1328 assert env['PLATFORM'] == "TestPlatform"
1329 assert env['SET_TOOL'] == "initialized"
1331 def test_Default_PLATFORM(self):
1332 """Test overriding the default PLATFORM variable"""
1334 def __str__(self): return "DefaultTestPlatform"
1335 def __call__(self, env): env['XYZZY'] = 888
1338 env['SET_TOOL'] = 'abcde'
1339 assert env['PLATFORM'] == "DefaultTestPlatform"
1341 import SCons.Defaults
1342 save = SCons.Defaults.ConstructionEnvironment.copy()
1344 import SCons.Defaults
1345 SCons.Defaults.ConstructionEnvironment.update({
1346 'PLATFORM' : platform(),
1348 env = self.TestEnvironment(tools = [tool])
1349 assert env['XYZZY'] == 888, env
1350 assert env['PLATFORM'] == "DefaultTestPlatform"
1351 assert env['SET_TOOL'] == "abcde"
1353 SCons.Defaults.ConstructionEnvironment = save
1355 def test_tools(self):
1356 """Test specifying a tool callable when instantiating."""
1362 env['AAA'] = env['XYZ']
1365 env = self.TestEnvironment(tools = [t1, t2, t3], XYZ = 'aaa')
1366 assert env['TOOL1'] == 111, env['TOOL1']
1367 assert env['TOOL2'] == 222, env
1368 assert env['AAA'] == 'aaa', env
1370 assert env['TOOL4'] == 444, env
1372 test = TestCmd.TestCmd(workdir = '')
1373 test.write('faketool.py', """\
1374 def generate(env, **kw):
1375 for k, v in kw.items():
1382 env = self.TestEnvironment(tools = [('faketool', {'a':1, 'b':2, 'c':3})],
1383 toolpath = [test.workpath('')])
1384 assert env['a'] == 1, env['a']
1385 assert env['b'] == 2, env['b']
1386 assert env['c'] == 3, env['c']
1388 def test_Default_TOOLS(self):
1389 """Test overriding the default TOOLS variable"""
1395 env['BBB'] = env['XYZ']
1399 import SCons.Defaults
1400 save = SCons.Defaults.ConstructionEnvironment.copy()
1402 SCons.Defaults.ConstructionEnvironment.update({
1403 'TOOLS' : [t5, t6, t7],
1405 env = Environment(XYZ = 'bbb')
1406 assert env['TOOL5'] == 555, env['TOOL5']
1407 assert env['TOOL6'] == 666, env
1408 assert env['BBB'] == 'bbb', env
1410 assert env['TOOL8'] == 888, env
1412 SCons.Defaults.ConstructionEnvironment = save
1414 def test_null_tools(self):
1415 """Test specifying a tool of None is OK."""
1420 env = self.TestEnvironment(tools = [t1, None, t2], XYZ = 'aaa')
1421 assert env['TOOL1'] == 111, env['TOOL1']
1422 assert env['TOOL2'] == 222, env
1423 assert env['XYZ'] == 'aaa', env
1424 env = self.TestEnvironment(tools = [None], XYZ = 'xyz')
1425 assert env['XYZ'] == 'xyz', env
1426 env = self.TestEnvironment(tools = [t1, '', t2], XYZ = 'ddd')
1427 assert env['TOOL1'] == 111, env['TOOL1']
1428 assert env['TOOL2'] == 222, env
1429 assert env['XYZ'] == 'ddd', env
1431 def test_concat(self):
1433 e1 = self.TestEnvironment(PRE='pre', SUF='suf', STR='a b', LIST=['a', 'b'])
1435 x = s("${_concat('', '', '', __env__)}")
1437 x = s("${_concat('', [], '', __env__)}")
1439 x = s("${_concat(PRE, '', SUF, __env__)}")
1441 x = s("${_concat(PRE, STR, SUF, __env__)}")
1442 assert x == 'prea bsuf', x
1443 x = s("${_concat(PRE, LIST, SUF, __env__)}")
1444 assert x == 'preasuf prebsuf', x
1446 def test_gvars(self):
1447 """Test the Environment gvars() method"""
1448 env = self.TestEnvironment(XXX = 'x', YYY = 'y', ZZZ = 'z')
1450 assert gvars['XXX'] == 'x', gvars['XXX']
1451 assert gvars['YYY'] == 'y', gvars['YYY']
1452 assert gvars['ZZZ'] == 'z', gvars['ZZZ']
1454 def test__update(self):
1455 """Test the _update() method"""
1456 env = self.TestEnvironment(X = 'x', Y = 'y', Z = 'z')
1457 assert env['X'] == 'x', env['X']
1458 assert env['Y'] == 'y', env['Y']
1459 assert env['Z'] == 'z', env['Z']
1460 env._update({'X' : 'xxx',
1466 assert env['X'] == 'xxx', env['X']
1467 assert env['Y'] == 'y', env['Y']
1468 assert env['Z'] == 'zzz', env['Z']
1469 assert env['TARGET'] == 't', env['TARGET']
1470 assert env['TARGETS'] == 'ttt', env['TARGETS']
1471 assert env['SOURCE'] == 's', env['SOURCE']
1472 assert env['SOURCES'] == 'sss', env['SOURCES']
1476 def test_Append(self):
1477 """Test appending to construction variables in an Environment
1480 b1 = Environment()['BUILDERS']
1481 b2 = Environment()['BUILDERS']
1482 assert b1 == b2, diff_dict(b1, b2)
1485 UD = UserDict.UserDict
1487 UL = UserList.UserList
1491 'a2', ['A2'], ['a2', 'A2'],
1492 'a3', UL(['A3']), UL(['a', '3', 'A3']),
1495 'a6', UL([]), UL(['a', '6']),
1496 'a7', [''], ['a7', ''],
1497 'a8', UL(['']), UL(['a', '8', '']),
1499 ['e1'], 'E1', ['e1', 'E1'],
1500 ['e2'], ['E2'], ['e2', 'E2'],
1501 ['e3'], UL(['E3']), UL(['e3', 'E3']),
1504 ['e6'], UL([]), UL(['e6']),
1505 ['e7'], [''], ['e7', ''],
1506 ['e8'], UL(['']), UL(['e8', '']),
1508 UL(['i1']), 'I1', UL(['i1', 'I', '1']),
1509 UL(['i2']), ['I2'], UL(['i2', 'I2']),
1510 UL(['i3']), UL(['I3']), UL(['i3', 'I3']),
1511 UL(['i4']), '', UL(['i4']),
1512 UL(['i5']), [], UL(['i5']),
1513 UL(['i6']), UL([]), UL(['i6']),
1514 UL(['i7']), [''], UL(['i7', '']),
1515 UL(['i8']), UL(['']), UL(['i8', '']),
1517 {'d1':1}, 'D1', {'d1':1, 'D1':None},
1518 {'d2':1}, ['D2'], {'d2':1, 'D2':None},
1519 {'d3':1}, UL(['D3']), {'d3':1, 'D3':None},
1520 {'d4':1}, {'D4':1}, {'d4':1, 'D4':1},
1521 {'d5':1}, UD({'D5':1}), UD({'d5':1, 'D5':1}),
1523 UD({'u1':1}), 'U1', UD({'u1':1, 'U1':None}),
1524 UD({'u2':1}), ['U2'], UD({'u2':1, 'U2':None}),
1525 UD({'u3':1}), UL(['U3']), UD({'u3':1, 'U3':None}),
1526 UD({'u4':1}), {'U4':1}, UD({'u4':1, 'U4':1}),
1527 UD({'u5':1}), UD({'U5':1}), UD({'u5':1, 'U5':1}),
1531 '', UL(['M3']), UL(['M3']),
1536 '', UL(['']), UL(['']),
1540 [], UL(['N3']), UL(['N3']),
1545 [], UL(['']), UL(['']),
1547 UL([]), 'O1', ['O', '1'],
1548 UL([]), ['O2'], ['O2'],
1549 UL([]), UL(['O3']), UL(['O3']),
1552 UL([]), UL([]), UL([]),
1553 UL([]), [''], UL(['']),
1554 UL([]), UL(['']), UL(['']),
1556 [''], 'P1', ['', 'P1'],
1557 [''], ['P2'], ['', 'P2'],
1558 [''], UL(['P3']), UL(['', 'P3']),
1561 [''], UL([]), UL(['']),
1562 [''], [''], ['', ''],
1563 [''], UL(['']), UL(['', '']),
1565 UL(['']), 'Q1', ['', 'Q', '1'],
1566 UL(['']), ['Q2'], ['', 'Q2'],
1567 UL(['']), UL(['Q3']), UL(['', 'Q3']),
1568 UL(['']), '', UL(['']),
1569 UL(['']), [], UL(['']),
1570 UL(['']), UL([]), UL(['']),
1571 UL(['']), [''], UL(['', '']),
1572 UL(['']), UL(['']), UL(['', '']),
1578 input, append, expect = cases[:3]
1579 env['XXX'] = copy.copy(input)
1581 env.Append(XXX = append)
1582 except Exception, e:
1583 if failed == 0: print
1584 print " %s Append %s exception: %s" % \
1585 (repr(input), repr(append), e)
1589 if result != expect:
1590 if failed == 0: print
1591 print " %s Append %s => %s did not match %s" % \
1592 (repr(input), repr(append), repr(result), repr(expect))
1595 assert failed == 0, "%d Append() cases failed" % failed
1597 env['UL'] = UL(['foo'])
1598 env.Append(UL = 'bar')
1600 assert isinstance(result, UL), repr(result)
1601 assert result == ['foo', 'b', 'a', 'r'], result
1603 env['CLVar'] = CLVar(['foo'])
1604 env.Append(CLVar = 'bar')
1605 result = env['CLVar']
1606 assert isinstance(result, CLVar), repr(result)
1607 assert result == ['foo', 'bar'], result
1610 def __init__(self, name):
1614 def __cmp__(self, other):
1615 raise "should not compare"
1619 env2 = self.TestEnvironment(CCC1 = ['c1'], CCC2 = ccc)
1620 env2.Append(CCC1 = ccc, CCC2 = ['c2'])
1621 assert env2['CCC1'][0] == 'c1', env2['CCC1']
1622 assert env2['CCC1'][1] is ccc, env2['CCC1']
1623 assert env2['CCC2'][0] is ccc, env2['CCC2']
1624 assert env2['CCC2'][1] == 'c2', env2['CCC2']
1626 env3 = self.TestEnvironment(X = {'x1' : 7})
1627 env3.Append(X = {'x1' : 8, 'x2' : 9}, Y = {'y1' : 10})
1628 assert env3['X'] == {'x1': 8, 'x2': 9}, env3['X']
1629 assert env3['Y'] == {'y1': 10}, env3['Y']
1631 env4 = self.TestEnvironment(BUILDERS = {'z1' : 11})
1632 env4.Append(BUILDERS = {'z2' : 12})
1633 assert env4['BUILDERS'] == {'z1' : 11, 'z2' : 12}, env4['BUILDERS']
1634 assert hasattr(env4, 'z1')
1635 assert hasattr(env4, 'z2')
1637 def test_AppendENVPath(self):
1638 """Test appending to an ENV path."""
1639 env1 = self.TestEnvironment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
1640 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
1641 # have to include the pathsep here so that the test will work on UNIX too.
1642 env1.AppendENVPath('PATH',r'C:\dir\num\two', sep = ';')
1643 env1.AppendENVPath('PATH',r'C:\dir\num\three', sep = ';')
1644 env1.AppendENVPath('MYPATH',r'C:\mydir\num\three','MYENV', sep = ';')
1645 env1.AppendENVPath('MYPATH',r'C:\mydir\num\one','MYENV', sep = ';')
1646 # this should do nothing since delete_existing is 0
1647 env1.AppendENVPath('MYPATH',r'C:\mydir\num\three','MYENV', sep = ';', delete_existing=0)
1648 assert(env1['ENV']['PATH'] == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
1649 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\two;C:\mydir\num\three;C:\mydir\num\one')
1651 test = TestCmd.TestCmd(workdir = '')
1652 test.subdir('sub1', 'sub2')
1653 p=env1['ENV']['PATH']
1654 env1.AppendENVPath('PATH','#sub1', sep = ';')
1655 env1.AppendENVPath('PATH',env1.fs.Dir('sub2'), sep = ';')
1656 assert env1['ENV']['PATH'] == p + ';sub1;sub2', env1['ENV']['PATH']
1658 def test_AppendUnique(self):
1659 """Test appending to unique values to construction variables
1661 This strips values that are already present when lists are
1663 env = self.TestEnvironment(AAA1 = 'a1',
1675 DDD1 = ['a', 'b', 'c'])
1676 env.AppendUnique(AAA1 = 'a1',
1678 AAA3 = ['a3', 'b', 'c', 'c', 'b', 'a3'], # ignore dups
1683 BBB3 = ['b3', 'c', 'd', 'c', 'b3'],
1690 assert env['AAA1'] == 'a1a1', env['AAA1']
1691 assert env['AAA2'] == ['a2'], env['AAA2']
1692 assert env['AAA3'] == ['a3', 'b', 'c'], env['AAA3']
1693 assert env['AAA4'] == 'a4a4.new', env['AAA4']
1694 assert env['AAA5'] == ['a5', 'a5.new'], env['AAA5']
1695 assert env['BBB1'] == ['b1'], env['BBB1']
1696 assert env['BBB2'] == ['b2'], env['BBB2']
1697 assert env['BBB3'] == ['b3', 'c', 'd'], env['BBB3']
1698 assert env['BBB4'] == ['b4', 'b4.new'], env['BBB4']
1699 assert env['BBB5'] == ['b5', 'b5.new'], env['BBB5']
1700 assert env['CCC1'] == 'c1', env['CCC1']
1701 assert env['CCC2'] == ['c2'], env['CCC2']
1702 assert env['DDD1'] == ['a', 'b', 'c'], env['DDD1']
1704 env.AppendUnique(DDD1 = 'b', delete_existing=1)
1705 assert env['DDD1'] == ['a', 'c', 'b'], env['DDD1'] # b moves to end
1706 env.AppendUnique(DDD1 = ['a','b'], delete_existing=1)
1707 assert env['DDD1'] == ['c', 'a', 'b'], env['DDD1'] # a & b move to end
1708 env.AppendUnique(DDD1 = ['e','f', 'e'], delete_existing=1)
1709 assert env['DDD1'] == ['c', 'a', 'b', 'f', 'e'], env['DDD1'] # add last
1711 env['CLVar'] = CLVar([])
1712 env.AppendUnique(CLVar = 'bar')
1713 result = env['CLVar']
1714 if sys.version[0] == '1' or sys.version[:3] == '2.0':
1715 # Python 2.0 and before have a quirky behavior where CLVar([])
1716 # actually matches '' and [] due to different __coerce__()
1717 # semantics in the UserList implementation. It isn't worth a
1718 # lot of effort to get this corner case to work identically
1719 # (support for Python 1.5 support will die soon anyway),
1720 # so just treat it separately for now.
1721 assert result == 'bar', result
1723 assert isinstance(result, CLVar), repr(result)
1724 assert result == ['bar'], result
1726 env['CLVar'] = CLVar(['abc'])
1727 env.AppendUnique(CLVar = 'bar')
1728 result = env['CLVar']
1729 assert isinstance(result, CLVar), repr(result)
1730 assert result == ['abc', 'bar'], result
1732 env['CLVar'] = CLVar(['bar'])
1733 env.AppendUnique(CLVar = 'bar')
1734 result = env['CLVar']
1735 assert isinstance(result, CLVar), repr(result)
1736 assert result == ['bar'], result
1738 def test_Clone(self):
1739 """Test construction environment copying
1741 Update the copy independently afterwards and check that
1742 the original remains intact (that is, no dangling
1743 references point to objects in the copied environment).
1744 Clone the original with some construction variable
1745 updates and check that the original remains intact
1746 and the copy has the updated values.
1748 env1 = self.TestEnvironment(XXX = 'x', YYY = 'y')
1750 env1copy = env1.Clone()
1751 assert env1copy == env1copy
1753 env2.Replace(YYY = 'yyy')
1756 assert env1 == env1copy
1758 env3 = env1.Clone(XXX = 'x3', ZZZ = 'z3')
1760 assert env3.Dictionary('XXX') == 'x3'
1761 assert env3.Dictionary('YYY') == 'y'
1762 assert env3.Dictionary('ZZZ') == 'z3'
1763 assert env1 == env1copy
1765 # Ensure that lists and dictionaries are
1766 # deep copied, but not instances.
1769 env1 = self.TestEnvironment(XXX=TestA(), YYY = [ 1, 2, 3 ],
1772 env2.Dictionary('YYY').append(4)
1773 env2.Dictionary('ZZZ')[5] = 6
1774 assert env1.Dictionary('XXX') is env2.Dictionary('XXX')
1775 assert 4 in env2.Dictionary('YYY')
1776 assert not 4 in env1.Dictionary('YYY')
1777 assert env2.Dictionary('ZZZ').has_key(5)
1778 assert not env1.Dictionary('ZZZ').has_key(5)
1781 env1 = self.TestEnvironment(BUILDERS = {'b1' : 1})
1782 assert hasattr(env1, 'b1'), "env1.b1 was not set"
1783 assert env1.b1.object == env1, "b1.object doesn't point to env1"
1784 env2 = env1.Clone(BUILDERS = {'b2' : 2})
1787 assert hasattr(env1, 'b1'), "b1 was mistakenly cleared from env1"
1788 assert env1.b1.object == env1, "b1.object was changed"
1789 assert not hasattr(env2, 'b1'), "b1 was not cleared from env2"
1790 assert hasattr(env2, 'b2'), "env2.b2 was not set"
1791 assert env2.b2.object == env2, "b2.object doesn't point to env2"
1793 # Ensure that specifying new tools in a copied environment
1795 def foo(env): env['FOO'] = 1
1796 def bar(env): env['BAR'] = 2
1797 def baz(env): env['BAZ'] = 3
1798 env1 = self.TestEnvironment(tools=[foo])
1800 env3 = env1.Clone(tools=[bar, baz])
1802 assert env1.get('FOO') is 1
1803 assert env1.get('BAR') is None
1804 assert env1.get('BAZ') is None
1805 assert env2.get('FOO') is 1
1806 assert env2.get('BAR') is None
1807 assert env2.get('BAZ') is None
1808 assert env3.get('FOO') is 1
1809 assert env3.get('BAR') is 2
1810 assert env3.get('BAZ') is 3
1812 # Ensure that recursive variable substitution when copying
1813 # environments works properly.
1814 env1 = self.TestEnvironment(CCFLAGS = '-DFOO', XYZ = '-DXYZ')
1815 env2 = env1.Clone(CCFLAGS = '$CCFLAGS -DBAR',
1816 XYZ = ['-DABC', 'x $XYZ y', '-DDEF'])
1817 x = env2.get('CCFLAGS')
1818 assert x == '-DFOO -DBAR', x
1820 assert x == ['-DABC', 'x -DXYZ y', '-DDEF'], x
1822 # Ensure that special properties of a class don't get
1824 env1 = self.TestEnvironment(FLAGS = CLVar('flag1 flag2'))
1825 x = env1.get('FLAGS')
1826 assert x == ['flag1', 'flag2'], x
1828 env2.Append(FLAGS = 'flag3 flag4')
1829 x = env2.get('FLAGS')
1830 assert x == ['flag1', 'flag2', 'flag3', 'flag4'], x
1832 # Test that the environment stores the toolpath and
1833 # re-uses it for copies.
1834 test = TestCmd.TestCmd(workdir = '')
1836 test.write('xxx.py', """\
1843 test.write('yyy.py', """\
1850 env = self.TestEnvironment(tools=['xxx'], toolpath=[test.workpath('')])
1851 assert env['XXX'] == 'one', env['XXX']
1852 env = env.Clone(tools=['yyy'])
1853 assert env['YYY'] == 'two', env['YYY']
1859 def my_tool(env, rv=real_value):
1860 assert env['KEY_THAT_I_WANT'] == rv[0]
1861 env['KEY_THAT_I_WANT'] = rv[0] + 1
1863 env = self.TestEnvironment()
1866 env = env.Clone(KEY_THAT_I_WANT=5, tools=[my_tool])
1867 assert env['KEY_THAT_I_WANT'] == real_value[0], env['KEY_THAT_I_WANT']
1870 env = env.Clone(KEY_THAT_I_WANT=6, tools=[my_tool])
1871 assert env['KEY_THAT_I_WANT'] == real_value[0], env['KEY_THAT_I_WANT']
1874 def test_Copy(self):
1875 """Test copying using the old env.Copy() method"""
1876 env1 = self.TestEnvironment(XXX = 'x', YYY = 'y')
1878 env1copy = env1.Copy()
1879 assert env1copy == env1copy
1881 env2.Replace(YYY = 'yyy')
1884 assert env1 == env1copy
1886 def test_Detect(self):
1887 """Test Detect()ing tools"""
1888 test = TestCmd.TestCmd(workdir = '')
1889 test.subdir('sub1', 'sub2')
1890 sub1 = test.workpath('sub1')
1891 sub2 = test.workpath('sub2')
1893 if sys.platform == 'win32':
1894 test.write(['sub1', 'xxx'], "sub1/xxx\n")
1895 test.write(['sub2', 'xxx'], "sub2/xxx\n")
1897 env = self.TestEnvironment(ENV = { 'PATH' : [sub1, sub2] })
1899 x = env.Detect('xxx.exe')
1902 test.write(['sub2', 'xxx.exe'], "sub2/xxx.exe\n")
1904 env = self.TestEnvironment(ENV = { 'PATH' : [sub1, sub2] })
1906 x = env.Detect('xxx.exe')
1907 assert x == 'xxx.exe', x
1909 test.write(['sub1', 'xxx.exe'], "sub1/xxx.exe\n")
1911 x = env.Detect('xxx.exe')
1912 assert x == 'xxx.exe', x
1915 test.write(['sub1', 'xxx.exe'], "sub1/xxx.exe\n")
1916 test.write(['sub2', 'xxx.exe'], "sub2/xxx.exe\n")
1918 env = self.TestEnvironment(ENV = { 'PATH' : [sub1, sub2] })
1920 x = env.Detect('xxx.exe')
1923 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
1924 os.chmod(sub2_xxx_exe, 0755)
1926 env = self.TestEnvironment(ENV = { 'PATH' : [sub1, sub2] })
1928 x = env.Detect('xxx.exe')
1929 assert x == 'xxx.exe', x
1931 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
1932 os.chmod(sub1_xxx_exe, 0755)
1934 x = env.Detect('xxx.exe')
1935 assert x == 'xxx.exe', x
1937 env = self.TestEnvironment(ENV = { 'PATH' : [] })
1938 x = env.Detect('xxx.exe')
1941 def test_Dictionary(self):
1942 """Test retrieval of known construction variables
1944 Fetch them from the Dictionary and check for well-known
1945 defaults that get inserted.
1947 env = self.TestEnvironment(XXX = 'x', YYY = 'y', ZZZ = 'z')
1948 assert env.Dictionary('XXX') == 'x'
1949 assert env.Dictionary('YYY') == 'y'
1950 assert env.Dictionary('XXX', 'ZZZ') == ['x', 'z']
1951 xxx, zzz = env.Dictionary('XXX', 'ZZZ')
1954 assert env.Dictionary().has_key('BUILDERS')
1955 assert env.Dictionary().has_key('CC')
1956 assert env.Dictionary().has_key('CCFLAGS')
1957 assert env.Dictionary().has_key('ENV')
1959 assert env['XXX'] == 'x'
1961 assert env.Dictionary('XXX') == 'foo'
1963 assert not env.Dictionary().has_key('XXX')
1965 def test_FindIxes(self):
1967 env = self.TestEnvironment(LIBPREFIX='lib',
1974 paths = [os.path.join('dir', 'libfoo.a'),
1975 os.path.join('dir', 'libfoo.so')]
1977 assert paths[0] == env.FindIxes(paths, 'LIBPREFIX', 'LIBSUFFIX')
1978 assert paths[1] == env.FindIxes(paths, 'SHLIBPREFIX', 'SHLIBSUFFIX')
1979 assert None is env.FindIxes(paths, 'PREFIX', 'POST')
1981 paths = ['libfoo.a', 'prefoopost']
1983 assert paths[0] == env.FindIxes(paths, 'LIBPREFIX', 'LIBSUFFIX')
1984 assert None is env.FindIxes(paths, 'SHLIBPREFIX', 'SHLIBSUFFIX')
1985 assert paths[1] == env.FindIxes(paths, 'PREFIX', 'SUFFIX')
1987 def test_ParseConfig(self):
1988 """Test the ParseConfig() method"""
1989 env = self.TestEnvironment(COMMAND='command',
1990 ASFLAGS='assembler',
2002 orig_backtick = env.backtick
2004 def __init__(self, save_command, output):
2005 self.save_command = save_command
2006 self.output = output
2007 def __call__(self, command):
2008 self.save_command.append(command)
2013 env.backtick = my_backtick(save_command,
2014 "-I/usr/include/fum -I bar -X\n" + \
2015 "-L/usr/fax -L foo -lxxx -l yyy " + \
2016 "-Wa,-as -Wl,-link " + \
2017 "-Wl,-rpath=rpath1 " + \
2018 "-Wl,-R,rpath2 " + \
2021 "-framework Carbon " + \
2022 "-frameworkdir=fwd1 " + \
2026 "-mno-cygwin -mwindows " + \
2027 "-arch i386 -isysroot /tmp +DD64 " + \
2028 "-DFOO -DBAR=value")
2029 env.ParseConfig("fake $COMMAND")
2030 assert save_command == ['fake command'], save_command
2031 assert env['ASFLAGS'] == ['assembler', '-as'], env['ASFLAGS']
2032 assert env['CCFLAGS'] == ['', '-X', '-Wa,-as',
2033 '-pthread', '-mno-cygwin',
2034 ('-arch', 'i386'), ('-isysroot', '/tmp'),
2035 '+DD64'], env['CCFLAGS']
2036 assert env['CPPDEFINES'] == ['FOO', ['BAR', 'value']], env['CPPDEFINES']
2037 assert env['CPPFLAGS'] == ['', '-Wp,-cpp'], env['CPPFLAGS']
2038 assert env['CPPPATH'] == ['string', '/usr/include/fum', 'bar'], env['CPPPATH']
2039 assert env['FRAMEWORKPATH'] == ['fwd1', 'fwd2', 'fwd3'], env['FRAMEWORKPATH']
2040 assert env['FRAMEWORKS'] == ['Carbon'], env['FRAMEWORKS']
2041 assert env['LIBPATH'] == ['list', '/usr/fax', 'foo'], env['LIBPATH']
2042 assert env['LIBS'] == ['xxx', 'yyy', env.File('abc')], env['LIBS']
2043 assert env['LINKFLAGS'] == ['', '-Wl,-link', '-pthread',
2044 '-mno-cygwin', '-mwindows',
2046 ('-isysroot', '/tmp'),
2047 '+DD64'], env['LINKFLAGS']
2048 assert env['RPATH'] == ['rpath1', 'rpath2', 'rpath3'], env['RPATH']
2050 env.backtick = my_backtick([], "-Ibar")
2051 env.ParseConfig("fake2")
2052 assert env['CPPPATH'] == ['string', '/usr/include/fum', 'bar'], env['CPPPATH']
2053 env.ParseConfig("fake2", unique=0)
2054 assert env['CPPPATH'] == ['string', '/usr/include/fum', 'bar', 'bar'], env['CPPPATH']
2056 env.backtick = orig_backtick
2058 def test_ParseDepends(self):
2059 """Test the ParseDepends() method"""
2060 test = TestCmd.TestCmd(workdir = '')
2062 test.write('single', """
2072 test.write('multiple', """
2083 env = self.TestEnvironment(SINGLE = test.workpath('single'))
2087 def my_depends(target, dependency, tlist=tlist, dlist=dlist):
2088 tlist.extend(target)
2089 dlist.extend(dependency)
2091 env.Depends = my_depends
2093 env.ParseDepends(test.workpath('does_not_exist'))
2097 env.ParseDepends(test.workpath('does_not_exist'), must_exist=1)
2100 assert exc_caught, "did not catch expected IOError"
2105 env.ParseDepends('$SINGLE', only_one=1)
2108 assert t == ['f0'], t
2109 assert d == ['d1', 'd2', 'd3'], d
2114 env.ParseDepends(test.workpath('multiple'))
2117 assert t == ['f1', 'f2', 'f3', 'f4', 'f5'], t
2118 assert d == ['foo', 'bar', 'abc', 'def', 'ghi', 'jkl', 'mno'], d
2122 env.ParseDepends(test.workpath('multiple'), only_one=1)
2123 except SCons.Errors.UserError:
2125 assert exc_caught, "did not catch expected UserError"
2127 def test_Platform(self):
2128 """Test the Platform() method"""
2129 env = self.TestEnvironment(WIN32='win32', NONE='no-such-platform')
2133 env.Platform('does_not_exist')
2134 except SCons.Errors.UserError:
2136 assert exc_caught, "did not catch expected UserError"
2140 env.Platform('$NONE')
2141 except SCons.Errors.UserError:
2143 assert exc_caught, "did not catch expected UserError"
2145 env.Platform('posix')
2146 assert env['OBJSUFFIX'] == '.o', env['OBJSUFFIX']
2148 env.Platform('$WIN32')
2149 assert env['OBJSUFFIX'] == '.obj', env['OBJSUFFIX']
2151 def test_Prepend(self):
2152 """Test prepending to construction variables in an Environment
2155 UD = UserDict.UserDict
2157 UL = UserList.UserList
2161 'a2', ['A2'], ['A2', 'a2'],
2162 'a3', UL(['A3']), UL(['A3', 'a', '3']),
2165 'a6', UL([]), UL(['a', '6']),
2166 'a7', [''], ['', 'a7'],
2167 'a8', UL(['']), UL(['', 'a', '8']),
2169 ['e1'], 'E1', ['E1', 'e1'],
2170 ['e2'], ['E2'], ['E2', 'e2'],
2171 ['e3'], UL(['E3']), UL(['E3', 'e3']),
2174 ['e6'], UL([]), UL(['e6']),
2175 ['e7'], [''], ['', 'e7'],
2176 ['e8'], UL(['']), UL(['', 'e8']),
2178 UL(['i1']), 'I1', UL(['I', '1', 'i1']),
2179 UL(['i2']), ['I2'], UL(['I2', 'i2']),
2180 UL(['i3']), UL(['I3']), UL(['I3', 'i3']),
2181 UL(['i4']), '', UL(['i4']),
2182 UL(['i5']), [], UL(['i5']),
2183 UL(['i6']), UL([]), UL(['i6']),
2184 UL(['i7']), [''], UL(['', 'i7']),
2185 UL(['i8']), UL(['']), UL(['', 'i8']),
2187 {'d1':1}, 'D1', {'d1':1, 'D1':None},
2188 {'d2':1}, ['D2'], {'d2':1, 'D2':None},
2189 {'d3':1}, UL(['D3']), {'d3':1, 'D3':None},
2190 {'d4':1}, {'D4':1}, {'d4':1, 'D4':1},
2191 {'d5':1}, UD({'D5':1}), UD({'d5':1, 'D5':1}),
2193 UD({'u1':1}), 'U1', UD({'u1':1, 'U1':None}),
2194 UD({'u2':1}), ['U2'], UD({'u2':1, 'U2':None}),
2195 UD({'u3':1}), UL(['U3']), UD({'u3':1, 'U3':None}),
2196 UD({'u4':1}), {'U4':1}, UD({'u4':1, 'U4':1}),
2197 UD({'u5':1}), UD({'U5':1}), UD({'u5':1, 'U5':1}),
2201 '', UL(['M3']), UL(['M3']),
2206 '', UL(['']), UL(['']),
2210 [], UL(['N3']), UL(['N3']),
2215 [], UL(['']), UL(['']),
2217 UL([]), 'O1', UL(['O', '1']),
2218 UL([]), ['O2'], UL(['O2']),
2219 UL([]), UL(['O3']), UL(['O3']),
2222 UL([]), UL([]), UL([]),
2223 UL([]), [''], UL(['']),
2224 UL([]), UL(['']), UL(['']),
2226 [''], 'P1', ['P1', ''],
2227 [''], ['P2'], ['P2', ''],
2228 [''], UL(['P3']), UL(['P3', '']),
2231 [''], UL([]), UL(['']),
2232 [''], [''], ['', ''],
2233 [''], UL(['']), UL(['', '']),
2235 UL(['']), 'Q1', UL(['Q', '1', '']),
2236 UL(['']), ['Q2'], UL(['Q2', '']),
2237 UL(['']), UL(['Q3']), UL(['Q3', '']),
2238 UL(['']), '', UL(['']),
2239 UL(['']), [], UL(['']),
2240 UL(['']), UL([]), UL(['']),
2241 UL(['']), [''], UL(['', '']),
2242 UL(['']), UL(['']), UL(['', '']),
2248 input, prepend, expect = cases[:3]
2249 env['XXX'] = copy.copy(input)
2251 env.Prepend(XXX = prepend)
2252 except Exception, e:
2253 if failed == 0: print
2254 print " %s Prepend %s exception: %s" % \
2255 (repr(input), repr(prepend), e)
2259 if result != expect:
2260 if failed == 0: print
2261 print " %s Prepend %s => %s did not match %s" % \
2262 (repr(input), repr(prepend), repr(result), repr(expect))
2265 assert failed == 0, "%d Prepend() cases failed" % failed
2267 env['UL'] = UL(['foo'])
2268 env.Prepend(UL = 'bar')
2270 assert isinstance(result, UL), repr(result)
2271 assert result == ['b', 'a', 'r', 'foo'], result
2273 env['CLVar'] = CLVar(['foo'])
2274 env.Prepend(CLVar = 'bar')
2275 result = env['CLVar']
2276 assert isinstance(result, CLVar), repr(result)
2277 assert result == ['bar', 'foo'], result
2279 env3 = self.TestEnvironment(X = {'x1' : 7})
2280 env3.Prepend(X = {'x1' : 8, 'x2' : 9}, Y = {'y1' : 10})
2281 assert env3['X'] == {'x1': 8, 'x2' : 9}, env3['X']
2282 assert env3['Y'] == {'y1': 10}, env3['Y']
2284 env4 = self.TestEnvironment(BUILDERS = {'z1' : 11})
2285 env4.Prepend(BUILDERS = {'z2' : 12})
2286 assert env4['BUILDERS'] == {'z1' : 11, 'z2' : 12}, env4['BUILDERS']
2287 assert hasattr(env4, 'z1')
2288 assert hasattr(env4, 'z2')
2290 def test_PrependENVPath(self):
2291 """Test prepending to an ENV path."""
2292 env1 = self.TestEnvironment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
2293 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
2294 # have to include the pathsep here so that the test will work on UNIX too.
2295 env1.PrependENVPath('PATH',r'C:\dir\num\two',sep = ';')
2296 env1.PrependENVPath('PATH',r'C:\dir\num\three',sep = ';')
2297 env1.PrependENVPath('MYPATH',r'C:\mydir\num\three','MYENV',sep = ';')
2298 env1.PrependENVPath('MYPATH',r'C:\mydir\num\one','MYENV',sep = ';')
2299 # this should do nothing since delete_existing is 0
2300 env1.PrependENVPath('MYPATH',r'C:\mydir\num\three','MYENV', sep = ';', delete_existing=0)
2301 assert(env1['ENV']['PATH'] == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
2302 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
2304 test = TestCmd.TestCmd(workdir = '')
2305 test.subdir('sub1', 'sub2')
2306 p=env1['ENV']['PATH']
2307 env1.PrependENVPath('PATH','#sub1', sep = ';')
2308 env1.PrependENVPath('PATH',env1.fs.Dir('sub2'), sep = ';')
2309 assert env1['ENV']['PATH'] == 'sub2;sub1;' + p, env1['ENV']['PATH']
2311 def test_PrependUnique(self):
2312 """Test prepending unique values to construction variables
2314 This strips values that are already present when lists are
2316 env = self.TestEnvironment(AAA1 = 'a1',
2328 DDD1 = ['a', 'b', 'c'])
2329 env.PrependUnique(AAA1 = 'a1',
2331 AAA3 = ['a3', 'b', 'c', 'b', 'a3'], # ignore dups
2336 BBB3 = ['b3', 'b', 'c', 'b3'],
2342 assert env['AAA1'] == 'a1a1', env['AAA1']
2343 assert env['AAA2'] == ['a2'], env['AAA2']
2344 assert env['AAA3'] == ['c', 'b', 'a3'], env['AAA3']
2345 assert env['AAA4'] == 'a4.newa4', env['AAA4']
2346 assert env['AAA5'] == ['a5.new', 'a5'], env['AAA5']
2347 assert env['BBB1'] == ['b1'], env['BBB1']
2348 assert env['BBB2'] == ['b2'], env['BBB2']
2349 assert env['BBB3'] == ['b', 'c', 'b3'], env['BBB3']
2350 assert env['BBB4'] == ['b4.new', 'b4'], env['BBB4']
2351 assert env['BBB5'] == ['b5.new', 'b5'], env['BBB5']
2352 assert env['CCC1'] == 'c1', env['CCC1']
2353 assert env['CCC2'] == ['c2'], env['CCC2']
2354 assert env['DDD1'] == ['a', 'b', 'c'], env['DDD1']
2356 env.PrependUnique(DDD1 = 'b', delete_existing=1)
2357 assert env['DDD1'] == ['b', 'a', 'c'], env['DDD1'] # b moves to front
2358 env.PrependUnique(DDD1 = ['a','c'], delete_existing=1)
2359 assert env['DDD1'] == ['a', 'c', 'b'], env['DDD1'] # a & c move to front
2360 env.PrependUnique(DDD1 = ['d','e','d'], delete_existing=1)
2361 assert env['DDD1'] == ['d', 'e', 'a', 'c', 'b'], env['DDD1']
2364 env['CLVar'] = CLVar([])
2365 env.PrependUnique(CLVar = 'bar')
2366 result = env['CLVar']
2367 if sys.version[0] == '1' or sys.version[:3] == '2.0':
2368 # Python 2.0 and before have a quirky behavior where CLVar([])
2369 # actually matches '' and [] due to different __coerce__()
2370 # semantics in the UserList implementation. It isn't worth a
2371 # lot of effort to get this corner case to work identically
2372 # (support for Python 1.5 support will die soon anyway),
2373 # so just treat it separately for now.
2374 assert result == 'bar', result
2376 assert isinstance(result, CLVar), repr(result)
2377 assert result == ['bar'], result
2379 env['CLVar'] = CLVar(['abc'])
2380 env.PrependUnique(CLVar = 'bar')
2381 result = env['CLVar']
2382 assert isinstance(result, CLVar), repr(result)
2383 assert result == ['bar', 'abc'], result
2385 env['CLVar'] = CLVar(['bar'])
2386 env.PrependUnique(CLVar = 'bar')
2387 result = env['CLVar']
2388 assert isinstance(result, CLVar), repr(result)
2389 assert result == ['bar'], result
2391 def test_Replace(self):
2392 """Test replacing construction variables in an Environment
2394 After creation of the Environment, of course.
2396 env1 = self.TestEnvironment(AAA = 'a', BBB = 'b')
2397 env1.Replace(BBB = 'bbb', CCC = 'ccc')
2399 env2 = self.TestEnvironment(AAA = 'a', BBB = 'bbb', CCC = 'ccc')
2400 assert env1 == env2, diff_env(env1, env2)
2402 env3 = self.TestEnvironment(BUILDERS = {'b1' : 1})
2403 assert hasattr(env3, 'b1'), "b1 was not set"
2404 env3.Replace(BUILDERS = {'b2' : 2})
2405 assert not hasattr(env3, 'b1'), "b1 was not cleared"
2406 assert hasattr(env3, 'b2'), "b2 was not set"
2408 def test_ReplaceIxes(self):
2409 "Test ReplaceIxes()"
2410 env = self.TestEnvironment(LIBPREFIX='lib',
2417 assert 'libfoo.a' == env.ReplaceIxes('libfoo.so',
2418 'SHLIBPREFIX', 'SHLIBSUFFIX',
2419 'LIBPREFIX', 'LIBSUFFIX')
2421 assert os.path.join('dir', 'libfoo.a') == env.ReplaceIxes(os.path.join('dir', 'libfoo.so'),
2422 'SHLIBPREFIX', 'SHLIBSUFFIX',
2423 'LIBPREFIX', 'LIBSUFFIX')
2425 assert 'libfoo.a' == env.ReplaceIxes('prefoopost',
2427 'LIBPREFIX', 'LIBSUFFIX')
2429 def test_SetDefault(self):
2430 """Test the SetDefault method"""
2431 env = self.TestEnvironment(tools = [])
2432 env.SetDefault(V1 = 1)
2433 env.SetDefault(V1 = 2)
2434 assert env['V1'] == 1
2436 env.SetDefault(V2 = 1)
2437 assert env['V2'] == 2
2439 def test_Tool(self):
2440 """Test the Tool() method"""
2441 env = self.TestEnvironment(LINK='link', NONE='no-such-tool')
2445 env.Tool('does_not_exist')
2446 except SCons.Errors.EnvironmentError:
2448 assert exc_caught, "did not catch expected EnvironmentError"
2453 except SCons.Errors.EnvironmentError:
2455 assert exc_caught, "did not catch expected EnvironmentError"
2457 # Use a non-existent toolpath directory just to make sure we
2458 # can call Tool() with the keyword argument.
2459 env.Tool('cc', toolpath=['/no/such/directory'])
2460 assert env['CC'] == 'cc', env['CC']
2463 assert env['LINK'] == '$SMARTLINK', env['LINK']
2465 # Test that the environment stores the toolpath and
2466 # re-uses it for later calls.
2467 test = TestCmd.TestCmd(workdir = '')
2469 test.write('xxx.py', """\
2476 test.write('yyy.py', """\
2483 env = self.TestEnvironment(tools=['xxx'], toolpath=[test.workpath('')])
2484 assert env['XXX'] == 'one', env['XXX']
2486 assert env['YYY'] == 'two', env['YYY']
2488 def test_WhereIs(self):
2489 """Test the WhereIs() method"""
2490 test = TestCmd.TestCmd(workdir = '')
2492 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
2493 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
2494 sub3_xxx_exe = test.workpath('sub3', 'xxx.exe')
2495 sub4_xxx_exe = test.workpath('sub4', 'xxx.exe')
2497 test.subdir('subdir', 'sub1', 'sub2', 'sub3', 'sub4')
2499 if sys.platform != 'win32':
2500 test.write(sub1_xxx_exe, "\n")
2502 os.mkdir(sub2_xxx_exe)
2504 test.write(sub3_xxx_exe, "\n")
2505 os.chmod(sub3_xxx_exe, 0777)
2507 test.write(sub4_xxx_exe, "\n")
2508 os.chmod(sub4_xxx_exe, 0777)
2510 env_path = os.environ['PATH']
2512 pathdirs_1234 = [ test.workpath('sub1'),
2513 test.workpath('sub2'),
2514 test.workpath('sub3'),
2515 test.workpath('sub4'),
2516 ] + string.split(env_path, os.pathsep)
2518 pathdirs_1243 = [ test.workpath('sub1'),
2519 test.workpath('sub2'),
2520 test.workpath('sub4'),
2521 test.workpath('sub3'),
2522 ] + string.split(env_path, os.pathsep)
2524 path = string.join(pathdirs_1234, os.pathsep)
2525 env = self.TestEnvironment(ENV = {'PATH' : path})
2526 wi = env.WhereIs('xxx.exe')
2527 assert wi == test.workpath(sub3_xxx_exe), wi
2528 wi = env.WhereIs('xxx.exe', pathdirs_1243)
2529 assert wi == test.workpath(sub4_xxx_exe), wi
2530 wi = env.WhereIs('xxx.exe', string.join(pathdirs_1243, os.pathsep))
2531 assert wi == test.workpath(sub4_xxx_exe), wi
2533 wi = env.WhereIs('xxx.exe', reject = sub3_xxx_exe)
2534 assert wi == test.workpath(sub4_xxx_exe), wi
2535 wi = env.WhereIs('xxx.exe', pathdirs_1243, reject = sub3_xxx_exe)
2536 assert wi == test.workpath(sub4_xxx_exe), wi
2538 path = string.join(pathdirs_1243, os.pathsep)
2539 env = self.TestEnvironment(ENV = {'PATH' : path})
2540 wi = env.WhereIs('xxx.exe')
2541 assert wi == test.workpath(sub4_xxx_exe), wi
2542 wi = env.WhereIs('xxx.exe', pathdirs_1234)
2543 assert wi == test.workpath(sub3_xxx_exe), wi
2544 wi = env.WhereIs('xxx.exe', string.join(pathdirs_1234, os.pathsep))
2545 assert wi == test.workpath(sub3_xxx_exe), wi
2547 if sys.platform == 'win32':
2548 wi = env.WhereIs('xxx', pathext = '')
2549 assert wi is None, wi
2551 wi = env.WhereIs('xxx', pathext = '.exe')
2552 assert wi == test.workpath(sub4_xxx_exe), wi
2554 wi = env.WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
2555 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
2557 # Test that we return a normalized path even when
2558 # the path contains forward slashes.
2559 forward_slash = test.workpath('') + '/sub3'
2560 wi = env.WhereIs('xxx', path = forward_slash, pathext = '.EXE')
2561 assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
2565 def test_Action(self):
2566 """Test the Action() method"""
2569 env = self.TestEnvironment(FOO = 'xyzzy')
2571 a = env.Action('foo')
2573 assert a.__class__ is SCons.Action.CommandAction, a.__class__
2575 a = env.Action('$FOO')
2577 assert a.__class__ is SCons.Action.CommandAction, a.__class__
2579 a = env.Action('$$FOO')
2581 assert a.__class__ is SCons.Action.LazyAction, a.__class__
2583 a = env.Action(['$FOO', 'foo'])
2585 assert a.__class__ is SCons.Action.ListAction, a.__class__
2589 a = env.Action(func)
2591 assert a.__class__ is SCons.Action.FunctionAction, a.__class__
2593 def test_AddPostAction(self):
2594 """Test the AddPostAction() method"""
2595 env = self.TestEnvironment(FOO='fff', BAR='bbb')
2597 n = env.AddPostAction('$FOO', lambda x: x)
2598 assert str(n[0]) == 'fff', n[0]
2600 n = env.AddPostAction(['ggg', '$BAR'], lambda x: x)
2601 assert str(n[0]) == 'ggg', n[0]
2602 assert str(n[1]) == 'bbb', n[1]
2604 def test_AddPreAction(self):
2605 """Test the AddPreAction() method"""
2606 env = self.TestEnvironment(FOO='fff', BAR='bbb')
2608 n = env.AddPreAction('$FOO', lambda x: x)
2609 assert str(n[0]) == 'fff', n[0]
2611 n = env.AddPreAction(['ggg', '$BAR'], lambda x: x)
2612 assert str(n[0]) == 'ggg', n[0]
2613 assert str(n[1]) == 'bbb', n[1]
2615 def test_Alias(self):
2616 """Test the Alias() method"""
2617 env = self.TestEnvironment(FOO='kkk', BAR='lll', EA='export_alias')
2619 tgt = env.Alias('new_alias')[0]
2620 assert str(tgt) == 'new_alias', tgt
2621 assert tgt.sources == [], tgt.sources
2622 assert not hasattr(tgt, 'builder'), tgt.builder
2624 tgt = env.Alias('None_alias', None)[0]
2625 assert str(tgt) == 'None_alias', tgt
2626 assert tgt.sources == [], tgt.sources
2628 tgt = env.Alias('empty_list', [])[0]
2629 assert str(tgt) == 'empty_list', tgt
2630 assert tgt.sources == [], tgt.sources
2632 tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ])[0]
2633 assert str(tgt) == 'export_alias', tgt
2634 assert len(tgt.sources) == 2, map(str, tgt.sources)
2635 assert str(tgt.sources[0]) == 'asrc1', map(str, tgt.sources)
2636 assert str(tgt.sources[1]) == 'kkk', map(str, tgt.sources)
2638 n = env.Alias(tgt, source = ['$BAR', 'asrc4'])[0]
2640 assert len(tgt.sources) == 4, map(str, tgt.sources)
2641 assert str(tgt.sources[2]) == 'lll', map(str, tgt.sources)
2642 assert str(tgt.sources[3]) == 'asrc4', map(str, tgt.sources)
2644 n = env.Alias('$EA', 'asrc5')[0]
2646 assert len(tgt.sources) == 5, map(str, tgt.sources)
2647 assert str(tgt.sources[4]) == 'asrc5', map(str, tgt.sources)
2649 t1, t2 = env.Alias(['t1', 't2'], ['asrc6', 'asrc7'])
2650 assert str(t1) == 't1', t1
2651 assert str(t2) == 't2', t2
2652 assert len(t1.sources) == 2, map(str, t1.sources)
2653 assert str(t1.sources[0]) == 'asrc6', map(str, t1.sources)
2654 assert str(t1.sources[1]) == 'asrc7', map(str, t1.sources)
2655 assert len(t2.sources) == 2, map(str, t2.sources)
2656 assert str(t2.sources[0]) == 'asrc6', map(str, t2.sources)
2657 assert str(t2.sources[1]) == 'asrc7', map(str, t2.sources)
2659 tgt = env.Alias('add', 's1')
2660 tgt = env.Alias('add', 's2')[0]
2661 s = map(str, tgt.sources)
2662 assert s == ['s1', 's2'], s
2663 tgt = env.Alias(tgt, 's3')[0]
2664 s = map(str, tgt.sources)
2665 assert s == ['s1', 's2', 's3'], s
2667 tgt = env.Alias('act', None, "action1")[0]
2668 s = str(tgt.builder.action)
2669 assert s == "action1", s
2670 tgt = env.Alias('act', None, "action2")[0]
2671 s = str(tgt.builder.action)
2672 assert s == "action1\naction2", s
2673 tgt = env.Alias(tgt, None, "action3")[0]
2674 s = str(tgt.builder.action)
2675 assert s == "action1\naction2\naction3", s
2677 def test_AlwaysBuild(self):
2678 """Test the AlwaysBuild() method"""
2679 env = self.TestEnvironment(FOO='fff', BAR='bbb')
2680 t = env.AlwaysBuild('a', 'b$FOO', ['c', 'd'], '$BAR',
2681 env.fs.Dir('dir'), env.fs.File('file'))
2682 assert t[0].__class__.__name__ == 'Entry'
2683 assert t[0].path == 'a'
2684 assert t[0].always_build
2685 assert t[1].__class__.__name__ == 'Entry'
2686 assert t[1].path == 'bfff'
2687 assert t[1].always_build
2688 assert t[2].__class__.__name__ == 'Entry'
2689 assert t[2].path == 'c'
2690 assert t[2].always_build
2691 assert t[3].__class__.__name__ == 'Entry'
2692 assert t[3].path == 'd'
2693 assert t[3].always_build
2694 assert t[4].__class__.__name__ == 'Entry'
2695 assert t[4].path == 'bbb'
2696 assert t[4].always_build
2697 assert t[5].__class__.__name__ == 'Dir'
2698 assert t[5].path == 'dir'
2699 assert t[5].always_build
2700 assert t[6].__class__.__name__ == 'File'
2701 assert t[6].path == 'file'
2702 assert t[6].always_build
2704 def test_VariantDir(self):
2705 """Test the VariantDir() method"""
2707 def Dir(self, name):
2709 def VariantDir(self, variant_dir, src_dir, duplicate):
2710 self.variant_dir = variant_dir
2711 self.src_dir = src_dir
2712 self.duplicate = duplicate
2714 env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb')
2717 env.VariantDir('build', 'src')
2718 assert env.fs.variant_dir == 'build', env.fs.variant_dir
2719 assert env.fs.src_dir == 'src', env.fs.src_dir
2720 assert env.fs.duplicate == 1, env.fs.duplicate
2722 env.VariantDir('build${FOO}', '${BAR}src', 0)
2723 assert env.fs.variant_dir == 'buildfff', env.fs.variant_dir
2724 assert env.fs.src_dir == 'bbbsrc', env.fs.src_dir
2725 assert env.fs.duplicate == 0, env.fs.duplicate
2727 def test_Builder(self):
2728 """Test the Builder() method"""
2729 env = self.TestEnvironment(FOO = 'xyzzy')
2731 b = env.Builder(action = 'foo')
2732 assert b is not None, b
2734 b = env.Builder(action = '$FOO')
2735 assert b is not None, b
2737 b = env.Builder(action = ['$FOO', 'foo'])
2738 assert b is not None, b
2742 b = env.Builder(action = func)
2743 assert b is not None, b
2744 b = env.Builder(generator = func)
2745 assert b is not None, b
2747 def test_CacheDir(self):
2748 """Test the CacheDir() method"""
2749 env = self.TestEnvironment(CD = 'CacheDir')
2752 assert env._CacheDir_path == 'foo', env._CacheDir_path
2755 assert env._CacheDir_path == 'CacheDir', env._CacheDir_path
2757 def test_Clean(self):
2758 """Test the Clean() method"""
2759 env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb')
2761 CT = SCons.Environment.CleanTargets
2763 foo = env.arg2nodes('foo')[0]
2764 fff = env.arg2nodes('fff')[0]
2766 t = env.Clean('foo', 'aaa')
2767 l = map(str, CT[foo])
2768 assert l == ['aaa'], l
2770 t = env.Clean(foo, ['$BAR', 'ccc'])
2771 l = map(str, CT[foo])
2772 assert l == ['aaa', 'bbb', 'ccc'], l
2774 eee = env.arg2nodes('eee')[0]
2776 t = env.Clean('$FOO', 'ddd')
2777 l = map(str, CT[fff])
2778 assert l == ['ddd'], l
2779 t = env.Clean(fff, [eee, 'fff'])
2780 l = map(str, CT[fff])
2781 assert l == ['ddd', 'eee', 'fff'], l
2783 def test_Command(self):
2784 """Test the Command() method."""
2786 t = env.Command(target='foo.out', source=['foo1.in', 'foo2.in'],
2787 action='buildfoo $target $source')[0]
2788 assert t.builder is not None
2789 assert t.builder.action.__class__.__name__ == 'CommandAction'
2790 assert t.builder.action.cmd_list == 'buildfoo $target $source'
2791 assert 'foo1.in' in map(lambda x: x.path, t.sources)
2792 assert 'foo2.in' in map(lambda x: x.path, t.sources)
2794 sub = env.fs.Dir('sub')
2795 t = env.Command(target='bar.out', source='sub',
2796 action='buildbar $target $source')[0]
2797 assert 'sub' in map(lambda x: x.path, t.sources)
2799 def testFunc(env, target, source):
2800 assert str(target[0]) == 'foo.out'
2801 assert 'foo1.in' in map(str, source) and 'foo2.in' in map(str, source), map(str, source)
2803 t = env.Command(target='foo.out', source=['foo1.in','foo2.in'],
2805 assert t.builder is not None
2806 assert t.builder.action.__class__.__name__ == 'FunctionAction'
2808 assert 'foo1.in' in map(lambda x: x.path, t.sources)
2809 assert 'foo2.in' in map(lambda x: x.path, t.sources)
2812 def test2(baz, x=x):
2814 env = self.TestEnvironment(TEST2 = test2)
2815 t = env.Command(target='baz.out', source='baz.in',
2816 action='${TEST2(XYZ)}',
2817 XYZ='magic word')[0]
2818 assert t.builder is not None
2820 assert x[0] == 'magic word', x
2822 t = env.Command(target='${X}.out', source='${X}.in',
2825 assert str(t) == 'xxx.out', str(t)
2826 assert 'xxx.in' in map(lambda x: x.path, t.sources)
2828 env = self.TestEnvironment(source_scanner = 'should_not_find_this')
2829 t = env.Command(target='file.out', source='file.in',
2831 source_scanner = 'fake')[0]
2832 assert t.builder.source_scanner == 'fake', t.builder.source_scanner
2834 def test_Configure(self):
2835 """Test the Configure() method"""
2836 # Configure() will write to a local temporary file.
2837 test = TestCmd.TestCmd(workdir = '')
2841 os.chdir(test.workpath())
2843 env = self.TestEnvironment(FOO = 'xyzzy')
2849 assert c is not None, c
2852 c = env.Configure(custom_tests = {'foo' : func, '$FOO' : func})
2853 assert c is not None, c
2854 assert hasattr(c, 'foo')
2855 assert hasattr(c, 'xyzzy')
2860 def test_Depends(self):
2861 """Test the explicit Depends method."""
2862 env = self.TestEnvironment(FOO = 'xxx', BAR='yyy')
2867 t = env.Depends(target='EnvironmentTest.py',
2868 dependency='Environment.py')[0]
2869 assert t.__class__.__name__ == 'Entry', t.__class__.__name__
2870 assert t.path == 'EnvironmentTest.py'
2871 assert len(t.depends) == 1
2873 assert d.__class__.__name__ == 'Entry', d.__class__.__name__
2874 assert d.path == 'Environment.py'
2876 t = env.Depends(target='${FOO}.py', dependency='${BAR}.py')[0]
2877 assert t.__class__.__name__ == 'File', t.__class__.__name__
2878 assert t.path == 'xxx.py'
2879 assert len(t.depends) == 1
2881 assert d.__class__.__name__ == 'File', d.__class__.__name__
2882 assert d.path == 'yyy.py'
2884 t = env.Depends(target='dir1', dependency='dir2')[0]
2885 assert t.__class__.__name__ == 'Dir', t.__class__.__name__
2886 assert t.path == 'dir1'
2887 assert len(t.depends) == 1
2889 assert d.__class__.__name__ == 'Dir', d.__class__.__name__
2890 assert d.path == 'dir2'
2893 """Test the Dir() method"""
2895 def Dir(self, name):
2896 return 'Dir(%s)' % name
2898 env = self.TestEnvironment(FOO = 'foodir', BAR = 'bardir')
2902 assert d == 'Dir(d)', d
2905 assert d == 'Dir(foodir)', d
2907 d = env.Dir('${BAR}_$BAR')
2908 assert d == 'Dir(bardir_bardir)', d
2910 d = env.Dir(['dir1'])
2911 assert d == ['Dir(dir1)'], d
2913 d = env.Dir(['dir1', 'dir2'])
2914 assert d == ['Dir(dir1)', 'Dir(dir2)'], d
2916 def test_NoClean(self):
2917 """Test the NoClean() method"""
2918 env = self.TestEnvironment(FOO='ggg', BAR='hhh')
2921 t = env.NoClean('p_a', 'p_${BAR}b', ['p_c', 'p_d'], 'p_$FOO')
2923 assert t[0].__class__.__name__ == 'Entry', t[0].__class__.__name__
2924 assert t[0].path == 'p_a'
2926 assert t[1].__class__.__name__ == 'Dir', t[1].__class__.__name__
2927 assert t[1].path == 'p_hhhb'
2929 assert t[2].__class__.__name__ == 'Entry', t[2].__class__.__name__
2930 assert t[2].path == 'p_c'
2932 assert t[3].__class__.__name__ == 'File', t[3].__class__.__name__
2933 assert t[3].path == 'p_d'
2935 assert t[4].__class__.__name__ == 'Entry', t[4].__class__.__name__
2936 assert t[4].path == 'p_ggg'
2939 def test_Dump(self):
2940 """Test the Dump() method"""
2942 env = self.TestEnvironment(FOO = 'foo')
2943 assert env.Dump('FOO') == "'foo'", env.Dump('FOO')
2944 assert len(env.Dump()) > 200, env.Dump() # no args version
2946 def test_Environment(self):
2947 """Test the Environment() method"""
2948 env = self.TestEnvironment(FOO = 'xxx', BAR = 'yyy')
2950 e2 = env.Environment(X = '$FOO', Y = '$BAR')
2951 assert e2['X'] == 'xxx', e2['X']
2952 assert e2['Y'] == 'yyy', e2['Y']
2954 def test_Execute(self):
2955 """Test the Execute() method"""
2958 def __init__(self, *args, **kw):
2960 def __call__(self, target, source, env):
2961 return "%s executed" % self.args
2964 env.Action = MyAction
2966 result = env.Execute("foo")
2967 assert result == "foo executed", result
2969 def test_Entry(self):
2970 """Test the Entry() method"""
2972 def Entry(self, name):
2973 return 'Entry(%s)' % name
2975 env = self.TestEnvironment(FOO = 'fooentry', BAR = 'barentry')
2979 assert e == 'Entry(e)', e
2981 e = env.Entry('$FOO')
2982 assert e == 'Entry(fooentry)', e
2984 e = env.Entry('${BAR}_$BAR')
2985 assert e == 'Entry(barentry_barentry)', e
2987 e = env.Entry(['entry1'])
2988 assert e == ['Entry(entry1)'], e
2990 e = env.Entry(['entry1', 'entry2'])
2991 assert e == ['Entry(entry1)', 'Entry(entry2)'], e
2993 def test_File(self):
2994 """Test the File() method"""
2996 def File(self, name):
2997 return 'File(%s)' % name
2999 env = self.TestEnvironment(FOO = 'foofile', BAR = 'barfile')
3003 assert f == 'File(f)', f
3005 f = env.File('$FOO')
3006 assert f == 'File(foofile)', f
3008 f = env.File('${BAR}_$BAR')
3009 assert f == 'File(barfile_barfile)', f
3011 f = env.File(['file1'])
3012 assert f == ['File(file1)'], f
3014 f = env.File(['file1', 'file2'])
3015 assert f == ['File(file1)', 'File(file2)'], f
3017 def test_FindFile(self):
3018 """Test the FindFile() method"""
3019 env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb')
3021 r = env.FindFile('foo', ['no_such_directory'])
3026 def test_Flatten(self):
3027 """Test the Flatten() method"""
3029 l = env.Flatten([1])
3031 l = env.Flatten([1, [2, [3, [4]]]])
3032 assert l == [1, 2, 3, 4], l
3034 def test_GetBuildPath(self):
3035 """Test the GetBuildPath() method."""
3036 env = self.TestEnvironment(MAGIC = 'xyzzy')
3038 p = env.GetBuildPath('foo')
3039 assert p == 'foo', p
3041 p = env.GetBuildPath('$MAGIC')
3042 assert p == 'xyzzy', p
3044 def test_Ignore(self):
3045 """Test the explicit Ignore method."""
3046 env = self.TestEnvironment(FOO='yyy', BAR='zzz')
3052 t = env.Ignore(target='targ.py', dependency='dep.py')[0]
3053 assert t.__class__.__name__ == 'Entry', t.__class__.__name__
3054 assert t.path == 'targ.py'
3055 assert len(t.ignore) == 1
3057 assert i.__class__.__name__ == 'Entry', i.__class__.__name__
3058 assert i.path == 'dep.py'
3060 t = env.Ignore(target='$FOO$BAR', dependency='$BAR$FOO')[0]
3061 assert t.__class__.__name__ == 'File', t.__class__.__name__
3062 assert t.path == 'yyyzzz'
3063 assert len(t.ignore) == 1
3065 assert i.__class__.__name__ == 'File', i.__class__.__name__
3066 assert i.path == 'zzzyyy'
3068 t = env.Ignore(target='dir1', dependency='dir2')[0]
3069 assert t.__class__.__name__ == 'Dir', t.__class__.__name__
3070 assert t.path == 'dir1'
3071 assert len(t.ignore) == 1
3073 assert i.__class__.__name__ == 'Dir', i.__class__.__name__
3074 assert i.path == 'dir2'
3076 def test_Literal(self):
3077 """Test the Literal() method"""
3078 env = self.TestEnvironment(FOO='fff', BAR='bbb')
3079 list = env.subst_list([env.Literal('$FOO'), '$BAR'])[0]
3080 assert list == ['$FOO', 'bbb'], list
3081 list = env.subst_list(['$FOO', env.Literal('$BAR')])[0]
3082 assert list == ['fff', '$BAR'], list
3084 def test_Local(self):
3085 """Test the Local() method."""
3086 env = self.TestEnvironment(FOO='lll')
3088 l = env.Local(env.fs.File('fff'))
3089 assert str(l[0]) == 'fff', l[0]
3091 l = env.Local('ggg', '$FOO')
3092 assert str(l[0]) == 'ggg', l[0]
3093 assert str(l[1]) == 'lll', l[1]
3095 def test_Precious(self):
3096 """Test the Precious() method"""
3097 env = self.TestEnvironment(FOO='ggg', BAR='hhh')
3100 t = env.Precious('p_a', 'p_${BAR}b', ['p_c', 'p_d'], 'p_$FOO')
3102 assert t[0].__class__.__name__ == 'Entry', t[0].__class__.__name__
3103 assert t[0].path == 'p_a'
3104 assert t[0].precious
3105 assert t[1].__class__.__name__ == 'Dir', t[1].__class__.__name__
3106 assert t[1].path == 'p_hhhb'
3107 assert t[1].precious
3108 assert t[2].__class__.__name__ == 'Entry', t[2].__class__.__name__
3109 assert t[2].path == 'p_c'
3110 assert t[2].precious
3111 assert t[3].__class__.__name__ == 'File', t[3].__class__.__name__
3112 assert t[3].path == 'p_d'
3113 assert t[3].precious
3114 assert t[4].__class__.__name__ == 'Entry', t[4].__class__.__name__
3115 assert t[4].path == 'p_ggg'
3116 assert t[4].precious
3118 def test_Repository(self):
3119 """Test the Repository() method."""
3123 def Repository(self, *dirs):
3124 self.list.extend(list(dirs))
3125 def Dir(self, name):
3127 env = self.TestEnvironment(FOO='rrr', BAR='sss')
3129 env.Repository('/tmp/foo')
3130 env.Repository('/tmp/$FOO', '/tmp/$BAR/foo')
3131 expect = ['/tmp/foo', '/tmp/rrr', '/tmp/sss/foo']
3132 assert env.fs.list == expect, env.fs.list
3134 def test_Scanner(self):
3135 """Test the Scanner() method"""
3136 def scan(node, env, target, arg):
3139 env = self.TestEnvironment(FOO = scan)
3141 s = env.Scanner('foo')
3142 assert s is not None, s
3144 s = env.Scanner(function = 'foo')
3145 assert s is not None, s
3148 s = env.Scanner('$FOO')
3149 assert s is not None, s
3151 s = env.Scanner(function = '$FOO')
3152 assert s is not None, s
3154 def test_SConsignFile(self):
3155 """Test the SConsignFile() method"""
3156 import SCons.SConsign
3159 SConstruct_dir = os.sep + 'dir'
3161 env = self.TestEnvironment(FOO = 'SConsign',
3162 BAR = os.path.join(os.sep, 'File'))
3164 env.Execute = lambda action: None
3169 def capture(name, dbm_module, fnames=fnames, dbms=dbms):
3171 dbms.append(dbm_module)
3173 save_SConsign_File = SCons.SConsign.File
3174 SCons.SConsign.File = capture
3176 env.SConsignFile('foo')
3177 assert fnames[-1] == os.path.join(os.sep, 'dir', 'foo'), fnames
3178 assert dbms[-1] is None, dbms
3180 env.SConsignFile('$FOO')
3181 assert fnames[-1] == os.path.join(os.sep, 'dir', 'SConsign'), fnames
3182 assert dbms[-1] is None, dbms
3184 env.SConsignFile('/$FOO')
3185 assert fnames[-1] == os.sep + 'SConsign', fnames
3186 assert dbms[-1] is None, dbms
3188 env.SConsignFile(os.sep + '$FOO')
3189 assert fnames[-1] == os.sep + 'SConsign', fnames
3190 assert dbms[-1] is None, dbms
3192 env.SConsignFile('$BAR', 'x')
3193 assert fnames[-1] == os.path.join(os.sep, 'File'), fnames
3194 assert dbms[-1] == 'x', dbms
3196 env.SConsignFile('__$BAR', 7)
3197 assert fnames[-1] == os.path.join(os.sep, 'dir', '__', 'File'), fnames
3198 assert dbms[-1] == 7, dbms
3201 assert fnames[-1] == os.path.join(os.sep, 'dir', '.sconsign'), fnames
3202 assert dbms[-1] is None, dbms
3204 env.SConsignFile(None)
3205 assert fnames[-1] is None, fnames
3206 assert dbms[-1] is None, dbms
3208 SCons.SConsign.File = save_SConsign_File
3210 def test_SideEffect(self):
3211 """Test the SideEffect() method"""
3212 env = self.TestEnvironment(LIB='lll', FOO='fff', BAR='bbb')
3213 env.File('mylll.pdb')
3214 env.Dir('mymmm.pdb')
3216 foo = env.Object('foo.obj', 'foo.cpp')[0]
3217 bar = env.Object('bar.obj', 'bar.cpp')[0]
3218 s = env.SideEffect('mylib.pdb', ['foo.obj', 'bar.obj'])[0]
3219 assert s.__class__.__name__ == 'Entry', s.__class__.__name__
3220 assert s.path == 'mylib.pdb'
3221 assert s.side_effect
3222 assert foo.side_effects == [s]
3223 assert bar.side_effects == [s]
3225 fff = env.Object('fff.obj', 'fff.cpp')[0]
3226 bbb = env.Object('bbb.obj', 'bbb.cpp')[0]
3227 s = env.SideEffect('my${LIB}.pdb', ['${FOO}.obj', '${BAR}.obj'])[0]
3228 assert s.__class__.__name__ == 'File', s.__class__.__name__
3229 assert s.path == 'mylll.pdb'
3230 assert s.side_effect
3231 assert fff.side_effects == [s], fff.side_effects
3232 assert bbb.side_effects == [s], bbb.side_effects
3234 ggg = env.Object('ggg.obj', 'ggg.cpp')[0]
3235 ccc = env.Object('ccc.obj', 'ccc.cpp')[0]
3236 s = env.SideEffect('mymmm.pdb', ['ggg.obj', 'ccc.obj'])[0]
3237 assert s.__class__.__name__ == 'Dir', s.__class__.__name__
3238 assert s.path == 'mymmm.pdb'
3239 assert s.side_effect
3240 assert ggg.side_effects == [s], ggg.side_effects
3241 assert ccc.side_effects == [s], ccc.side_effects
3243 def test_SourceCode(self):
3244 """Test the SourceCode() method."""
3245 env = self.TestEnvironment(FOO='mmm', BAR='nnn')
3246 e = env.SourceCode('foo', None)[0]
3247 assert e.path == 'foo'
3252 e = env.SourceCode(e, b)[0]
3253 assert e.path == 'foo'
3257 e = env.SourceCode('$BAR$FOO', None)[0]
3258 assert e.path == 'nnnmmm'
3262 def test_SourceSignatures(type):
3263 """Test the SourceSignatures() method"""
3266 env = type.TestEnvironment(M = 'MD5', T = 'timestamp')
3270 env.SourceSignatures('invalid_type')
3271 except SCons.Errors.UserError:
3273 assert exc_caught, "did not catch expected UserError"
3275 env.SourceSignatures('MD5')
3276 assert env.src_sig_type == 'MD5', env.src_sig_type
3278 env.SourceSignatures('$M')
3279 assert env.src_sig_type == 'MD5', env.src_sig_type
3281 env.SourceSignatures('timestamp')
3282 assert env.src_sig_type == 'timestamp', env.src_sig_type
3284 env.SourceSignatures('$T')
3285 assert env.src_sig_type == 'timestamp', env.src_sig_type
3289 save_md5 = SCons.Util.md5
3290 SCons.Util.md5 = None
3292 env.SourceSignatures('MD5')
3293 except SCons.Errors.UserError:
3296 self.fail('Did not catch expected UserError')
3298 SCons.Util.md5 = save_md5
3300 def test_Split(self):
3301 """Test the Split() method"""
3302 env = self.TestEnvironment(FOO='fff', BAR='bbb')
3303 s = env.Split("foo bar")
3304 assert s == ["foo", "bar"], s
3305 s = env.Split("$FOO bar")
3306 assert s == ["fff", "bar"], s
3307 s = env.Split(["foo", "bar"])
3308 assert s == ["foo", "bar"], s
3309 s = env.Split(["foo", "${BAR}-bbb"])
3310 assert s == ["foo", "bbb-bbb"], s
3311 s = env.Split("foo")
3312 assert s == ["foo"], s
3313 s = env.Split("$FOO$BAR")
3314 assert s == ["fffbbb"], s
3316 def test_TargetSignatures(type):
3317 """Test the TargetSignatures() method"""
3320 env = type.TestEnvironment(B = 'build', C = 'content')
3324 env.TargetSignatures('invalid_type')
3325 except SCons.Errors.UserError:
3327 assert exc_caught, "did not catch expected UserError"
3328 assert not hasattr(env, '_build_signature')
3330 env.TargetSignatures('build')
3331 assert env.tgt_sig_type == 'build', env.tgt_sig_type
3333 env.TargetSignatures('$B')
3334 assert env.tgt_sig_type == 'build', env.tgt_sig_type
3336 env.TargetSignatures('content')
3337 assert env.tgt_sig_type == 'content', env.tgt_sig_type
3339 env.TargetSignatures('$C')
3340 assert env.tgt_sig_type == 'content', env.tgt_sig_type
3342 env.TargetSignatures('MD5')
3343 assert env.tgt_sig_type == 'MD5', env.tgt_sig_type
3345 env.TargetSignatures('timestamp')
3346 assert env.tgt_sig_type == 'timestamp', env.tgt_sig_type
3350 save_md5 = SCons.Util.md5
3351 SCons.Util.md5 = None
3353 env.TargetSignatures('MD5')
3354 except SCons.Errors.UserError:
3357 self.fail('Did not catch expected UserError')
3359 env.TargetSignatures('content')
3360 except SCons.Errors.UserError:
3363 self.fail('Did not catch expected UserError')
3365 SCons.Util.md5 = save_md5
3367 def test_Value(self):
3368 """Test creating a Value() object
3372 assert v1.value == 'a', v1.value
3375 v2 = env.Value(value2)
3376 assert v2.value == value2, v2.value
3377 assert v2.value is value2, v2.value
3380 assert v1.value == v2.value
3382 v3 = env.Value('c', 'build-c')
3383 assert v3.value == 'c', v3.value
3387 def test_Environment_global_variable(type):
3388 """Test setting Environment variable to an Environment.Base subclass"""
3389 class MyEnv(SCons.Environment.Base):
3390 def xxx(self, string):
3391 return self.subst(string)
3393 SCons.Environment.Environment = MyEnv
3395 env = SCons.Environment.Environment(FOO = 'foo')
3397 f = env.subst('$FOO')
3398 assert f == 'foo', f
3401 assert f == 'foo', f
3403 def test_bad_keywords(self):
3404 """Test trying to use reserved keywords in an Environment"""
3407 env = self.TestEnvironment(TARGETS = 'targets',
3408 SOURCES = 'sources',
3411 CHANGED_SOURCES = 'changed_sources',
3412 CHANGED_TARGETS = 'changed_targets',
3413 UNCHANGED_SOURCES = 'unchanged_sources',
3414 UNCHANGED_TARGETS = 'unchanged_targets',
3416 bad_msg = '%s is not reserved, but got omitted; see Environment.construction_var_name_ok'
3417 added.append('INIT')
3418 for x in self.reserved_variables:
3419 assert not env.has_key(x), env[x]
3421 assert env.has_key(x), bad_msg % x
3423 env.Append(TARGETS = 'targets',
3424 SOURCES = 'sources',
3427 CHANGED_SOURCES = 'changed_sources',
3428 CHANGED_TARGETS = 'changed_targets',
3429 UNCHANGED_SOURCES = 'unchanged_sources',
3430 UNCHANGED_TARGETS = 'unchanged_targets',
3432 added.append('APPEND')
3433 for x in self.reserved_variables:
3434 assert not env.has_key(x), env[x]
3436 assert env.has_key(x), bad_msg % x
3438 env.AppendUnique(TARGETS = 'targets',
3439 SOURCES = 'sources',
3442 CHANGED_SOURCES = 'changed_sources',
3443 CHANGED_TARGETS = 'changed_targets',
3444 UNCHANGED_SOURCES = 'unchanged_sources',
3445 UNCHANGED_TARGETS = 'unchanged_targets',
3446 APPENDUNIQUE = 'appendunique')
3447 added.append('APPENDUNIQUE')
3448 for x in self.reserved_variables:
3449 assert not env.has_key(x), env[x]
3451 assert env.has_key(x), bad_msg % x
3453 env.Prepend(TARGETS = 'targets',
3454 SOURCES = 'sources',
3457 CHANGED_SOURCES = 'changed_sources',
3458 CHANGED_TARGETS = 'changed_targets',
3459 UNCHANGED_SOURCES = 'unchanged_sources',
3460 UNCHANGED_TARGETS = 'unchanged_targets',
3461 PREPEND = 'prepend')
3462 added.append('PREPEND')
3463 for x in self.reserved_variables:
3464 assert not env.has_key(x), env[x]
3466 assert env.has_key(x), bad_msg % x
3468 env.Prepend(TARGETS = 'targets',
3469 SOURCES = 'sources',
3472 CHANGED_SOURCES = 'changed_sources',
3473 CHANGED_TARGETS = 'changed_targets',
3474 UNCHANGED_SOURCES = 'unchanged_sources',
3475 UNCHANGED_TARGETS = 'unchanged_targets',
3476 PREPENDUNIQUE = 'prependunique')
3477 added.append('PREPENDUNIQUE')
3478 for x in self.reserved_variables:
3479 assert not env.has_key(x), env[x]
3481 assert env.has_key(x), bad_msg % x
3483 env.Replace(TARGETS = 'targets',
3484 SOURCES = 'sources',
3487 CHANGED_SOURCES = 'changed_sources',
3488 CHANGED_TARGETS = 'changed_targets',
3489 UNCHANGED_SOURCES = 'unchanged_sources',
3490 UNCHANGED_TARGETS = 'unchanged_targets',
3491 REPLACE = 'replace')
3492 added.append('REPLACE')
3493 for x in self.reserved_variables:
3494 assert not env.has_key(x), env[x]
3496 assert env.has_key(x), bad_msg % x
3498 copy = env.Clone(TARGETS = 'targets',
3499 SOURCES = 'sources',
3502 CHANGED_SOURCES = 'changed_sources',
3503 CHANGED_TARGETS = 'changed_targets',
3504 UNCHANGED_SOURCES = 'unchanged_sources',
3505 UNCHANGED_TARGETS = 'unchanged_targets',
3507 for x in self.reserved_variables:
3508 assert not copy.has_key(x), env[x]
3509 for x in added + ['COPY']:
3510 assert copy.has_key(x), bad_msg % x
3512 over = env.Override({'TARGETS' : 'targets',
3513 'SOURCES' : 'sources',
3514 'SOURCE' : 'source',
3515 'TARGET' : 'target',
3516 'CHANGED_SOURCES' : 'changed_sources',
3517 'CHANGED_TARGETS' : 'changed_targets',
3518 'UNCHANGED_SOURCES' : 'unchanged_sources',
3519 'UNCHANGED_TARGETS' : 'unchanged_targets',
3520 'OVERRIDE' : 'override'})
3521 for x in self.reserved_variables:
3522 assert not over.has_key(x), over[x]
3523 for x in added + ['OVERRIDE']:
3524 assert over.has_key(x), bad_msg % x
3526 def test_parse_flags(self):
3527 '''Test the Base class parse_flags argument'''
3528 # all we have to show is that it gets to MergeFlags internally
3529 env = Environment(tools=[], parse_flags = '-X')
3530 assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
3532 env = Environment(tools=[], CCFLAGS=None, parse_flags = '-Y')
3533 assert env['CCFLAGS'] == ['-Y'], env['CCFLAGS']
3535 env = Environment(tools=[], CPPDEFINES = 'FOO', parse_flags = '-std=c99 -X -DBAR')
3536 assert env['CFLAGS'] == ['-std=c99'], env['CFLAGS']
3537 assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
3538 assert env['CPPDEFINES'] == ['FOO', 'BAR'], env['CPPDEFINES']
3540 def test_clone_parse_flags(self):
3541 '''Test the env.Clone() parse_flags argument'''
3542 # all we have to show is that it gets to MergeFlags internally
3543 env = Environment(tools = [])
3544 env2 = env.Clone(parse_flags = '-X')
3545 assert not env.has_key('CCFLAGS')
3546 assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
3548 env = Environment(tools = [], CCFLAGS=None)
3549 env2 = env.Clone(parse_flags = '-Y')
3550 assert env['CCFLAGS'] is None, env['CCFLAGS']
3551 assert env2['CCFLAGS'] == ['-Y'], env2['CCFLAGS']
3553 env = Environment(tools = [], CPPDEFINES = 'FOO')
3554 env2 = env.Clone(parse_flags = '-std=c99 -X -DBAR')
3555 assert not env.has_key('CFLAGS')
3556 assert env2['CFLAGS'] == ['-std=c99'], env2['CFLAGS']
3557 assert not env.has_key('CCFLAGS')
3558 assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
3559 assert env['CPPDEFINES'] == 'FOO', env['CPPDEFINES']
3560 assert env2['CPPDEFINES'] == ['FOO','BAR'], env2['CPPDEFINES']
3564 class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture):
3568 env._dict = {'XXX' : 'x', 'YYY' : 'y'}
3569 env2 = OverrideEnvironment(env, {'XXX' : 'x2'})
3570 env3 = OverrideEnvironment(env2, {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'})
3571 self.envs = [ env, env2, env3 ]
3573 def checkpath(self, node, expect):
3574 return str(node) == os.path.normpath(expect)
3576 def test___init__(self):
3577 """Test OverrideEnvironment initialization"""
3578 env, env2, env3 = self.envs
3579 assert env['XXX'] == 'x', env['XXX']
3580 assert env2['XXX'] == 'x2', env2['XXX']
3581 assert env3['XXX'] == 'x3', env3['XXX']
3582 assert env['YYY'] == 'y', env['YYY']
3583 assert env2['YYY'] == 'y', env2['YYY']
3584 assert env3['YYY'] == 'y3', env3['YYY']
3586 def test___delitem__(self):
3587 """Test deleting variables from an OverrideEnvironment"""
3588 env, env2, env3 = self.envs
3591 assert not env.has_key('XXX'), "env has XXX?"
3592 assert not env2.has_key('XXX'), "env2 has XXX?"
3593 assert not env3.has_key('XXX'), "env3 has XXX?"
3596 assert not env.has_key('YYY'), "env has YYY?"
3597 assert not env2.has_key('YYY'), "env2 has YYY?"
3598 assert not env3.has_key('YYY'), "env3 has YYY?"
3601 assert not env.has_key('ZZZ'), "env has ZZZ?"
3602 assert not env2.has_key('ZZZ'), "env2 has ZZZ?"
3603 assert not env3.has_key('ZZZ'), "env3 has ZZZ?"
3606 """Test the OverrideEnvironment get() method"""
3607 env, env2, env3 = self.envs
3608 assert env.get('XXX') == 'x', env.get('XXX')
3609 assert env2.get('XXX') == 'x2', env2.get('XXX')
3610 assert env3.get('XXX') == 'x3', env3.get('XXX')
3611 assert env.get('YYY') == 'y', env.get('YYY')
3612 assert env2.get('YYY') == 'y', env2.get('YYY')
3613 assert env3.get('YYY') == 'y3', env3.get('YYY')
3614 assert env.get('ZZZ') is None, env.get('ZZZ')
3615 assert env2.get('ZZZ') is None, env2.get('ZZZ')
3616 assert env3.get('ZZZ') == 'z3', env3.get('ZZZ')
3618 def test_has_key(self):
3619 """Test the OverrideEnvironment has_key() method"""
3620 env, env2, env3 = self.envs
3621 assert env.has_key('XXX'), env.has_key('XXX')
3622 assert env2.has_key('XXX'), env2.has_key('XXX')
3623 assert env3.has_key('XXX'), env3.has_key('XXX')
3624 assert env.has_key('YYY'), env.has_key('YYY')
3625 assert env2.has_key('YYY'), env2.has_key('YYY')
3626 assert env3.has_key('YYY'), env3.has_key('YYY')
3627 assert not env.has_key('ZZZ'), env.has_key('ZZZ')
3628 assert not env2.has_key('ZZZ'), env2.has_key('ZZZ')
3629 assert env3.has_key('ZZZ'), env3.has_key('ZZZ')
3631 def test_contains(self):
3632 """Test the OverrideEnvironment __contains__() method"""
3637 # An early version of Python that doesn't support "in"
3638 # on dictionaries. Just pass the test.
3641 env, env2, env3 = self.envs
3643 assert 'XXX' in env2
3644 assert 'XXX' in env3
3646 assert 'YYY' in env2
3647 assert 'YYY' in env3
3648 assert not 'ZZZ' in env
3649 assert not 'ZZZ' in env2
3650 assert 'ZZZ' in env3
3652 def test_items(self):
3653 """Test the OverrideEnvironment Dictionary() method"""
3654 env, env2, env3 = self.envs
3655 items = env.Dictionary()
3656 assert items == {'XXX' : 'x', 'YYY' : 'y'}, items
3657 items = env2.Dictionary()
3658 assert items == {'XXX' : 'x2', 'YYY' : 'y'}, items
3659 items = env3.Dictionary()
3660 assert items == {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}, items
3662 def test_items(self):
3663 """Test the OverrideEnvironment items() method"""
3664 env, env2, env3 = self.envs
3667 assert items == [('XXX', 'x'), ('YYY', 'y')], items
3668 items = env2.items()
3670 assert items == [('XXX', 'x2'), ('YYY', 'y')], items
3671 items = 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 not env.has_key('CCFLAGS')
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 not env.has_key('CFLAGS')
3827 assert env2['CFLAGS'] == ['-std=c99'], env2['CFLAGS']
3828 assert not env.has_key('CCFLAGS')
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 = apply(env.subst_target_source, args, kw)
3931 assert x == 'x ttt sss y', x
3932 x = apply(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(map(tclass, names))
3980 if not unittest.TextTestRunner().run(suite).wasSuccessful():
3985 # indent-tabs-mode:nil
3987 # vim: set expandtab tabstop=4 shiftwidth=4: