#
-# Copyright (c) 2001, 2002 Steven Knight
+# __COPYRIGHT__
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
-
+#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-# Define a null function for use as a builder action.
-# Where this is defined in the file seems to affect its
-# byte-code contents, so try to minimize changes by
-# defining it here, before we even import anything.
-def Func():
+# Define a null function and a null class for use as builder actions.
+# Where these are defined in the file seems to affect their byte-code
+# contents, so try to minimize changes by defining them here, before we
+# even import anything.
+def GlobalFunc():
pass
+class GlobalActFunc:
+ def __call__(self):
+ pass
+
import os
+import re
+import StringIO
+import string
import sys
import types
import unittest
# for each test, they can just use the one.
test = TestCmd.TestCmd(workdir = '')
-test.write('act.py', """import os, string, sys
+test.write('act.py', """\
+import os, string, sys
f = open(sys.argv[1], 'w')
f.write("act.py: '" + string.join(sys.argv[2:], "' '") + "'\\n")
try:
except:
pass
f.close()
+if os.environ.has_key( 'ACTPY_PIPE' ):
+ if os.environ.has_key( 'PIPE_STDOUT_FILE' ):
+ stdout_msg = open(os.environ['PIPE_STDOUT_FILE'], 'r').read()
+ else:
+ stdout_msg = "act.py: stdout: executed act.py %s\\n" % string.join(sys.argv[1:])
+ sys.stdout.write( stdout_msg )
+ if os.environ.has_key( 'PIPE_STDERR_FILE' ):
+ stderr_msg = open(os.environ['PIPE_STDERR_FILE'], 'r').read()
+ else:
+ stderr_msg = "act.py: stderr: executed act.py %s\\n" % string.join(sys.argv[1:])
+ sys.stderr.write( stderr_msg )
sys.exit(0)
""")
+test.write('exit.py', """\
+import sys
+sys.exit(int(sys.argv[1]))
+""")
+
act_py = test.workpath('act.py')
+exit_py = test.workpath('exit.py')
outfile = test.workpath('outfile')
outfile2 = test.workpath('outfile2')
+pipe_file = test.workpath('pipe.out')
scons_env = SCons.Environment.Environment()
+# Capture all the stuff the Actions will print,
+# so it doesn't clutter the output.
+sys.stdout = StringIO.StringIO()
+
+class CmdStringHolder:
+ def __init__(self, cmd, literal=None):
+ self.data = str(cmd)
+ self.literal = literal
+
+ def is_literal(self):
+ return self.literal
+
+ def escape(self, escape_func):
+ """Escape the string with the supplied function. The
+ function is expected to take an arbitrary string, then
+ return it with all special characters escaped and ready
+ for passing to the command interpreter.
+
+ After calling this function, the next call to str() will
+ return the escaped string.
+ """
+
+ if self.is_literal():
+ return escape_func(self.data)
+ elif ' ' in self.data or '\t' in self.data:
+ return '"%s"' % self.data
+ else:
+ return self.data
+
class Environment:
def __init__(self, **kw):
self.d = {}
self.d['SHELL'] = scons_env['SHELL']
self.d['SPAWN'] = scons_env['SPAWN']
+ self.d['PSPAWN'] = scons_env['PSPAWN']
self.d['ESCAPE'] = scons_env['ESCAPE']
for k, v in kw.items():
self.d[k] = v
- def subst(self, s):
- if not SCons.Util.is_String(s):
- return s
- try:
- if s[0] == '$':
- return self.d.get(s[1:], '')
- except IndexError:
- pass
- return self.d.get(s, s)
+ # Just use the underlying scons_subst*() utility methods.
+ def subst(self, strSubst, raw=0, target=[], source=[], conv=None):
+ return SCons.Subst.scons_subst(strSubst, self, raw,
+ target, source, self.d, conv=conv)
+ subst_target_source = subst
+ def subst_list(self, strSubst, raw=0, target=[], source=[], conv=None):
+ return SCons.Subst.scons_subst_list(strSubst, self, raw,
+ target, source, self.d, conv=conv)
def __getitem__(self, item):
return self.d[item]
+ def __setitem__(self, item, value):
+ self.d[item] = value
def has_key(self, item):
return self.d.has_key(item)
- def get(self, key, value):
+ def get(self, key, value=None):
return self.d.get(key, value)
def items(self):
return self.d.items()
+ def Dictionary(self):
+ return self.d
+ def Clone(self, **kw):
+ res = Environment()
+ res.d = SCons.Util.semi_deepcopy(self.d)
+ for k, v in kw.items():
+ res.d[k] = v
+ return res
+ def sig_dict(self):
+ d = {}
+ for k,v in self.items(): d[k] = v
+ d['TARGETS'] = ['__t1__', '__t2__', '__t3__', '__t4__', '__t5__', '__t6__']
+ d['TARGET'] = d['TARGETS'][0]
+ d['SOURCES'] = ['__s1__', '__s2__', '__s3__', '__s4__', '__s5__', '__s6__']
+ d['SOURCE'] = d['SOURCES'][0]
+ return d
+
+class DummyNode:
+ def __init__(self, name):
+ self.name = name
+ def __str__(self):
+ return self.name
+ def rfile(self):
+ return self
+ def get_subst_proxy(self):
+ return self
if os.name == 'java':
python = os.path.join(sys.prefix, 'jython')
else:
python = sys.executable
+_python_ = '"' + python + '"'
+
class ActionTestCase(unittest.TestCase):
+ """Test the Action() factory function"""
- def test_factory(self):
- """Test the Action factory
+ def test_FunctionAction(self):
+ """Test the Action() factory's creation of FunctionAction objects
"""
def foo():
pass
assert isinstance(a1, SCons.Action.FunctionAction), a1
assert a1.execfunction == foo, a1.execfunction
- a2 = SCons.Action.Action("string")
- assert isinstance(a2, SCons.Action.CommandAction), a2
- assert a2.cmd_list == ["string"], a2.cmd_list
+ a11 = SCons.Action.Action(foo, strfunction=bar)
+ assert isinstance(a11, SCons.Action.FunctionAction), a11
+ assert a11.execfunction == foo, a11.execfunction
+ assert a11.strfunction == bar, a11.strfunction
+
+ def test_CommandAction(self):
+ """Test the Action() factory's creation of CommandAction objects
+ """
+ a1 = SCons.Action.Action("string")
+ assert isinstance(a1, SCons.Action.CommandAction), a1
+ assert a1.cmd_list == "string", a1.cmd_list
if hasattr(types, 'UnicodeType'):
- exec "a3 = SCons.Action.Action(u'string')"
- exec "assert isinstance(a3, SCons.Action.CommandAction), a3"
+ exec "a2 = SCons.Action.Action(u'string')"
+ exec "assert isinstance(a2, SCons.Action.CommandAction), a2"
+
+ a3 = SCons.Action.Action(["a3"])
+ assert isinstance(a3, SCons.Action.CommandAction), a3
+ assert a3.cmd_list == "a3", a3.cmd_list
+
+ a4 = SCons.Action.Action([[ "explicit", "command", "line" ]])
+ assert isinstance(a4, SCons.Action.CommandAction), a4
+ assert a4.cmd_list == [ "explicit", "command", "line" ], a4.cmd_list
+
+ def foo():
+ pass
- a4 = SCons.Action.Action(["x", "y", "z", [ "a", "b", "c"]])
+ a5 = SCons.Action.Action("string", strfunction=foo)
+ assert isinstance(a5, SCons.Action.CommandAction), a5
+ assert a5.cmd_list == "string", a5.cmd_list
+ assert a5.strfunction == foo, a5.strfunction
+
+ def test_ListAction(self):
+ """Test the Action() factory's creation of ListAction objects
+ """
+ a1 = SCons.Action.Action(["x", "y", "z", [ "a", "b", "c"]])
+ assert isinstance(a1, SCons.Action.ListAction), a1
+ assert isinstance(a1.list[0], SCons.Action.CommandAction), a1.list[0]
+ assert a1.list[0].cmd_list == "x", a1.list[0].cmd_list
+ assert isinstance(a1.list[1], SCons.Action.CommandAction), a1.list[1]
+ assert a1.list[1].cmd_list == "y", a1.list[1].cmd_list
+ assert isinstance(a1.list[2], SCons.Action.CommandAction), a1.list[2]
+ assert a1.list[2].cmd_list == "z", a1.list[2].cmd_list
+ assert isinstance(a1.list[3], SCons.Action.CommandAction), a1.list[3]
+ assert a1.list[3].cmd_list == [ "a", "b", "c" ], a1.list[3].cmd_list
+
+ a2 = SCons.Action.Action("x\ny\nz")
+ assert isinstance(a2, SCons.Action.ListAction), a2
+ assert isinstance(a2.list[0], SCons.Action.CommandAction), a2.list[0]
+ assert a2.list[0].cmd_list == "x", a2.list[0].cmd_list
+ assert isinstance(a2.list[1], SCons.Action.CommandAction), a2.list[1]
+ assert a2.list[1].cmd_list == "y", a2.list[1].cmd_list
+ assert isinstance(a2.list[2], SCons.Action.CommandAction), a2.list[2]
+ assert a2.list[2].cmd_list == "z", a2.list[2].cmd_list
+
+ def foo():
+ pass
+
+ a3 = SCons.Action.Action(["x", foo, "z"])
+ assert isinstance(a3, SCons.Action.ListAction), a3
+ assert isinstance(a3.list[0], SCons.Action.CommandAction), a3.list[0]
+ assert a3.list[0].cmd_list == "x", a3.list[0].cmd_list
+ assert isinstance(a3.list[1], SCons.Action.FunctionAction), a3.list[1]
+ assert a3.list[1].execfunction == foo, a3.list[1].execfunction
+ assert isinstance(a3.list[2], SCons.Action.CommandAction), a3.list[2]
+ assert a3.list[2].cmd_list == "z", a3.list[2].cmd_list
+
+ a4 = SCons.Action.Action(["x", "y"], strfunction=foo)
assert isinstance(a4, SCons.Action.ListAction), a4
assert isinstance(a4.list[0], SCons.Action.CommandAction), a4.list[0]
- assert a4.list[0].cmd_list == ["x"], a4.list[0].cmd_list
+ assert a4.list[0].cmd_list == "x", a4.list[0].cmd_list
+ assert a4.list[0].strfunction == foo, a4.list[0].strfunction
assert isinstance(a4.list[1], SCons.Action.CommandAction), a4.list[1]
- assert a4.list[1].cmd_list == ["y"], a4.list[1].cmd_list
- assert isinstance(a4.list[2], SCons.Action.CommandAction), a4.list[2]
- assert a4.list[2].cmd_list == ["z"], a4.list[2].cmd_list
- assert isinstance(a4.list[3], SCons.Action.CommandAction), a4.list[3]
- assert a4.list[3].cmd_list == [ "a", "b", "c" ], a4.list[3].cmd_list
+ assert a4.list[1].cmd_list == "y", a4.list[1].cmd_list
+ assert a4.list[1].strfunction == foo, a4.list[1].strfunction
+
+ a5 = SCons.Action.Action("x\ny", strfunction=foo)
+ assert isinstance(a5, SCons.Action.ListAction), a5
+ assert isinstance(a5.list[0], SCons.Action.CommandAction), a5.list[0]
+ assert a5.list[0].cmd_list == "x", a5.list[0].cmd_list
+ assert a5.list[0].strfunction == foo, a5.list[0].strfunction
+ assert isinstance(a5.list[1], SCons.Action.CommandAction), a5.list[1]
+ assert a5.list[1].cmd_list == "y", a5.list[1].cmd_list
+ assert a5.list[1].strfunction == foo, a5.list[1].strfunction
+
+ def test_CommandGeneratorAction(self):
+ """Test the Action() factory's creation of CommandGeneratorAction objects
+ """
+ def foo():
+ pass
+ def bar():
+ pass
+ a1 = SCons.Action.Action(foo, generator=1)
+ assert isinstance(a1, SCons.Action.CommandGeneratorAction), a1
+ assert a1.generator is foo, a1.generator
+ a2 = SCons.Action.Action(foo, strfunction=bar, generator=1)
+ assert isinstance(a2, SCons.Action.CommandGeneratorAction), a2
+ assert a2.generator is foo, a2.generator
+
+ def test_LazyCmdGeneratorAction(self):
+ """Test the Action() factory's creation of lazy CommandGeneratorAction objects
+ """
+ def foo():
+ pass
+
+ a1 = SCons.Action.Action("$FOO")
+ assert isinstance(a1, SCons.Action.LazyAction), a1
+
+ a2 = SCons.Action.Action("$FOO", strfunction=foo)
+ assert isinstance(a2, SCons.Action.LazyAction), a2
+
+ def test_no_action(self):
+ """Test when the Action() factory can't create an action object
+ """
a5 = SCons.Action.Action(1)
assert a5 is None, a5
- a6 = SCons.Action.Action(a1)
- assert a6 is a1, a6
-
- a7 = SCons.Action.Action([[ "explicit", "command", "line" ]])
- assert isinstance(a7, SCons.Action.CommandAction), a7
- assert a7.cmd_list == [ "explicit", "command", "line" ], a7.cmd_list
-
- a8 = SCons.Action.Action(["a8"])
- assert isinstance(a8, SCons.Action.CommandAction), a8
- assert a8.cmd_list == [ "a8" ], a8.cmd_list
-
- a9 = SCons.Action.Action("x\ny\nz")
- assert isinstance(a9, SCons.Action.ListAction), a9
- assert isinstance(a9.list[0], SCons.Action.CommandAction), a9.list[0]
- assert a9.list[0].cmd_list == ["x"], a9.list[0].cmd_list
- assert isinstance(a9.list[1], SCons.Action.CommandAction), a9.list[1]
- assert a9.list[1].cmd_list == ["y"], a9.list[1].cmd_list
- assert isinstance(a9.list[2], SCons.Action.CommandAction), a9.list[2]
- assert a9.list[2].cmd_list == ["z"], a9.list[2].cmd_list
-
- a10 = SCons.Action.Action(["x", foo, "z"])
- assert isinstance(a10, SCons.Action.ListAction), a10
- assert isinstance(a10.list[0], SCons.Action.CommandAction), a10.list[0]
- assert a10.list[0].cmd_list == ["x"], a10.list[0].cmd_list
- assert isinstance(a10.list[1], SCons.Action.FunctionAction), a10.list[1]
- assert a10.list[1].execfunction == foo, a10.list[1].execfunction
- assert isinstance(a10.list[2], SCons.Action.CommandAction), a10.list[2]
- assert a10.list[2].cmd_list == ["z"], a10.list[2].cmd_list
-
- a11 = SCons.Action.Action(foo, strfunction=bar)
- assert isinstance(a11, SCons.Action.FunctionAction), a11
- assert a11.execfunction == foo, a11.execfunction
- assert a11.strfunction == bar, a11.strfunction
+ def test_reentrance(self):
+ """Test the Action() factory when the action is already an Action object
+ """
+ a1 = SCons.Action.Action("foo")
+ a2 = SCons.Action.Action(a1)
+ assert a2 is a1, a2
class ActionBaseTestCase(unittest.TestCase):
+ def test_get_executor(self):
+ """Test the ActionBase.get_executor() method"""
+ a = SCons.Action.Action('foo')
+ x = a.get_executor({}, {}, [], [], {})
+ assert not x is None, x
+
+class _ActionActionTestCase(unittest.TestCase):
+
+ def test__init__(self):
+ """Test creation of _ActionAction objects
+ """
- def test_cmp(self):
+ def func1():
+ pass
+
+ def func2():
+ pass
+
+ a = SCons.Action._ActionAction()
+ assert not hasattr(a, 'strfunction')
+
+ assert SCons.Action._ActionAction(kwarg = 1)
+ assert not hasattr(a, 'strfunction')
+ assert not hasattr(a, 'kwarg')
+
+ a = SCons.Action._ActionAction(strfunction=func1)
+ assert a.strfunction is func1, a.strfunction
+
+ a = SCons.Action._ActionAction(presub=func1)
+ assert a.presub is func1, a.presub
+
+ a = SCons.Action._ActionAction(chdir=1)
+ assert a.chdir is 1, a.chdir
+
+ a = SCons.Action._ActionAction(func1, func2, 'x')
+ assert a.strfunction is func1, a.strfunction
+ assert a.presub is func2, a.presub
+ assert a.chdir is 'x', a.chdir
+
+ def test___cmp__(self):
"""Test Action comparison
"""
a1 = SCons.Action.Action("x")
assert a1 != a3
assert a2 != a3
- def test_get_actions(self):
- """Test the get_actions() method
+ def test_print_cmd_lines(self):
+ """Test the print_cmd_lines() method
"""
- a = SCons.Action.Action("x")
- l = a.get_actions()
- assert l == [a], l
+ save_stdout = sys.stdout
+
+ try:
+ def execfunc(target, source, env):
+ pass
+ a = SCons.Action.Action(execfunc)
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ a.print_cmd_line("foo bar", None, None, None)
+ s = sio.getvalue()
+ assert s == "foo bar\n", s
+
+ finally:
+ sys.stdout = save_stdout
+
+ def test___call__(self):
+ """Test calling an Action
+ """
+ save_stdout = sys.stdout
+
+ save_print_actions = SCons.Action.print_actions
+ save_print_actions_presub = SCons.Action.print_actions_presub
+ save_execute_actions = SCons.Action.execute_actions
+ #SCons.Action.print_actions = 0
+
+ test = TestCmd.TestCmd(workdir = '')
+ test.subdir('sub', 'xyz')
+ os.chdir(test.workpath())
+
+ try:
+ env = Environment()
+
+ def execfunc(target, source, env):
+ assert type(target) is type([]), type(target)
+ assert type(source) is type([]), type(source)
+ return 7
+ a = SCons.Action.Action(execfunc)
+
+ def firstfunc(target, source, env):
+ assert type(target) is type([]), type(target)
+ assert type(source) is type([]), type(source)
+ return 0
+ def lastfunc(target, source, env):
+ assert type(target) is type([]), type(target)
+ assert type(source) is type([]), type(source)
+ return 9
+ b = SCons.Action.Action([firstfunc, execfunc, lastfunc])
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = a("out", "in", env)
+ assert result.status == 7, result
+ s = sio.getvalue()
+ assert s == 'execfunc(["out"], ["in"])\n', s
+
+ a.chdir = 'xyz'
+ expect = 'os.chdir(%s)\nexecfunc(["out"], ["in"])\nos.chdir(%s)\n'
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = a("out", "in", env)
+ assert result.status == 7, result.status
+ s = sio.getvalue()
+ assert s == expect % (repr('xyz'), repr(test.workpath())), s
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = a("out", "in", env, chdir='sub')
+ assert result.status == 7, result.status
+ s = sio.getvalue()
+ assert s == expect % (repr('sub'), repr(test.workpath())), s
+
+ a.chdir = None
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = b("out", "in", env)
+ assert result.status == 7, result.status
+ s = sio.getvalue()
+ assert s == 'firstfunc(["out"], ["in"])\nexecfunc(["out"], ["in"])\n', s
+
+ SCons.Action.execute_actions = 0
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = a("out", "in", env)
+ assert result == 0, result
+ s = sio.getvalue()
+ assert s == 'execfunc(["out"], ["in"])\n', s
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = b("out", "in", env)
+ assert result == 0, result
+ s = sio.getvalue()
+ assert s == 'firstfunc(["out"], ["in"])\nexecfunc(["out"], ["in"])\nlastfunc(["out"], ["in"])\n', s
+
+ SCons.Action.print_actions_presub = 1
+ SCons.Action.execute_actions = 1
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = a("out", "in", env)
+ assert result.status == 7, result.status
+ s = sio.getvalue()
+ assert s == 'Building out with action:\n execfunc(target, source, env)\nexecfunc(["out"], ["in"])\n', s
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = a("out", "in", env, presub=0)
+ assert result.status == 7, result.status
+ s = sio.getvalue()
+ assert s == 'execfunc(["out"], ["in"])\n', s
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = a("out", "in", env, presub=1)
+ assert result.status == 7, result.status
+ s = sio.getvalue()
+ assert s == 'Building out with action:\n execfunc(target, source, env)\nexecfunc(["out"], ["in"])\n', s
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = b(["out"], "in", env, presub=1)
+ assert result.status == 7, result.status
+ s = sio.getvalue()
+ assert s == 'Building out with action:\n firstfunc(target, source, env)\nfirstfunc(["out"], ["in"])\nBuilding out with action:\n execfunc(target, source, env)\nexecfunc(["out"], ["in"])\n', s
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = b(["out", "list"], "in", env, presub=1)
+ assert result.status == 7, result.status
+ s = sio.getvalue()
+ assert s == 'Building out and list with action:\n firstfunc(target, source, env)\nfirstfunc(["out", "list"], ["in"])\nBuilding out and list with action:\n execfunc(target, source, env)\nexecfunc(["out", "list"], ["in"])\n', s
+
+ a2 = SCons.Action.Action(execfunc)
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = a2("out", "in", env)
+ assert result.status == 7, result.status
+ s = sio.getvalue()
+ assert s == 'Building out with action:\n execfunc(target, source, env)\nexecfunc(["out"], ["in"])\n', s
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = a2("out", "in", env, presub=0)
+ assert result.status == 7, result.status
+ s = sio.getvalue()
+ assert s == 'execfunc(["out"], ["in"])\n', s
+
+ SCons.Action.execute_actions = 0
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = a2("out", "in", env, presub=0)
+ assert result == 0, result
+ s = sio.getvalue()
+ assert s == 'execfunc(["out"], ["in"])\n', s
+
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ result = a("out", "in", env, presub=0, execute=1, show=0)
+ assert result.status == 7, result.status
+ s = sio.getvalue()
+ assert s == '', s
+
+ sys.stdout = save_stdout
+ exitstatfunc_result = []
+
+ def exitstatfunc(stat, result=exitstatfunc_result):
+ result.append(stat)
+ return stat
+
+ result = a("out", "in", env, exitstatfunc=exitstatfunc)
+ assert result == 0, result
+ assert exitstatfunc_result == [], exitstatfunc_result
+
+ result = a("out", "in", env, execute=1, exitstatfunc=exitstatfunc)
+ assert result.status == 7, result.status
+ assert exitstatfunc_result == [7], exitstatfunc_result
+
+ SCons.Action.execute_actions = 1
+
+ result = []
+ def my_print_cmd_line(s, target, source, env, result=result):
+ result.append(s)
+ env['PRINT_CMD_LINE_FUNC'] = my_print_cmd_line
+ a("output", "input", env)
+ assert result == ['execfunc(["output"], ["input"])'], result
+
+
+ finally:
+ sys.stdout = save_stdout
+ SCons.Action.print_actions = save_print_actions
+ SCons.Action.print_actions_presub = save_print_actions_presub
+ SCons.Action.execute_actions = save_execute_actions
- def test_subst_dict(self):
- """Test substituting dictionary values in an Action
+ def test_presub_lines(self):
+ """Test the presub_lines() method
"""
+ env = Environment()
a = SCons.Action.Action("x")
+ s = a.presub_lines(env)
+ assert s == ['x'], s
- d = a.subst_dict([], [], Environment(a = 'A', b = 'B'))
- assert d['a'] == 'A', d
- assert d['b'] == 'B', d
-
- d = a.subst_dict(target = 't', source = 's', env = Environment())
- assert str(d['TARGETS']) == 't', d['TARGETS']
- assert str(d['TARGET']) == 't', d['TARGET']
- assert str(d['SOURCES']) == 's', d['SOURCES']
- assert str(d['SOURCE']) == 's', d['SOURCE']
-
- d = a.subst_dict(target = ['t1', 't2'],
- source = ['s1', 's2'],
- env = Environment())
- TARGETS = map(lambda x: str(x), d['TARGETS'])
- TARGETS.sort()
- assert TARGETS == ['t1', 't2'], d['TARGETS']
- assert str(d['TARGET']) == 't1', d['TARGET']
- SOURCES = map(lambda x: str(x), d['SOURCES'])
- SOURCES.sort()
- assert SOURCES == ['s1', 's2'], d['SOURCES']
- assert str(d['SOURCE']) == 's1', d['SOURCE']
-
- class N:
- def __init__(self, name):
- self.name = name
- def __str__(self):
- return self.name
- def rstr(self):
- return 'rstr-' + self.name
-
- d = a.subst_dict(target = [N('t3'), 't4'],
- source = ['s3', N('s4')],
- env = Environment())
- TARGETS = map(lambda x: str(x), d['TARGETS'])
- TARGETS.sort()
- assert TARGETS == ['t3', 't4'], d['TARGETS']
- SOURCES = map(lambda x: str(x), d['SOURCES'])
- SOURCES.sort()
- assert SOURCES == ['rstr-s4', 's3'], d['SOURCES']
+ a = SCons.Action.Action(["y", "z"])
+ s = a.presub_lines(env)
+ assert s == ['y', 'z'], s
+
+ def func():
+ pass
+ a = SCons.Action.Action(func)
+ s = a.presub_lines(env)
+ assert s == ["func(target, source, env)"], s
+
+ def gen(target, source, env, for_signature):
+ return 'generat' + env.get('GEN', 'or')
+ a = SCons.Action.Action(gen, generator=1)
+ s = a.presub_lines(env)
+ assert s == ["generator"], s
+ s = a.presub_lines(Environment(GEN = 'ed'))
+ assert s == ["generated"], s
+
+ a = SCons.Action.Action("$ACT")
+ s = a.presub_lines(env)
+ assert s == [''], s
+ s = a.presub_lines(Environment(ACT = 'expanded action'))
+ assert s == ['expanded action'], s
+
+ def test_add(self):
+ """Test adding Actions to stuff."""
+ # Adding actions to other Actions or to stuff that can
+ # be converted into an Action should produce a ListAction
+ # containing all the Actions.
+ def bar():
+ return None
+ baz = SCons.Action.Action(bar, generator=1)
+ act1 = SCons.Action.Action('foo bar')
+ act2 = SCons.Action.Action([ 'foo', bar ])
+
+ sum = act1 + act2
+ assert isinstance(sum, SCons.Action.ListAction), str(sum)
+ assert len(sum.list) == 3, len(sum.list)
+ assert map(lambda x: isinstance(x, SCons.Action.ActionBase),
+ sum.list) == [ 1, 1, 1 ]
+
+ sum = act1 + act1
+ assert isinstance(sum, SCons.Action.ListAction), str(sum)
+ assert len(sum.list) == 2, len(sum.list)
+
+ sum = act2 + act2
+ assert isinstance(sum, SCons.Action.ListAction), str(sum)
+ assert len(sum.list) == 4, len(sum.list)
+
+ # Should also be able to add command generators to each other
+ # or to actions
+ sum = baz + baz
+ assert isinstance(sum, SCons.Action.ListAction), str(sum)
+ assert len(sum.list) == 2, len(sum.list)
+
+ sum = baz + act1
+ assert isinstance(sum, SCons.Action.ListAction), str(sum)
+ assert len(sum.list) == 2, len(sum.list)
+
+ sum = act2 + baz
+ assert isinstance(sum, SCons.Action.ListAction), str(sum)
+ assert len(sum.list) == 3, len(sum.list)
+
+ # Also should be able to add Actions to anything that can
+ # be converted into an action.
+ sum = act1 + bar
+ assert isinstance(sum, SCons.Action.ListAction), str(sum)
+ assert len(sum.list) == 2, len(sum.list)
+ assert isinstance(sum.list[1], SCons.Action.FunctionAction)
+
+ sum = 'foo bar' + act2
+ assert isinstance(sum, SCons.Action.ListAction), str(sum)
+ assert len(sum.list) == 3, len(sum.list)
+ assert isinstance(sum.list[0], SCons.Action.CommandAction)
+
+ sum = [ 'foo', 'bar' ] + act1
+ assert isinstance(sum, SCons.Action.ListAction), str(sum)
+ assert len(sum.list) == 3, sum.list
+ assert isinstance(sum.list[0], SCons.Action.CommandAction)
+ assert isinstance(sum.list[1], SCons.Action.CommandAction)
+
+ sum = act2 + [ baz, bar ]
+ assert isinstance(sum, SCons.Action.ListAction), str(sum)
+ assert len(sum.list) == 4, len(sum.list)
+ assert isinstance(sum.list[2], SCons.Action.CommandGeneratorAction)
+ assert isinstance(sum.list[3], SCons.Action.FunctionAction)
+
+ try:
+ sum = act2 + 1
+ except TypeError:
+ pass
+ else:
+ assert 0, "Should have thrown a TypeError adding to an int."
+
+ try:
+ sum = 1 + act2
+ except TypeError:
+ pass
+ else:
+ assert 0, "Should have thrown a TypeError adding to an int."
class CommandActionTestCase(unittest.TestCase):
- def test_init(self):
+ def test___init__(self):
"""Test creation of a command Action
"""
a = SCons.Action.CommandAction(["xyzzy"])
assert a.cmd_list == [ "xyzzy" ], a.cmd_list
+ assert a.cmdstr is None, a.cmdstr
+
+ a = SCons.Action.CommandAction(["abra"], "cadabra")
+ assert a.cmd_list == [ "abra" ], a.cmd_list
+ assert a.cmdstr == "cadabra", a.cmdstr
+
+ def test_bad_cmdstr(self):
+ """Test handling of bad CommandAction(cmdstr) arguments
+ """
+ try:
+ a = SCons.Action.CommandAction('foo', [])
+ except SCons.Errors.UserError, e:
+ s = str(e)
+ m = 'Invalid command display variable'
+ assert string.find(s, m) != -1, 'Unexpected string: %s' % s
+ else:
+ raise Exception, "did not catch expected UserError"
+
+ def test___str__(self):
+ """Test fetching the pre-substitution string for command Actions
+ """
+ env = Environment()
+ act = SCons.Action.CommandAction('xyzzy $TARGET $SOURCE')
+ s = str(act)
+ assert s == 'xyzzy $TARGET $SOURCE', s
+
+ act = SCons.Action.CommandAction(['xyzzy',
+ '$TARGET', '$SOURCE',
+ '$TARGETS', '$SOURCES'])
+ s = str(act)
+ assert s == "xyzzy $TARGET $SOURCE $TARGETS $SOURCES", s
+
+ def test_genstring(self):
+ """Test the genstring() method for command Actions
+ """
+
+ env = Environment()
+ t1 = DummyNode('t1')
+ t2 = DummyNode('t2')
+ s1 = DummyNode('s1')
+ s2 = DummyNode('s2')
+ act = SCons.Action.CommandAction('xyzzy $TARGET $SOURCE')
+ expect = 'xyzzy $TARGET $SOURCE'
+ s = act.genstring([], [], env)
+ assert s == expect, s
+ s = act.genstring([t1], [s1], env)
+ assert s == expect, s
+ s = act.genstring([t1, t2], [s1, s2], env)
+ assert s == expect, s
+
+ act = SCons.Action.CommandAction('xyzzy $TARGETS $SOURCES')
+ expect = 'xyzzy $TARGETS $SOURCES'
+ s = act.genstring([], [], env)
+ assert s == expect, s
+ s = act.genstring([t1], [s1], env)
+ assert s == expect, s
+ s = act.genstring([t1, t2], [s1, s2], env)
+ assert s == expect, s
+
+ act = SCons.Action.CommandAction(['xyzzy',
+ '$TARGET', '$SOURCE',
+ '$TARGETS', '$SOURCES'])
+ expect = "xyzzy $TARGET $SOURCE $TARGETS $SOURCES"
+ s = act.genstring([], [], env)
+ assert s == expect, s
+ s = act.genstring([t1], [s1], env)
+ assert s == expect, s
+ s = act.genstring([t1, t2], [s1, s2], env)
+ assert s == expect, s
+
+ def test_strfunction(self):
+ """Test fetching the string representation of command Actions
+ """
+
+ env = Environment()
+ t1 = DummyNode('t1')
+ t2 = DummyNode('t2')
+ s1 = DummyNode('s1')
+ s2 = DummyNode('s2')
+ act = SCons.Action.CommandAction('xyzzy $TARGET $SOURCE')
+ s = act.strfunction([], [], env)
+ assert s == 'xyzzy', s
+ s = act.strfunction([t1], [s1], env)
+ assert s == 'xyzzy t1 s1', s
+ s = act.strfunction([t1, t2], [s1, s2], env)
+ assert s == 'xyzzy t1 s1', s
+
+ act = SCons.Action.CommandAction('xyzzy $TARGET $SOURCE',
+ 'cmdstr - $SOURCE - $TARGET -')
+ s = act.strfunction([], [], env)
+ assert s == 'cmdstr - - -', s
+ s = act.strfunction([t1], [s1], env)
+ assert s == 'cmdstr - s1 - t1 -', s
+ s = act.strfunction([t1, t2], [s1, s2], env)
+ assert s == 'cmdstr - s1 - t1 -', s
+
+ act = SCons.Action.CommandAction('xyzzy $TARGETS $SOURCES')
+ s = act.strfunction([], [], env)
+ assert s == 'xyzzy', s
+ s = act.strfunction([t1], [s1], env)
+ assert s == 'xyzzy t1 s1', s
+ s = act.strfunction([t1, t2], [s1, s2], env)
+ assert s == 'xyzzy t1 t2 s1 s2', s
+
+ act = SCons.Action.CommandAction('xyzzy $TARGETS $SOURCES',
+ 'cmdstr = $SOURCES = $TARGETS =')
+ s = act.strfunction([], [], env)
+ assert s == 'cmdstr = = =', s
+ s = act.strfunction([t1], [s1], env)
+ assert s == 'cmdstr = s1 = t1 =', s
+ s = act.strfunction([t1, t2], [s1, s2], env)
+ assert s == 'cmdstr = s1 s2 = t1 t2 =', s
+
+ act = SCons.Action.CommandAction(['xyzzy',
+ '$TARGET', '$SOURCE',
+ '$TARGETS', '$SOURCES'])
+ s = act.strfunction([], [], env)
+ assert s == 'xyzzy', s
+ s = act.strfunction([t1], [s1], env)
+ assert s == 'xyzzy t1 s1 t1 s1', s
+ s = act.strfunction([t1, t2], [s1, s2], env)
+ assert s == 'xyzzy t1 s1 t1 t2 s1 s2', s
+
+ act = SCons.Action.CommandAction('xyzzy $TARGETS $SOURCES',
+ 'cmdstr\t$TARGETS\n$SOURCES ')
+
+ s = act.strfunction([], [], env)
+ assert s == 'cmdstr\t\n ', s
+ s = act.strfunction([t1], [s1], env)
+ assert s == 'cmdstr\tt1\ns1 ', s
+ s = act.strfunction([t1, t2], [s1, s2], env)
+ assert s == 'cmdstr\tt1 t2\ns1 s2 ', s
+
+ def sf(target, source, env):
+ return "sf was called"
+ act = SCons.Action.CommandAction('foo', strfunction=sf)
+ s = act.strfunction([], [], env)
+ assert s == "sf was called", s
+
+ class actclass1:
+ def __init__(self, targets, sources, env):
+ pass
+ def __call__(self):
+ return 1
+ class actclass2:
+ def __init__(self, targets, sources, env):
+ self.strfunction = 5
+ def __call__(self):
+ return 2
+ class actclass3:
+ def __init__(self, targets, sources, env):
+ pass
+ def __call__(self):
+ return 3
+ def strfunction(self, targets, sources, env):
+ return 'actclass3 on %s to get %s'%(str(sources[0]),
+ str(targets[0]))
+ class actclass4:
+ def __init__(self, targets, sources, env):
+ pass
+ def __call__(self):
+ return 4
+ strfunction = None
+
+ act1 = SCons.Action.Action(actclass1([t1], [s1], env))
+ s = act1.strfunction([t1], [s1], env)
+ assert s == 'actclass1(["t1"], ["s1"])', s
+
+ act2 = SCons.Action.Action(actclass2([t1], [s1], env))
+ s = act2.strfunction([t1], [s1], env)
+ assert s == 'actclass2(["t1"], ["s1"])', s
+
+ act3 = SCons.Action.Action(actclass3([t1], [s1], env))
+ s = act3.strfunction([t1], [s1], env)
+ assert s == 'actclass3 on s1 to get t1', s
+
+ act4 = SCons.Action.Action(actclass4([t1], [s1], env))
+ s = act4.strfunction([t1], [s1], env)
+ assert s is None, s
+
+ act = SCons.Action.CommandAction("@foo bar")
+ s = act.strfunction([], [], env)
+ assert s == "", s
+
+ act = SCons.Action.CommandAction("@-foo bar")
+ s = act.strfunction([], [], env)
+ assert s == "", s
+
+ act = SCons.Action.CommandAction("-@foo bar")
+ s = act.strfunction([], [], env)
+ assert s == "", s
+
+ act = SCons.Action.CommandAction("-foo bar")
+ s = act.strfunction([], [], env)
+ assert s == "foo bar", s
+
+ act = SCons.Action.CommandAction("@ foo bar")
+ s = act.strfunction([], [], env)
+ assert s == "", s
+
+ act = SCons.Action.CommandAction("@- foo bar")
+ s = act.strfunction([], [], env)
+ assert s == "", s
+
+ act = SCons.Action.CommandAction("-@ foo bar")
+ s = act.strfunction([], [], env)
+ assert s == "", s
+
+ act = SCons.Action.CommandAction("- foo bar")
+ s = act.strfunction([], [], env)
+ assert s == "foo bar", s
def test_execute(self):
"""Test execution of command Actions
"""
- cmd1 = r'%s %s %s xyzzy' % (python, act_py, outfile)
+ try:
+ env = self.env
+ except AttributeError:
+ env = Environment()
+
+ cmd1 = r'%s %s %s xyzzy' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd1)
- r = act([], [], Environment())
+ r = act([], [], env.Clone())
assert r == 0
c = test.read(outfile, 'r')
assert c == "act.py: 'xyzzy'\n", c
- cmd2 = r'%s %s %s $TARGET' % (python, act_py, outfile)
+ cmd2 = r'%s %s %s $TARGET' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd2)
- r = act('foo', [], Environment())
+ r = act(DummyNode('foo'), [], env.Clone())
assert r == 0
c = test.read(outfile, 'r')
assert c == "act.py: 'foo'\n", c
- cmd3 = r'%s %s %s ${TARGETS}' % (python, act_py, outfile)
+ cmd3 = r'%s %s %s ${TARGETS}' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd3)
- r = act(['aaa', 'bbb'], [], Environment())
+ r = act(map(DummyNode, ['aaa', 'bbb']), [], env.Clone())
assert r == 0
c = test.read(outfile, 'r')
assert c == "act.py: 'aaa' 'bbb'\n", c
- cmd4 = r'%s %s %s $SOURCES' % (python, act_py, outfile)
+ cmd4 = r'%s %s %s $SOURCES' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd4)
- r = act([], ['one', 'two'], Environment())
+ r = act([], [DummyNode('one'), DummyNode('two')], env.Clone())
assert r == 0
c = test.read(outfile, 'r')
assert c == "act.py: 'one' 'two'\n", c
- cmd4 = r'%s %s %s ${SOURCES[:2]}' % (python, act_py, outfile)
+ cmd4 = r'%s %s %s ${SOURCES[:2]}' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd4)
- r = act([],
- source = ['three', 'four', 'five'],
- env = Environment())
+ sources = [DummyNode('three'), DummyNode('four'), DummyNode('five')]
+ env2 = env.Clone()
+ r = act([], source = sources, env = env2)
assert r == 0
c = test.read(outfile, 'r')
assert c == "act.py: 'three' 'four'\n", c
- cmd5 = r'%s %s %s $TARGET XYZZY' % (python, act_py, outfile)
+ cmd5 = r'%s %s %s $TARGET XYZZY' % (_python_, act_py, outfile)
+
+ act = SCons.Action.CommandAction(cmd5)
+ env5 = Environment()
+ if scons_env.has_key('ENV'):
+ env5['ENV'] = scons_env['ENV']
+ PATH = scons_env['ENV'].get('PATH', '')
+ else:
+ env5['ENV'] = {}
+ PATH = ''
+
+ env5['ENV']['XYZZY'] = 'xyzzy'
+ r = act(target = DummyNode('out5'), source = [], env = env5)
act = SCons.Action.CommandAction(cmd5)
- r = act(target = 'out5',
- source = [],
- env = Environment(ENV = {'XYZZY' : 'xyzzy'}))
+ r = act(target = DummyNode('out5'),
+ source = [],
+ env = env.Clone(ENV = {'XYZZY' : 'xyzzy5',
+ 'PATH' : PATH}))
assert r == 0
c = test.read(outfile, 'r')
- assert c == "act.py: 'out5' 'XYZZY'\nact.py: 'xyzzy'\n", c
+ assert c == "act.py: 'out5' 'XYZZY'\nact.py: 'xyzzy5'\n", c
class Obj:
def __init__(self, str):
self._str = str
def __str__(self):
return self._str
+ def rfile(self):
+ return self
+ def get_subst_proxy(self):
+ return self
- cmd6 = r'%s %s %s ${TARGETS[1]} $TARGET ${SOURCES[:2]}' % (python, act_py, outfile)
+ cmd6 = r'%s %s %s ${TARGETS[1]} $TARGET ${SOURCES[:2]}' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd6)
r = act(target = [Obj('111'), Obj('222')],
source = [Obj('333'), Obj('444'), Obj('555')],
- env = Environment())
+ env = env.Clone())
assert r == 0
c = test.read(outfile, 'r')
assert c == "act.py: '222' '111' '333' '444'\n", c
- cmd7 = '%s %s %s one\n\n%s %s %s two' % (python, act_py, outfile,
- python, act_py, outfile)
- expect7 = '%s %s %s one\n%s %s %s two\n' % (python, act_py, outfile,
- python, act_py, outfile)
-
- act = SCons.Action.CommandAction(cmd7)
-
- global show_string
- show_string = ""
- def my_show(string):
- global show_string
- show_string = show_string + string + "\n"
- act.show = my_show
-
- r = act([], [], Environment())
- assert r == 0
- assert show_string == expect7, show_string
-
if os.name == 'nt':
# NT treats execs of directories and non-executable files
# as "file not found" errors
expect_nonexistent = 1
expect_nonexecutable = 1
+ elif sys.platform == 'cygwin':
+ expect_nonexistent = 127
+ # Newer cygwin seems to return 126 for following
+ expect_nonexecutable_file = 126
+ expect_nonexecutable_dir = 127
else:
expect_nonexistent = 127
- expect_nonexecutable = 126
+ expect_nonexecutable_file = 126
+ expect_nonexecutable_dir = 126
# Test that a nonexistent command returns 127
- act = SCons.Action.CommandAction(python + "_XyZzY_")
- r = act([], [], Environment(out = outfile))
- assert r == expect_nonexistent, "r == %d" % r
+ act = SCons.Action.CommandAction(python + "_no_such_command_")
+ r = act([], [], env.Clone(out = outfile))
+ assert r.status == expect_nonexistent, r.status
# Test that trying to execute a directory returns 126
dir, tail = os.path.split(python)
act = SCons.Action.CommandAction(dir)
- r = act([], [], Environment(out = outfile))
- assert r == expect_nonexecutable, "r == %d" % r
+ r = act([], [], env.Clone(out = outfile))
+ assert r.status == expect_nonexecutable_file, r.status
# Test that trying to execute a non-executable file returns 126
act = SCons.Action.CommandAction(outfile)
- r = act([], [], Environment(out = outfile))
- assert r == expect_nonexecutable, "r == %d" % r
+ r = act([], [], env.Clone(out = outfile))
+ assert r.status == expect_nonexecutable_dir, r.status
+
+ act = SCons.Action.CommandAction('%s %s 1' % (_python_, exit_py))
+ r = act([], [], env)
+ assert r.status == 1, r.status
+
+ act = SCons.Action.CommandAction('@%s %s 1' % (_python_, exit_py))
+ r = act([], [], env)
+ assert r.status == 1, r.status
+
+ act = SCons.Action.CommandAction('@-%s %s 1' % (_python_, exit_py))
+ r = act([], [], env)
+ assert r == 0, r
+
+ act = SCons.Action.CommandAction('-%s %s 1' % (_python_, exit_py))
+ r = act([], [], env)
+ assert r == 0, r
+
+ act = SCons.Action.CommandAction('@ %s %s 1' % (_python_, exit_py))
+ r = act([], [], env)
+ assert r.status == 1, r.status
+
+ act = SCons.Action.CommandAction('@- %s %s 1' % (_python_, exit_py))
+ r = act([], [], env)
+ assert r == 0, r
+
+ act = SCons.Action.CommandAction('- %s %s 1' % (_python_, exit_py))
+ r = act([], [], env)
+ assert r == 0, r
+
+ def _DO_NOT_EXECUTE_test_pipe_execute(self):
+ """Test capturing piped output from an action
+
+ We used to have PIPE_BUILD support built right into
+ Action.execute() for the benefit of the SConf subsystem, but we've
+ moved that logic back into SConf itself. We'll leave this code
+ here, just in case we ever want to resurrect this functionality
+ in the future, but change the name of the test so it doesn't
+ get executed as part of the normal test suite.
+ """
+ pipe = open( pipe_file, "w" )
+ self.env = Environment(ENV = {'ACTPY_PIPE' : '1'}, PIPE_BUILD = 1,
+ PSTDOUT = pipe, PSTDERR = pipe)
+ # everything should also work when piping output
+ self.test_execute()
+ self.env['PSTDOUT'].close()
+ pipe_out = test.read( pipe_file )
+
+ act_out = "act.py: stdout: executed act.py"
+ act_err = "act.py: stderr: executed act.py"
+
+ # Since we are now using select(), stdout and stderr can be
+ # intermixed, so count the lines separately.
+ outlines = re.findall(act_out, pipe_out)
+ errlines = re.findall(act_err, pipe_out)
+ assert len(outlines) == 6, pipe_out + repr(outlines)
+ assert len(errlines) == 6, pipe_out + repr(errlines)
+
+ # test redirection operators
+ def test_redirect(self, redir, stdout_msg, stderr_msg):
+ cmd = r'%s %s %s xyzzy %s' % (_python_, act_py, outfile, redir)
+ # Write the output and error messages to files because
+ # Windows can't handle strings that are too big in its
+ # external environment (os.spawnve() returns EINVAL,
+ # "Invalid argument").
+ stdout_file = test.workpath('stdout_msg')
+ stderr_file = test.workpath('stderr_msg')
+ open(stdout_file, 'w').write(stdout_msg)
+ open(stderr_file, 'w').write(stderr_msg)
+ pipe = open( pipe_file, "w" )
+ act = SCons.Action.CommandAction(cmd)
+ env = Environment( ENV = {'ACTPY_PIPE' : '1',
+ 'PIPE_STDOUT_FILE' : stdout_file,
+ 'PIPE_STDERR_FILE' : stderr_file},
+ PIPE_BUILD = 1,
+ PSTDOUT = pipe, PSTDERR = pipe )
+ r = act([], [], env)
+ pipe.close()
+ assert r == 0
+ return (test.read(outfile2, 'r'), test.read(pipe_file, 'r'))
+
+ (redirected, pipe_out) = test_redirect(self,'> %s' % outfile2,
+ act_out, act_err)
+ assert redirected == act_out
+ assert pipe_out == act_err
+
+ (redirected, pipe_out) = test_redirect(self,'2> %s' % outfile2,
+ act_out, act_err)
+ assert redirected == act_err
+ assert pipe_out == act_out
+
+ (redirected, pipe_out) = test_redirect(self,'> %s 2>&1' % outfile2,
+ act_out, act_err)
+ assert (redirected == act_out + act_err or
+ redirected == act_err + act_out)
+ assert pipe_out == ""
+
+ act_err = "Long Command Output\n"*3000
+ # the size of the string should exceed the system's default block size
+ act_out = ""
+ (redirected, pipe_out) = test_redirect(self,'> %s' % outfile2,
+ act_out, act_err)
+ assert (redirected == act_out)
+ assert (pipe_out == act_err)
def test_set_handler(self):
"""Test setting the command handler...
self.data = x
def __str__(self):
return self.data
+ def escape(self, escape_func):
+ return escape_func(self.data)
def is_literal(self):
return 1
- try:
- SCons.Action.SetCommandHandler(func)
- except SCons.Errors.UserError:
- pass
- else:
- assert 0, "should have gotten user error"
-
a = SCons.Action.CommandAction(["xyzzy"])
- a([], [], Environment(SPAWN = func))
- assert t.executed == [ 'xyzzy' ]
+ e = Environment(SPAWN = func)
+ a([], [], e)
+ assert t.executed == [ 'xyzzy' ], t.executed
a = SCons.Action.CommandAction(["xyzzy"])
- a([], [], Environment(SPAWN = func, SHELL = 'fake shell'))
- assert t.executed == [ 'xyzzy' ]
- assert t.shell == 'fake shell'
+ e = Environment(SPAWN = '$FUNC', FUNC = func)
+ a([], [], e)
+ assert t.executed == [ 'xyzzy' ], t.executed
+
+ a = SCons.Action.CommandAction(["xyzzy"])
+ e = Environment(SPAWN = func, SHELL = 'fake shell')
+ a([], [], e)
+ assert t.executed == [ 'xyzzy' ], t.executed
+ assert t.shell == 'fake shell', t.shell
a = SCons.Action.CommandAction([ LiteralStr("xyzzy") ])
- a([], [], Environment(SPAWN = func, ESCAPE = escape_func))
+ e = Environment(SPAWN = func, ESCAPE = escape_func)
+ a([], [], e)
assert t.executed == [ '**xyzzy**' ], t.executed
- def test_get_raw_contents(self):
- """Test fetching the contents of a command Action
- """
- a = SCons.Action.CommandAction(["|", "$(", "$foo", "|", "$bar",
- "$)", "|"])
- c = a.get_raw_contents(target=[], source=[],
- env=Environment(foo = 'FFF', bar = 'BBB'))
- assert c == "| $( FFF | BBB $) |", c
-
def test_get_contents(self):
"""Test fetching the contents of a command Action
"""
+ def CmdGen(target, source, env, for_signature):
+ assert for_signature
+ return "%s %s" % \
+ (env["foo"], env["bar"])
+
+ # The number 1 is there to make sure all args get converted to strings.
a = SCons.Action.CommandAction(["|", "$(", "$foo", "|", "$bar",
- "$)", "|"])
+ "$)", "|", "$baz", 1])
c = a.get_contents(target=[], source=[],
- env=Environment(foo = 'FFF', bar = 'BBB'))
- assert c == "| |", c
+ env=Environment(foo = 'FFF', bar = 'BBB',
+ baz = CmdGen))
+ assert c == "| | FFF BBB 1", c
+
+ # Make sure that CommandActions use an Environment's
+ # subst_target_source() method for substitution.
+ class SpecialEnvironment(Environment):
+ def subst_target_source(self, strSubst, raw=0, target=[], source=[]):
+ return 'subst_target_source: ' + strSubst
+
+ c = a.get_contents(target=DummyNode('ttt'), source = DummyNode('sss'),
+ env=SpecialEnvironment(foo = 'GGG', bar = 'CCC',
+ baz = 'ZZZ'))
+ assert c == 'subst_target_source: | $( $foo | $bar $) | $baz 1', c
+
+ # We've discussed using the real target and source names in a
+ # CommandAction's signature contents. This would have have the
+ # advantage of recompiling when a file's name changes (keeping
+ # debug info current), but it would currently break repository
+ # logic that will change the file name based on whether the
+ # files come from a repository or locally. If we ever move to
+ # that scheme, then all of the '__t1__' and '__s6__' file names
+ # in the asserts below would change to 't1' and 's6' and the
+ # like.
+ t = map(DummyNode, ['t1', 't2', 't3', 't4', 't5', 't6'])
+ s = map(DummyNode, ['s1', 's2', 's3', 's4', 's5', 's6'])
+ env = Environment()
+
+ a = SCons.Action.CommandAction(["$TARGET"])
+ c = a.get_contents(target=t, source=s, env=env)
+ assert c == "t1", c
+
+ a = SCons.Action.CommandAction(["$TARGETS"])
+ c = a.get_contents(target=t, source=s, env=env)
+ assert c == "t1 t2 t3 t4 t5 t6", c
+
+ a = SCons.Action.CommandAction(["${TARGETS[2]}"])
+ c = a.get_contents(target=t, source=s, env=env)
+ assert c == "t3", c
+
+ a = SCons.Action.CommandAction(["${TARGETS[3:5]}"])
+ c = a.get_contents(target=t, source=s, env=env)
+ assert c == "t4 t5", c
+
+ a = SCons.Action.CommandAction(["$SOURCE"])
+ c = a.get_contents(target=t, source=s, env=env)
+ assert c == "s1", c
+
+ a = SCons.Action.CommandAction(["$SOURCES"])
+ c = a.get_contents(target=t, source=s, env=env)
+ assert c == "s1 s2 s3 s4 s5 s6", c
+
+ a = SCons.Action.CommandAction(["${SOURCES[2]}"])
+ c = a.get_contents(target=t, source=s, env=env)
+ assert c == "s3", c
+
+ a = SCons.Action.CommandAction(["${SOURCES[3:5]}"])
+ c = a.get_contents(target=t, source=s, env=env)
+ assert c == "s4 s5", c
class CommandGeneratorActionTestCase(unittest.TestCase):
- def test_init(self):
+ def test___init__(self):
"""Test creation of a command generator Action
"""
def f(target, source, env):
a = SCons.Action.CommandGeneratorAction(f)
assert a.generator == f
+ def test___str__(self):
+ """Test the pre-substitution strings for command generator Actions
+ """
+ def f(target, source, env, for_signature, self=self):
+
+ # See if "env" is really a construction environment (or
+ # looks like one) by accessing the FindIxes attribute.
+ # (The Tool/mingw.py module has a generator that uses this,
+ # and the __str__() method used to cause problems by passing
+ # us a regular dictionary as a fallback.)
+
+ env.FindIxes
+ return "FOO"
+ a = SCons.Action.CommandGeneratorAction(f)
+ s = str(a)
+ assert s == 'FOO', s
+
+ def test_genstring(self):
+ """Test the command generator Action genstring() method
+ """
+ def f(target, source, env, for_signature, self=self):
+ dummy = env['dummy']
+ self.dummy = dummy
+ return "$FOO $TARGET $SOURCE $TARGETS $SOURCES"
+ a = SCons.Action.CommandGeneratorAction(f)
+ self.dummy = 0
+ s = a.genstring([], [], env=Environment(FOO='xyzzy', dummy=1))
+ assert self.dummy == 1, self.dummy
+ assert s == "$FOO $TARGET $SOURCE $TARGETS $SOURCES", s
+
def test_execute(self):
"""Test executing a command generator Action
"""
self.t = t
def rfile(self):
self.t.rfile_called = 1
+ return self
+ def get_subst_proxy(self):
+ return self
def f3(target, source, env, for_signature):
return ''
c = SCons.Action.CommandGeneratorAction(f3)
foo = env['foo']
bar = env['bar']
assert for_signature, for_signature
- return [["guux", foo, "$(", "ignore", "$)", bar]]
+ return [["guux", foo, "$(", "$ignore", "$)", bar,
+ '${test("$( foo $bar $)")}' ]]
+
+ def test(mystr):
+ assert mystr == "$( foo $bar $)", mystr
+ return "test"
+ env = Environment(foo = 'FFF', bar = 'BBB',
+ ignore = 'foo', test=test)
a = SCons.Action.CommandGeneratorAction(f)
- c = a.get_contents(target=[], source=[],
- env=Environment(foo = 'FFF', bar = 'BBB'))
- assert c == "guux FFF BBB", c
+ c = a.get_contents(target=[], source=[], env=env)
+ assert c == "guux FFF BBB test", c
class FunctionActionTestCase(unittest.TestCase):
- def test_init(self):
+ def test___init__(self):
"""Test creation of a function Action
"""
def func1():
a = SCons.Action.FunctionAction(func1)
assert a.execfunction == func1, a.execfunction
- assert isinstance(a.strfunction, types.FunctionType)
+ assert isinstance(a.strfunction, types.MethodType), type(a.strfunction)
a = SCons.Action.FunctionAction(func2, strfunction=func3)
assert a.execfunction == func2, a.execfunction
assert a.strfunction == func3, a.strfunction
- a = SCons.Action.FunctionAction(func3, func4)
- assert a.execfunction == func3, a.execfunction
- assert a.strfunction == func4, a.strfunction
+ def test_cmdstr_bad(self):
+ """Test handling of bad FunctionAction(cmdstr) arguments
+ """
+ def func():
+ pass
+ try:
+ a = SCons.Action.FunctionAction(func, [])
+ except SCons.Errors.UserError, e:
+ s = str(e)
+ m = 'Invalid function display variable'
+ assert string.find(s, m) != -1, 'Unexpected string: %s' % s
+ else:
+ raise "did not catch expected UserError"
- a = SCons.Action.FunctionAction(func4, None)
- assert a.execfunction == func4, a.execfunction
- assert a.strfunction is None, a.strfunction
+ def test___str__(self):
+ """Test the __str__() method for function Actions
+ """
+ def func1():
+ pass
+ a = SCons.Action.FunctionAction(func1)
+ s = str(a)
+ assert s == "func1(target, source, env)", s
+
+ class class1:
+ def __call__(self):
+ pass
+ a = SCons.Action.FunctionAction(class1())
+ s = str(a)
+ assert s == "class1(target, source, env)", s
def test_execute(self):
"""Test executing a function Action
return 1
act = SCons.Action.FunctionAction(function1)
- r = None
- try:
- r = act(target = [outfile, outfile2], source=[], env=Environment())
- except SCons.Errors.BuildError:
- pass
- assert r == 1
- assert count == 1
+ r = act(target = [outfile, outfile2], source=[], env=Environment())
+ assert r.status == 1, r.status
+
+ assert count == 1, count
c = test.read(outfile, 'r')
assert c == "function1\n", c
c = test.read(outfile2, 'r')
act = SCons.Action.FunctionAction(class1a)
r = act([], [], Environment(out = outfile))
- assert r.__class__ == class1a
+ assert isinstance(r.status, class1a), r.status
c = test.read(outfile, 'r')
assert c == "class1a\n", c
act = SCons.Action.FunctionAction(class1b())
r = act([], [], Environment(out = outfile))
- assert r == 2
+ assert r.status == 2, r.status
c = test.read(outfile, 'r')
assert c == "class1b\n", c
def build_it(target, source, env, self=self):
self.build_it = 1
return 0
- def string_it(target, source, self=self):
+ def string_it(target, source, env, self=self):
self.string_it = 1
return None
- act = SCons.Action.FunctionAction(build_it, string_it)
+ act = SCons.Action.FunctionAction(build_it, strfunction=string_it)
r = act([], [], Environment())
assert r == 0, r
assert self.build_it
def test_get_contents(self):
"""Test fetching the contents of a function Action
"""
- a = SCons.Action.FunctionAction(Func)
+
+ def LocalFunc():
+ pass
+
+ func_matches = [
+ "0,0,0,0,(),(),(d\000\000S),(),()",
+ "0,0,0,0,(),(),(d\x00\x00S),(),()",
+ ]
+
+ meth_matches = [
+ "1,1,0,0,(),(),(d\000\000S),(),()",
+ "1,1,0,0,(),(),(d\x00\x00S),(),()",
+ ]
+
+ a = SCons.Action.FunctionAction(GlobalFunc)
+ c = a.get_contents(target=[], source=[], env=Environment())
+ assert c in func_matches, repr(c)
+
+ a = SCons.Action.FunctionAction(LocalFunc)
+ c = a.get_contents(target=[], source=[], env=Environment())
+ assert c in func_matches, repr(c)
+
+ a = SCons.Action.FunctionAction(GlobalFunc, varlist=['XYZ'])
+
+ matches_foo = map(lambda x: x + "foo", func_matches)
+
+ c = a.get_contents(target=[], source=[], env=Environment())
+ assert c in func_matches, repr(c)
+ c = a.get_contents(target=[], source=[], env=Environment(XYZ = 'foo'))
+ assert c in matches_foo, repr(c)
+
+ class Foo:
+ def get_contents(self, target, source, env):
+ return 'xyzzy'
+ a = SCons.Action.FunctionAction(Foo())
+ c = a.get_contents(target=[], source=[], env=Environment())
+ assert c == 'xyzzy', repr(c)
+
+ class LocalClass:
+ def LocalMethod(self):
+ pass
+ lc = LocalClass()
+ a = SCons.Action.FunctionAction(lc.LocalMethod)
c = a.get_contents(target=[], source=[], env=Environment())
- assert c == "\177\036\000\177\037\000d\000\000S", repr(c)
+ assert c in meth_matches, repr(c)
+
+ def test_strfunction(self):
+ """Test the FunctionAction.strfunction() method
+ """
+ def func():
+ pass
+
+ a = SCons.Action.FunctionAction(func)
+ s = a.strfunction(target=[], source=[], env=Environment())
+ assert s == 'func([], [])', s
+
+ a = SCons.Action.FunctionAction(func, None)
+ s = a.strfunction(target=[], source=[], env=Environment())
+ assert s is None, s
+
+ a = SCons.Action.FunctionAction(func, 'function')
+ s = a.strfunction(target=[], source=[], env=Environment())
+ assert s == 'function', s
class ListActionTestCase(unittest.TestCase):
- def test_init(self):
+ def test___init__(self):
"""Test creation of a list of subsidiary Actions
"""
def func():
assert isinstance(a.list[0], SCons.Action.CommandAction)
assert isinstance(a.list[1], SCons.Action.FunctionAction)
assert isinstance(a.list[2], SCons.Action.ListAction)
- assert a.list[2].list[0].cmd_list == [ 'y' ]
+ assert a.list[2].list[0].cmd_list == 'y'
- def test_get_actions(self):
- """Test the get_actions() method for ListActions
+ def test___str__(self):
+ """Test the __str__() method for a list of subsidiary Actions
"""
- a = SCons.Action.ListAction(["x", "y"])
- l = a.get_actions()
- assert len(l) == 2, l
- assert isinstance(l[0], SCons.Action.CommandAction), l[0]
- g = l[0].get_actions()
- assert g == [l[0]], g
- assert isinstance(l[1], SCons.Action.CommandAction), l[1]
- g = l[1].get_actions()
- assert g == [l[1]], g
+ def f(target,source,env):
+ pass
+ def g(target,source,env):
+ pass
+ a = SCons.Action.ListAction([f, g, "XXX", f])
+ s = str(a)
+ assert s == "f(target, source, env)\ng(target, source, env)\nXXX\nf(target, source, env)", s
+
+ def test_genstring(self):
+ """Test the genstring() method for a list of subsidiary Actions
+ """
+ def f(target,source,env):
+ pass
+ def g(target,source,env,for_signature):
+ return 'generated %s %s' % (target[0], source[0])
+ g = SCons.Action.Action(g, generator=1)
+ a = SCons.Action.ListAction([f, g, "XXX", f])
+ s = a.genstring(['foo.x'], ['bar.y'], Environment())
+ assert s == "f(target, source, env)\ngenerated foo.x bar.y\nXXX\nf(target, source, env)", s
def test_execute(self):
"""Test executing a list of subsidiary Actions
a([], [], Environment(s = self))
assert self.inc == 3, self.inc
- cmd2 = r'%s %s %s syzygy' % (python, act_py, outfile)
+ cmd2 = r'%s %s %s syzygy' % (_python_, act_py, outfile)
def function2(target, source, env):
open(env['out'], 'a').write("function2\n")
open(env['out'], 'a').write("class2b\n")
act = SCons.Action.ListAction([cmd2, function2, class2a(), class2b])
r = act([], [], Environment(out = outfile))
- assert r.__class__ == class2b
+ assert isinstance(r.status, class2b), r.status
c = test.read(outfile, 'r')
assert c == "act.py: 'syzygy'\nfunction2\nclass2a\nclass2b\n", c
s.foo=1
return "y"
a = SCons.Action.ListAction(["x",
- SCons.Action.CommandGenerator(gen),
+ SCons.Action.Action(gen, generator=1),
"z"])
c = a.get_contents(target=[], source=[], env=Environment(s = self))
assert self.foo==1, self.foo
assert c == "xyz", c
class LazyActionTestCase(unittest.TestCase):
- def test_init(self):
+ def test___init__(self):
"""Test creation of a lazy-evaluation Action
"""
- # Environment variable references should create a special
- # type of CommandGeneratorAction that lazily evaluates the
- # variable.
+ # Environment variable references should create a special type
+ # of LazyAction that lazily evaluates the variable for whether
+ # it's a string or something else before doing anything.
a9 = SCons.Action.Action('$FOO')
- assert isinstance(a9, SCons.Action.CommandGeneratorAction), a9
- assert a9.generator.var == 'FOO', a9.generator.var
+ assert isinstance(a9, SCons.Action.LazyAction), a9
+ assert a9.var == 'FOO', a9.var
a10 = SCons.Action.Action('${FOO}')
- assert isinstance(a9, SCons.Action.CommandGeneratorAction), a10
- assert a10.generator.var == 'FOO', a10.generator.var
+ assert isinstance(a10, SCons.Action.LazyAction), a10
+ assert a10.var == 'FOO', a10.var
+
+ def test_genstring(self):
+ """Test the lazy-evaluation Action genstring() method
+ """
+ def f(target, source, env):
+ pass
+ a = SCons.Action.Action('$BAR')
+ env1 = Environment(BAR=f, s=self)
+ env2 = Environment(BAR='xxx', s=self)
+ s = a.genstring([], [], env=env1)
+ assert s == "f(target, source, env)", s
+ s = a.genstring([], [], env=env2)
+ assert s == 'xxx', s
def test_execute(self):
"""Test executing a lazy-evaluation Action
a = SCons.Action.Action('$BAR')
a([], [], env=Environment(BAR = f, s = self))
assert self.test == 1, self.test
+ cmd = r'%s %s %s lazy' % (_python_, act_py, outfile)
+ a([], [], env=Environment(BAR = cmd, s = self))
+ c = test.read(outfile, 'r')
+ assert c == "act.py: 'lazy'\n", c
def test_get_contents(self):
"""Test fetching the contents of a lazy-evaluation Action
"""
a = SCons.Action.Action("${FOO}")
- c = a.get_contents(target=[], source=[],
- env = Environment(FOO = [["This", "is", "$(", "a", "$)", "test"]]))
- assert c == "This is test", c
+ env = Environment(FOO = [["This", "is", "a", "test"]])
+ c = a.get_contents(target=[], source=[], env=env)
+ assert c == "This is a test", c
+
+class ActionCallerTestCase(unittest.TestCase):
+ def test___init__(self):
+ """Test creation of an ActionCaller"""
+ ac = SCons.Action.ActionCaller(1, [2, 3], {'FOO' : 4, 'BAR' : 5})
+ assert ac.parent == 1, ac.parent
+ assert ac.args == [2, 3], ac.args
+ assert ac.kw == {'FOO' : 4, 'BAR' : 5}, ac.kw
+
+ def test_get_contents(self):
+ """Test fetching the contents of an ActionCaller"""
+ def strfunc():
+ pass
+
+ def LocalFunc():
+ pass
+
+ matches = [
+ "d\000\000S",
+ "d\x00\x00S"
+ ]
+
+ af = SCons.Action.ActionFactory(GlobalFunc, strfunc)
+ ac = SCons.Action.ActionCaller(af, [], {})
+ c = ac.get_contents([], [], Environment())
+ assert c in matches, repr(c)
+
+ af = SCons.Action.ActionFactory(LocalFunc, strfunc)
+ ac = SCons.Action.ActionCaller(af, [], {})
+ c = ac.get_contents([], [], Environment())
+ assert c in matches, repr(c)
+
+ matches = [
+ 'd\000\000S',
+ "d\x00\x00S"
+ ]
+
+ class LocalActFunc:
+ def __call__(self):
+ pass
+
+ af = SCons.Action.ActionFactory(GlobalActFunc(), strfunc)
+ ac = SCons.Action.ActionCaller(af, [], {})
+ c = ac.get_contents([], [], Environment())
+ assert c in matches, repr(c)
+
+ af = SCons.Action.ActionFactory(LocalActFunc(), strfunc)
+ ac = SCons.Action.ActionCaller(af, [], {})
+ c = ac.get_contents([], [], Environment())
+ assert c in matches, repr(c)
+
+ matches = [
+ "<built-in function str>",
+ "<type 'str'>",
+ ]
+
+ af = SCons.Action.ActionFactory(str, strfunc)
+ ac = SCons.Action.ActionCaller(af, [], {})
+ c = ac.get_contents([], [], Environment())
+ assert c == "<built-in function str>" or \
+ c == "<type 'str'>", repr(c)
+
+ def test___call__(self):
+ """Test calling an ActionCaller"""
+ actfunc_args = []
+ def actfunc(a1, a2, a3, args=actfunc_args):
+ args.extend([a1, a2, a3])
+ def strfunc(a1, a2, a3):
+ pass
+
+ e = Environment(FOO = 2, BAR = 5)
+
+ af = SCons.Action.ActionFactory(actfunc, strfunc)
+ ac = SCons.Action.ActionCaller(af, ['$__env__', '$FOO', 3], {})
+ ac([], [], e)
+ assert actfunc_args[0] is e, actfunc_args
+ assert actfunc_args[1] == '2', actfunc_args
+ assert actfunc_args[2] == 3, actfunc_args
+ del actfunc_args[:]
+
+ ac = SCons.Action.ActionCaller(af, [], {'a3' : '$__env__', 'a2' : '$BAR', 'a1' : 4})
+ ac([], [], e)
+ assert actfunc_args[0] == 4, actfunc_args
+ assert actfunc_args[1] == '5', actfunc_args
+ assert actfunc_args[2] is e, actfunc_args
+ del actfunc_args[:]
+
+ def test_strfunction(self):
+ """Test calling the ActionCaller strfunction() method"""
+ strfunc_args = []
+ def actfunc(a1, a2, a3, a4):
+ pass
+ def strfunc(a1, a2, a3, a4, args=strfunc_args):
+ args.extend([a1, a2, a3, a4])
+
+ af = SCons.Action.ActionFactory(actfunc, strfunc)
+ ac = SCons.Action.ActionCaller(af, [1, '$FOO', 3, '$WS'], {})
+ ac.strfunction([], [], Environment(FOO = 2, WS='white space'))
+ assert strfunc_args == [1, '2', 3, 'white space'], strfunc_args
+
+ del strfunc_args[:]
+ d = {'a3' : 6, 'a2' : '$BAR', 'a1' : 4, 'a4' : '$WS'}
+ ac = SCons.Action.ActionCaller(af, [], d)
+ ac.strfunction([], [], Environment(BAR = 5, WS='w s'))
+ assert strfunc_args == [4, '5', 6, 'w s'], strfunc_args
+
+class ActionFactoryTestCase(unittest.TestCase):
+ def test___init__(self):
+ """Test creation of an ActionFactory"""
+ def actfunc():
+ pass
+ def strfunc():
+ pass
+ ac = SCons.Action.ActionFactory(actfunc, strfunc)
+ assert ac.actfunc is actfunc, ac.actfunc
+ assert ac.strfunc is strfunc, ac.strfunc
+
+ def test___call__(self):
+ """Test calling whatever's returned from an ActionFactory"""
+ actfunc_args = []
+ strfunc_args = []
+ def actfunc(a1, a2, a3, args=actfunc_args):
+ args.extend([a1, a2, a3])
+ def strfunc(a1, a2, a3, args=strfunc_args):
+ args.extend([a1, a2, a3])
+ af = SCons.Action.ActionFactory(actfunc, strfunc)
+ af(3, 6, 9)([], [], Environment())
+ assert actfunc_args == [3, 6, 9], actfunc_args
+ assert strfunc_args == [3, 6, 9], strfunc_args
+
+
+class ActionCompareTestCase(unittest.TestCase):
+
+ def test_1_solo_name(self):
+ """Test Lazy Cmd Generator Action get_name alone.
+
+ Basically ensures we can locate the builder, comparing it to
+ itself along the way."""
+ bar = SCons.Builder.Builder(action = {})
+ env = Environment( BUILDERS = {'BAR' : bar} )
+ name = bar.get_name(env)
+ assert name == 'BAR', name
+
+ def test_2_multi_name(self):
+ """Test LazyCmdGenerator Action get_name multi builders.
+
+ Ensure that we can compare builders (and thereby actions) to
+ each other safely."""
+ foo = SCons.Builder.Builder(action = '$FOO', suffix = '.foo')
+ bar = SCons.Builder.Builder(action = {})
+ assert foo != bar
+ assert foo.action != bar.action
+ env = Environment( BUILDERS = {'FOO' : foo,
+ 'BAR' : bar} )
+ name = foo.get_name(env)
+ assert name == 'FOO', name
+ name = bar.get_name(env)
+ assert name == 'BAR', name
+
+ def test_3_dict_names(self):
+ """Test Action/Suffix dicts with get_name.
+
+ Verifies that Action/Suffix dictionaries work correctly,
+ especially two builders that can generate the same suffix,
+ where one of the builders has a suffix dictionary with a None
+ key."""
+
+ foo = SCons.Builder.Builder(action = '$FOO', suffix = '.foo')
+ bar = SCons.Builder.Builder(action = {}, suffix={None:'.bar'})
+ bar.add_action('.cow', "$MOO")
+ dog = SCons.Builder.Builder(suffix = '.bar')
+
+ env = Environment( BUILDERS = {'FOO' : foo,
+ 'BAR' : bar,
+ 'DOG' : dog} )
+
+ assert foo.get_name(env) == 'FOO', foo.get_name(env)
+ assert bar.get_name(env) == 'BAR', bar.get_name(env)
+ assert dog.get_name(env) == 'DOG', dog.get_name(env)
if __name__ == "__main__":
suite = unittest.TestSuite()
tclasses = [ ActionTestCase,
ActionBaseTestCase,
+ _ActionActionTestCase,
CommandActionTestCase,
CommandGeneratorActionTestCase,
FunctionActionTestCase,
ListActionTestCase,
- LazyActionTestCase ]
+ LazyActionTestCase,
+ ActionCallerTestCase,
+ ActionFactoryTestCase,
+ ActionCompareTestCase ]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
suite.addTests(map(tclass, names))