# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
+from __future__ import generators ### KEEP FOR COMPATIBILITY FIXERS
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+import SCons.compat
+
+import collections
import os
import re
-import string
import sys
-import types
import unittest
-import UserList
import SCons.Errors
import SCons.Node
+import SCons.Util
all.append(curr_a)
elif isinstance(curr_a, MyListAction):
all.extend(curr_a.list)
- elif type(curr_a) == type([1,2]):
+ elif isinstance(curr_a, list):
all.extend(curr_a)
else:
- raise 'Cannot Combine Actions'
+ raise Exception('Cannot Combine Actions')
return MyListAction(all)
class MyActionBase:
def __init__(self):
self.order = 0
- def __call__(self, target, source, env, errfunc):
+ def __call__(self, target, source, env, executor=None):
global built_it, built_target, built_source, built_args, built_order
+ if executor:
+ target = executor.get_all_targets()
+ source = executor.get_all_sources()
built_it = 1
built_target = target
built_source = source
self.order = built_order
return 0
+ def get_implicit_deps(self, target, source, env):
+ return []
+
class MyExecutor:
def __init__(self, env=None, targets=[], sources=[]):
self.env = env
class MyListAction(MyActionBase):
def __init__(self, list):
self.list = list
- def __call__(self, target, source, env, errfunc):
+ def __call__(self, target, source, env):
for A in self.list:
- A(target, source, env, errfunc)
+ A(target, source, env)
class Environment:
def __init__(self, **kw):
def Override(self, overrides):
d = self._dict.copy()
d.update(overrides)
- return apply(Environment, (), d)
+ return Environment(**d)
def _update(self, dict):
self._dict.update(dict)
- def get_calculator(self):
- return SCons.Sig.default_calc
def get_factory(self, factory):
return factory or MyNode
def get_scanner(self, scanner_key):
class ExceptBuilder2:
def execute(self, target, source, env):
- raise "foo"
+ raise Exception("foo")
class Scanner:
called = None
class NodeInfoBaseTestCase(unittest.TestCase):
- def test_prepare_dependencies(self):
- """Test that we have a prepare_dependencies() method"""
- ni = SCons.Node.NodeInfoBase(SCons.Node.Node())
- ni.prepare_dependencies()
-
- def test___cmp__(self):
- """Test comparing NodeInfoBase objects"""
- ni1 = SCons.Node.NodeInfoBase(SCons.Node.Node())
- ni2 = SCons.Node.NodeInfoBase(SCons.Node.Node())
-
- assert ni1 == ni2, "%s != %s" % (ni1.__dict__, ni2.__dict__)
-
- ni1.foo = 777
- assert ni1 != ni2, "%s == %s" % (ni1.__dict__, ni2.__dict__)
-
- ni2.foo = 888
- assert ni1 != ni2, "%s == %s" % (ni1.__dict__, ni2.__dict__)
-
- ni1.foo = 888
- assert ni1 == ni2, "%s != %s" % (ni1.__dict__, ni2.__dict__)
-
def test_merge(self):
"""Test merging NodeInfoBase attributes"""
ni1 = SCons.Node.NodeInfoBase(SCons.Node.Node())
ni2.a3 = 333
ni1.merge(ni2)
- assert ni1.__dict__ == {'a1':1, 'a2':222, 'a3':333}, ni1.__dict__
+ expect = {'a1':1, 'a2':222, 'a3':333, '_version_id':1}
+ assert ni1.__dict__ == expect, ni1.__dict__
def test_update(self):
"""Test the update() method"""
ni1.zzz = 'z'
f = ni1.format()
- assert f == 'x y z', f
+ assert f == ['1', 'x', 'y', 'z'], f
ni1.field_list = ['xxx', 'zzz', 'aaa']
f = ni1.format()
- assert f == 'x z None', f
+ assert f == ['x', 'z', 'None'], f
def test___init__(self):
"""Test BuildInfoBase initialization"""
- bi = SCons.Node.BuildInfoBase(SCons.Node.Node())
- assert hasattr(bi, 'ninfo')
-
- class MyNode(SCons.Node.Node):
- def NodeInfo(self, node):
- return 'ninfo initialization'
- bi = SCons.Node.BuildInfoBase(MyNode())
- assert bi.ninfo == 'ninfo initialization', bi.ninfo
-
- def test___cmp__(self):
- """Test comparing BuildInfoBase objects"""
- bi1 = SCons.Node.BuildInfoBase(SCons.Node.Node())
- bi2 = SCons.Node.BuildInfoBase(SCons.Node.Node())
-
- assert bi1 == bi2, "%s != %s" % (bi1.__dict__, bi2.__dict__)
-
- bi1.ninfo.foo = 777
- assert bi1 != bi2, "%s == %s" % (bi1.__dict__, bi2.__dict__)
-
- bi2.ninfo.foo = 888
- assert bi1 != bi2, "%s == %s" % (bi1.__dict__, bi2.__dict__)
-
- bi1.ninfo.foo = 888
- assert bi1 == bi2, "%s != %s" % (bi1.__dict__, bi2.__dict__)
-
- bi1.foo = 999
- assert bi1 == bi2, "%s != %s" % (bi1.__dict__, bi2.__dict__)
+ n = SCons.Node.Node()
+ bi = SCons.Node.BuildInfoBase(n)
+ assert bi
def test_merge(self):
"""Test merging BuildInfoBase attributes"""
- bi1 = SCons.Node.BuildInfoBase(SCons.Node.Node())
- bi2 = SCons.Node.BuildInfoBase(SCons.Node.Node())
+ n1 = SCons.Node.Node()
+ bi1 = SCons.Node.BuildInfoBase(n1)
+ n2 = SCons.Node.Node()
+ bi2 = SCons.Node.BuildInfoBase(n2)
bi1.a1 = 1
bi1.a2 = 2
bi2.a2 = 222
bi2.a3 = 333
- bi1.ninfo.a4 = 4
- bi1.ninfo.a5 = 5
- bi2.ninfo.a5 = 555
- bi2.ninfo.a6 = 666
-
bi1.merge(bi2)
assert bi1.a1 == 1, bi1.a1
assert bi1.a2 == 222, bi1.a2
assert bi1.a3 == 333, bi1.a3
- assert bi1.ninfo.a4 == 4, bi1.ninfo.a4
- assert bi1.ninfo.a5 == 555, bi1.ninfo.a5
- assert bi1.ninfo.a6 == 666, bi1.ninfo.a6
-
class NodeTestCase(unittest.TestCase):
# Make sure it doesn't blow up if no builder is set.
node = MyNode("www")
node.build()
- assert built_it == None
+ assert built_it is None
node.build(extra_kw_argument = 1)
- assert built_it == None
+ assert built_it is None
node = MyNode("xxx")
node.builder_set(Builder())
def test_built(self):
"""Test the built() method"""
+ class SubNodeInfo(SCons.Node.NodeInfoBase):
+ def update(self, node):
+ self.updated = 1
class SubNode(SCons.Node.Node):
def clear(self):
self.cleared = 1
n = SubNode()
+ n.ninfo = SubNodeInfo(n)
n.built()
assert n.cleared, n.cleared
+ assert n.ninfo.updated, n.ninfo.cleared
+
+ def test_push_to_cache(self):
+ """Test the base push_to_cache() method"""
+ n = SCons.Node.Node()
+ r = n.push_to_cache()
+ assert r is None, r
def test_retrieve_from_cache(self):
"""Test the base retrieve_from_cache() method"""
n = SCons.Node.Node()
t, m = n.alter_targets()
assert t == [], t
- assert m == None, m
+ assert m is None, m
- def test_current(self):
- """Test the default current() method
+ def test_is_up_to_date(self):
+ """Test the default is_up_to_date() method
"""
node = SCons.Node.Node()
- assert node.current() is None
+ assert node.is_up_to_date() is None
def test_children_are_up_to_date(self):
"""Test the children_are_up_to_date() method used by subclasses
n1 = SCons.Node.Node()
n2 = SCons.Node.Node()
- calc = Calculator(111)
-
- n1.add_source(n2)
- assert n1.children_are_up_to_date(calc), "expected up to date"
+ n1.add_source([n2])
+ assert n1.children_are_up_to_date(), "expected up to date"
n2.set_state(SCons.Node.executed)
- assert not n1.children_are_up_to_date(calc), "expected not up to date"
+ assert not n1.children_are_up_to_date(), "expected not up to date"
n2.set_state(SCons.Node.up_to_date)
- assert n1.children_are_up_to_date(calc), "expected up to date"
+ assert n1.children_are_up_to_date(), "expected up to date"
n1.always_build = 1
- assert not n1.children_are_up_to_date(calc), "expected not up to date"
+ assert not n1.children_are_up_to_date(), "expected not up to date"
def test_env_set(self):
"""Test setting a Node's Environment
a = node.builder.get_actions()
assert isinstance(a[0], MyAction), a[0]
- def test_get_bsig(self):
- """Test generic build signature calculation
+ def test_get_csig(self):
+ """Test generic content signature calculation
"""
node = SCons.Node.Node()
- result = node.get_bsig(Calculator(222))
- assert result == 222, result
- result = node.get_bsig(Calculator(333))
- assert result == 222, result
+ node.get_contents = lambda: 444
+ result = node.get_csig()
+ assert result == '550a141f12de6341fba65b0ad0433500', result
- def test_get_csig(self):
- """Test generic content signature calculation
+ def test_get_cachedir_csig(self):
+ """Test content signature calculation for CacheDir
"""
node = SCons.Node.Node()
- result = node.get_csig(Calculator(444))
- assert result == 444, result
- result = node.get_csig(Calculator(555))
- assert result == 444, result
+ node.get_contents = lambda: 555
+ result = node.get_cachedir_csig()
+ assert result == '15de21c670ae7c3f6f3f1f37029303c9', result
def test_get_binfo(self):
"""Test fetching/creating a build information structure
binfo = node.get_binfo()
assert isinstance(binfo, SCons.Node.BuildInfoBase), binfo
- node.binfo = 777
- binfo = node.get_binfo()
- assert binfo == 777, binfo
-
- def test_gen_binfo(self):
- """Test generating a build information structure
- """
node = SCons.Node.Node()
d = SCons.Node.Node()
+ d.get_ninfo().csig = 777
i = SCons.Node.Node()
+ i.get_ninfo().csig = 888
node.depends = [d]
node.implicit = [i]
- node.gen_binfo(Calculator(666))
- binfo = node.binfo
+
+ binfo = node.get_binfo()
assert isinstance(binfo, SCons.Node.BuildInfoBase), binfo
assert hasattr(binfo, 'bsources')
assert hasattr(binfo, 'bsourcesigs')
assert hasattr(binfo, 'bdependsigs')
assert binfo.bimplicit == [i]
assert hasattr(binfo, 'bimplicitsigs')
- assert binfo.ninfo.bsig == 1998, binfo.ninfo.bsig
def test_explain(self):
"""Test explaining why a Node must be rebuilt
class testNode2(SCons.Node.Node):
def __str__(self): return 'null_binfo'
+ class FS:
+ pass
node = testNode2()
+ node.fs = FS()
+ node.fs.Top = SCons.Node.Node()
result = node.explain()
- assert result == None, result
+ assert result is None, result
def get_null_info():
- class Null_BInfo:
- def prepare_dependencies(self):
- pass
- return Null_BInfo()
+ class Null_SConsignEntry:
+ class Null_BuildInfo:
+ def prepare_dependencies(self):
+ pass
+ binfo = Null_BuildInfo()
+ return Null_SConsignEntry()
node.get_stored_info = get_null_info
#see above: node.__str__ = lambda: 'null_binfo'
# XXX additional tests for the guts of the functionality some day
- def test_del_binfo(self):
- """Test deleting the build information from a Node
- """
- node = SCons.Node.Node()
- node.binfo = None
- node.del_binfo()
- assert not hasattr(node, 'binfo'), node
+ #def test_del_binfo(self):
+ # """Test deleting the build information from a Node
+ # """
+ # node = SCons.Node.Node()
+ # node.binfo = None
+ # node.del_binfo()
+ # assert not hasattr(node, 'binfo'), node
def test_store_info(self):
"""Test calling the method to store build information
"""
- class Entry:
- pass
node = SCons.Node.Node()
- node.store_info(Entry())
+ node.store_info()
def test_get_stored_info(self):
"""Test calling the method to fetch stored build information
n1 = SCons.Node.Node()
n1.builder_set(Builder())
node.implicit = []
- node.implicit_dict = {}
- node._add_child(node.implicit, node.implicit_dict, [n1])
+ node.implicit_set = set()
+ node._add_child(node.implicit, node.implicit_set, [n1])
node.prepare() # should not throw an exception
n2 = SCons.Node.Node()
n2.linked = 1
node.implicit = []
- node.implicit_dict = {}
- node._add_child(node.implicit, node.implicit_dict, [n2])
+ node.implicit_set = set()
+ node._add_child(node.implicit, node.implicit_set, [n2])
node.prepare() # should not throw an exception
n3 = SCons.Node.Node()
node.implicit = []
- node.implicit_dict = {}
- node._add_child(node.implicit, node.implicit_dict, [n3])
+ node.implicit_set = set()
+ node._add_child(node.implicit, node.implicit_set, [n3])
node.prepare() # should not throw an exception
return None
n4 = MyNode()
node.implicit = []
- node.implicit_dict = {}
- node._add_child(node.implicit, node.implicit_dict, [n4])
+ node.implicit_set = set()
+ node._add_child(node.implicit, node.implicit_set, [n4])
exc_caught = 0
try:
node.prepare()
five = SCons.Node.Node()
six = SCons.Node.Node()
- node.add_dependency(zero)
+ node.add_dependency([zero])
assert node.depends == [zero]
node.add_dependency([one])
assert node.depends == [zero, one]
except:
pass
else:
- raise "did not catch expected exception"
+ raise Exception("did not catch expected exception")
assert node.depends == [zero, one, two, three, four]
five = SCons.Node.Node()
six = SCons.Node.Node()
- node.add_source(zero)
+ node.add_source([zero])
assert node.sources == [zero]
node.add_source([one])
assert node.sources == [zero, one]
except:
pass
else:
- raise "did not catch expected exception"
- assert node.sources == [zero, one, two, three, four]
+ raise Exception("did not catch expected exception")
+ assert node.sources == [zero, one, two, three, four], node.sources
def test_add_ignore(self):
"""Test adding files whose dependencies should be ignored.
five = SCons.Node.Node()
six = SCons.Node.Node()
- node.add_ignore(zero)
+ node.add_ignore([zero])
assert node.ignore == [zero]
node.add_ignore([one])
assert node.ignore == [zero, one]
except:
pass
else:
- raise "did not catch expected exception"
+ raise Exception("did not catch expected exception")
assert node.ignore == [zero, one, two, three, four]
def test_get_found_includes(self):
d2.found_includes = [e, f]
f.found_includes = [g]
deps = node.get_implicit_deps(env, s, target)
- assert deps == [d1, d2, e, f, g], map(str, deps)
+ assert deps == [d1, d2, e, f, g], list(map(str, deps))
# Recursive scanning eliminates duplicates
e.found_includes = [f]
deps = node.get_implicit_deps(env, s, target)
- assert deps == [d1, d2, e, f, g], map(str, deps)
+ assert deps == [d1, d2, e, f, g], list(map(str, deps))
# Scanner method can select specific nodes to recurse
def no_fff(nodes):
- return filter(lambda n: str(n)[0] != 'f', nodes)
+ return [n for n in nodes if str(n)[0] != 'f']
s.recurse_nodes = no_fff
deps = node.get_implicit_deps(env, s, target)
- assert deps == [d1, d2, e, f], map(str, deps)
+ assert deps == [d1, d2, e, f], list(map(str, deps))
# Scanner method can short-circuit recursing entirely
s.recurse_nodes = lambda nodes: []
deps = node.get_implicit_deps(env, s, target)
- assert deps == [d1, d2], map(str, deps)
+ assert deps == [d1, d2], list(map(str, deps))
def test_get_env_scanner(self):
"""Test fetching the environment scanner for a Node
target = SCons.Node.Node()
source = SCons.Node.Node()
s = target.get_source_scanner(source)
- assert s is None, s
+ assert isinstance(s, SCons.Util.Null), s
ts1 = Scanner()
ts2 = Scanner()
# if the stored dependencies need recalculation.
class StoredNode(MyNode):
def get_stored_implicit(self):
- return ['implicit1', 'implicit2']
-
- class NotCurrent:
- def current(self, node, sig):
- return None
- def bsig(self, node):
- return 0
-
- import SCons.Sig
+ return [MyNode('implicit1'), MyNode('implicit2')]
- save_default_calc = SCons.Sig.default_calc
save_implicit_cache = SCons.Node.implicit_cache
save_implicit_deps_changed = SCons.Node.implicit_deps_changed
save_implicit_deps_unchanged = SCons.Node.implicit_deps_unchanged
- SCons.Sig.default_calc = NotCurrent()
SCons.Node.implicit_cache = 1
SCons.Node.implicit_deps_changed = None
SCons.Node.implicit_deps_unchanged = None
assert sn.children() == [], sn.children()
finally:
- SCons.Sig.default_calc = save_default_calc
SCons.Node.implicit_cache = save_implicit_cache
SCons.Node.implicit_deps_changed = save_implicit_deps_changed
SCons.Node.implicit_deps_unchanged = save_implicit_deps_unchanged
def test_scanner_key(self):
"""Test that a scanner_key() method exists"""
- assert SCons.Node.Node().scanner_key() == None
+ assert SCons.Node.Node().scanner_key() is None
def test_children(self):
"""Test fetching the non-ignored "children" of a Node.
node.add_source([n1, n2, n3])
node.add_dependency([n4, n5, n6])
node.implicit = []
- node.implicit_dict = {}
- node._add_child(node.implicit, node.implicit_dict, [n7, n8, n9])
- node._add_child(node.implicit, node.implicit_dict, [n10, n11, n12])
+ node.implicit_set = set()
+ node._add_child(node.implicit, node.implicit_set, [n7, n8, n9])
+ node._add_child(node.implicit, node.implicit_set, [n10, n11, n12])
node.add_ignore([n2, n5, n8, n11])
kids = node.children()
node.add_source([n1, n2, n3])
node.add_dependency([n4, n5, n6])
node.implicit = []
- node.implicit_dict = {}
- node._add_child(node.implicit, node.implicit_dict, [n7, n8, n9])
- node._add_child(node.implicit, node.implicit_dict, [n10, n11, n12])
+ node.implicit_set = set()
+ node._add_child(node.implicit, node.implicit_set, [n7, n8, n9])
+ node._add_child(node.implicit, node.implicit_set, [n10, n11, n12])
node.add_ignore([n2, n5, n8, n11])
kids = node.all_children()
nw = SCons.Node.Walker(n1)
assert not nw.is_done()
- assert nw.next().name == "n1"
+ assert nw.get_next().name == "n1"
assert nw.is_done()
- assert nw.next() == None
+ assert nw.get_next() is None
n2 = MyNode("n2")
n3 = MyNode("n3")
n1.add_source([n2, n3])
nw = SCons.Node.Walker(n1)
- n = nw.next()
+ n = nw.get_next()
assert n.name == "n2", n.name
- n = nw.next()
+ n = nw.get_next()
assert n.name == "n3", n.name
- n = nw.next()
+ n = nw.get_next()
assert n.name == "n1", n.name
- n = nw.next()
- assert n == None, n
+ n = nw.get_next()
+ assert n is None, n
n4 = MyNode("n4")
n5 = MyNode("n5")
n3.add_dependency([n6, n7])
nw = SCons.Node.Walker(n1)
- assert nw.next().name == "n4"
- assert nw.next().name == "n5"
- assert nw.history.has_key(n2)
- assert nw.next().name == "n2"
- assert nw.next().name == "n6"
- assert nw.next().name == "n7"
- assert nw.history.has_key(n3)
- assert nw.next().name == "n3"
- assert nw.history.has_key(n1)
- assert nw.next().name == "n1"
- assert nw.next() == None
+ assert nw.get_next().name == "n4"
+ assert nw.get_next().name == "n5"
+ assert n2 in nw.history
+ assert nw.get_next().name == "n2"
+ assert nw.get_next().name == "n6"
+ assert nw.get_next().name == "n7"
+ assert n3 in nw.history
+ assert nw.get_next().name == "n3"
+ assert n1 in nw.history
+ assert nw.get_next().name == "n1"
+ assert nw.get_next() is None
n8 = MyNode("n8")
n8.add_dependency([n3])
global cycle_detected
nw = SCons.Node.Walker(n3, cycle_func = cycle)
- n = nw.next()
+ n = nw.get_next()
assert n.name == "n6", n.name
- n = nw.next()
+ n = nw.get_next()
assert n.name == "n8", n.name
assert cycle_detected
cycle_detected = None
- n = nw.next()
+ n = nw.get_next()
assert n.name == "n7", n.name
- n = nw.next()
- assert nw.next() == None
+ n = nw.get_next()
+ assert nw.get_next() is None
def test_abspath(self):
"""Test the get_abspath() method."""
n.clear()
- assert not hasattr(n, 'binfo'), n.bsig
assert n.includes is None, n.includes
- assert n.found_includes == {}, n.found_includes
- assert n.implicit is None, n.implicit
assert x.cleaned_up
def test_get_subst_proxy(self):
def test_postprocess(self):
"""Test calling the base Node postprocess() method"""
n = SCons.Node.Node()
- n.waiting_parents = {'foo':1, 'bar':1}
+ n.waiting_parents = set( ['foo','bar'] )
n.postprocess()
- assert n.waiting_parents == {}, n.waiting_parents
+ assert n.waiting_parents == set(), n.waiting_parents
def test_add_to_waiting_parents(self):
"""Test the add_to_waiting_parents() method"""
n1 = SCons.Node.Node()
n2 = SCons.Node.Node()
- assert n1.waiting_parents == {}, n1.waiting_parents
- n1.add_to_waiting_parents(n2)
- assert n1.waiting_parents == {n2:1}, n1.waiting_parents
+ assert n1.waiting_parents == set(), n1.waiting_parents
+ r = n1.add_to_waiting_parents(n2)
+ assert r == 1, r
+ assert n1.waiting_parents == set((n2,)), n1.waiting_parents
+ r = n1.add_to_waiting_parents(n2)
+ assert r == 0, r
- def test_call_for_all_waiting_parents(self):
- """Test the call_for_all_waiting_parents() method"""
- n1 = SCons.Node.Node()
- n2 = SCons.Node.Node()
- n1.add_to_waiting_parents(n2)
- result = []
- def func(node, result=result):
- result.append(node)
- n1.call_for_all_waiting_parents(func)
- assert result == [n1, n2], result
class NodeListTestCase(unittest.TestCase):
def test___str__(self):
nl = SCons.Node.NodeList([n3, n2, n1])
l = [1]
- ul = UserList.UserList([2])
+ ul = collections.UserList([2])
try:
l.extend(ul)
except TypeError:
# New-style classes report as "object"; classic classes report
# as "instance"...
r = re.sub("object", "instance", r)
- l = string.join(["<MyNode instance at 0x>"]*3, ", ")
+ l = ", ".join(["<MyNode instance at 0x>"]*3)
assert r == '[%s]' % l, r
NodeListTestCase ]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4: