4 # Permission is hereby granted, free of charge, to any person obtaining
5 # a copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including
7 # without limitation the rights to use, copy, modify, merge, publish,
8 # distribute, sublicense, and/or sell copies of the Software, and to
9 # permit persons to whom the Software is furnished to do so, subject to
10 # the following conditions:
12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
16 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
17 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
36 from SCons.Environment import *
39 def diff_env(env1, env2):
43 for k in env1._dict.keys() + env2._dict.keys():
45 for k in sorted(d.keys()):
48 if env1[k] != env2[k]:
49 s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n"
50 s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n"
52 s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n"
54 s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n"
59 def diff_dict(d1, d2):
63 for k in d1.keys() + d2.keys():
65 for k in sorted(d.keys()):
69 s1 = s1 + " " + repr(k) + " : " + repr(d1[k]) + "\n"
70 s2 = s2 + " " + repr(k) + " : " + repr(d2[k]) + "\n"
72 s1 = s1 + " " + repr(k) + " : " + repr(d1[k]) + "\n"
74 s2 = s2 + " " + repr(k) + " : " + repr(d2[k]) + "\n"
82 class Builder(SCons.Builder.BuilderBase):
83 """A dummy Builder class for testing purposes. "Building"
84 a target is simply setting a value in the dictionary.
86 def __init__(self, name = None):
89 def __call__(self, env, target=None, source=None, **kw):
91 called_it['target'] = target
92 called_it['source'] = source
95 def execute(self, target = None, **kw):
104 """A dummy Scanner class for testing purposes. "Scanning"
105 a target is simply setting a value in the dictionary.
107 def __init__(self, name, skeys=[]):
111 def __call__(self, filename):
113 scanned_it[filename] = 1
115 def __cmp__(self, other):
117 return cmp(self.__dict__, other.__dict__)
118 except AttributeError:
121 def get_skeys(self, env):
129 class CLVar(collections.UserList):
130 def __init__(self, seq):
131 if isinstance(seq, str):
133 collections.UserList.__init__(self, seq)
134 def __add__(self, other):
135 return collections.UserList.__add__(self, CLVar(other))
136 def __radd__(self, other):
137 return collections.UserList.__radd__(self, CLVar(other))
138 def __coerce__(self, other):
139 return (self, CLVar(other))
144 def __init__(self, name):
150 def get_subst_proxy(self):
153 def test_tool( env ):
154 env['_F77INCFLAGS'] = '$( ${_concat(INCPREFIX, F77PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
156 class TestEnvironmentFixture:
157 def TestEnvironment(self, *args, **kw):
158 if not kw or 'tools' not in kw:
159 kw['tools'] = [test_tool]
160 default_keys = { 'CC' : 'cc',
161 'CCFLAGS' : '-DNDEBUG',
162 'ENV' : { 'TMP' : '/tmp' } }
163 for key, value in default_keys.items():
166 if 'BUILDERS' not in kw:
167 static_obj = SCons.Builder.Builder(action = {},
171 kw['BUILDERS'] = {'Object' : static_obj}
172 static_obj.add_action('.cpp', 'fake action')
174 env = Environment(*args, **kw)
177 class SubstitutionTestCase(unittest.TestCase):
179 def test___init__(self):
180 """Test initializing a SubstitutionEnvironment
182 env = SubstitutionEnvironment()
183 assert '__env__' not in env
185 def test___cmp__(self):
186 """Test comparing SubstitutionEnvironments
189 env1 = SubstitutionEnvironment(XXX = 'x')
190 env2 = SubstitutionEnvironment(XXX = 'x')
191 env3 = SubstitutionEnvironment(XXX = 'xxx')
192 env4 = SubstitutionEnvironment(XXX = 'x', YYY = 'x')
198 def test___delitem__(self):
199 """Test deleting a variable from a SubstitutionEnvironment
201 env1 = SubstitutionEnvironment(XXX = 'x', YYY = 'y')
202 env2 = SubstitutionEnvironment(XXX = 'x')
206 def test___getitem__(self):
207 """Test fetching a variable from a SubstitutionEnvironment
209 env = SubstitutionEnvironment(XXX = 'x')
210 assert env['XXX'] == 'x', env['XXX']
212 def test___setitem__(self):
213 """Test setting a variable in a SubstitutionEnvironment
215 env1 = SubstitutionEnvironment(XXX = 'x')
216 env2 = SubstitutionEnvironment(XXX = 'x', YYY = 'y')
221 """Test the SubstitutionEnvironment get() method
223 env = SubstitutionEnvironment(XXX = 'x')
224 assert env.get('XXX') == 'x', env.get('XXX')
225 assert env.get('YYY') is None, env.get('YYY')
227 def test_has_key(self):
228 """Test the SubstitutionEnvironment has_key() method
230 env = SubstitutionEnvironment(XXX = 'x')
232 assert 'YYY' not in env
234 def test_contains(self):
235 """Test the SubstitutionEnvironment __contains__() method
241 # An early version of Python that doesn't support "in"
242 # on dictionaries. Just pass the test.
245 env = SubstitutionEnvironment(XXX = 'x')
247 assert not 'YYY' in env
249 def test_items(self):
250 """Test the SubstitutionEnvironment items() method
252 env = SubstitutionEnvironment(XXX = 'x', YYY = 'y')
254 assert items == [('XXX','x'), ('YYY','y')], items
256 def test_arg2nodes(self):
257 """Test the arg2nodes method
259 env = SubstitutionEnvironment()
261 class X(SCons.Node.Node):
263 def Factory(name, directory = None, create = 1, dict=dict, X=X):
266 dict[name].name = name
269 nodes = env.arg2nodes("Util.py UtilTests.py", Factory)
270 assert len(nodes) == 1, nodes
271 assert isinstance(nodes[0], X)
272 assert nodes[0].name == "Util.py UtilTests.py"
275 except NameError: pass
278 nodes = env.arg2nodes(u"Util.py UtilTests.py", Factory)
279 assert len(nodes) == 1, nodes
280 assert isinstance(nodes[0], X)
281 assert nodes[0].name == u"Util.py UtilTests.py"
283 exec code in globals(), locals()
285 nodes = env.arg2nodes(["Util.py", "UtilTests.py"], Factory)
286 assert len(nodes) == 2, nodes
287 assert isinstance(nodes[0], X)
288 assert isinstance(nodes[1], X)
289 assert nodes[0].name == "Util.py"
290 assert nodes[1].name == "UtilTests.py"
292 n1 = Factory("Util.py")
293 nodes = env.arg2nodes([n1, "UtilTests.py"], Factory)
294 assert len(nodes) == 2, nodes
295 assert isinstance(nodes[0], X)
296 assert isinstance(nodes[1], X)
297 assert nodes[0].name == "Util.py"
298 assert nodes[1].name == "UtilTests.py"
300 class SConsNode(SCons.Node.Node):
302 nodes = env.arg2nodes(SConsNode())
303 assert len(nodes) == 1, nodes
304 assert isinstance(nodes[0], SConsNode), node
308 nodes = env.arg2nodes(OtherNode())
309 assert len(nodes) == 1, nodes
310 assert isinstance(nodes[0], OtherNode), node
312 def lookup_a(str, F=Factory):
320 def lookup_b(str, F=Factory):
328 env_ll = SubstitutionEnvironment()
329 env_ll.lookup_list = [lookup_a, lookup_b]
331 nodes = env_ll.arg2nodes(['aaa', 'bbb', 'ccc'], Factory)
332 assert len(nodes) == 3, nodes
334 assert nodes[0].name == 'aaa', nodes[0]
335 assert nodes[0].a == 1, nodes[0]
336 assert not hasattr(nodes[0], 'b'), nodes[0]
338 assert nodes[1].name == 'bbb'
339 assert not hasattr(nodes[1], 'a'), nodes[1]
340 assert nodes[1].b == 1, nodes[1]
342 assert nodes[2].name == 'ccc'
343 assert not hasattr(nodes[2], 'a'), nodes[1]
344 assert not hasattr(nodes[2], 'b'), nodes[1]
346 def lookup_bbbb(str, F=Factory):
354 def lookup_c(str, F=Factory):
362 nodes = env.arg2nodes(['bbbb', 'ccc'], Factory,
363 [lookup_c, lookup_bbbb, lookup_b])
364 assert len(nodes) == 2, nodes
366 assert nodes[0].name == 'bbbb'
367 assert not hasattr(nodes[0], 'a'), nodes[1]
368 assert not hasattr(nodes[0], 'b'), nodes[1]
369 assert nodes[0].bbbb == 1, nodes[1]
370 assert not hasattr(nodes[0], 'c'), nodes[0]
372 assert nodes[1].name == 'ccc'
373 assert not hasattr(nodes[1], 'a'), nodes[1]
374 assert not hasattr(nodes[1], 'b'), nodes[1]
375 assert not hasattr(nodes[1], 'bbbb'), nodes[0]
376 assert nodes[1].c == 1, nodes[1]
378 def test_arg2nodes_target_source(self):
379 """Test the arg2nodes method with target= and source= keywords
381 targets = [DummyNode('t1'), DummyNode('t2')]
382 sources = [DummyNode('s1'), DummyNode('s2')]
383 env = SubstitutionEnvironment()
384 nodes = env.arg2nodes(['${TARGET}-a',
391 names = [n.name for n in nodes]
392 assert names == ['t1-a', 's1-b', 't2-c', 's2-d'], names
394 def test_gvars(self):
395 """Test the base class gvars() method"""
396 env = SubstitutionEnvironment()
398 assert gvars == {}, gvars
400 def test_lvars(self):
401 """Test the base class lvars() method"""
402 env = SubstitutionEnvironment()
404 assert lvars == {}, lvars
406 def test_subst(self):
407 """Test substituting construction variables within strings
409 Check various combinations, including recursive expansion
410 of variables into other variables.
412 env = SubstitutionEnvironment(AAA = 'a', BBB = 'b')
413 mystr = env.subst("$AAA ${AAA}A $BBBB $BBB")
414 assert mystr == "a aA b", mystr
416 # Changed the tests below to reflect a bug fix in
418 env = SubstitutionEnvironment(AAA = '$BBB', BBB = 'b', BBBA = 'foo')
419 mystr = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
420 assert mystr == "b bA bB b", mystr
422 env = SubstitutionEnvironment(AAA = '$BBB', BBB = '$CCC', CCC = 'c')
423 mystr = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
424 assert mystr == "c cA cB c", mystr
427 env = SubstitutionEnvironment(AAA = ['a', 'aa', 'aaa'])
428 mystr = env.subst("$AAA")
429 assert mystr == "a aa aaa", mystr
432 env = SubstitutionEnvironment(AAA = ('a', 'aa', 'aaa'))
433 mystr = env.subst("$AAA")
434 assert mystr == "a aa aaa", mystr
441 env = SubstitutionEnvironment(AAA = 'aaa')
442 s = env.subst('$AAA $TARGET $SOURCES', target=[t1, t2], source=[s1, s2])
443 assert s == "aaa t1 s1 s2", s
444 s = env.subst('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2])
445 assert s == "aaa t1 t2 s1", s
447 # Test callables in the SubstitutionEnvironment
448 def foo(target, source, env, for_signature):
449 assert str(target) == 't', target
450 assert str(source) == 's', source
453 env = SubstitutionEnvironment(BAR=foo, FOO='baz')
457 subst = env.subst('test $BAR', target=t, source=s)
458 assert subst == 'test baz', subst
460 # Test not calling callables in the SubstitutionEnvironment
462 # This will take some serious surgery to subst() and
463 # subst_list(), so just leave these tests out until we can
468 env = SubstitutionEnvironment(BAR=bar, FOO='$BAR')
470 subst = env.subst('$BAR', call=None)
471 assert subst is bar, subst
473 subst = env.subst('$FOO', call=None)
474 assert subst is bar, subst
476 def test_subst_kw(self):
477 """Test substituting construction variables within dictionaries"""
478 env = SubstitutionEnvironment(AAA = 'a', BBB = 'b')
479 kw = env.subst_kw({'$AAA' : 'aaa', 'bbb' : '$BBB'})
480 assert len(kw) == 2, kw
481 assert kw['a'] == 'aaa', kw['a']
482 assert kw['bbb'] == 'b', kw['bbb']
484 def test_subst_list(self):
485 """Test substituting construction variables in command lists
487 env = SubstitutionEnvironment(AAA = 'a', BBB = 'b')
488 l = env.subst_list("$AAA ${AAA}A $BBBB $BBB")
489 assert l == [["a", "aA", "b"]], l
491 # Changed the tests below to reflect a bug fix in
493 env = SubstitutionEnvironment(AAA = '$BBB', BBB = 'b', BBBA = 'foo')
494 l = env.subst_list("$AAA ${AAA}A ${AAA}B $BBB")
495 assert l == [["b", "bA", "bB", "b"]], l
497 env = SubstitutionEnvironment(AAA = '$BBB', BBB = '$CCC', CCC = 'c')
498 l = env.subst_list("$AAA ${AAA}A ${AAA}B $BBB")
499 assert l == [["c", "cA", "cB", "c"]], mystr
501 env = SubstitutionEnvironment(AAA = '$BBB', BBB = '$CCC', CCC = [ 'a', 'b\nc' ])
502 lst = env.subst_list([ "$AAA", "B $CCC" ])
503 assert lst == [[ "a", "b"], ["c", "B a", "b"], ["c"]], lst
510 env = SubstitutionEnvironment(AAA = 'aaa')
511 s = env.subst_list('$AAA $TARGET $SOURCES', target=[t1, t2], source=[s1, s2])
512 assert s == [["aaa", "t1", "s1", "s2"]], s
513 s = env.subst_list('$AAA $TARGETS $SOURCE', target=[t1, t2], source=[s1, s2])
514 assert s == [["aaa", "t1", "t2", "s1"]], s
516 # Test callables in the SubstitutionEnvironment
517 def foo(target, source, env, for_signature):
518 assert str(target) == 't', target
519 assert str(source) == 's', source
522 env = SubstitutionEnvironment(BAR=foo, FOO='baz')
526 lst = env.subst_list('test $BAR', target=t, source=s)
527 assert lst == [['test', 'baz']], lst
529 # Test not calling callables in the SubstitutionEnvironment
531 # This will take some serious surgery to subst() and
532 # subst_list(), so just leave these tests out until we can
537 env = SubstitutionEnvironment(BAR=bar, FOO='$BAR')
539 subst = env.subst_list('$BAR', call=None)
540 assert subst is bar, subst
542 subst = env.subst_list('$FOO', call=None)
543 assert subst is bar, subst
545 def test_subst_path(self):
546 """Test substituting a path list
549 def __init__(self, val):
552 return self.val + '-proxy'
555 def __init__(self, val):
557 def get_subst_proxy(self):
566 env = SubstitutionEnvironment(FOO='foo',
569 PROXY=MyProxy('my1'))
571 r = env.subst_path('$FOO')
572 assert r == ['foo'], r
574 r = env.subst_path(['$FOO', 'xxx', '$BAR'])
575 assert r == ['foo', 'xxx', 'bar'], r
577 r = env.subst_path(['$FOO', '$LIST', '$BAR'])
578 assert list(map(str, r)) == ['foo', 'one two', 'bar'], r
580 r = env.subst_path(['$FOO', '$TARGET', '$SOURCE', '$BAR'])
581 assert r == ['foo', '', '', 'bar'], r
583 r = env.subst_path(['$FOO', '$TARGET', '$BAR'], target=MyNode('ttt'))
584 assert list(map(str, r)) == ['foo', 'ttt', 'bar'], r
586 r = env.subst_path(['$FOO', '$SOURCE', '$BAR'], source=MyNode('sss'))
587 assert list(map(str, r)) == ['foo', 'sss', 'bar'], r
591 r = env.subst_path(['$PROXY', MyProxy('my2'), n])
592 assert r == ['my1-proxy', 'my2-proxy', n], r
595 def __init__(self, s):
600 env = SubstitutionEnvironment(FOO=StringableObj("foo"),
601 BAR=StringableObj("bar"))
603 r = env.subst_path([ "${FOO}/bar", "${BAR}/baz" ])
604 assert r == [ "foo/bar", "bar/baz" ], r
606 r = env.subst_path([ "bar/${FOO}", "baz/${BAR}" ])
607 assert r == [ "bar/foo", "baz/bar" ], r
609 r = env.subst_path([ "bar/${FOO}/bar", "baz/${BAR}/baz" ])
610 assert r == [ "bar/foo/bar", "baz/bar/baz" ], r
612 def test_subst_target_source(self):
613 """Test the base environment subst_target_source() method"""
614 env = SubstitutionEnvironment(AAA = 'a', BBB = 'b')
615 mystr = env.subst_target_source("$AAA ${AAA}A $BBBB $BBB")
616 assert mystr == "a aA b", mystr
618 def test_backtick(self):
619 """Test the backtick() method for capturing command output"""
620 env = SubstitutionEnvironment()
622 test = TestCmd.TestCmd(workdir = '')
623 test.write('stdout.py', """\
625 sys.stdout.write('this came from stdout.py\\n')
628 test.write('stderr.py', """\
630 sys.stderr.write('this came from stderr.py\\n')
633 test.write('fail.py', """\
637 test.write('echo.py', """\
639 sys.stdout.write(os.environ['ECHO'] + '\\n')
643 save_stderr = sys.stderr
645 python = '"' + sys.executable + '"'
648 sys.stderr = io.StringIO()
649 cmd = '%s %s' % (python, test.workpath('stdout.py'))
650 output = env.backtick(cmd)
651 errout = sys.stderr.getvalue()
652 assert output == 'this came from stdout.py\n', output
653 assert errout == '', errout
655 sys.stderr = io.StringIO()
656 cmd = '%s %s' % (python, test.workpath('stderr.py'))
657 output = env.backtick(cmd)
658 errout = sys.stderr.getvalue()
659 assert output == '', output
660 assert errout == 'this came from stderr.py\n', errout
662 sys.stderr = io.StringIO()
663 cmd = '%s %s' % (python, test.workpath('fail.py'))
667 assert str(e) == "'%s' exited 1" % cmd, str(e)
669 self.fail("did not catch expected OSError")
671 sys.stderr = io.StringIO()
672 cmd = '%s %s' % (python, test.workpath('echo.py'))
673 env['ENV'] = os.environ.copy()
674 env['ENV']['ECHO'] = 'this came from ECHO'
675 output = env.backtick(cmd)
676 errout = sys.stderr.getvalue()
677 assert output == 'this came from ECHO\n', output
678 assert errout == '', errout
681 sys.stderr = save_stderr
683 def test_AddMethod(self):
684 """Test the AddMethod() method"""
685 env = SubstitutionEnvironment(FOO = 'foo')
688 return 'func-' + self['FOO']
690 assert not hasattr(env, 'func')
693 assert r == 'func-foo', r
695 assert not hasattr(env, 'bar')
696 env.AddMethod(func, 'bar')
698 assert r == 'func-foo', r
700 def func2(self, arg=''):
701 return 'func2-' + self['FOO'] + arg
705 assert r == 'func2-foo', r
706 r = env.func2('-xxx')
707 assert r == 'func2-foo-xxx', r
709 env.AddMethod(func2, 'func')
711 assert r == 'func2-foo', r
713 assert r == 'func2-foo-yyy', r
715 # Test that clones of clones correctly re-bind added methods.
716 env1 = Environment(FOO = '1')
717 env1.AddMethod(func2)
718 env2 = env1.Clone(FOO = '2')
719 env3 = env2.Clone(FOO = '3')
720 env4 = env3.Clone(FOO = '4')
722 assert r == 'func2-1', r
724 assert r == 'func2-2', r
726 assert r == 'func2-3', r
728 assert r == 'func2-4', r
730 # Test that clones don't re-bind an attribute that the user
731 env1 = Environment(FOO = '1')
732 env1.AddMethod(func2)
734 return 'replace_func2'
735 env1.func2 = replace_func2
736 env2 = env1.Clone(FOO = '2')
738 assert r == 'replace_func2', r
740 def test_Override(self):
741 "Test overriding construction variables"
742 env = SubstitutionEnvironment(ONE=1, TWO=2, THREE=3, FOUR=4)
743 assert env['ONE'] == 1, env['ONE']
744 assert env['TWO'] == 2, env['TWO']
745 assert env['THREE'] == 3, env['THREE']
746 assert env['FOUR'] == 4, env['FOUR']
748 env2 = env.Override({'TWO' : '10',
749 'THREE' :'x $THREE y',
750 'FOUR' : ['x', '$FOUR', 'y']})
751 assert env2['ONE'] == 1, env2['ONE']
752 assert env2['TWO'] == '10', env2['TWO']
753 assert env2['THREE'] == 'x 3 y', env2['THREE']
754 assert env2['FOUR'] == ['x', 4, 'y'], env2['FOUR']
756 assert env['ONE'] == 1, env['ONE']
757 assert env['TWO'] == 2, env['TWO']
758 assert env['THREE'] == 3, env['THREE']
759 assert env['FOUR'] == 4, env['FOUR']
761 env2.Replace(ONE = "won")
762 assert env2['ONE'] == "won", env2['ONE']
763 assert env['ONE'] == 1, env['ONE']
765 def test_ParseFlags(self):
766 """Test the ParseFlags() method
768 env = SubstitutionEnvironment()
777 'FRAMEWORKPATH' : [],
785 d = env.ParseFlags(None)
788 d = env.ParseFlags('')
791 d = env.ParseFlags([])
794 s = "-I/usr/include/fum -I bar -X\n" + \
795 '-I"C:\\Program Files\\ASCEND\\include" ' + \
796 "-L/usr/fax -L foo -lxxx -l yyy " + \
797 '-L"C:\\Program Files\\ASCEND" -lascend ' + \
798 "-Wa,-as -Wl,-link " + \
799 "-Wl,-rpath=rpath1 " + \
804 "-framework Carbon " + \
805 "-frameworkdir=fwd1 " + \
809 "-mno-cygwin -mwindows " + \
810 "-arch i386 -isysroot /tmp +DD64 " + \
811 "-DFOO -DBAR=value -D BAZ "
813 d = env.ParseFlags(s)
815 assert d['ASFLAGS'] == ['-as'], d['ASFLAGS']
816 assert d['CFLAGS'] == ['-std=c99']
817 assert d['CCFLAGS'] == ['-X', '-Wa,-as',
818 '-pthread', '-mno-cygwin',
819 ('-arch', 'i386'), ('-isysroot', '/tmp'),
820 '+DD64'], d['CCFLAGS']
821 assert d['CPPDEFINES'] == ['FOO', ['BAR', 'value'], 'BAZ'], d['CPPDEFINES']
822 assert d['CPPFLAGS'] == ['-Wp,-cpp'], d['CPPFLAGS']
823 assert d['CPPPATH'] == ['/usr/include/fum',
825 'C:\\Program Files\\ASCEND\\include'], d['CPPPATH']
826 assert d['FRAMEWORKPATH'] == ['fwd1', 'fwd2', 'fwd3'], d['FRAMEWORKPATH']
827 assert d['FRAMEWORKS'] == ['Carbon'], d['FRAMEWORKS']
828 assert d['LIBPATH'] == ['/usr/fax',
830 'C:\\Program Files\\ASCEND'], d['LIBPATH']
831 LIBS = list(map(str, d['LIBS']))
832 assert LIBS == ['xxx', 'yyy', 'ascend'], (d['LIBS'], LIBS)
833 assert d['LINKFLAGS'] == ['-Wl,-link', '-pthread',
834 '-mno-cygwin', '-mwindows',
836 ('-isysroot', '/tmp'),
837 '+DD64'], d['LINKFLAGS']
838 assert d['RPATH'] == ['rpath1', 'rpath2', 'rpath3'], d['RPATH']
841 def test_MergeFlags(self):
842 """Test the MergeFlags() method
844 env = SubstitutionEnvironment()
846 assert 'CCFLAGS' not in env, env['CCFLAGS']
848 assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
850 assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
852 env = SubstitutionEnvironment(CCFLAGS=None)
854 assert env['CCFLAGS'] == ['-Y'], env['CCFLAGS']
856 env = SubstitutionEnvironment()
857 env.MergeFlags({'A':['aaa'], 'B':['bbb']})
858 assert env['A'] == ['aaa'], env['A']
859 assert env['B'] == ['bbb'], env['B']
861 # def test_MergeShellPaths(self):
862 # """Test the MergeShellPaths() method
864 # env = Environment()
865 # env.MergeShellPaths({})
866 # assert not env['ENV'].has_key('INCLUDE'), env['INCLUDE']
867 # env.MergeShellPaths({'INCLUDE': r'c:\Program Files\Stuff'})
868 # assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff', env['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'xyz'})
872 # assert env['ENV']['INCLUDE'] == r'xyz%sc:\Program Files\Stuff'%os.pathsep, env['ENV']['INCLUDE']
874 # env = Environment()
875 # env['ENV']['INCLUDE'] = 'xyz'
876 # env.MergeShellPaths({'INCLUDE':['c:/inc1', 'c:/inc2']} )
877 # assert env['ENV']['INCLUDE'] == r'c:/inc1%sc:/inc2%sxyz'%(os.pathsep, os.pathsep), env['ENV']['INCLUDE']
880 # env = Environment()
881 # env.MergeShellPaths({'INCLUDE': r'c:\Program Files\Stuff'}, prepend=0)
882 # assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff', env['ENV']['INCLUDE']
883 # env.MergeShellPaths({'INCLUDE': r'xyz'}, prepend=0)
884 # assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff%sxyz'%os.pathsep, env['ENV']['INCLUDE']
887 class BaseTestCase(unittest.TestCase,TestEnvironmentFixture):
889 reserved_variables = [
900 def test___init__(self):
901 """Test construction Environment creation
903 Create two with identical arguments and check that
904 they compare the same.
906 env1 = self.TestEnvironment(XXX = 'x', YYY = 'y')
907 env2 = self.TestEnvironment(XXX = 'x', YYY = 'y')
908 assert env1 == env2, diff_env(env1, env2)
910 assert '__env__' not in env1
911 assert '__env__' not in env2
913 def test_variables(self):
914 """Test that variables only get applied once."""
916 def __init__(self, key, val):
922 def Update(self, env):
923 env[self.key] = self.val
924 self.calls = self.calls + 1
926 o = FakeOptions('AAA', 'fake_opt')
927 env = Environment(variables=o, AAA='keyword_arg')
928 assert o.calls == 1, o.calls
929 assert env['AAA'] == 'fake_opt', env['AAA']
932 """Test the get() method."""
933 env = self.TestEnvironment(aaa = 'AAA')
937 x = env.get('aaa', 'XXX')
941 x = env.get('bbb', 'XXX')
944 def test_Builder_calls(self):
945 """Test Builder calls through different environments
953 env.Replace(BUILDERS = { 'builder1' : b1,
957 assert called_it['target'] is None, called_it
958 assert called_it['source'] == ['in1'], called_it
961 env.builder2(source = 'in2', xyzzy = 1)
962 assert called_it['target'] is None, called_it
963 assert called_it['source'] == ['in2'], called_it
964 assert called_it['xyzzy'] == 1, called_it
967 env.builder1(foo = 'bar')
968 assert called_it['foo'] == 'bar', called_it
969 assert called_it['target'] is None, called_it
970 assert called_it['source'] is None, called_it
972 def test_BuilderWrapper_attributes(self):
973 """Test getting and setting of BuilderWrapper attributes
980 e1.Replace(BUILDERS = {'b' : b1})
987 assert bw.builder is b1
989 assert bw.builder is b2
991 self.assertRaises(AttributeError, getattr, bw, 'foobar')
993 assert bw.foobar is 42
995 # This unit test is currently disabled because we don't think the
996 # underlying method it tests (Environment.BuilderWrapper.execute())
997 # is necessary, but we're leaving the code here for now in case
999 def _DO_NOT_test_Builder_execs(self):
1000 """Test Builder execution through different environments
1002 One environment is initialized with a single
1003 Builder object, one with a list of a single Builder
1004 object, and one with a list of two Builder objects.
1012 env3 = Environment()
1013 env3.Replace(BUILDERS = { 'builder1' : b1,
1015 env3.builder1.execute(target = 'out1')
1016 env3.builder2.execute(target = 'out2')
1017 env3.builder1.execute(target = 'out3')
1018 assert built_it['out1']
1019 assert built_it['out2']
1020 assert built_it['out3']
1023 assert env4.builder1.env is env4, "builder1.env (%s) == env3 (%s)?" % (
1024 env4.builder1.env, env3)
1025 assert env4.builder2.env is env4, "builder2.env (%s) == env3 (%s)?" % (
1026 env4.builder1.env, env3)
1028 # Now test BUILDERS as a dictionary.
1030 env5 = self.TestEnvironment(BUILDERS={ 'foo' : b1 })
1031 env5['BUILDERS']['bar'] = b2
1032 env5.foo.execute(target='out1')
1033 env5.bar.execute(target='out2')
1034 assert built_it['out1']
1035 assert built_it['out2']
1038 env6 = Environment()
1039 env6['BUILDERS'] = { 'foo' : b1,
1041 env6.foo.execute(target='out1')
1042 env6.bar.execute(target='out2')
1043 assert built_it['out1']
1044 assert built_it['out2']
1048 def test_Scanners(self):
1049 """Test setting SCANNERS in various ways
1051 One environment is initialized with a single
1052 Scanner object, one with a list of a single Scanner
1053 object, and one with a list of two Scanner objects.
1057 s1 = Scanner(name = 'scanner1', skeys = [".c", ".cc"])
1058 s2 = Scanner(name = 'scanner2', skeys = [".m4"])
1059 s3 = Scanner(name = 'scanner3', skeys = [".m4", ".m5"])
1060 s4 = Scanner(name = 'scanner4', skeys = [None])
1062 # XXX Tests for scanner execution through different environments,
1063 # XXX if we ever want to do that some day
1065 # env1 = self.TestEnvironment(SCANNERS = s1)
1066 # env1.scanner1(filename = 'out1')
1067 # assert scanned_it['out1']
1070 # env2 = self.TestEnvironment(SCANNERS = [s1])
1071 # env1.scanner1(filename = 'out1')
1072 # assert scanned_it['out1']
1075 # env3 = Environment()
1076 # env3.Replace(SCANNERS = [s1])
1077 # env3.scanner1(filename = 'out1')
1078 # env3.scanner2(filename = 'out2')
1079 # env3.scanner1(filename = 'out3')
1080 # assert scanned_it['out1']
1081 # assert scanned_it['out2']
1082 # assert scanned_it['out3']
1084 suffixes = [".c", ".cc", ".cxx", ".m4", ".m5"]
1087 try: del env['SCANNERS']
1088 except KeyError: pass
1089 s = list(map(env.get_scanner, suffixes))
1090 assert s == [None, None, None, None, None], s
1092 env = self.TestEnvironment(SCANNERS = [])
1093 s = list(map(env.get_scanner, suffixes))
1094 assert s == [None, None, None, None, None], s
1096 env.Replace(SCANNERS = [s1])
1097 s = list(map(env.get_scanner, suffixes))
1098 assert s == [s1, s1, None, None, None], s
1100 env.Append(SCANNERS = [s2])
1101 s = list(map(env.get_scanner, suffixes))
1102 assert s == [s1, s1, None, s2, None], s
1104 env.AppendUnique(SCANNERS = [s3])
1105 s = list(map(env.get_scanner, suffixes))
1106 assert s == [s1, s1, None, s2, s3], s
1108 env = env.Clone(SCANNERS = [s2])
1109 s = list(map(env.get_scanner, suffixes))
1110 assert s == [None, None, None, s2, None], s
1112 env['SCANNERS'] = [s1]
1113 s = list(map(env.get_scanner, suffixes))
1114 assert s == [s1, s1, None, None, None], s
1116 env.PrependUnique(SCANNERS = [s2, s1])
1117 s = list(map(env.get_scanner, suffixes))
1118 assert s == [s1, s1, None, s2, None], s
1120 env.Prepend(SCANNERS = [s3])
1121 s = list(map(env.get_scanner, suffixes))
1122 assert s == [s1, s1, None, s3, s3], s
1124 # Verify behavior of case-insensitive suffix matches on Windows.
1125 uc_suffixes = [_.upper() for _ in suffixes]
1127 env = Environment(SCANNERS = [s1, s2, s3],
1130 s = list(map(env.get_scanner, suffixes))
1131 assert s == [s1, s1, None, s2, s3], s
1133 s = list(map(env.get_scanner, uc_suffixes))
1134 assert s == [None, None, None, None, None], s
1136 env['PLATFORM'] = 'win32'
1138 s = list(map(env.get_scanner, uc_suffixes))
1139 assert s == [s1, s1, None, s2, s3], s
1141 # Verify behavior for a scanner returning None (on Windows
1142 # where we might try to perform case manipulation on None).
1143 env.Replace(SCANNERS = [s4])
1144 s = list(map(env.get_scanner, suffixes))
1145 assert s == [None, None, None, None, None], s
1148 """Test setting the external ENV in Environments
1151 assert 'ENV' in env.Dictionary()
1153 env = self.TestEnvironment(ENV = { 'PATH' : '/foo:/bar' })
1154 assert env.Dictionary('ENV')['PATH'] == '/foo:/bar'
1156 def test_ReservedVariables(self):
1157 """Test warning generation when reserved variable names are set"""
1159 reserved_variables = [
1166 'UNCHANGED_SOURCES',
1167 'UNCHANGED_TARGETS',
1170 warning = SCons.Warnings.ReservedVariableWarning
1171 SCons.Warnings.enableWarningClass(warning)
1172 old = SCons.Warnings.warningAsException(1)
1175 env4 = Environment()
1176 for kw in self.reserved_variables:
1182 assert exc_caught, "Did not catch ReservedVariableWarning for `%s'" % kw
1183 assert kw not in env4, "`%s' variable was incorrectly set" % kw
1185 SCons.Warnings.warningAsException(old)
1187 def test_FutureReservedVariables(self):
1188 """Test warning generation when future reserved variable names are set"""
1190 future_reserved_variables = []
1192 warning = SCons.Warnings.FutureReservedVariableWarning
1193 SCons.Warnings.enableWarningClass(warning)
1194 old = SCons.Warnings.warningAsException(1)
1197 env4 = Environment()
1198 for kw in future_reserved_variables:
1204 assert exc_caught, "Did not catch FutureReservedVariableWarning for `%s'" % kw
1205 assert kw in env4, "`%s' variable was not set" % kw
1207 SCons.Warnings.warningAsException(old)
1209 def test_IllegalVariables(self):
1210 """Test that use of illegal variables raises an exception"""
1212 def test_it(var, env=env):
1216 except SCons.Errors.UserError:
1218 assert exc_caught, "did not catch UserError for '%s'" % var
1220 assert env['aaa'] == 1, env['aaa']
1225 def test_autogenerate(dict):
1226 """Test autogenerating variables in a dictionary."""
1228 drive, p = os.path.splitdrive(os.getcwd())
1229 def normalize_path(path, drive=drive):
1230 if path[0] in '\\/':
1232 path = os.path.normpath(path)
1233 drive, path = os.path.splitdrive(path)
1234 return drive.lower() + path
1236 env = dict.TestEnvironment(LIBS = [ 'foo', 'bar', 'baz' ],
1237 LIBLINKPREFIX = 'foo',
1238 LIBLINKSUFFIX = 'bar')
1240 def RDirs(pathlist, fs=env.fs):
1241 return fs.Dir('xx').Rfindalldirs(pathlist)
1243 env['RDirs'] = RDirs
1244 flags = env.subst_list('$_LIBFLAGS', 1)[0]
1245 assert flags == ['foobar', 'foobar', 'foobazbar'], flags
1247 blat = env.fs.Dir('blat')
1249 env.Replace(CPPPATH = [ 'foo', '$FOO/bar', blat ],
1253 flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
1255 normalize_path('foo'),
1256 normalize_path('xx/foobar'),
1257 normalize_path('foo'),
1258 normalize_path('xx/baz/bar'),
1259 normalize_path('foo'),
1260 normalize_path('blatbar'),
1263 assert flags == expect, flags
1265 env.Replace(F77PATH = [ 'foo', '$FOO/bar', blat ],
1269 flags = env.subst_list('$_F77INCFLAGS', 1)[0]
1271 normalize_path('foo'),
1272 normalize_path('xx/foobar'),
1273 normalize_path('foo'),
1274 normalize_path('xx/baz/bar'),
1275 normalize_path('foo'),
1276 normalize_path('blatbar'),
1279 assert flags == expect, flags
1281 env.Replace(CPPPATH = '', F77PATH = '', LIBPATH = '')
1282 l = env.subst_list('$_CPPINCFLAGS')
1284 l = env.subst_list('$_F77INCFLAGS')
1286 l = env.subst_list('$_LIBDIRFLAGS')
1289 env.fs.Repository('/rep1')
1290 env.fs.Repository('/rep2')
1291 env.Replace(CPPPATH = [ 'foo', '/a/b', '$FOO/bar', blat],
1295 flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
1297 '-I', normalize_path('xx/fooXXX'),
1298 '-I', normalize_path('/rep1/xx/fooXXX'),
1299 '-I', normalize_path('/rep2/xx/fooXXX'),
1300 '-I', normalize_path('/a/bXXX'),
1301 '-I', normalize_path('xx/baz/barXXX'),
1302 '-I', normalize_path('/rep1/xx/baz/barXXX'),
1303 '-I', normalize_path('/rep2/xx/baz/barXXX'),
1304 '-I', normalize_path('blatXXX'),
1307 def normalize_if_path(arg, np=normalize_path):
1308 if arg not in ('$(','$)','-I'):
1311 flags = list(map(normalize_if_path, flags))
1312 assert flags == expect, flags
1314 def test_platform(self):
1315 """Test specifying a platform callable when instantiating."""
1317 def __str__(self): return "TestPlatform"
1318 def __call__(self, env): env['XYZZY'] = 777
1321 env['SET_TOOL'] = 'initialized'
1322 assert env['PLATFORM'] == "TestPlatform"
1324 env = self.TestEnvironment(platform = platform(), tools = [tool])
1325 assert env['XYZZY'] == 777, env
1326 assert env['PLATFORM'] == "TestPlatform"
1327 assert env['SET_TOOL'] == "initialized"
1329 def test_Default_PLATFORM(self):
1330 """Test overriding the default PLATFORM variable"""
1332 def __str__(self): return "DefaultTestPlatform"
1333 def __call__(self, env): env['XYZZY'] = 888
1336 env['SET_TOOL'] = 'abcde'
1337 assert env['PLATFORM'] == "DefaultTestPlatform"
1339 import SCons.Defaults
1340 save = SCons.Defaults.ConstructionEnvironment.copy()
1342 import SCons.Defaults
1343 SCons.Defaults.ConstructionEnvironment.update({
1344 'PLATFORM' : platform(),
1346 env = self.TestEnvironment(tools = [tool])
1347 assert env['XYZZY'] == 888, env
1348 assert env['PLATFORM'] == "DefaultTestPlatform"
1349 assert env['SET_TOOL'] == "abcde"
1351 SCons.Defaults.ConstructionEnvironment = save
1353 def test_tools(self):
1354 """Test specifying a tool callable when instantiating."""
1360 env['AAA'] = env['XYZ']
1363 env = self.TestEnvironment(tools = [t1, t2, t3], XYZ = 'aaa')
1364 assert env['TOOL1'] == 111, env['TOOL1']
1365 assert env['TOOL2'] == 222, env
1366 assert env['AAA'] == 'aaa', env
1368 assert env['TOOL4'] == 444, env
1370 test = TestCmd.TestCmd(workdir = '')
1371 test.write('faketool.py', """\
1372 def generate(env, **kw):
1373 for k, v in kw.items():
1380 env = self.TestEnvironment(tools = [('faketool', {'a':1, 'b':2, 'c':3})],
1381 toolpath = [test.workpath('')])
1382 assert env['a'] == 1, env['a']
1383 assert env['b'] == 2, env['b']
1384 assert env['c'] == 3, env['c']
1386 def test_Default_TOOLS(self):
1387 """Test overriding the default TOOLS variable"""
1393 env['BBB'] = env['XYZ']
1397 import SCons.Defaults
1398 save = SCons.Defaults.ConstructionEnvironment.copy()
1400 SCons.Defaults.ConstructionEnvironment.update({
1401 'TOOLS' : [t5, t6, t7],
1403 env = Environment(XYZ = 'bbb')
1404 assert env['TOOL5'] == 555, env['TOOL5']
1405 assert env['TOOL6'] == 666, env
1406 assert env['BBB'] == 'bbb', env
1408 assert env['TOOL8'] == 888, env
1410 SCons.Defaults.ConstructionEnvironment = save
1412 def test_null_tools(self):
1413 """Test specifying a tool of None is OK."""
1418 env = self.TestEnvironment(tools = [t1, None, t2], XYZ = 'aaa')
1419 assert env['TOOL1'] == 111, env['TOOL1']
1420 assert env['TOOL2'] == 222, env
1421 assert env['XYZ'] == 'aaa', env
1422 env = self.TestEnvironment(tools = [None], XYZ = 'xyz')
1423 assert env['XYZ'] == 'xyz', env
1424 env = self.TestEnvironment(tools = [t1, '', t2], XYZ = 'ddd')
1425 assert env['TOOL1'] == 111, env['TOOL1']
1426 assert env['TOOL2'] == 222, env
1427 assert env['XYZ'] == 'ddd', env
1429 def test_concat(self):
1431 e1 = self.TestEnvironment(PRE='pre', SUF='suf', STR='a b', LIST=['a', 'b'])
1433 x = s("${_concat('', '', '', __env__)}")
1435 x = s("${_concat('', [], '', __env__)}")
1437 x = s("${_concat(PRE, '', SUF, __env__)}")
1439 x = s("${_concat(PRE, STR, SUF, __env__)}")
1440 assert x == 'prea bsuf', x
1441 x = s("${_concat(PRE, LIST, SUF, __env__)}")
1442 assert x == 'preasuf prebsuf', x
1444 def test_gvars(self):
1445 """Test the Environment gvars() method"""
1446 env = self.TestEnvironment(XXX = 'x', YYY = 'y', ZZZ = 'z')
1448 assert gvars['XXX'] == 'x', gvars['XXX']
1449 assert gvars['YYY'] == 'y', gvars['YYY']
1450 assert gvars['ZZZ'] == 'z', gvars['ZZZ']
1452 def test__update(self):
1453 """Test the _update() method"""
1454 env = self.TestEnvironment(X = 'x', Y = 'y', Z = 'z')
1455 assert env['X'] == 'x', env['X']
1456 assert env['Y'] == 'y', env['Y']
1457 assert env['Z'] == 'z', env['Z']
1458 env._update({'X' : 'xxx',
1464 assert env['X'] == 'xxx', env['X']
1465 assert env['Y'] == 'y', env['Y']
1466 assert env['Z'] == 'zzz', env['Z']
1467 assert env['TARGET'] == 't', env['TARGET']
1468 assert env['TARGETS'] == 'ttt', env['TARGETS']
1469 assert env['SOURCE'] == 's', env['SOURCE']
1470 assert env['SOURCES'] == 'sss', env['SOURCES']
1474 def test_Append(self):
1475 """Test appending to construction variables in an Environment
1478 b1 = Environment()['BUILDERS']
1479 b2 = Environment()['BUILDERS']
1480 assert b1 == b2, diff_dict(b1, b2)
1483 UD = collections.UserDict
1485 UL = collections.UserList
1489 'a2', ['A2'], ['a2', 'A2'],
1490 'a3', UL(['A3']), UL(['a', '3', 'A3']),
1493 'a6', UL([]), UL(['a', '6']),
1494 'a7', [''], ['a7', ''],
1495 'a8', UL(['']), UL(['a', '8', '']),
1497 ['e1'], 'E1', ['e1', 'E1'],
1498 ['e2'], ['E2'], ['e2', 'E2'],
1499 ['e3'], UL(['E3']), UL(['e3', 'E3']),
1502 ['e6'], UL([]), UL(['e6']),
1503 ['e7'], [''], ['e7', ''],
1504 ['e8'], UL(['']), UL(['e8', '']),
1506 UL(['i1']), 'I1', UL(['i1', 'I', '1']),
1507 UL(['i2']), ['I2'], UL(['i2', 'I2']),
1508 UL(['i3']), UL(['I3']), UL(['i3', 'I3']),
1509 UL(['i4']), '', UL(['i4']),
1510 UL(['i5']), [], UL(['i5']),
1511 UL(['i6']), UL([]), UL(['i6']),
1512 UL(['i7']), [''], UL(['i7', '']),
1513 UL(['i8']), UL(['']), UL(['i8', '']),
1515 {'d1':1}, 'D1', {'d1':1, 'D1':None},
1516 {'d2':1}, ['D2'], {'d2':1, 'D2':None},
1517 {'d3':1}, UL(['D3']), {'d3':1, 'D3':None},
1518 {'d4':1}, {'D4':1}, {'d4':1, 'D4':1},
1519 {'d5':1}, UD({'D5':1}), UD({'d5':1, 'D5':1}),
1521 UD({'u1':1}), 'U1', UD({'u1':1, 'U1':None}),
1522 UD({'u2':1}), ['U2'], UD({'u2':1, 'U2':None}),
1523 UD({'u3':1}), UL(['U3']), UD({'u3':1, 'U3':None}),
1524 UD({'u4':1}), {'U4':1}, UD({'u4':1, 'U4':1}),
1525 UD({'u5':1}), UD({'U5':1}), UD({'u5':1, 'U5':1}),
1529 '', UL(['M3']), UL(['M3']),
1534 '', UL(['']), UL(['']),
1538 [], UL(['N3']), UL(['N3']),
1543 [], UL(['']), UL(['']),
1545 UL([]), 'O1', ['O', '1'],
1546 UL([]), ['O2'], ['O2'],
1547 UL([]), UL(['O3']), UL(['O3']),
1550 UL([]), UL([]), UL([]),
1551 UL([]), [''], UL(['']),
1552 UL([]), UL(['']), UL(['']),
1554 [''], 'P1', ['', 'P1'],
1555 [''], ['P2'], ['', 'P2'],
1556 [''], UL(['P3']), UL(['', 'P3']),
1559 [''], UL([]), UL(['']),
1560 [''], [''], ['', ''],
1561 [''], UL(['']), UL(['', '']),
1563 UL(['']), 'Q1', ['', 'Q', '1'],
1564 UL(['']), ['Q2'], ['', 'Q2'],
1565 UL(['']), UL(['Q3']), UL(['', 'Q3']),
1566 UL(['']), '', UL(['']),
1567 UL(['']), [], UL(['']),
1568 UL(['']), UL([]), UL(['']),
1569 UL(['']), [''], UL(['', '']),
1570 UL(['']), UL(['']), UL(['', '']),
1576 input, append, expect = cases[:3]
1577 env['XXX'] = copy.copy(input)
1579 env.Append(XXX = append)
1580 except Exception, e:
1581 if failed == 0: print
1582 print " %s Append %s exception: %s" % \
1583 (repr(input), repr(append), e)
1587 if result != expect:
1588 if failed == 0: print
1589 print " %s Append %s => %s did not match %s" % \
1590 (repr(input), repr(append), repr(result), repr(expect))
1593 assert failed == 0, "%d Append() cases failed" % failed
1595 env['UL'] = UL(['foo'])
1596 env.Append(UL = 'bar')
1598 assert isinstance(result, UL), repr(result)
1599 assert result == ['foo', 'b', 'a', 'r'], result
1601 env['CLVar'] = CLVar(['foo'])
1602 env.Append(CLVar = 'bar')
1603 result = env['CLVar']
1604 assert isinstance(result, CLVar), repr(result)
1605 assert result == ['foo', 'bar'], result
1608 def __init__(self, name):
1612 def __cmp__(self, other):
1613 raise Exception("should not compare")
1617 env2 = self.TestEnvironment(CCC1 = ['c1'], CCC2 = ccc)
1618 env2.Append(CCC1 = ccc, CCC2 = ['c2'])
1619 assert env2['CCC1'][0] == 'c1', env2['CCC1']
1620 assert env2['CCC1'][1] is ccc, env2['CCC1']
1621 assert env2['CCC2'][0] is ccc, env2['CCC2']
1622 assert env2['CCC2'][1] == 'c2', env2['CCC2']
1624 env3 = self.TestEnvironment(X = {'x1' : 7})
1625 env3.Append(X = {'x1' : 8, 'x2' : 9}, Y = {'y1' : 10})
1626 assert env3['X'] == {'x1': 8, 'x2': 9}, env3['X']
1627 assert env3['Y'] == {'y1': 10}, env3['Y']
1631 env4 = self.TestEnvironment(BUILDERS = {'z1' : z1})
1632 env4.Append(BUILDERS = {'z2' : z2})
1633 assert env4['BUILDERS'] == {'z1' : z1, 'z2' : z2}, 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 5 in env2.Dictionary('ZZZ')
1778 assert 5 not in env1.Dictionary('ZZZ')
1781 env1 = self.TestEnvironment(BUILDERS = {'b1' : Builder()})
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' : Builder()})
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 'BUILDERS' in env.Dictionary()
1955 assert 'CC' in env.Dictionary()
1956 assert 'CCFLAGS' in env.Dictionary()
1957 assert 'ENV' in env.Dictionary()
1959 assert env['XXX'] == 'x'
1961 assert env.Dictionary('XXX') == 'foo'
1963 assert 'XXX' not in env.Dictionary()
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)
2106 t = list(map(str, tlist))
2107 d = list(map(str, dlist))
2108 assert t == ['f0'], t
2109 assert d == ['d1', 'd2', 'd3'], d
2114 env.ParseDepends(test.workpath('multiple'))
2115 t = list(map(str, tlist))
2116 d = list(map(str, dlist))
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 = collections.UserDict
2157 UL = collections.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']
2286 env4 = self.TestEnvironment(BUILDERS = {'z1' : z1})
2287 env4.Prepend(BUILDERS = {'z2' : z2})
2288 assert env4['BUILDERS'] == {'z1' : z1, 'z2' : z2}, env4['BUILDERS']
2289 assert hasattr(env4, 'z1')
2290 assert hasattr(env4, 'z2')
2292 def test_PrependENVPath(self):
2293 """Test prepending to an ENV path."""
2294 env1 = self.TestEnvironment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
2295 MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
2296 # have to include the pathsep here so that the test will work on UNIX too.
2297 env1.PrependENVPath('PATH',r'C:\dir\num\two',sep = ';')
2298 env1.PrependENVPath('PATH',r'C:\dir\num\three',sep = ';')
2299 env1.PrependENVPath('MYPATH',r'C:\mydir\num\three','MYENV',sep = ';')
2300 env1.PrependENVPath('MYPATH',r'C:\mydir\num\one','MYENV',sep = ';')
2301 # this should do nothing since delete_existing is 0
2302 env1.PrependENVPath('MYPATH',r'C:\mydir\num\three','MYENV', sep = ';', delete_existing=0)
2303 assert(env1['ENV']['PATH'] == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
2304 assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
2306 test = TestCmd.TestCmd(workdir = '')
2307 test.subdir('sub1', 'sub2')
2308 p=env1['ENV']['PATH']
2309 env1.PrependENVPath('PATH','#sub1', sep = ';')
2310 env1.PrependENVPath('PATH',env1.fs.Dir('sub2'), sep = ';')
2311 assert env1['ENV']['PATH'] == 'sub2;sub1;' + p, env1['ENV']['PATH']
2313 def test_PrependUnique(self):
2314 """Test prepending unique values to construction variables
2316 This strips values that are already present when lists are
2318 env = self.TestEnvironment(AAA1 = 'a1',
2330 DDD1 = ['a', 'b', 'c'])
2331 env.PrependUnique(AAA1 = 'a1',
2333 AAA3 = ['a3', 'b', 'c', 'b', 'a3'], # ignore dups
2338 BBB3 = ['b3', 'b', 'c', 'b3'],
2344 assert env['AAA1'] == 'a1a1', env['AAA1']
2345 assert env['AAA2'] == ['a2'], env['AAA2']
2346 assert env['AAA3'] == ['c', 'b', 'a3'], env['AAA3']
2347 assert env['AAA4'] == 'a4.newa4', env['AAA4']
2348 assert env['AAA5'] == ['a5.new', 'a5'], env['AAA5']
2349 assert env['BBB1'] == ['b1'], env['BBB1']
2350 assert env['BBB2'] == ['b2'], env['BBB2']
2351 assert env['BBB3'] == ['b', 'c', 'b3'], env['BBB3']
2352 assert env['BBB4'] == ['b4.new', 'b4'], env['BBB4']
2353 assert env['BBB5'] == ['b5.new', 'b5'], env['BBB5']
2354 assert env['CCC1'] == 'c1', env['CCC1']
2355 assert env['CCC2'] == ['c2'], env['CCC2']
2356 assert env['DDD1'] == ['a', 'b', 'c'], env['DDD1']
2358 env.PrependUnique(DDD1 = 'b', delete_existing=1)
2359 assert env['DDD1'] == ['b', 'a', 'c'], env['DDD1'] # b moves to front
2360 env.PrependUnique(DDD1 = ['a','c'], delete_existing=1)
2361 assert env['DDD1'] == ['a', 'c', 'b'], env['DDD1'] # a & c move to front
2362 env.PrependUnique(DDD1 = ['d','e','d'], delete_existing=1)
2363 assert env['DDD1'] == ['d', 'e', 'a', 'c', 'b'], env['DDD1']
2366 env['CLVar'] = CLVar([])
2367 env.PrependUnique(CLVar = 'bar')
2368 result = env['CLVar']
2369 if sys.version[0] == '1' or sys.version[:3] == '2.0':
2370 # Python 2.0 and before have a quirky behavior where CLVar([])
2371 # actually matches '' and [] due to different __coerce__()
2372 # semantics in the UserList implementation. It isn't worth a
2373 # lot of effort to get this corner case to work identically
2374 # (support for Python 1.5 support will die soon anyway),
2375 # so just treat it separately for now.
2376 assert result == 'bar', result
2378 assert isinstance(result, CLVar), repr(result)
2379 assert result == ['bar'], result
2381 env['CLVar'] = CLVar(['abc'])
2382 env.PrependUnique(CLVar = 'bar')
2383 result = env['CLVar']
2384 assert isinstance(result, CLVar), repr(result)
2385 assert result == ['bar', 'abc'], result
2387 env['CLVar'] = CLVar(['bar'])
2388 env.PrependUnique(CLVar = 'bar')
2389 result = env['CLVar']
2390 assert isinstance(result, CLVar), repr(result)
2391 assert result == ['bar'], result
2393 def test_Replace(self):
2394 """Test replacing construction variables in an Environment
2396 After creation of the Environment, of course.
2398 env1 = self.TestEnvironment(AAA = 'a', BBB = 'b')
2399 env1.Replace(BBB = 'bbb', CCC = 'ccc')
2401 env2 = self.TestEnvironment(AAA = 'a', BBB = 'bbb', CCC = 'ccc')
2402 assert env1 == env2, diff_env(env1, env2)
2406 env3 = self.TestEnvironment(BUILDERS = {'b1' : b1})
2407 assert hasattr(env3, 'b1'), "b1 was not set"
2408 env3.Replace(BUILDERS = {'b2' : b2})
2409 assert not hasattr(env3, 'b1'), "b1 was not cleared"
2410 assert hasattr(env3, 'b2'), "b2 was not set"
2412 def test_ReplaceIxes(self):
2413 "Test ReplaceIxes()"
2414 env = self.TestEnvironment(LIBPREFIX='lib',
2421 assert 'libfoo.a' == env.ReplaceIxes('libfoo.so',
2422 'SHLIBPREFIX', 'SHLIBSUFFIX',
2423 'LIBPREFIX', 'LIBSUFFIX')
2425 assert os.path.join('dir', 'libfoo.a') == env.ReplaceIxes(os.path.join('dir', 'libfoo.so'),
2426 'SHLIBPREFIX', 'SHLIBSUFFIX',
2427 'LIBPREFIX', 'LIBSUFFIX')
2429 assert 'libfoo.a' == env.ReplaceIxes('prefoopost',
2431 'LIBPREFIX', 'LIBSUFFIX')
2433 def test_SetDefault(self):
2434 """Test the SetDefault method"""
2435 env = self.TestEnvironment(tools = [])
2436 env.SetDefault(V1 = 1)
2437 env.SetDefault(V1 = 2)
2438 assert env['V1'] == 1
2440 env.SetDefault(V2 = 1)
2441 assert env['V2'] == 2
2443 def test_Tool(self):
2444 """Test the Tool() method"""
2445 env = self.TestEnvironment(LINK='link', NONE='no-such-tool')
2449 env.Tool('does_not_exist')
2450 except SCons.Errors.EnvironmentError:
2452 assert exc_caught, "did not catch expected EnvironmentError"
2457 except SCons.Errors.EnvironmentError:
2459 assert exc_caught, "did not catch expected EnvironmentError"
2461 # Use a non-existent toolpath directory just to make sure we
2462 # can call Tool() with the keyword argument.
2463 env.Tool('cc', toolpath=['/no/such/directory'])
2464 assert env['CC'] == 'cc', env['CC']
2467 assert env['LINK'] == '$SMARTLINK', env['LINK']
2469 # Test that the environment stores the toolpath and
2470 # re-uses it for later calls.
2471 test = TestCmd.TestCmd(workdir = '')
2473 test.write('xxx.py', """\
2480 test.write('yyy.py', """\
2487 env = self.TestEnvironment(tools=['xxx'], toolpath=[test.workpath('')])
2488 assert env['XXX'] == 'one', env['XXX']
2490 assert env['YYY'] == 'two', env['YYY']
2492 def test_WhereIs(self):
2493 """Test the WhereIs() method"""
2494 test = TestCmd.TestCmd(workdir = '')
2496 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
2497 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
2498 sub3_xxx_exe = test.workpath('sub3', 'xxx.exe')
2499 sub4_xxx_exe = test.workpath('sub4', 'xxx.exe')
2501 test.subdir('subdir', 'sub1', 'sub2', 'sub3', 'sub4')
2503 if sys.platform != 'win32':
2504 test.write(sub1_xxx_exe, "\n")
2506 os.mkdir(sub2_xxx_exe)
2508 test.write(sub3_xxx_exe, "\n")
2509 os.chmod(sub3_xxx_exe, 0777)
2511 test.write(sub4_xxx_exe, "\n")
2512 os.chmod(sub4_xxx_exe, 0777)
2514 env_path = os.environ['PATH']
2516 pathdirs_1234 = [ test.workpath('sub1'),
2517 test.workpath('sub2'),
2518 test.workpath('sub3'),
2519 test.workpath('sub4'),
2520 ] + env_path.split(os.pathsep)
2522 pathdirs_1243 = [ test.workpath('sub1'),
2523 test.workpath('sub2'),
2524 test.workpath('sub4'),
2525 test.workpath('sub3'),
2526 ] + env_path.split(os.pathsep)
2528 path = os.pathsep.join(pathdirs_1234)
2529 env = self.TestEnvironment(ENV = {'PATH' : path})
2530 wi = env.WhereIs('xxx.exe')
2531 assert wi == test.workpath(sub3_xxx_exe), wi
2532 wi = env.WhereIs('xxx.exe', pathdirs_1243)
2533 assert wi == test.workpath(sub4_xxx_exe), wi
2534 wi = env.WhereIs('xxx.exe', os.pathsep.join(pathdirs_1243))
2535 assert wi == test.workpath(sub4_xxx_exe), wi
2537 wi = env.WhereIs('xxx.exe', reject = sub3_xxx_exe)
2538 assert wi == test.workpath(sub4_xxx_exe), wi
2539 wi = env.WhereIs('xxx.exe', pathdirs_1243, reject = sub3_xxx_exe)
2540 assert wi == test.workpath(sub4_xxx_exe), wi
2542 path = os.pathsep.join(pathdirs_1243)
2543 env = self.TestEnvironment(ENV = {'PATH' : path})
2544 wi = env.WhereIs('xxx.exe')
2545 assert wi == test.workpath(sub4_xxx_exe), wi
2546 wi = env.WhereIs('xxx.exe', pathdirs_1234)
2547 assert wi == test.workpath(sub3_xxx_exe), wi
2548 wi = env.WhereIs('xxx.exe', os.pathsep.join(pathdirs_1234))
2549 assert wi == test.workpath(sub3_xxx_exe), wi
2551 if sys.platform == 'win32':
2552 wi = env.WhereIs('xxx', pathext = '')
2553 assert wi is None, wi
2555 wi = env.WhereIs('xxx', pathext = '.exe')
2556 assert wi == test.workpath(sub4_xxx_exe), wi
2558 wi = env.WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
2559 assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
2561 # Test that we return a normalized path even when
2562 # the path contains forward slashes.
2563 forward_slash = test.workpath('') + '/sub3'
2564 wi = env.WhereIs('xxx', path = forward_slash, pathext = '.EXE')
2565 assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
2569 def test_Action(self):
2570 """Test the Action() method"""
2573 env = self.TestEnvironment(FOO = 'xyzzy')
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.CommandAction, a.__class__
2583 a = env.Action('$$FOO')
2585 assert a.__class__ is SCons.Action.LazyAction, a.__class__
2587 a = env.Action(['$FOO', 'foo'])
2589 assert a.__class__ is SCons.Action.ListAction, a.__class__
2593 a = env.Action(func)
2595 assert a.__class__ is SCons.Action.FunctionAction, a.__class__
2597 def test_AddPostAction(self):
2598 """Test the AddPostAction() method"""
2599 env = self.TestEnvironment(FOO='fff', BAR='bbb')
2601 n = env.AddPostAction('$FOO', lambda x: x)
2602 assert str(n[0]) == 'fff', n[0]
2604 n = env.AddPostAction(['ggg', '$BAR'], lambda x: x)
2605 assert str(n[0]) == 'ggg', n[0]
2606 assert str(n[1]) == 'bbb', n[1]
2608 def test_AddPreAction(self):
2609 """Test the AddPreAction() method"""
2610 env = self.TestEnvironment(FOO='fff', BAR='bbb')
2612 n = env.AddPreAction('$FOO', lambda x: x)
2613 assert str(n[0]) == 'fff', n[0]
2615 n = env.AddPreAction(['ggg', '$BAR'], lambda x: x)
2616 assert str(n[0]) == 'ggg', n[0]
2617 assert str(n[1]) == 'bbb', n[1]
2619 def test_Alias(self):
2620 """Test the Alias() method"""
2621 env = self.TestEnvironment(FOO='kkk', BAR='lll', EA='export_alias')
2623 tgt = env.Alias('new_alias')[0]
2624 assert str(tgt) == 'new_alias', tgt
2625 assert tgt.sources == [], tgt.sources
2626 assert not hasattr(tgt, 'builder'), tgt.builder
2628 tgt = env.Alias('None_alias', None)[0]
2629 assert str(tgt) == 'None_alias', tgt
2630 assert tgt.sources == [], tgt.sources
2632 tgt = env.Alias('empty_list', [])[0]
2633 assert str(tgt) == 'empty_list', tgt
2634 assert tgt.sources == [], tgt.sources
2636 tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ])[0]
2637 assert str(tgt) == 'export_alias', tgt
2638 assert len(tgt.sources) == 2, list(map(str, tgt.sources))
2639 assert str(tgt.sources[0]) == 'asrc1', list(map(str, tgt.sources))
2640 assert str(tgt.sources[1]) == 'kkk', list(map(str, tgt.sources))
2642 n = env.Alias(tgt, source = ['$BAR', 'asrc4'])[0]
2644 assert len(tgt.sources) == 4, list(map(str, tgt.sources))
2645 assert str(tgt.sources[2]) == 'lll', list(map(str, tgt.sources))
2646 assert str(tgt.sources[3]) == 'asrc4', list(map(str, tgt.sources))
2648 n = env.Alias('$EA', 'asrc5')[0]
2650 assert len(tgt.sources) == 5, list(map(str, tgt.sources))
2651 assert str(tgt.sources[4]) == 'asrc5', list(map(str, tgt.sources))
2653 t1, t2 = env.Alias(['t1', 't2'], ['asrc6', 'asrc7'])
2654 assert str(t1) == 't1', t1
2655 assert str(t2) == 't2', t2
2656 assert len(t1.sources) == 2, list(map(str, t1.sources))
2657 assert str(t1.sources[0]) == 'asrc6', list(map(str, t1.sources))
2658 assert str(t1.sources[1]) == 'asrc7', list(map(str, t1.sources))
2659 assert len(t2.sources) == 2, list(map(str, t2.sources))
2660 assert str(t2.sources[0]) == 'asrc6', list(map(str, t2.sources))
2661 assert str(t2.sources[1]) == 'asrc7', list(map(str, t2.sources))
2663 tgt = env.Alias('add', 's1')
2664 tgt = env.Alias('add', 's2')[0]
2665 s = list(map(str, tgt.sources))
2666 assert s == ['s1', 's2'], s
2667 tgt = env.Alias(tgt, 's3')[0]
2668 s = list(map(str, tgt.sources))
2669 assert s == ['s1', 's2', 's3'], s
2671 tgt = env.Alias('act', None, "action1")[0]
2672 s = str(tgt.builder.action)
2673 assert s == "action1", s
2674 tgt = env.Alias('act', None, "action2")[0]
2675 s = str(tgt.builder.action)
2676 assert s == "action1\naction2", s
2677 tgt = env.Alias(tgt, None, "action3")[0]
2678 s = str(tgt.builder.action)
2679 assert s == "action1\naction2\naction3", s
2681 def test_AlwaysBuild(self):
2682 """Test the AlwaysBuild() method"""
2683 env = self.TestEnvironment(FOO='fff', BAR='bbb')
2684 t = env.AlwaysBuild('a', 'b$FOO', ['c', 'd'], '$BAR',
2685 env.fs.Dir('dir'), env.fs.File('file'))
2686 assert t[0].__class__.__name__ == 'Entry'
2687 assert t[0].path == 'a'
2688 assert t[0].always_build
2689 assert t[1].__class__.__name__ == 'Entry'
2690 assert t[1].path == 'bfff'
2691 assert t[1].always_build
2692 assert t[2].__class__.__name__ == 'Entry'
2693 assert t[2].path == 'c'
2694 assert t[2].always_build
2695 assert t[3].__class__.__name__ == 'Entry'
2696 assert t[3].path == 'd'
2697 assert t[3].always_build
2698 assert t[4].__class__.__name__ == 'Entry'
2699 assert t[4].path == 'bbb'
2700 assert t[4].always_build
2701 assert t[5].__class__.__name__ == 'Dir'
2702 assert t[5].path == 'dir'
2703 assert t[5].always_build
2704 assert t[6].__class__.__name__ == 'File'
2705 assert t[6].path == 'file'
2706 assert t[6].always_build
2708 def test_VariantDir(self):
2709 """Test the VariantDir() method"""
2711 def Dir(self, name):
2713 def VariantDir(self, variant_dir, src_dir, duplicate):
2714 self.variant_dir = variant_dir
2715 self.src_dir = src_dir
2716 self.duplicate = duplicate
2718 env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb')
2721 env.VariantDir('build', 'src')
2722 assert env.fs.variant_dir == 'build', env.fs.variant_dir
2723 assert env.fs.src_dir == 'src', env.fs.src_dir
2724 assert env.fs.duplicate == 1, env.fs.duplicate
2726 env.VariantDir('build${FOO}', '${BAR}src', 0)
2727 assert env.fs.variant_dir == 'buildfff', env.fs.variant_dir
2728 assert env.fs.src_dir == 'bbbsrc', env.fs.src_dir
2729 assert env.fs.duplicate == 0, env.fs.duplicate
2731 def test_Builder(self):
2732 """Test the Builder() method"""
2733 env = self.TestEnvironment(FOO = 'xyzzy')
2735 b = env.Builder(action = 'foo')
2736 assert b is not None, b
2738 b = env.Builder(action = '$FOO')
2739 assert b is not None, b
2741 b = env.Builder(action = ['$FOO', 'foo'])
2742 assert b is not None, b
2746 b = env.Builder(action = func)
2747 assert b is not None, b
2748 b = env.Builder(generator = func)
2749 assert b is not None, b
2751 def test_CacheDir(self):
2752 """Test the CacheDir() method"""
2753 env = self.TestEnvironment(CD = 'CacheDir')
2756 assert env._CacheDir_path == 'foo', env._CacheDir_path
2759 assert env._CacheDir_path == 'CacheDir', env._CacheDir_path
2761 def test_Clean(self):
2762 """Test the Clean() method"""
2763 env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb')
2765 CT = SCons.Environment.CleanTargets
2767 foo = env.arg2nodes('foo')[0]
2768 fff = env.arg2nodes('fff')[0]
2770 t = env.Clean('foo', 'aaa')
2771 l = list(map(str, CT[foo]))
2772 assert l == ['aaa'], l
2774 t = env.Clean(foo, ['$BAR', 'ccc'])
2775 l = list(map(str, CT[foo]))
2776 assert l == ['aaa', 'bbb', 'ccc'], l
2778 eee = env.arg2nodes('eee')[0]
2780 t = env.Clean('$FOO', 'ddd')
2781 l = list(map(str, CT[fff]))
2782 assert l == ['ddd'], l
2783 t = env.Clean(fff, [eee, 'fff'])
2784 l = list(map(str, CT[fff]))
2785 assert l == ['ddd', 'eee', 'fff'], l
2787 def test_Command(self):
2788 """Test the Command() method."""
2790 t = env.Command(target='foo.out', source=['foo1.in', 'foo2.in'],
2791 action='buildfoo $target $source')[0]
2792 assert t.builder is not None
2793 assert t.builder.action.__class__.__name__ == 'CommandAction'
2794 assert t.builder.action.cmd_list == 'buildfoo $target $source'
2795 assert 'foo1.in' in [x.path for x in t.sources]
2796 assert 'foo2.in' in [x.path for x in t.sources]
2798 sub = env.fs.Dir('sub')
2799 t = env.Command(target='bar.out', source='sub',
2800 action='buildbar $target $source')[0]
2801 assert 'sub' in [x.path for x in t.sources]
2803 def testFunc(env, target, source):
2804 assert str(target[0]) == 'foo.out'
2805 assert 'foo1.in' in list(map(str, source)) and 'foo2.in' in list(map(str, source)), list(map(str, source))
2807 t = env.Command(target='foo.out', source=['foo1.in','foo2.in'],
2809 assert t.builder is not None
2810 assert t.builder.action.__class__.__name__ == 'FunctionAction'
2812 assert 'foo1.in' in [x.path for x in t.sources]
2813 assert 'foo2.in' in [x.path for x in t.sources]
2816 def test2(baz, x=x):
2818 env = self.TestEnvironment(TEST2 = test2)
2819 t = env.Command(target='baz.out', source='baz.in',
2820 action='${TEST2(XYZ)}',
2821 XYZ='magic word')[0]
2822 assert t.builder is not None
2824 assert x[0] == 'magic word', x
2826 t = env.Command(target='${X}.out', source='${X}.in',
2829 assert str(t) == 'xxx.out', str(t)
2830 assert 'xxx.in' in [x.path for x in t.sources]
2832 env = self.TestEnvironment(source_scanner = 'should_not_find_this')
2833 t = env.Command(target='file.out', source='file.in',
2835 source_scanner = 'fake')[0]
2836 assert t.builder.source_scanner == 'fake', t.builder.source_scanner
2838 def test_Configure(self):
2839 """Test the Configure() method"""
2840 # Configure() will write to a local temporary file.
2841 test = TestCmd.TestCmd(workdir = '')
2845 os.chdir(test.workpath())
2847 env = self.TestEnvironment(FOO = 'xyzzy')
2853 assert c is not None, c
2856 c = env.Configure(custom_tests = {'foo' : func, '$FOO' : func})
2857 assert c is not None, c
2858 assert hasattr(c, 'foo')
2859 assert hasattr(c, 'xyzzy')
2864 def test_Depends(self):
2865 """Test the explicit Depends method."""
2866 env = self.TestEnvironment(FOO = 'xxx', BAR='yyy')
2871 t = env.Depends(target='EnvironmentTest.py',
2872 dependency='Environment.py')[0]
2873 assert t.__class__.__name__ == 'Entry', t.__class__.__name__
2874 assert t.path == 'EnvironmentTest.py'
2875 assert len(t.depends) == 1
2877 assert d.__class__.__name__ == 'Entry', d.__class__.__name__
2878 assert d.path == 'Environment.py'
2880 t = env.Depends(target='${FOO}.py', dependency='${BAR}.py')[0]
2881 assert t.__class__.__name__ == 'File', t.__class__.__name__
2882 assert t.path == 'xxx.py'
2883 assert len(t.depends) == 1
2885 assert d.__class__.__name__ == 'File', d.__class__.__name__
2886 assert d.path == 'yyy.py'
2888 t = env.Depends(target='dir1', dependency='dir2')[0]
2889 assert t.__class__.__name__ == 'Dir', t.__class__.__name__
2890 assert t.path == 'dir1'
2891 assert len(t.depends) == 1
2893 assert d.__class__.__name__ == 'Dir', d.__class__.__name__
2894 assert d.path == 'dir2'
2897 """Test the Dir() method"""
2899 def Dir(self, name):
2900 return 'Dir(%s)' % name
2902 env = self.TestEnvironment(FOO = 'foodir', BAR = 'bardir')
2906 assert d == 'Dir(d)', d
2909 assert d == 'Dir(foodir)', d
2911 d = env.Dir('${BAR}_$BAR')
2912 assert d == 'Dir(bardir_bardir)', d
2914 d = env.Dir(['dir1'])
2915 assert d == ['Dir(dir1)'], d
2917 d = env.Dir(['dir1', 'dir2'])
2918 assert d == ['Dir(dir1)', 'Dir(dir2)'], d
2920 def test_NoClean(self):
2921 """Test the NoClean() method"""
2922 env = self.TestEnvironment(FOO='ggg', BAR='hhh')
2925 t = env.NoClean('p_a', 'p_${BAR}b', ['p_c', 'p_d'], 'p_$FOO')
2927 assert t[0].__class__.__name__ == 'Entry', t[0].__class__.__name__
2928 assert t[0].path == 'p_a'
2930 assert t[1].__class__.__name__ == 'Dir', t[1].__class__.__name__
2931 assert t[1].path == 'p_hhhb'
2933 assert t[2].__class__.__name__ == 'Entry', t[2].__class__.__name__
2934 assert t[2].path == 'p_c'
2936 assert t[3].__class__.__name__ == 'File', t[3].__class__.__name__
2937 assert t[3].path == 'p_d'
2939 assert t[4].__class__.__name__ == 'Entry', t[4].__class__.__name__
2940 assert t[4].path == 'p_ggg'
2943 def test_Dump(self):
2944 """Test the Dump() method"""
2946 env = self.TestEnvironment(FOO = 'foo')
2947 assert env.Dump('FOO') == "'foo'", env.Dump('FOO')
2948 assert len(env.Dump()) > 200, env.Dump() # no args version
2950 def test_Environment(self):
2951 """Test the Environment() method"""
2952 env = self.TestEnvironment(FOO = 'xxx', BAR = 'yyy')
2954 e2 = env.Environment(X = '$FOO', Y = '$BAR')
2955 assert e2['X'] == 'xxx', e2['X']
2956 assert e2['Y'] == 'yyy', e2['Y']
2958 def test_Execute(self):
2959 """Test the Execute() method"""
2962 def __init__(self, *args, **kw):
2964 def __call__(self, target, source, env):
2965 return "%s executed" % self.args
2968 env.Action = MyAction
2970 result = env.Execute("foo")
2971 assert result == "foo executed", result
2973 def test_Entry(self):
2974 """Test the Entry() method"""
2976 def Entry(self, name):
2977 return 'Entry(%s)' % name
2979 env = self.TestEnvironment(FOO = 'fooentry', BAR = 'barentry')
2983 assert e == 'Entry(e)', e
2985 e = env.Entry('$FOO')
2986 assert e == 'Entry(fooentry)', e
2988 e = env.Entry('${BAR}_$BAR')
2989 assert e == 'Entry(barentry_barentry)', e
2991 e = env.Entry(['entry1'])
2992 assert e == ['Entry(entry1)'], e
2994 e = env.Entry(['entry1', 'entry2'])
2995 assert e == ['Entry(entry1)', 'Entry(entry2)'], e
2997 def test_File(self):
2998 """Test the File() method"""
3000 def File(self, name):
3001 return 'File(%s)' % name
3003 env = self.TestEnvironment(FOO = 'foofile', BAR = 'barfile')
3007 assert f == 'File(f)', f
3009 f = env.File('$FOO')
3010 assert f == 'File(foofile)', f
3012 f = env.File('${BAR}_$BAR')
3013 assert f == 'File(barfile_barfile)', f
3015 f = env.File(['file1'])
3016 assert f == ['File(file1)'], f
3018 f = env.File(['file1', 'file2'])
3019 assert f == ['File(file1)', 'File(file2)'], f
3021 def test_FindFile(self):
3022 """Test the FindFile() method"""
3023 env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb')
3025 r = env.FindFile('foo', ['no_such_directory'])
3030 def test_Flatten(self):
3031 """Test the Flatten() method"""
3033 l = env.Flatten([1])
3035 l = env.Flatten([1, [2, [3, [4]]]])
3036 assert l == [1, 2, 3, 4], l
3038 def test_GetBuildPath(self):
3039 """Test the GetBuildPath() method."""
3040 env = self.TestEnvironment(MAGIC = 'xyzzy')
3042 p = env.GetBuildPath('foo')
3043 assert p == 'foo', p
3045 p = env.GetBuildPath('$MAGIC')
3046 assert p == 'xyzzy', p
3048 def test_Ignore(self):
3049 """Test the explicit Ignore method."""
3050 env = self.TestEnvironment(FOO='yyy', BAR='zzz')
3056 t = env.Ignore(target='targ.py', dependency='dep.py')[0]
3057 assert t.__class__.__name__ == 'Entry', t.__class__.__name__
3058 assert t.path == 'targ.py'
3059 assert len(t.ignore) == 1
3061 assert i.__class__.__name__ == 'Entry', i.__class__.__name__
3062 assert i.path == 'dep.py'
3064 t = env.Ignore(target='$FOO$BAR', dependency='$BAR$FOO')[0]
3065 assert t.__class__.__name__ == 'File', t.__class__.__name__
3066 assert t.path == 'yyyzzz'
3067 assert len(t.ignore) == 1
3069 assert i.__class__.__name__ == 'File', i.__class__.__name__
3070 assert i.path == 'zzzyyy'
3072 t = env.Ignore(target='dir1', dependency='dir2')[0]
3073 assert t.__class__.__name__ == 'Dir', t.__class__.__name__
3074 assert t.path == 'dir1'
3075 assert len(t.ignore) == 1
3077 assert i.__class__.__name__ == 'Dir', i.__class__.__name__
3078 assert i.path == 'dir2'
3080 def test_Literal(self):
3081 """Test the Literal() method"""
3082 env = self.TestEnvironment(FOO='fff', BAR='bbb')
3083 list = env.subst_list([env.Literal('$FOO'), '$BAR'])[0]
3084 assert list == ['$FOO', 'bbb'], list
3085 list = env.subst_list(['$FOO', env.Literal('$BAR')])[0]
3086 assert list == ['fff', '$BAR'], list
3088 def test_Local(self):
3089 """Test the Local() method."""
3090 env = self.TestEnvironment(FOO='lll')
3092 l = env.Local(env.fs.File('fff'))
3093 assert str(l[0]) == 'fff', l[0]
3095 l = env.Local('ggg', '$FOO')
3096 assert str(l[0]) == 'ggg', l[0]
3097 assert str(l[1]) == 'lll', l[1]
3099 def test_Precious(self):
3100 """Test the Precious() method"""
3101 env = self.TestEnvironment(FOO='ggg', BAR='hhh')
3104 t = env.Precious('p_a', 'p_${BAR}b', ['p_c', 'p_d'], 'p_$FOO')
3106 assert t[0].__class__.__name__ == 'Entry', t[0].__class__.__name__
3107 assert t[0].path == 'p_a'
3108 assert t[0].precious
3109 assert t[1].__class__.__name__ == 'Dir', t[1].__class__.__name__
3110 assert t[1].path == 'p_hhhb'
3111 assert t[1].precious
3112 assert t[2].__class__.__name__ == 'Entry', t[2].__class__.__name__
3113 assert t[2].path == 'p_c'
3114 assert t[2].precious
3115 assert t[3].__class__.__name__ == 'File', t[3].__class__.__name__
3116 assert t[3].path == 'p_d'
3117 assert t[3].precious
3118 assert t[4].__class__.__name__ == 'Entry', t[4].__class__.__name__
3119 assert t[4].path == 'p_ggg'
3120 assert t[4].precious
3122 def test_Repository(self):
3123 """Test the Repository() method."""
3127 def Repository(self, *dirs):
3128 self.list.extend(list(dirs))
3129 def Dir(self, name):
3131 env = self.TestEnvironment(FOO='rrr', BAR='sss')
3133 env.Repository('/tmp/foo')
3134 env.Repository('/tmp/$FOO', '/tmp/$BAR/foo')
3135 expect = ['/tmp/foo', '/tmp/rrr', '/tmp/sss/foo']
3136 assert env.fs.list == expect, env.fs.list
3138 def test_Scanner(self):
3139 """Test the Scanner() method"""
3140 def scan(node, env, target, arg):
3143 env = self.TestEnvironment(FOO = scan)
3145 s = env.Scanner('foo')
3146 assert s is not None, s
3148 s = env.Scanner(function = 'foo')
3149 assert s is not None, s
3152 s = env.Scanner('$FOO')
3153 assert s is not None, s
3155 s = env.Scanner(function = '$FOO')
3156 assert s is not None, s
3158 def test_SConsignFile(self):
3159 """Test the SConsignFile() method"""
3160 import SCons.SConsign
3163 SConstruct_dir = os.sep + 'dir'
3165 env = self.TestEnvironment(FOO = 'SConsign',
3166 BAR = os.path.join(os.sep, 'File'))
3168 env.Execute = lambda action: None
3173 def capture(name, dbm_module, fnames=fnames, dbms=dbms):
3175 dbms.append(dbm_module)
3177 save_SConsign_File = SCons.SConsign.File
3178 SCons.SConsign.File = capture
3180 env.SConsignFile('foo')
3181 assert fnames[-1] == os.path.join(os.sep, 'dir', 'foo'), fnames
3182 assert dbms[-1] is None, dbms
3184 env.SConsignFile('$FOO')
3185 assert fnames[-1] == os.path.join(os.sep, 'dir', 'SConsign'), fnames
3186 assert dbms[-1] is None, dbms
3188 env.SConsignFile('/$FOO')
3189 assert fnames[-1] == os.sep + 'SConsign', fnames
3190 assert dbms[-1] is None, dbms
3192 env.SConsignFile(os.sep + '$FOO')
3193 assert fnames[-1] == os.sep + 'SConsign', fnames
3194 assert dbms[-1] is None, dbms
3196 env.SConsignFile('$BAR', 'x')
3197 assert fnames[-1] == os.path.join(os.sep, 'File'), fnames
3198 assert dbms[-1] == 'x', dbms
3200 env.SConsignFile('__$BAR', 7)
3201 assert fnames[-1] == os.path.join(os.sep, 'dir', '__', 'File'), fnames
3202 assert dbms[-1] == 7, dbms
3205 assert fnames[-1] == os.path.join(os.sep, 'dir', '.sconsign'), fnames
3206 assert dbms[-1] is None, dbms
3208 env.SConsignFile(None)
3209 assert fnames[-1] is None, fnames
3210 assert dbms[-1] is None, dbms
3212 SCons.SConsign.File = save_SConsign_File
3214 def test_SideEffect(self):
3215 """Test the SideEffect() method"""
3216 env = self.TestEnvironment(LIB='lll', FOO='fff', BAR='bbb')
3217 env.File('mylll.pdb')
3218 env.Dir('mymmm.pdb')
3220 foo = env.Object('foo.obj', 'foo.cpp')[0]
3221 bar = env.Object('bar.obj', 'bar.cpp')[0]
3222 s = env.SideEffect('mylib.pdb', ['foo.obj', 'bar.obj'])[0]
3223 assert s.__class__.__name__ == 'Entry', s.__class__.__name__
3224 assert s.path == 'mylib.pdb'
3225 assert s.side_effect
3226 assert foo.side_effects == [s]
3227 assert bar.side_effects == [s]
3229 fff = env.Object('fff.obj', 'fff.cpp')[0]
3230 bbb = env.Object('bbb.obj', 'bbb.cpp')[0]
3231 s = env.SideEffect('my${LIB}.pdb', ['${FOO}.obj', '${BAR}.obj'])[0]
3232 assert s.__class__.__name__ == 'File', s.__class__.__name__
3233 assert s.path == 'mylll.pdb'
3234 assert s.side_effect
3235 assert fff.side_effects == [s], fff.side_effects
3236 assert bbb.side_effects == [s], bbb.side_effects
3238 ggg = env.Object('ggg.obj', 'ggg.cpp')[0]
3239 ccc = env.Object('ccc.obj', 'ccc.cpp')[0]
3240 s = env.SideEffect('mymmm.pdb', ['ggg.obj', 'ccc.obj'])[0]
3241 assert s.__class__.__name__ == 'Dir', s.__class__.__name__
3242 assert s.path == 'mymmm.pdb'
3243 assert s.side_effect
3244 assert ggg.side_effects == [s], ggg.side_effects
3245 assert ccc.side_effects == [s], ccc.side_effects
3247 def test_SourceCode(self):
3248 """Test the SourceCode() method."""
3249 env = self.TestEnvironment(FOO='mmm', BAR='nnn')
3250 e = env.SourceCode('foo', None)[0]
3251 assert e.path == 'foo'
3256 e = env.SourceCode(e, b)[0]
3257 assert e.path == 'foo'
3261 e = env.SourceCode('$BAR$FOO', None)[0]
3262 assert e.path == 'nnnmmm'
3266 def test_SourceSignatures(type):
3267 """Test the SourceSignatures() method"""
3270 env = type.TestEnvironment(M = 'MD5', T = 'timestamp')
3274 env.SourceSignatures('invalid_type')
3275 except SCons.Errors.UserError:
3277 assert exc_caught, "did not catch expected UserError"
3279 env.SourceSignatures('MD5')
3280 assert env.src_sig_type == 'MD5', env.src_sig_type
3282 env.SourceSignatures('$M')
3283 assert env.src_sig_type == 'MD5', env.src_sig_type
3285 env.SourceSignatures('timestamp')
3286 assert env.src_sig_type == 'timestamp', env.src_sig_type
3288 env.SourceSignatures('$T')
3289 assert env.src_sig_type == 'timestamp', env.src_sig_type
3293 save_md5 = SCons.Util.md5
3294 SCons.Util.md5 = None
3296 env.SourceSignatures('MD5')
3297 except SCons.Errors.UserError:
3300 self.fail('Did not catch expected UserError')
3302 SCons.Util.md5 = save_md5
3304 def test_Split(self):
3305 """Test the Split() method"""
3306 env = self.TestEnvironment(FOO='fff', BAR='bbb')
3307 s = env.Split("foo bar")
3308 assert s == ["foo", "bar"], s
3309 s = env.Split("$FOO bar")
3310 assert s == ["fff", "bar"], s
3311 s = env.Split(["foo", "bar"])
3312 assert s == ["foo", "bar"], s
3313 s = env.Split(["foo", "${BAR}-bbb"])
3314 assert s == ["foo", "bbb-bbb"], s
3315 s = env.Split("foo")
3316 assert s == ["foo"], s
3317 s = env.Split("$FOO$BAR")
3318 assert s == ["fffbbb"], s
3320 def test_TargetSignatures(type):
3321 """Test the TargetSignatures() method"""
3324 env = type.TestEnvironment(B = 'build', C = 'content')
3328 env.TargetSignatures('invalid_type')
3329 except SCons.Errors.UserError:
3331 assert exc_caught, "did not catch expected UserError"
3332 assert not hasattr(env, '_build_signature')
3334 env.TargetSignatures('build')
3335 assert env.tgt_sig_type == 'build', env.tgt_sig_type
3337 env.TargetSignatures('$B')
3338 assert env.tgt_sig_type == 'build', env.tgt_sig_type
3340 env.TargetSignatures('content')
3341 assert env.tgt_sig_type == 'content', env.tgt_sig_type
3343 env.TargetSignatures('$C')
3344 assert env.tgt_sig_type == 'content', env.tgt_sig_type
3346 env.TargetSignatures('MD5')
3347 assert env.tgt_sig_type == 'MD5', env.tgt_sig_type
3349 env.TargetSignatures('timestamp')
3350 assert env.tgt_sig_type == 'timestamp', env.tgt_sig_type
3354 save_md5 = SCons.Util.md5
3355 SCons.Util.md5 = None
3357 env.TargetSignatures('MD5')
3358 except SCons.Errors.UserError:
3361 self.fail('Did not catch expected UserError')
3363 env.TargetSignatures('content')
3364 except SCons.Errors.UserError:
3367 self.fail('Did not catch expected UserError')
3369 SCons.Util.md5 = save_md5
3371 def test_Value(self):
3372 """Test creating a Value() object
3376 assert v1.value == 'a', v1.value
3379 v2 = env.Value(value2)
3380 assert v2.value == value2, v2.value
3381 assert v2.value is value2, v2.value
3384 assert v1.value == v2.value
3386 v3 = env.Value('c', 'build-c')
3387 assert v3.value == 'c', v3.value
3391 def test_Environment_global_variable(type):
3392 """Test setting Environment variable to an Environment.Base subclass"""
3393 class MyEnv(SCons.Environment.Base):
3394 def xxx(self, string):
3395 return self.subst(string)
3397 SCons.Environment.Environment = MyEnv
3399 env = SCons.Environment.Environment(FOO = 'foo')
3401 f = env.subst('$FOO')
3402 assert f == 'foo', f
3405 assert f == 'foo', f
3407 def test_bad_keywords(self):
3408 """Test trying to use reserved keywords in an Environment"""
3411 env = self.TestEnvironment(TARGETS = 'targets',
3412 SOURCES = 'sources',
3415 CHANGED_SOURCES = 'changed_sources',
3416 CHANGED_TARGETS = 'changed_targets',
3417 UNCHANGED_SOURCES = 'unchanged_sources',
3418 UNCHANGED_TARGETS = 'unchanged_targets',
3420 bad_msg = '%s is not reserved, but got omitted; see Environment.construction_var_name_ok'
3421 added.append('INIT')
3422 for x in self.reserved_variables:
3423 assert x not in env, env[x]
3425 assert x in env, bad_msg % x
3427 env.Append(TARGETS = 'targets',
3428 SOURCES = 'sources',
3431 CHANGED_SOURCES = 'changed_sources',
3432 CHANGED_TARGETS = 'changed_targets',
3433 UNCHANGED_SOURCES = 'unchanged_sources',
3434 UNCHANGED_TARGETS = 'unchanged_targets',
3436 added.append('APPEND')
3437 for x in self.reserved_variables:
3438 assert x not in env, env[x]
3440 assert x in env, bad_msg % x
3442 env.AppendUnique(TARGETS = 'targets',
3443 SOURCES = 'sources',
3446 CHANGED_SOURCES = 'changed_sources',
3447 CHANGED_TARGETS = 'changed_targets',
3448 UNCHANGED_SOURCES = 'unchanged_sources',
3449 UNCHANGED_TARGETS = 'unchanged_targets',
3450 APPENDUNIQUE = 'appendunique')
3451 added.append('APPENDUNIQUE')
3452 for x in self.reserved_variables:
3453 assert x not in env, env[x]
3455 assert x in env, bad_msg % x
3457 env.Prepend(TARGETS = 'targets',
3458 SOURCES = 'sources',
3461 CHANGED_SOURCES = 'changed_sources',
3462 CHANGED_TARGETS = 'changed_targets',
3463 UNCHANGED_SOURCES = 'unchanged_sources',
3464 UNCHANGED_TARGETS = 'unchanged_targets',
3465 PREPEND = 'prepend')
3466 added.append('PREPEND')
3467 for x in self.reserved_variables:
3468 assert x not in env, env[x]
3470 assert x in env, bad_msg % x
3472 env.Prepend(TARGETS = 'targets',
3473 SOURCES = 'sources',
3476 CHANGED_SOURCES = 'changed_sources',
3477 CHANGED_TARGETS = 'changed_targets',
3478 UNCHANGED_SOURCES = 'unchanged_sources',
3479 UNCHANGED_TARGETS = 'unchanged_targets',
3480 PREPENDUNIQUE = 'prependunique')
3481 added.append('PREPENDUNIQUE')
3482 for x in self.reserved_variables:
3483 assert x not in env, env[x]
3485 assert x in env, bad_msg % x
3487 env.Replace(TARGETS = 'targets',
3488 SOURCES = 'sources',
3491 CHANGED_SOURCES = 'changed_sources',
3492 CHANGED_TARGETS = 'changed_targets',
3493 UNCHANGED_SOURCES = 'unchanged_sources',
3494 UNCHANGED_TARGETS = 'unchanged_targets',
3495 REPLACE = 'replace')
3496 added.append('REPLACE')
3497 for x in self.reserved_variables:
3498 assert x not in env, env[x]
3500 assert x in env, bad_msg % x
3502 copy = env.Clone(TARGETS = 'targets',
3503 SOURCES = 'sources',
3506 CHANGED_SOURCES = 'changed_sources',
3507 CHANGED_TARGETS = 'changed_targets',
3508 UNCHANGED_SOURCES = 'unchanged_sources',
3509 UNCHANGED_TARGETS = 'unchanged_targets',
3511 for x in self.reserved_variables:
3512 assert x not in copy, env[x]
3513 for x in added + ['COPY']:
3514 assert x in copy, bad_msg % x
3516 over = env.Override({'TARGETS' : 'targets',
3517 'SOURCES' : 'sources',
3518 'SOURCE' : 'source',
3519 'TARGET' : 'target',
3520 'CHANGED_SOURCES' : 'changed_sources',
3521 'CHANGED_TARGETS' : 'changed_targets',
3522 'UNCHANGED_SOURCES' : 'unchanged_sources',
3523 'UNCHANGED_TARGETS' : 'unchanged_targets',
3524 'OVERRIDE' : 'override'})
3525 for x in self.reserved_variables:
3526 assert x not in over, over[x]
3527 for x in added + ['OVERRIDE']:
3528 assert x in over, bad_msg % x
3530 def test_parse_flags(self):
3531 '''Test the Base class parse_flags argument'''
3532 # all we have to show is that it gets to MergeFlags internally
3533 env = Environment(tools=[], parse_flags = '-X')
3534 assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
3536 env = Environment(tools=[], CCFLAGS=None, parse_flags = '-Y')
3537 assert env['CCFLAGS'] == ['-Y'], env['CCFLAGS']
3539 env = Environment(tools=[], CPPDEFINES = 'FOO', parse_flags = '-std=c99 -X -DBAR')
3540 assert env['CFLAGS'] == ['-std=c99'], env['CFLAGS']
3541 assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
3542 assert env['CPPDEFINES'] == ['FOO', 'BAR'], env['CPPDEFINES']
3544 def test_clone_parse_flags(self):
3545 '''Test the env.Clone() parse_flags argument'''
3546 # all we have to show is that it gets to MergeFlags internally
3547 env = Environment(tools = [])
3548 env2 = env.Clone(parse_flags = '-X')
3549 assert 'CCFLAGS' not in env
3550 assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
3552 env = Environment(tools = [], CCFLAGS=None)
3553 env2 = env.Clone(parse_flags = '-Y')
3554 assert env['CCFLAGS'] is None, env['CCFLAGS']
3555 assert env2['CCFLAGS'] == ['-Y'], env2['CCFLAGS']
3557 env = Environment(tools = [], CPPDEFINES = 'FOO')
3558 env2 = env.Clone(parse_flags = '-std=c99 -X -DBAR')
3559 assert 'CFLAGS' not in env
3560 assert env2['CFLAGS'] == ['-std=c99'], env2['CFLAGS']
3561 assert 'CCFLAGS' not in env
3562 assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
3563 assert env['CPPDEFINES'] == 'FOO', env['CPPDEFINES']
3564 assert env2['CPPDEFINES'] == ['FOO','BAR'], env2['CPPDEFINES']
3568 class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture):
3572 env._dict = {'XXX' : 'x', 'YYY' : 'y'}
3573 env2 = OverrideEnvironment(env, {'XXX' : 'x2'})
3574 env3 = OverrideEnvironment(env2, {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'})
3575 self.envs = [ env, env2, env3 ]
3577 def checkpath(self, node, expect):
3578 return str(node) == os.path.normpath(expect)
3580 def test___init__(self):
3581 """Test OverrideEnvironment initialization"""
3582 env, env2, env3 = self.envs
3583 assert env['XXX'] == 'x', env['XXX']
3584 assert env2['XXX'] == 'x2', env2['XXX']
3585 assert env3['XXX'] == 'x3', env3['XXX']
3586 assert env['YYY'] == 'y', env['YYY']
3587 assert env2['YYY'] == 'y', env2['YYY']
3588 assert env3['YYY'] == 'y3', env3['YYY']
3590 def test___delitem__(self):
3591 """Test deleting variables from an OverrideEnvironment"""
3592 env, env2, env3 = self.envs
3595 assert 'XXX' not in env, "env has XXX?"
3596 assert 'XXX' not in env2, "env2 has XXX?"
3597 assert 'XXX' not in env3, "env3 has XXX?"
3600 assert 'YYY' not in env, "env has YYY?"
3601 assert 'YYY' not in env2, "env2 has YYY?"
3602 assert 'YYY' not in env3, "env3 has YYY?"
3605 assert 'ZZZ' not in env, "env has ZZZ?"
3606 assert 'ZZZ' not in env2, "env2 has ZZZ?"
3607 assert 'ZZZ' not in env3, "env3 has ZZZ?"
3610 """Test the OverrideEnvironment get() method"""
3611 env, env2, env3 = self.envs
3612 assert env.get('XXX') == 'x', env.get('XXX')
3613 assert env2.get('XXX') == 'x2', env2.get('XXX')
3614 assert env3.get('XXX') == 'x3', env3.get('XXX')
3615 assert env.get('YYY') == 'y', env.get('YYY')
3616 assert env2.get('YYY') == 'y', env2.get('YYY')
3617 assert env3.get('YYY') == 'y3', env3.get('YYY')
3618 assert env.get('ZZZ') is None, env.get('ZZZ')
3619 assert env2.get('ZZZ') is None, env2.get('ZZZ')
3620 assert env3.get('ZZZ') == 'z3', env3.get('ZZZ')
3622 def test_has_key(self):
3623 """Test the OverrideEnvironment has_key() method"""
3624 env, env2, env3 = self.envs
3625 assert 'XXX' in env, 'XXX' in env
3626 assert 'XXX' in env2, 'XXX' in env2
3627 assert 'XXX' in env3, 'XXX' in env3
3628 assert 'YYY' in env, 'YYY' in env
3629 assert 'YYY' in env2, 'YYY' in env2
3630 assert 'YYY' in env3, 'YYY' in env3
3631 assert 'ZZZ' not in env, 'ZZZ' in env
3632 assert 'ZZZ' not in env2, 'ZZZ' in env2
3633 assert 'ZZZ' in env3, 'ZZZ' in env3
3635 def test_contains(self):
3636 """Test the OverrideEnvironment __contains__() method"""
3641 # An early version of Python that doesn't support "in"
3642 # on dictionaries. Just pass the test.
3645 env, env2, env3 = self.envs
3647 assert 'XXX' in env2
3648 assert 'XXX' in env3
3650 assert 'YYY' in env2
3651 assert 'YYY' in env3
3652 assert not 'ZZZ' in env
3653 assert not 'ZZZ' in env2
3654 assert 'ZZZ' in env3
3656 def test_items(self):
3657 """Test the OverrideEnvironment Dictionary() method"""
3658 env, env2, env3 = self.envs
3659 items = env.Dictionary()
3660 assert items == {'XXX' : 'x', 'YYY' : 'y'}, items
3661 items = env2.Dictionary()
3662 assert items == {'XXX' : 'x2', 'YYY' : 'y'}, items
3663 items = env3.Dictionary()
3664 assert items == {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}, items
3666 def test_items(self):
3667 """Test the OverrideEnvironment items() method"""
3668 env, env2, env3 = self.envs
3669 items = sorted(env.items())
3670 assert items == [('XXX', 'x'), ('YYY', 'y')], items
3671 items = sorted(env2.items())
3672 assert items == [('XXX', 'x2'), ('YYY', 'y')], items
3673 items = sorted(env3.items())
3674 assert items == [('XXX', 'x3'), ('YYY', 'y3'), ('ZZZ', 'z3')], items
3676 def test_gvars(self):
3677 """Test the OverrideEnvironment gvars() method"""
3678 env, env2, env3 = self.envs
3680 assert gvars == {'XXX' : 'x', 'YYY' : 'y'}, gvars
3681 gvars = env2.gvars()
3682 assert gvars == {'XXX' : 'x', 'YYY' : 'y'}, gvars
3683 gvars = env3.gvars()
3684 assert gvars == {'XXX' : 'x', 'YYY' : 'y'}, gvars
3686 def test_lvars(self):
3687 """Test the OverrideEnvironment lvars() method"""
3688 env, env2, env3 = self.envs
3690 assert lvars == {}, lvars
3691 lvars = env2.lvars()
3692 assert lvars == {'XXX' : 'x2'}, lvars
3693 lvars = env3.lvars()
3694 assert lvars == {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}, lvars
3696 def test_Replace(self):
3697 """Test the OverrideEnvironment Replace() method"""
3698 env, env2, env3 = self.envs
3699 assert env['XXX'] == 'x', env['XXX']
3700 assert env2['XXX'] == 'x2', env2['XXX']
3701 assert env3['XXX'] == 'x3', env3['XXX']
3702 assert env['YYY'] == 'y', env['YYY']
3703 assert env2['YYY'] == 'y', env2['YYY']
3704 assert env3['YYY'] == 'y3', env3['YYY']
3706 env.Replace(YYY = 'y4')
3708 assert env['XXX'] == 'x', env['XXX']
3709 assert env2['XXX'] == 'x2', env2['XXX']
3710 assert env3['XXX'] == 'x3', env3['XXX']
3711 assert env['YYY'] == 'y4', env['YYY']
3712 assert env2['YYY'] == 'y4', env2['YYY']
3713 assert env3['YYY'] == 'y3', env3['YYY']
3715 # Tests a number of Base methods through an OverrideEnvironment to
3716 # make sure they handle overridden constructionv variables properly.
3718 # The following Base methods also call self.subst(), and so could
3719 # theoretically be subject to problems with evaluating overridden
3720 # variables, but they're never really called that way in the rest
3721 # of our code, so we won't worry about them (at least for now):
3736 # SourceSignatures()
3737 # TargetSignatures()
3739 # It's unlikely Clone() will ever be called this way, so let the
3740 # other methods test that handling overridden values works.
3741 #def test_Clone(self):
3742 # """Test the OverrideEnvironment Clone() method"""
3745 def test_FindIxes(self):
3746 """Test the OverrideEnvironment FindIxes() method"""
3747 env, env2, env3 = self.envs
3748 x = env.FindIxes(['xaaay'], 'XXX', 'YYY')
3749 assert x == 'xaaay', x
3750 x = env2.FindIxes(['x2aaay'], 'XXX', 'YYY')
3751 assert x == 'x2aaay', x
3752 x = env3.FindIxes(['x3aaay3'], 'XXX', 'YYY')
3753 assert x == 'x3aaay3', x
3755 def test_ReplaceIxes(self):
3756 """Test the OverrideEnvironment ReplaceIxes() method"""
3757 env, env2, env3 = self.envs
3758 x = env.ReplaceIxes('xaaay', 'XXX', 'YYY', 'YYY', 'XXX')
3759 assert x == 'yaaax', x
3760 x = env2.ReplaceIxes('x2aaay', 'XXX', 'YYY', 'YYY', 'XXX')
3761 assert x == 'yaaax2', x
3762 x = env3.ReplaceIxes('x3aaay3', 'XXX', 'YYY', 'YYY', 'XXX')
3763 assert x == 'y3aaax3', x
3765 # It's unlikely WhereIs() will ever be called this way, so let the
3766 # other methods test that handling overridden values works.
3767 #def test_WhereIs(self):
3768 # """Test the OverrideEnvironment WhereIs() method"""
3772 """Test the OverrideEnvironment Dir() method"""
3773 env, env2, env3 = self.envs
3774 x = env.Dir('ddir/$XXX')
3775 assert self.checkpath(x, 'ddir/x'), str(x)
3776 x = env2.Dir('ddir/$XXX')
3777 assert self.checkpath(x, 'ddir/x2'), str(x)
3778 x = env3.Dir('ddir/$XXX')
3779 assert self.checkpath(x, 'ddir/x3'), str(x)
3781 def test_Entry(self):
3782 """Test the OverrideEnvironment Entry() method"""
3783 env, env2, env3 = self.envs
3784 x = env.Entry('edir/$XXX')
3785 assert self.checkpath(x, 'edir/x'), str(x)
3786 x = env2.Entry('edir/$XXX')
3787 assert self.checkpath(x, 'edir/x2'), str(x)
3788 x = env3.Entry('edir/$XXX')
3789 assert self.checkpath(x, 'edir/x3'), str(x)
3791 def test_File(self):
3792 """Test the OverrideEnvironment File() method"""
3793 env, env2, env3 = self.envs
3794 x = env.File('fdir/$XXX')
3795 assert self.checkpath(x, 'fdir/x'), str(x)
3796 x = env2.File('fdir/$XXX')
3797 assert self.checkpath(x, 'fdir/x2'), str(x)
3798 x = env3.File('fdir/$XXX')
3799 assert self.checkpath(x, 'fdir/x3'), str(x)
3801 def test_Split(self):
3802 """Test the OverrideEnvironment Split() method"""
3803 env, env2, env3 = self.envs
3804 env['AAA'] = '$XXX $YYY $ZZZ'
3805 x = env.Split('$AAA')
3806 assert x == ['x', 'y'], x
3807 x = env2.Split('$AAA')
3808 assert x == ['x2', 'y'], x
3809 x = env3.Split('$AAA')
3810 assert x == ['x3', 'y3', 'z3'], x
3812 def test_parse_flags(self):
3813 '''Test the OverrideEnvironment parse_flags argument'''
3814 # all we have to show is that it gets to MergeFlags internally
3815 env = SubstitutionEnvironment()
3816 env2 = env.Override({'parse_flags' : '-X'})
3817 assert 'CCFLAGS' not in env
3818 assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
3820 env = SubstitutionEnvironment(CCFLAGS=None)
3821 env2 = env.Override({'parse_flags' : '-Y'})
3822 assert env['CCFLAGS'] is None, env['CCFLAGS']
3823 assert env2['CCFLAGS'] == ['-Y'], env2['CCFLAGS']
3825 env = SubstitutionEnvironment(CPPDEFINES = 'FOO')
3826 env2 = env.Override({'parse_flags' : '-std=c99 -X -DBAR'})
3827 assert 'CFLAGS' not in env
3828 assert env2['CFLAGS'] == ['-std=c99'], env2['CFLAGS']
3829 assert 'CCFLAGS' not in env
3830 assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
3831 assert env['CPPDEFINES'] == 'FOO', env['CPPDEFINES']
3832 assert env2['CPPDEFINES'] == ['FOO','BAR'], env2['CPPDEFINES']
3836 class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture):
3838 def test___init__(self):
3839 """Test NoSubstitutionProxy initialization"""
3840 env = self.TestEnvironment(XXX = 'x', YYY = 'y')
3841 assert env['XXX'] == 'x', env['XXX']
3842 assert env['YYY'] == 'y', env['YYY']
3844 proxy = NoSubstitutionProxy(env)
3845 assert proxy['XXX'] == 'x', proxy['XXX']
3846 assert proxy['YYY'] == 'y', proxy['YYY']
3848 def test_attributes(self):
3849 """Test getting and setting NoSubstitutionProxy attributes"""
3851 setattr(env, 'env_attr', 'value1')
3853 proxy = NoSubstitutionProxy(env)
3854 setattr(proxy, 'proxy_attr', 'value2')
3856 x = getattr(env, 'env_attr')
3857 assert x == 'value1', x
3858 x = getattr(proxy, 'env_attr')
3859 assert x == 'value1', x
3861 x = getattr(env, 'proxy_attr')
3862 assert x == 'value2', x
3863 x = getattr(proxy, 'proxy_attr')
3864 assert x == 'value2', x
3866 def test_subst(self):
3867 """Test the NoSubstitutionProxy.subst() method"""
3868 env = self.TestEnvironment(XXX = 'x', YYY = 'y')
3869 assert env['XXX'] == 'x', env['XXX']
3870 assert env['YYY'] == 'y', env['YYY']
3872 proxy = NoSubstitutionProxy(env)
3873 assert proxy['XXX'] == 'x', proxy['XXX']
3874 assert proxy['YYY'] == 'y', proxy['YYY']
3876 x = env.subst('$XXX')
3878 x = proxy.subst('$XXX')
3879 assert x == '$XXX', x
3881 x = proxy.subst('$YYY', raw=7, target=None, source=None,
3883 extra_meaningless_keyword_argument=None)
3884 assert x == '$YYY', x
3886 def test_subst_kw(self):
3887 """Test the NoSubstitutionProxy.subst_kw() method"""
3888 env = self.TestEnvironment(XXX = 'x', YYY = 'y')
3889 assert env['XXX'] == 'x', env['XXX']
3890 assert env['YYY'] == 'y', env['YYY']
3892 proxy = NoSubstitutionProxy(env)
3893 assert proxy['XXX'] == 'x', proxy['XXX']
3894 assert proxy['YYY'] == 'y', proxy['YYY']
3896 x = env.subst_kw({'$XXX':'$YYY'})
3897 assert x == {'x':'y'}, x
3898 x = proxy.subst_kw({'$XXX':'$YYY'})
3899 assert x == {'$XXX':'$YYY'}, x
3901 def test_subst_list(self):
3902 """Test the NoSubstitutionProxy.subst_list() method"""
3903 env = self.TestEnvironment(XXX = 'x', YYY = 'y')
3904 assert env['XXX'] == 'x', env['XXX']
3905 assert env['YYY'] == 'y', env['YYY']
3907 proxy = NoSubstitutionProxy(env)
3908 assert proxy['XXX'] == 'x', proxy['XXX']
3909 assert proxy['YYY'] == 'y', proxy['YYY']
3911 x = env.subst_list('$XXX')
3912 assert x == [['x']], x
3913 x = proxy.subst_list('$XXX')
3916 x = proxy.subst_list('$YYY', raw=0, target=None, source=None, conv=None)
3919 def test_subst_target_source(self):
3920 """Test the NoSubstitutionProxy.subst_target_source() method"""
3921 env = self.TestEnvironment(XXX = 'x', YYY = 'y')
3922 assert env['XXX'] == 'x', env['XXX']
3923 assert env['YYY'] == 'y', env['YYY']
3925 proxy = NoSubstitutionProxy(env)
3926 assert proxy['XXX'] == 'x', proxy['XXX']
3927 assert proxy['YYY'] == 'y', proxy['YYY']
3929 args = ('$XXX $TARGET $SOURCE $YYY',)
3930 kw = {'target' : DummyNode('ttt'), 'source' : DummyNode('sss')}
3931 x = env.subst_target_source(*args, **kw)
3932 assert x == 'x ttt sss y', x
3933 x = proxy.subst_target_source(*args, **kw)
3934 assert x == ' ttt sss ', x
3936 class EnvironmentVariableTestCase(unittest.TestCase):
3938 def test_is_valid_construction_var(self):
3939 """Testing is_valid_construction_var()"""
3940 r = is_valid_construction_var("_a")
3941 assert r is not None, r
3942 r = is_valid_construction_var("z_")
3943 assert r is not None, r
3944 r = is_valid_construction_var("X_")
3945 assert r is not None, r
3946 r = is_valid_construction_var("2a")
3948 r = is_valid_construction_var("a2_")
3949 assert r is not None, r
3950 r = is_valid_construction_var("/")
3952 r = is_valid_construction_var("_/")
3954 r = is_valid_construction_var("a/")
3956 r = is_valid_construction_var(".b")
3958 r = is_valid_construction_var("_.b")
3960 r = is_valid_construction_var("b1._")
3962 r = is_valid_construction_var("-b")
3964 r = is_valid_construction_var("_-b")
3966 r = is_valid_construction_var("b1-_")
3971 if __name__ == "__main__":
3972 suite = unittest.TestSuite()
3973 tclasses = [ SubstitutionTestCase,
3975 OverrideEnvironmentTestCase,
3976 NoSubstitutionProxyTestCase,
3977 EnvironmentVariableTestCase ]
3978 for tclass in tclasses:
3979 names = unittest.getTestCaseNames(tclass, 'test_')
3980 suite.addTests(list(map(tclass, names)))
3981 if not unittest.TextTestRunner().run(suite).wasSuccessful():
3986 # indent-tabs-mode:nil
3988 # vim: set expandtab tabstop=4 shiftwidth=4: