__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+import SCons.compat
+
# 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
def Func():
pass
+import collections
+import io
import os.path
+import re
import sys
-import types
import unittest
-import UserList
import TestCmd
import SCons.Builder
import SCons.Environment
import SCons.Errors
+import SCons.Subst
+import SCons.Util
+
+sys.stdout = io.StringIO()
# Initial setup of the common environment for all tests,
# a temporary working directory containing a
def subst(self, s):
if not SCons.Util.is_String(s):
return s
- try:
- if s[0] == '$':
- return self.d.get(s[1:], '')
- if s[1] == '$':
- return s[0] + self.d.get(s[2:], '')
- except IndexError:
- pass
- return self.d.get(s, s)
+ def substitute(m, d=self.d):
+ return d.get(m.group(1), '')
+ return re.sub(r'\$(\w+)', substitute, s)
def subst_target_source(self, string, raw=0, target=None,
source=None, dict=None, conv=None):
- return SCons.Util.scons_subst(string, self, raw, target,
- source, dict, conv)
- def subst_list(self, string, raw=0, target=None,
- source=None, dict=None, conv=None):
- return SCons.Util.scons_subst_list(string, self, raw, target,
- source, dict, conv)
- def arg2nodes(self, args, factory):
+ return SCons.Subst.scons_subst(string, self, raw, target,
+ source, dict, conv)
+ def subst_list(self, string, raw=0, target=None, source=None, conv=None):
+ return SCons.Subst.scons_subst_list(string, self, raw, target,
+ source, {}, {}, conv)
+ def arg2nodes(self, args, factory, **kw):
global env_arg2nodes_called
env_arg2nodes_called = 1
if not SCons.Util.is_List(args):
list = []
for a in args:
if SCons.Util.is_String(a):
- a = factory(a)
+ a = factory(self.subst(a))
list.append(a)
return list
def get_factory(self, factory):
self.d[item] = var
def __getitem__(self, item):
return self.d[item]
+ def __contains__(self, item):
+ return self.d.__contains__(item)
def has_key(self, item):
- return self.d.has_key(item)
+ return item in self.d
def keys(self):
return self.d.keys()
def get(self, key, value=None):
return self.d.get(key, value)
def Override(self, overrides):
- env = apply(Environment, (), self.d)
+ env = Environment(**self.d)
env.d.update(overrides)
env.scanner = self.scanner
return env
def __cmp__(self, other):
return cmp(self.scanner, other.scanner) or cmp(self.d, other.d)
+class MyAction:
+ def __init__(self, action):
+ self.action = action
+ def __call__(self, *args, **kw):
+ pass
+ def get_executor(self, env, overrides, tlist, slist, executor_kw):
+ return ['executor'] + [self.action]
+
class MyNode_without_target_from_source:
def __init__(self, name):
self.name = name
self.builder = None
self.is_explicit = None
self.side_effect = 0
+ self.suffix = os.path.splitext(name)[1]
+ def disambiguate(self):
+ return self
def __str__(self):
return self.name
def builder_set(self, builder):
assert not hasattr(n2, 'env')
l = [1]
- ul = UserList.UserList([2])
+ ul = collections.UserList([2])
try:
l.extend(ul)
except TypeError:
def mystr(l):
- return str(map(str, l))
+ return str(list(map(str, l)))
else:
mystr = str
tlist = builder(env, target = [nnn1, nnn2], source = [])
s = mystr(tlist)
assert s == "['nnn1', 'nnn2']", s
- l = map(str, tlist)
+ l = list(map(str, tlist))
assert l == ['nnn1', 'nnn2'], l
tlist = builder(env, target = 'n3', source = 'n4')
s = mystr(tlist)
assert s == "['n3']", s
target = tlist[0]
- l = map(str, tlist)
+ l = list(map(str, tlist))
assert l == ['n3'], l
assert target.name == 'n3'
assert target.sources[0].name == 'n4'
tlist = builder(env, target = 'n4 n5', source = ['n6 n7'])
s = mystr(tlist)
assert s == "['n4 n5']", s
- l = map(str, tlist)
+ l = list(map(str, tlist))
assert l == ['n4 n5'], l
target = tlist[0]
assert target.name == 'n4 n5'
tlist = builder(env, target = ['n8 n9'], source = 'n10 n11')
s = mystr(tlist)
assert s == "['n8 n9']", s
- l = map(str, tlist)
+ l = list(map(str, tlist))
assert l == ['n8 n9'], l
target = tlist[0]
assert target.name == 'n8 n9'
#be = target.get_build_env()
#assert be['VAR'] == 'foo', be['VAR']
- if not hasattr(types, 'UnicodeType'):
+ try: unicode
+ except NameError:
uni = str
else:
uni = unicode
except SCons.Errors.UserError, e:
pass
else:
- raise "Did not catch expected UserError."
+ raise Exception("Did not catch expected UserError.")
+
+ builder = SCons.Builder.Builder(action="foo")
+ target = builder(env, None, source='n22', srcdir='src_dir')[0]
+ p = target.sources[0].path
+ assert p == os.path.join('src_dir', 'n22'), p
def test_mistaken_variables(self):
"""Test keyword arguments that are often mistakes
builder = SCons.Builder.Builder(generator=generator)
assert builder.action.generator == generator
+ def test_get_name(self):
+ """Test the get_name() method
+ """
+
def test_cmp(self):
"""Test simple comparisons of Builder objects
"""
tgt = builder(my_env, target = None, source = 'f6.zzz')[0]
assert tgt.path == 'emit-f6', tgt.path
+ def test_set_suffix(self):
+ """Test the set_suffix() method"""
+ b = SCons.Builder.Builder(action='')
+ env = Environment(XSUFFIX = '.x')
+
+ s = b.get_suffix(env)
+ assert s == '', s
+
+ b.set_suffix('.foo')
+ s = b.get_suffix(env)
+ assert s == '.foo', s
+
+ b.set_suffix('$XSUFFIX')
+ s = b.get_suffix(env)
+ assert s == '.x', s
+
def test_src_suffix(self):
"""Test Builder creation with a specified source file suffix
"Unexpected tgt.sources[0] name: %s" % tgt.sources[0].path
b2 = SCons.Builder.Builder(src_suffix = '.2', src_builder = b1)
- assert b2.src_suffixes(env) == ['.2', '.c'], b2.src_suffixes(env)
+ r = sorted(b2.src_suffixes(env))
+ assert r == ['.2', '.c'], r
b3 = SCons.Builder.Builder(action = {'.3a' : '', '.3b' : ''})
- s = b3.src_suffixes(env)
- s.sort()
+ s = sorted(b3.src_suffixes(env))
assert s == ['.3a', '.3b'], s
b4 = SCons.Builder.Builder(src_suffix = '$XSUFFIX')
tgt = b9(env, target=None, source='foo_altsrc.b')
assert str(tgt[0]) == 'foo.c', str(tgt[0])
+ def test_src_suffix_expansion(self):
+ """Test handling source suffixes when an expansion is involved"""
+ env = Environment(OBJSUFFIX = '.obj')
+
+ b1 = SCons.Builder.Builder(action = '',
+ src_suffix='.c',
+ suffix='.obj')
+ b2 = SCons.Builder.Builder(action = '',
+ src_builder=b1,
+ src_suffix='.obj',
+ suffix='.exe')
+ tgt = b2(env, target=None, source=['foo$OBJSUFFIX'])
+ s = list(map(str, tgt[0].sources))
+ assert s == ['foo.obj'], s
+
def test_suffix(self):
"""Test Builder creation with a specified target suffix
single_source = 1, suffix='.out')
env['CNT'] = [0]
tgt = builder(env, target=outfiles[0], source=infiles[0])[0]
+ s = str(tgt)
+ t = os.path.normcase(test.workpath('0.out'))
+ assert os.path.normcase(s) == t, s
tgt.prepare()
tgt.build()
assert env['CNT'][0] == 1, env['CNT'][0]
tgt = builder(env, outfiles[1], infiles[1])[0]
+ s = str(tgt)
+ t = os.path.normcase(test.workpath('1.out'))
+ assert os.path.normcase(s) == t, s
tgt.prepare()
tgt.build()
assert env['CNT'][0] == 2
tgts = builder(env, None, infiles[2:4])
+ try:
+ [].extend(collections.UserList())
+ except TypeError:
+ # Old Python version (1.5.2) that can't handle extending
+ # a list with list-like objects. That means the return
+ # value from the builder call is a real list with Nodes,
+ # and doesn't have a __str__() method that stringifies
+ # the individual elements. Since we're gong to drop 1.5.2
+ # support anyway, don't bother trying to test for it.
+ pass
+ else:
+ s = list(map(str, tgts))
+ expect = [test.workpath('2.out'), test.workpath('3.out')]
+ expect = list(map(os.path.normcase, expect))
+ assert list(map(os.path.normcase, s)) == expect, s
for t in tgts: t.prepare()
tgts[0].build()
tgts[1].build()
assert 0
- def test_ListBuilder(self):
- """Testing ListBuilder class."""
+ def test_lists(self):
+ """Testing handling lists of targets and source"""
def function2(target, source, env, tlist = [outfile, outfile2], **kw):
for t in target:
open(str(t), 'w').write("function2\n")
for t in tlist:
- if not t in map(str, target):
+ if not t in list(map(str, target)):
open(t, 'w').write("function2\n")
return 1
for t in target:
open(str(t), 'w').write("function3\n")
for t in tlist:
- if not t in map(str, target):
+ if not t in list(map(str, target)):
open(t, 'w').write("function3\n")
return 1
assert os.path.exists(test.workpath('sub1'))
assert os.path.exists(test.workpath('sub2'))
- def test_MultiStepBuilder(self):
- """Testing MultiStepBuilder class."""
+ def test_src_builder(self):
+ """Testing Builders with src_builder"""
+ # These used to be MultiStepBuilder objects until we
+ # eliminated it as a separate class
env = Environment()
builder1 = SCons.Builder.Builder(action='foo',
src_suffix='.bar',
suffix='.foo')
- builder2 = SCons.Builder.MultiStepBuilder(action='bar',
- src_builder = builder1,
- src_suffix = '.foo')
+ builder2 = SCons.Builder.Builder(action=MyAction('act'),
+ src_builder = builder1,
+ src_suffix = '.foo')
tgt = builder2(env, source=[])
assert tgt == [], tgt
- tgt = builder2(env, target='baz',
- source=['test.bar', 'test2.foo', 'test3.txt'])[0]
- assert str(tgt.sources[0]) == 'test.foo', str(tgt.sources[0])
- assert str(tgt.sources[0].sources[0]) == 'test.bar', \
- str(tgt.sources[0].sources[0])
- assert str(tgt.sources[1]) == 'test2.foo', str(tgt.sources[1])
- assert str(tgt.sources[2]) == 'test3.txt', str(tgt.sources[2])
+ sources = ['test.bar', 'test2.foo', 'test3.txt', 'test4']
+ tgt = builder2(env, target='baz', source=sources)[0]
+ s = str(tgt)
+ assert s == 'baz', s
+ s = list(map(str, tgt.sources))
+ assert s == ['test.foo', 'test2.foo', 'test3.txt', 'test4.foo'], s
+ s = list(map(str, tgt.sources[0].sources))
+ assert s == ['test.bar'], s
tgt = builder2(env, None, 'aaa.bar')[0]
- assert str(tgt) == 'aaa', str(tgt)
- assert str(tgt.sources[0]) == 'aaa.foo', str(tgt.sources[0])
- assert str(tgt.sources[0].sources[0]) == 'aaa.bar', \
- str(tgt.sources[0].sources[0])
+ s = str(tgt)
+ assert s == 'aaa', s
+ s = list(map(str, tgt.sources))
+ assert s == ['aaa.foo'], s
+ s = list(map(str, tgt.sources[0].sources))
+ assert s == ['aaa.bar'], s
- builder3 = SCons.Builder.MultiStepBuilder(action = 'foo',
- src_builder = 'xyzzy',
- src_suffix = '.xyzzy')
- assert builder3.get_src_builders(Environment()) == []
+ builder3 = SCons.Builder.Builder(action='bld3')
+ assert not builder3.src_builder is builder1.src_builder
builder4 = SCons.Builder.Builder(action='bld4',
src_suffix='.i',
suffix='_wrap.c')
- builder5 = SCons.Builder.MultiStepBuilder(action='bld5',
- src_builder=builder4,
- suffix='.obj',
- src_suffix='.c')
- builder6 = SCons.Builder.MultiStepBuilder(action='bld6',
- src_builder=builder5,
- suffix='.exe',
- src_suffix='.obj')
+ builder5 = SCons.Builder.Builder(action=MyAction('act'),
+ src_builder=builder4,
+ suffix='.obj',
+ src_suffix='.c')
+ builder6 = SCons.Builder.Builder(action=MyAction('act'),
+ src_builder=builder5,
+ suffix='.exe',
+ src_suffix='.obj')
tgt = builder6(env, 'test', 'test.i')[0]
- assert str(tgt) == 'test.exe', str(tgt)
- assert str(tgt.sources[0]) == 'test_wrap.obj', str(tgt.sources[0])
- assert str(tgt.sources[0].sources[0]) == 'test_wrap.c', \
- str(tgt.sources[0].sources[0])
- assert str(tgt.sources[0].sources[0].sources[0]) == 'test.i', \
- str(tgt.sources[0].sources[0].sources[0])
-
- def test_CompositeBuilder(self):
- """Testing CompositeBuilder class."""
- def func_action(target, source, env):
- return 0
-
- env = Environment(BAR_SUFFIX = '.BAR2', FOO_SUFFIX = '.FOO2')
- builder = SCons.Builder.Builder(action={ '.foo' : func_action,
- '.bar' : func_action,
- '$BAR_SUFFIX' : func_action,
- '$FOO_SUFFIX' : func_action })
-
- tgt = builder(env, source=[])
- assert tgt == [], tgt
-
- assert isinstance(builder, SCons.Builder.CompositeBuilder)
- assert isinstance(builder.action, SCons.Action.CommandGeneratorAction)
-
- tgt = builder(env, target='test1', source='test1.foo')[0]
- assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
- assert tgt.builder.action is builder.action
-
- tgt = builder(env, target='test2', source='test1.bar')[0]
- assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
- assert tgt.builder.action is builder.action
-
- flag = 0
- tgt = builder(env, target='test3', source=['test2.bar', 'test1.foo'])[0]
- try:
- tgt.build()
- except SCons.Errors.UserError, e:
- flag = 1
- assert flag, "UserError should be thrown when we build targets with files of different suffixes."
- match = str(e) == "While building `['test3']' from `test1.foo': Cannot build multiple sources with different extensions: .bar, .foo"
- assert match, e
-
- tgt = builder(env, target='test4', source=['test4.BAR2'])[0]
- assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
- try:
- tgt.build()
- flag = 1
- except SCons.Errors.UserError, e:
- print e
- flag = 0
- assert flag, "It should be possible to define actions in composite builders using variables."
- env['FOO_SUFFIX'] = '.BAR2'
- builder.add_action('$NEW_SUFFIX', func_action)
- flag = 0
- tgt = builder(env, target='test5', source=['test5.BAR2'])[0]
- try:
- tgt.build()
- except SCons.Errors.UserError:
- flag = 1
- assert flag, "UserError should be thrown when we build targets with ambigous suffixes."
- del env.d['FOO_SUFFIX']
- del env.d['BAR_SUFFIX']
-
- foo_bld = SCons.Builder.Builder(action = 'a-foo',
- src_suffix = '.ina',
- suffix = '.foo')
- assert isinstance(foo_bld, SCons.Builder.BuilderBase)
- builder = SCons.Builder.Builder(action = { '.foo' : 'foo',
- '.bar' : 'bar' },
- src_builder = foo_bld)
- assert isinstance(builder, SCons.Builder.CompositeBuilder)
- assert isinstance(builder.action, SCons.Action.CommandGeneratorAction)
-
- tgt = builder(env, target='t1', source='t1a.ina t1b.ina')[0]
- assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
-
- tgt = builder(env, target='t2', source='t2a.foo t2b.ina')[0]
- assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder), tgt.builder.__dict__
-
- bar_bld = SCons.Builder.Builder(action = 'a-bar',
- src_suffix = '.inb',
- suffix = '.bar')
- assert isinstance(bar_bld, SCons.Builder.BuilderBase)
- builder = SCons.Builder.Builder(action = { '.foo' : 'foo'},
- src_builder = [foo_bld, bar_bld])
- assert isinstance(builder, SCons.Builder.CompositeBuilder)
- assert isinstance(builder.action, SCons.Action.CommandGeneratorAction)
-
- builder.add_action('.bar', 'bar')
-
- tgt = builder(env, target='t3-foo', source='t3a.foo t3b.ina')[0]
- assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder)
-
- tgt = builder(env, target='t3-bar', source='t3a.bar t3b.inb')[0]
- assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder)
-
- flag = 0
- tgt = builder(env, target='t5', source=['test5a.foo', 'test5b.inb'])[0]
- try:
- tgt.build()
- except SCons.Errors.UserError, e:
- flag = 1
- assert flag, "UserError should be thrown when we build targets with files of different suffixes."
- match = str(e) == "While building `['t5']' from `test5b.bar': Cannot build multiple sources with different extensions: .foo, .bar"
- assert match, e
-
- flag = 0
- tgt = builder(env, target='t6', source=['test6a.bar', 'test6b.ina'])[0]
- try:
- tgt.build()
- except SCons.Errors.UserError, e:
- flag = 1
- assert flag, "UserError should be thrown when we build targets with files of different suffixes."
- match = str(e) == "While building `['t6']' from `test6b.foo': Cannot build multiple sources with different extensions: .bar, .foo"
- assert match, e
-
- flag = 0
- tgt = builder(env, target='t4', source=['test4a.ina', 'test4b.inb'])[0]
- try:
- tgt.build()
- except SCons.Errors.UserError, e:
- flag = 1
- assert flag, "UserError should be thrown when we build targets with files of different suffixes."
- match = str(e) == "While building `['t4']' from `test4b.bar': Cannot build multiple sources with different extensions: .foo, .bar"
- assert match, e
-
- flag = 0
- tgt = builder(env, target='t7', source=['test7'])[0]
- try:
- tgt.build()
- except SCons.Errors.UserError, e:
- flag = 1
- assert flag, "UserError should be thrown when we build targets with files of different suffixes."
- match = str(e) == "While building `['t7']': Cannot deduce file extension from source files: ['test7']"
- assert match, e
-
- flag = 0
- tgt = builder(env, target='t8', source=['test8.unknown'])[0]
- try:
- tgt.build()
- except SCons.Errors.UserError, e:
- flag = 1
- assert flag, "UserError should be thrown when we build targets with files of different suffixes."
- match = str(e) == "While building `['t8']': Don't know how to build a file with suffix `.unknown'."
- assert match, e
+ s = str(tgt)
+ assert s == 'test.exe', s
+ s = list(map(str, tgt.sources))
+ assert s == ['test_wrap.obj'], s
+ s = list(map(str, tgt.sources[0].sources))
+ assert s == ['test_wrap.c'], s
+ s = list(map(str, tgt.sources[0].sources[0].sources))
+ assert s == ['test.i'], s
def test_target_scanner(self):
"""Testing ability to set target and source scanners through a builder."""
def func(self):
pass
- scanner = SCons.Scanner.Scanner(func, name='fooscan')
+ scanner = SCons.Scanner.Base(func, name='fooscan')
b1 = SCons.Builder.Builder(action='bld', target_scanner=scanner)
b2 = SCons.Builder.Builder(action='bld', target_scanner=scanner)
assert tgt.builder.source_scanner is None, tgt.builder.source_scanner
assert tgt.get_source_scanner(bar_y) is None, tgt.get_source_scanner(bar_y)
assert not src.has_builder(), src.has_builder()
- assert src.get_source_scanner(bar_y) is None, src.get_source_scanner(bar_y)
+ s = src.get_source_scanner(bar_y)
+ assert isinstance(s, SCons.Util.Null), repr(s)
# An Environment that has suffix-specified SCANNERS should
# provide a source scanner to the target.
assert tgt.get_source_scanner(bar_y), tgt.get_source_scanner(bar_y)
assert str(tgt.get_source_scanner(bar_y)) == 'EnvTestScanner', tgt.get_source_scanner(bar_y)
assert not src.has_builder(), src.has_builder()
- assert src.get_source_scanner(bar_y) is None, src.get_source_scanner(bar_y)
+ s = src.get_source_scanner(bar_y)
+ assert isinstance(s, SCons.Util.Null), repr(s)
# Can't simply specify the scanner as a builder argument; it's
# global to all invocations of this builder.
assert tgt.get_source_scanner(bar_y), tgt.get_source_scanner(bar_y)
assert str(tgt.get_source_scanner(bar_y)) == 'EnvTestScanner', tgt.get_source_scanner(bar_y)
assert not src.has_builder(), src.has_builder()
- assert src.get_source_scanner(bar_y) is None, src.get_source_scanner(bar_y)
+ s = src.get_source_scanner(bar_y)
+ assert isinstance(s, SCons.Util.Null), s
# Now use a builder that actually has scanners and ensure that
# the target is set accordingly (using the specified scanner
assert tgt.get_source_scanner(bar_y) == scanner, tgt.get_source_scanner(bar_y)
assert str(tgt.get_source_scanner(bar_y)) == 'TestScanner', tgt.get_source_scanner(bar_y)
assert not src.has_builder(), src.has_builder()
- assert src.get_source_scanner(bar_y) is None, src.get_source_scanner(bar_y)
+ s = src.get_source_scanner(bar_y)
+ assert isinstance(s, SCons.Util.Null), s
forms of component specifications."""
builder = SCons.Builder.Builder()
-
env = Environment(BUILDERS={'Bld':builder})
+
r = builder.get_name(env)
assert r == 'Bld', r
r = builder.get_prefix(env)
assert r == '', r
r = builder.src_suffixes(env)
assert r == [], r
- r = builder.targets('foo')
- assert r == ['foo'], r
# src_suffix can be a single string or a list of strings
+ # src_suffixes() caches its return value, so we use a new
+ # Builder each time we do any of these tests
- builder.set_src_suffix('.foo')
- r = builder.get_src_suffix(env)
+ bld = SCons.Builder.Builder()
+ env = Environment(BUILDERS={'Bld':bld})
+
+ bld.set_src_suffix('.foo')
+ r = bld.get_src_suffix(env)
assert r == '.foo', r
- r = builder.src_suffixes(env)
+ r = bld.src_suffixes(env)
assert r == ['.foo'], r
- builder.set_src_suffix(['.foo', '.bar'])
- r = builder.get_src_suffix(env)
+ bld = SCons.Builder.Builder()
+ env = Environment(BUILDERS={'Bld':bld})
+
+ bld.set_src_suffix(['.foo', '.bar'])
+ r = bld.get_src_suffix(env)
assert r == '.foo', r
- r = builder.src_suffixes(env)
+ r = bld.src_suffixes(env)
assert r == ['.foo', '.bar'], r
- builder.set_src_suffix(['.bar', '.foo'])
- r = builder.get_src_suffix(env)
+ bld = SCons.Builder.Builder()
+ env = Environment(BUILDERS={'Bld':bld})
+
+ bld.set_src_suffix(['.bar', '.foo'])
+ r = bld.get_src_suffix(env)
assert r == '.bar', r
- r = builder.src_suffixes(env)
+ r = sorted(bld.src_suffixes(env))
assert r == ['.bar', '.foo'], r
# adjust_suffix normalizes the suffix, adding a `.' if needed
assert r == 'A_', r
r = builder.get_suffix(env)
assert r == '.B', r
- r = builder.get_prefix(env, ['X.C'])
+ r = builder.get_prefix(env, [MyNode('X.C')])
assert r == 'E_', r
- r = builder.get_suffix(env, ['X.C'])
+ r = builder.get_suffix(env, [MyNode('X.C')])
assert r == '.D', r
builder = SCons.Builder.Builder(prefix='A_', suffix={}, action={})
-
env = Environment(BUILDERS={'Bld':builder})
+
r = builder.get_name(env)
assert r == 'Bld', r
r = builder.get_prefix(env)
assert r == 'A_', r
r = builder.get_suffix(env)
- assert r == None, r
+ assert r is None, r
r = builder.get_src_suffix(env)
assert r == '', r
r = builder.src_suffixes(env)
# whose keys are the source suffix. The add_action()
# specifies a new source suffix/action binding.
+ builder = SCons.Builder.Builder(prefix='A_', suffix={}, action={})
+ env = Environment(BUILDERS={'Bld':builder})
builder.add_action('.src_sfx1', 'FOO')
+
r = builder.get_name(env)
assert r == 'Bld', r
r = builder.get_prefix(env)
assert r == 'A_', r
r = builder.get_suffix(env)
- assert r == None, r
- r = builder.get_suffix(env, ['X.src_sfx1'])
- assert r == None, r
+ assert r is None, r
+ r = builder.get_suffix(env, [MyNode('X.src_sfx1')])
+ assert r is None, r
r = builder.get_src_suffix(env)
assert r == '.src_sfx1', r
r = builder.src_suffixes(env)
assert r == ['.src_sfx1'], r
+ builder = SCons.Builder.Builder(prefix='A_', suffix={}, action={})
+ env = Environment(BUILDERS={'Bld':builder})
+ builder.add_action('.src_sfx1', 'FOO')
builder.add_action('.src_sfx2', 'BAR')
r = builder.get_name(env)
r = builder.get_prefix(env)
assert r == 'A_', r
r = builder.get_suffix(env)
- assert r == None, r
+ assert r is None, r
r = builder.get_src_suffix(env)
assert r == '.src_sfx1', r
- r = builder.src_suffixes(env)
+ r = sorted(builder.src_suffixes(env))
assert r == ['.src_sfx1', '.src_sfx2'], r
tgt = builder(env, target='foo3', source='bar', foo=1)
assert len(tgt) == 2, len(tgt)
- assert 'foo3' in map(str, tgt), map(str, tgt)
- assert 'bar1' in map(str, tgt), map(str, tgt)
+ assert 'foo3' in list(map(str, tgt)), list(map(str, tgt))
+ assert 'bar1' in list(map(str, tgt)), list(map(str, tgt))
tgt = builder(env, target='foo4', source='bar', bar=1)[0]
assert str(tgt) == 'foo4', str(tgt)
assert len(tgt.sources) == 2, len(tgt.sources)
- assert 'baz' in map(str, tgt.sources), map(str, tgt.sources)
- assert 'bar' in map(str, tgt.sources), map(str, tgt.sources)
+ assert 'baz' in list(map(str, tgt.sources)), list(map(str, tgt.sources))
+ assert 'bar' in list(map(str, tgt.sources)), list(map(str, tgt.sources))
env2=Environment(FOO=emit)
builder2=SCons.Builder.Builder(action='foo',
target_factory=MyNode,
source_factory=MyNode)
+ builder2a=SCons.Builder.Builder(action='foo',
+ emitter="$FOO",
+ target_factory=MyNode,
+ source_factory=MyNode)
+
+ assert builder2 == builder2a, repr(builder2.__dict__) + "\n" + repr(builder2a.__dict__)
+
tgt = builder2(env2, target='foo5', source='bar')[0]
assert str(tgt) == 'foo5', str(tgt)
assert str(tgt.sources[0]) == 'bar', str(tgt.sources[0])
tgt = builder2(env2, target='foo6', source='bar', foo=2)
assert len(tgt) == 2, len(tgt)
- assert 'foo6' in map(str, tgt), map(str, tgt)
- assert 'bar2' in map(str, tgt), map(str, tgt)
+ assert 'foo6' in list(map(str, tgt)), list(map(str, tgt))
+ assert 'bar2' in list(map(str, tgt)), list(map(str, tgt))
tgt = builder2(env2, target='foo7', source='bar', bar=1)[0]
assert str(tgt) == 'foo7', str(tgt)
assert len(tgt.sources) == 2, len(tgt.sources)
- assert 'baz' in map(str, tgt.sources), map(str, tgt.sources)
- assert 'bar' in map(str, tgt.sources), map(str, tgt.sources)
+ assert 'baz' in list(map(str, tgt.sources)), list(map(str, tgt.sources))
+ assert 'bar' in list(map(str, tgt.sources)), list(map(str, tgt.sources))
- builder2a=SCons.Builder.Builder(action='foo',
- emitter="$FOO",
- target_factory=MyNode,
- source_factory=MyNode)
- assert builder2 == builder2a, repr(builder2.__dict__) + "\n" + repr(builder2a.__dict__)
+ def test_emitter_preserve_builder(self):
+ """Test an emitter not overwriting a newly-set builder"""
+ env = Environment()
- # Test that, if an emitter sets a builder on the passed-in
- # targets and passes back new targets, the new builder doesn't
- # get overwritten.
new_builder = SCons.Builder.Builder(action='new')
node = MyNode('foo8')
new_node = MyNode('foo8.new')
- def emit3(target, source, env, nb=new_builder, nn=new_node):
+
+ def emit(target, source, env, nb=new_builder, nn=new_node):
for t in target:
t.builder = nb
return [nn], source
- builder3=SCons.Builder.Builder(action='foo',
- emitter=emit3,
- target_factory=MyNode,
- source_factory=MyNode)
- tgt = builder3(env, target=node, source='bar')[0]
+ builder=SCons.Builder.Builder(action='foo',
+ emitter=emit,
+ target_factory=MyNode,
+ source_factory=MyNode)
+ tgt = builder(env, target=node, source='bar')[0]
assert tgt is new_node, tgt
- assert tgt.builder is builder3, tgt.builder
+ assert tgt.builder is builder, tgt.builder
assert node.builder is new_builder, node.builder
- # Test use of a dictionary mapping file suffixes to
- # emitter functions
+ def test_emitter_suffix_map(self):
+ """Test mapping file suffixes to emitter functions"""
+ env = Environment()
+
def emit4a(target, source, env):
- source = map(str, source)
- target = map(lambda x: 'emit4a-' + x[:-3], source)
+ source = list(map(str, source))
+ target = ['emit4a-' + x[:-3] for x in source]
return (target, source)
def emit4b(target, source, env):
- source = map(str, source)
- target = map(lambda x: 'emit4b-' + x[:-3], source)
+ source = list(map(str, source))
+ target = ['emit4b-' + x[:-3] for x in source]
return (target, source)
- builder4 = SCons.Builder.Builder(action='foo',
- emitter={'.4a':emit4a,
- '.4b':emit4b},
- target_factory=MyNode,
- source_factory=MyNode)
- tgt = builder4(env, None, source='aaa.4a')[0]
+
+ builder = SCons.Builder.Builder(action='foo',
+ emitter={'.4a':emit4a,
+ '.4b':emit4b},
+ target_factory=MyNode,
+ source_factory=MyNode)
+ tgt = builder(env, None, source='aaa.4a')[0]
assert str(tgt) == 'emit4a-aaa', str(tgt)
- tgt = builder4(env, None, source='bbb.4b')[0]
+ tgt = builder(env, None, source='bbb.4b')[0]
assert str(tgt) == 'emit4b-bbb', str(tgt)
- tgt = builder4(env, None, source='ccc.4c')[0]
+ tgt = builder(env, None, source='ccc.4c')[0]
assert str(tgt) == 'ccc', str(tgt)
def emit4c(target, source, env):
- source = map(str, source)
- target = map(lambda x: 'emit4c-' + x[:-3], source)
+ source = list(map(str, source))
+ target = ['emit4c-' + x[:-3] for x in source]
return (target, source)
- builder4.add_emitter('.4c', emit4c)
- tgt = builder4(env, None, source='ccc.4c')[0]
+
+ builder.add_emitter('.4c', emit4c)
+ tgt = builder(env, None, source='ccc.4c')[0]
assert str(tgt) == 'emit4c-ccc', str(tgt)
- # Test a list of emitter functions.
- def emit5a(target, source, env):
- source = map(str, source)
- target = target + map(lambda x: 'emit5a-' + x[:-2], source)
+ def test_emitter_function_list(self):
+ """Test lists of emitter functions"""
+ env = Environment()
+
+ def emit1a(target, source, env):
+ source = list(map(str, source))
+ target = target + ['emit1a-' + x[:-2] for x in source]
return (target, source)
- def emit5b(target, source, env):
- source = map(str, source)
- target = target + map(lambda x: 'emit5b-' + x[:-2], source)
+ def emit1b(target, source, env):
+ source = list(map(str, source))
+ target = target + ['emit1b-' + x[:-2] for x in source]
return (target, source)
- builder5 = SCons.Builder.Builder(action='foo',
- emitter=[emit5a, emit5b],
+ builder1 = SCons.Builder.Builder(action='foo',
+ emitter=[emit1a, emit1b],
node_factory=MyNode)
- tgts = builder5(env, target='target-5', source='aaa.5')
- tgts = map(str, tgts)
- assert tgts == ['target-5', 'emit5a-aaa', 'emit5b-aaa'], tgts
+ tgts = builder1(env, target='target-1', source='aaa.1')
+ tgts = list(map(str, tgts))
+ assert tgts == ['target-1', 'emit1a-aaa', 'emit1b-aaa'], tgts
# Test a list of emitter functions through the environment.
- def emit6a(target, source, env):
- source = map(str, source)
- target = target + map(lambda x: 'emit6a-' + x[:-2], source)
+ def emit2a(target, source, env):
+ source = list(map(str, source))
+ target = target + ['emit2a-' + x[:-2] for x in source]
return (target, source)
- def emit6b(target, source, env):
- source = map(str, source)
- target = target + map(lambda x: 'emit6b-' + x[:-2], source)
+ def emit2b(target, source, env):
+ source = list(map(str, source))
+ target = target + ['emit2b-' + x[:-2] for x in source]
return (target, source)
- builder6 = SCons.Builder.Builder(action='foo',
+ builder2 = SCons.Builder.Builder(action='foo',
emitter='$EMITTERLIST',
node_factory=MyNode)
- env = Environment(EMITTERLIST = [emit6a, emit6b])
+ env = Environment(EMITTERLIST = [emit2a, emit2b])
+
+ tgts = builder2(env, target='target-2', source='aaa.2')
+ tgts = list(map(str, tgts))
+ assert tgts == ['target-2', 'emit2a-aaa', 'emit2b-aaa'], tgts
+
+ def test_emitter_TARGET_SOURCE(self):
+ """Test use of $TARGET and $SOURCE in emitter results"""
+
+ env = SCons.Environment.Environment()
+
+ def emit(target, source, env):
+ return (target + ['${SOURCE}.s1', '${TARGET}.t1'],
+ source + ['${TARGET}.t2', '${SOURCE}.s2'])
- tgts = builder6(env, target='target-6', source='aaa.6')
- tgts = map(str, tgts)
- assert tgts == ['target-6', 'emit6a-aaa', 'emit6b-aaa'], tgts
+ builder = SCons.Builder.Builder(action='foo',
+ emitter = emit,
+ node_factory = MyNode)
+
+ targets = builder(env, target = 'TTT', source ='SSS')
+ sources = targets[0].sources
+ targets = list(map(str, targets))
+ sources = list(map(str, sources))
+ assert targets == ['TTT', 'SSS.s1', 'TTT.t1'], targets
+ assert sources == ['SSS', 'TTT.t2', 'SSS.s2'], targets
def test_no_target(self):
"""Test deducing the target from the source."""
tgt = b(env, None, 'aaa')[0]
assert str(tgt) == 'aaa.o', str(tgt)
- assert len(tgt.sources) == 1, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'aaa', map(str, tgt.sources)
+ assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'aaa', list(map(str, tgt.sources))
tgt = b(env, None, 'bbb.c')[0]
assert str(tgt) == 'bbb.o', str(tgt)
- assert len(tgt.sources) == 1, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'bbb.c', map(str, tgt.sources)
+ assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'bbb.c', list(map(str, tgt.sources))
tgt = b(env, None, 'ccc.x.c')[0]
assert str(tgt) == 'ccc.x.o', str(tgt)
- assert len(tgt.sources) == 1, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'ccc.x.c', map(str, tgt.sources)
+ assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'ccc.x.c', list(map(str, tgt.sources))
tgt = b(env, None, ['d0.c', 'd1.c'])[0]
assert str(tgt) == 'd0.o', str(tgt)
- assert len(tgt.sources) == 2, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'd0.c', map(str, tgt.sources)
- assert str(tgt.sources[1]) == 'd1.c', map(str, tgt.sources)
+ assert len(tgt.sources) == 2, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'd0.c', list(map(str, tgt.sources))
+ assert str(tgt.sources[1]) == 'd1.c', list(map(str, tgt.sources))
tgt = b(env, target = None, source='eee')[0]
assert str(tgt) == 'eee.o', str(tgt)
- assert len(tgt.sources) == 1, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'eee', map(str, tgt.sources)
+ assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'eee', list(map(str, tgt.sources))
tgt = b(env, target = None, source='fff.c')[0]
assert str(tgt) == 'fff.o', str(tgt)
- assert len(tgt.sources) == 1, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'fff.c', map(str, tgt.sources)
+ assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'fff.c', list(map(str, tgt.sources))
tgt = b(env, target = None, source='ggg.x.c')[0]
assert str(tgt) == 'ggg.x.o', str(tgt)
- assert len(tgt.sources) == 1, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'ggg.x.c', map(str, tgt.sources)
+ assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'ggg.x.c', list(map(str, tgt.sources))
tgt = b(env, target = None, source=['h0.c', 'h1.c'])[0]
assert str(tgt) == 'h0.o', str(tgt)
- assert len(tgt.sources) == 2, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'h0.c', map(str, tgt.sources)
- assert str(tgt.sources[1]) == 'h1.c', map(str, tgt.sources)
+ assert len(tgt.sources) == 2, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'h0.c', list(map(str, tgt.sources))
+ assert str(tgt.sources[1]) == 'h1.c', list(map(str, tgt.sources))
w = b(env, target='i0.w', source=['i0.x'])[0]
y = b(env, target='i1.y', source=['i1.z'])[0]
tgt = b(env, None, source=[w, y])[0]
assert str(tgt) == 'i0.o', str(tgt)
- assert len(tgt.sources) == 2, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'i0.w', map(str, tgt.sources)
- assert str(tgt.sources[1]) == 'i1.y', map(str, tgt.sources)
+ assert len(tgt.sources) == 2, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'i0.w', list(map(str, tgt.sources))
+ assert str(tgt.sources[1]) == 'i1.y', list(map(str, tgt.sources))
def test_get_name(self):
"""Test getting name of builder.
b1 = SCons.Builder.Builder(action='foo', suffix='.o')
b2 = SCons.Builder.Builder(action='foo', suffix='.c')
- b3 = SCons.Builder.MultiStepBuilder(action='bar',
- src_suffix = '.foo',
- src_builder = b1)
+ b3 = SCons.Builder.Builder(action='bar', src_suffix = '.foo',
+ src_builder = b1)
b4 = SCons.Builder.Builder(action={})
b5 = SCons.Builder.Builder(action='foo', name='builder5')
b6 = SCons.Builder.Builder(action='foo')
'B2': b2,
'B3': b3,
'B4': b4})
- assert b1.get_name(env) == 'bldr1', b1.get_name(env)
- assert b2.get_name(env) == 'bldr2', b2.get_name(env)
- assert b3.get_name(env) == 'bldr3', b3.get_name(env)
- assert b4.get_name(env) == 'bldr4', b4.get_name(env)
- assert b5.get_name(env) == 'builder5', b5.get_name(env)
# With no name, get_name will return the class. Allow
# for caching...
- assert b6.get_name(env) in [
+ b6_names = [
'SCons.Builder.BuilderBase',
"<class 'SCons.Builder.BuilderBase'>",
'SCons.Memoize.BuilderBase',
"<class 'SCons.Memoize.BuilderBase'>",
- ], b6.get_name(env)
+ ]
+
+ assert b1.get_name(env) == 'bldr1', b1.get_name(env)
+ assert b2.get_name(env) == 'bldr2', b2.get_name(env)
+ assert b3.get_name(env) == 'bldr3', b3.get_name(env)
+ assert b4.get_name(env) == 'bldr4', b4.get_name(env)
+ assert b5.get_name(env) == 'builder5', b5.get_name(env)
+ assert b6.get_name(env) in b6_names, b6.get_name(env)
+
assert b1.get_name(env2) == 'B1', b1.get_name(env2)
assert b2.get_name(env2) == 'B2', b2.get_name(env2)
assert b3.get_name(env2) == 'B3', b3.get_name(env2)
assert b4.get_name(env2) == 'B4', b4.get_name(env2)
assert b5.get_name(env2) == 'builder5', b5.get_name(env2)
- assert b6.get_name(env2) in [
- 'SCons.Builder.BuilderBase',
- "<class 'SCons.Builder.BuilderBase'>",
- 'SCons.Memoize.BuilderBase',
- "<class 'SCons.Memoize.BuilderBase'>",
- ], b6.get_name(env2)
+ assert b6.get_name(env2) in b6_names, b6.get_name(env2)
- for B in b3.get_src_builders(env):
- assert B.get_name(env) == 'bldr1'
- for B in b3.get_src_builders(env2):
- assert B.get_name(env2) == 'B1'
+ assert b5.get_name(None) == 'builder5', b5.get_name(None)
+ assert b6.get_name(None) in b6_names, b6.get_name(None)
- tgts = b1(env, target = [outfile, outfile2], source='moo')
- for t in tgts:
- assert t.builder.get_name(env) == 'ListBuilder(bldr1)'
- # The following are not symbolically correct, because the
- # ListBuilder was only created on behalf of env, so it
- # would probably be OK if better correctness
- # env-to-builder mappings caused this to fail in the
- # future.
- assert t.builder.get_name(env2) == 'ListBuilder(B1)'
+ # This test worked before adding batch builders, but we must now
+ # be able to disambiguate a CompositeAction into a more specific
+ # action based on file suffix at call time. Leave this commented
+ # out (for now) in case this reflects a real-world use case that
+ # we must accomodate and we want to resurrect this test.
+ #tgt = b4(env, target = 'moo', source='cow')
+ #assert tgt[0].builder.get_name(env) == 'bldr4'
+
+class CompositeBuilderTestCase(unittest.TestCase):
- tgt = b4(env, target = 'moo', source='cow')
- assert tgt[0].builder.get_name(env) == 'bldr4'
+ def setUp(self):
+ def func_action(target, source, env):
+ return 0
+
+ builder = SCons.Builder.Builder(action={ '.foo' : func_action,
+ '.bar' : func_action})
+
+ self.func_action = func_action
+ self.builder = builder
+
+ def test___init__(self):
+ """Test CompositeBuilder creation"""
+ env = Environment()
+ builder = SCons.Builder.Builder(action={})
+
+ tgt = builder(env, source=[])
+ assert tgt == [], tgt
+
+ assert isinstance(builder, SCons.Builder.CompositeBuilder)
+ assert isinstance(builder.action, SCons.Action.CommandGeneratorAction)
+
+ def test_target_action(self):
+ """Test CompositeBuilder setting of target builder actions"""
+ env = Environment()
+ builder = self.builder
+
+ tgt = builder(env, target='test1', source='test1.foo')[0]
+ assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
+ assert tgt.builder.action is builder.action
+
+ tgt = builder(env, target='test2', source='test1.bar')[0]
+ assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
+ assert tgt.builder.action is builder.action
+
+ def test_multiple_suffix_error(self):
+ """Test the CompositeBuilder multiple-source-suffix error"""
+ env = Environment()
+ builder = self.builder
+
+ flag = 0
+ try:
+ builder(env, target='test3', source=['test2.bar', 'test1.foo'])[0]
+ except SCons.Errors.UserError, e:
+ flag = 1
+ assert flag, "UserError should be thrown when we call a builder with files of different suffixes."
+ expect = "While building `['test3']' from `test1.foo': Cannot build multiple sources with different extensions: .bar, .foo"
+ assert str(e) == expect, e
+
+ def test_source_ext_match(self):
+ """Test the CompositeBuilder source_ext_match argument"""
+ env = Environment()
+ func_action = self.func_action
+ builder = SCons.Builder.Builder(action={ '.foo' : func_action,
+ '.bar' : func_action},
+ source_ext_match = None)
+
+ tgt = builder(env, target='test3', source=['test2.bar', 'test1.foo'])[0]
+ tgt.build()
+
+ def test_suffix_variable(self):
+ """Test CompositeBuilder defining action suffixes through a variable"""
+ env = Environment(BAR_SUFFIX = '.BAR2', FOO_SUFFIX = '.FOO2')
+ func_action = self.func_action
+ builder = SCons.Builder.Builder(action={ '.foo' : func_action,
+ '.bar' : func_action,
+ '$BAR_SUFFIX' : func_action,
+ '$FOO_SUFFIX' : func_action })
+
+ tgt = builder(env, target='test4', source=['test4.BAR2'])[0]
+ assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
+ try:
+ tgt.build()
+ flag = 1
+ except SCons.Errors.UserError, e:
+ print e
+ flag = 0
+ assert flag, "It should be possible to define actions in composite builders using variables."
+ env['FOO_SUFFIX'] = '.BAR2'
+ builder.add_action('$NEW_SUFFIX', func_action)
+ flag = 0
+ try:
+ builder(env, target='test5', source=['test5.BAR2'])[0]
+ except SCons.Errors.UserError:
+ flag = 1
+ assert flag, "UserError should be thrown when we call a builder with ambigous suffixes."
+
+ def test_src_builder(self):
+ """Test CompositeBuilder's use of a src_builder"""
+ env = Environment()
+
+ foo_bld = SCons.Builder.Builder(action = 'a-foo',
+ src_suffix = '.ina',
+ suffix = '.foo')
+ assert isinstance(foo_bld, SCons.Builder.BuilderBase)
+ builder = SCons.Builder.Builder(action = { '.foo' : 'foo',
+ '.bar' : 'bar' },
+ src_builder = foo_bld)
+ assert isinstance(builder, SCons.Builder.CompositeBuilder)
+ assert isinstance(builder.action, SCons.Action.CommandGeneratorAction)
+
+ tgt = builder(env, target='t1', source='t1a.ina t1b.ina')[0]
+ assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
+
+ tgt = builder(env, target='t2', source='t2a.foo t2b.ina')[0]
+ assert isinstance(tgt.builder, SCons.Builder.BuilderBase), tgt.builder.__dict__
+
+ bar_bld = SCons.Builder.Builder(action = 'a-bar',
+ src_suffix = '.inb',
+ suffix = '.bar')
+ assert isinstance(bar_bld, SCons.Builder.BuilderBase)
+ builder = SCons.Builder.Builder(action = { '.foo' : 'foo'},
+ src_builder = [foo_bld, bar_bld])
+ assert isinstance(builder, SCons.Builder.CompositeBuilder)
+ assert isinstance(builder.action, SCons.Action.CommandGeneratorAction)
+
+ builder.add_action('.bar', 'bar')
+
+ tgt = builder(env, target='t3-foo', source='t3a.foo t3b.ina')[0]
+ assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
+
+ tgt = builder(env, target='t3-bar', source='t3a.bar t3b.inb')[0]
+ assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
+
+ flag = 0
+ try:
+ builder(env, target='t5', source=['test5a.foo', 'test5b.inb'])[0]
+ except SCons.Errors.UserError, e:
+ flag = 1
+ assert flag, "UserError should be thrown when we call a builder with files of different suffixes."
+ expect = "While building `['t5']' from `test5b.bar': Cannot build multiple sources with different extensions: .foo, .bar"
+ assert str(e) == expect, e
+
+ flag = 0
+ try:
+ builder(env, target='t6', source=['test6a.bar', 'test6b.ina'])[0]
+ except SCons.Errors.UserError, e:
+ flag = 1
+ assert flag, "UserError should be thrown when we call a builder with files of different suffixes."
+ expect = "While building `['t6']' from `test6b.foo': Cannot build multiple sources with different extensions: .bar, .foo"
+ assert str(e) == expect, e
+
+ flag = 0
+ try:
+ builder(env, target='t4', source=['test4a.ina', 'test4b.inb'])[0]
+ except SCons.Errors.UserError, e:
+ flag = 1
+ assert flag, "UserError should be thrown when we call a builder with files of different suffixes."
+ expect = "While building `['t4']' from `test4b.bar': Cannot build multiple sources with different extensions: .foo, .bar"
+ assert str(e) == expect, e
+
+ flag = 0
+ try:
+ builder(env, target='t7', source=[env.fs.File('test7')])[0]
+ except SCons.Errors.UserError, e:
+ flag = 1
+ assert flag, "UserError should be thrown when we call a builder with files of different suffixes."
+ expect = "While building `['t7']': Cannot deduce file extension from source files: ['test7']"
+ assert str(e) == expect, e
+
+ flag = 0
+ try:
+ builder(env, target='t8', source=['test8.unknown'])[0]
+ except SCons.Errors.UserError, e:
+ flag = 1
+ assert flag, "UserError should be thrown when we call a builder target with an unknown suffix."
+ expect = "While building `['t8']' from `['test8.unknown']': Don't know how to build from a source file with suffix `.unknown'. Expected a suffix in this list: ['.foo', '.bar']."
+ assert str(e) == expect, e
if __name__ == "__main__":
- suite = unittest.makeSuite(BuilderTestCase, 'test_')
+ suite = unittest.TestSuite()
+ tclasses = [
+ BuilderTestCase,
+ CompositeBuilderTestCase
+ ]
+ for tclass in tclasses:
+ names = unittest.getTestCaseNames(tclass, 'test_')
+ 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: