2 # Copyright (c) 2001, 2002 Steven Knight
4 # Permission is hereby granted, free of charge, to any person obtaining
5 # a copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including
7 # without limitation the rights to use, copy, modify, merge, publish,
8 # distribute, sublicense, and/or sell copies of the Software, and to
9 # permit persons to whom the Software is furnished to do so, subject to
10 # the following conditions:
12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
16 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
17 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
26 # Define a null function for use as a builder action.
27 # Where this is defined in the file seems to affect its
28 # byte-code contents, so try to minimize changes by
29 # defining it here, before we even import anything.
45 import SCons.Environment
47 # Initial setup of the common environment for all tests,
48 # a temporary working directory containing a
49 # script for writing arguments to an output file.
51 # We don't do this as a setUp() method because it's
52 # unnecessary to create a separate directory and script
53 # for each test, they can just use the one.
54 test = TestCmd.TestCmd(workdir = '')
56 outfile = test.workpath('outfile')
57 outfile2 = test.workpath('outfile2')
62 scons_env = SCons.Environment.Environment()
65 def __init__(self, **kw):
67 self.d['SHELL'] = scons_env['SHELL']
68 self.d['SPAWN'] = scons_env['SPAWN']
69 self.d['ESCAPE'] = scons_env['ESCAPE']
70 for k, v in kw.items():
73 if not SCons.Util.is_String(s):
77 return self.d.get(s[1:], '')
80 return self.d.get(s, s)
81 def get_scanner(self, ext):
85 def autogenerate(self, dir=''):
87 def __getitem__(self, item):
89 def has_key(self, item):
90 return self.d.has_key(item)
93 def get(self, key, value):
94 return self.d.get(key, value)
95 def Override(self, overrides):
96 env = apply(Environment, (), self.d)
97 env.d.update(overrides)
100 return self.d.items()
104 class BuilderTestCase(unittest.TestCase):
106 def test__call__(self):
107 """Test calling a builder to establish source dependencies
110 def __init__(self, name):
117 def builder_set(self, builder):
118 self.builder = builder
119 def has_builder(self):
120 return not self.builder is None
121 def env_set(self, env, safe=0):
123 def add_source(self, source):
124 self.sources.extend(source)
125 def scanner_key(self):
127 builder = SCons.Builder.Builder(name="builder", action="foo", node_factory=Node)
131 builder(env, target = n1, source = n2)
133 assert n1.builder == builder
134 assert n1.sources == [n2]
135 assert not hasattr(n2, 'env')
137 target = builder(env, target = 'n3', source = 'n4')
138 assert target.name == 'n3'
139 assert target.sources[0].name == 'n4'
141 target = builder(env, target = 'n4 n5', source = ['n6 n7'])
142 assert target.name == 'n4 n5'
143 assert target.sources[0].name == 'n6 n7'
145 target = builder(env, target = ['n8 n9'], source = 'n10 n11')
146 assert target.name == 'n8 n9'
147 assert target.sources[0].name == 'n10 n11'
149 if not hasattr(types, 'UnicodeType'):
154 target = builder(env, target = uni('n12 n13'),
155 source = [uni('n14 n15')])
156 assert target.name == uni('n12 n13')
157 assert target.sources[0].name == uni('n14 n15')
159 target = builder(env, target = [uni('n16 n17')],
160 source = uni('n18 n19'))
161 assert target.name == uni('n16 n17')
162 assert target.sources[0].name == uni('n18 n19')
164 def test_noname(self):
165 """Test deprecated warning for Builder name.
167 Using the name argument for Builder() is deprectaed and the
168 user should receive a warning.
170 SCons.Warnings.enableWarningClass(SCons.Warnings.DeprecatedWarning)
171 SCons.Warnings.warningAsException(1)
175 b = SCons.Builder.Builder(name='foo')
176 except SCons.Warnings.DeprecatedWarning:
181 SCons.Warnings.suppressWarningClass(SCons.Warnings.DeprecatedWarning)
182 SCons.Warnings.warningAsException(0)
184 def test_action(self):
185 """Test Builder creation
187 Verify that we can retrieve the supplied action attribute.
189 builder = SCons.Builder.Builder(name="builder", action="foo")
190 assert builder.action.cmd_list == ["foo"]
194 builder = SCons.Builder.Builder(name="builder", action=func)
195 assert isinstance(builder.action, SCons.Action.FunctionAction)
196 # Preserve the following so that the baseline test will fail.
197 # Remove it in favor of the previous test at some convenient
198 # point in the future.
199 assert builder.action.execfunction == func
201 def test_generator(self):
202 """Test Builder creation given a generator function."""
207 builder = SCons.Builder.Builder(name="builder", generator=generator)
208 assert builder.action.generator == generator
211 """Test simple comparisons of Builder objects
213 b1 = SCons.Builder.Builder(name="b1", src_suffix = '.o')
214 b2 = SCons.Builder.Builder(name="b1", src_suffix = '.o')
216 b3 = SCons.Builder.Builder(name="b3", src_suffix = '.x')
220 def test_get_actions(self):
221 """Test fetching the Builder's Action list
225 builder = SCons.Builder.Builder(name="builder",
226 action=SCons.Action.ListAction(["x",
229 a = builder.get_actions()
230 assert len(a) == 3, a
231 assert isinstance(a[0], SCons.Action.CommandAction), a[0]
232 assert isinstance(a[1], SCons.Action.FunctionAction), a[1]
233 assert isinstance(a[2], SCons.Action.CommandAction), a[2]
235 def test_get_contents(self):
236 """Test returning the signature contents of a Builder
239 b1 = SCons.Builder.Builder(name = "b1", action = "foo")
240 contents = b1.get_contents([],[],Environment())
241 assert contents == "foo", contents
243 b2 = SCons.Builder.Builder(name = "b2", action = Func)
244 contents = b2.get_contents([],[],Environment())
245 assert contents == "\177\036\000\177\037\000d\000\000S", repr(contents)
247 b3 = SCons.Builder.Builder(name = "b3", action = SCons.Action.ListAction(["foo", Func, "bar"]))
248 contents = b3.get_contents([],[],Environment())
249 assert contents == "foo\177\036\000\177\037\000d\000\000Sbar", repr(contents)
251 def test_node_factory(self):
252 """Test a Builder that creates nodes of a specified class
256 def FooFactory(target):
259 builder = SCons.Builder.Builder(name = "builder", node_factory = FooFactory)
260 assert builder.target_factory is FooFactory
261 assert builder.source_factory is FooFactory
263 def test_target_factory(self):
264 """Test a Builder that creates target nodes of a specified class
268 def FooFactory(target):
271 builder = SCons.Builder.Builder(name = "builder", target_factory = FooFactory)
272 assert builder.target_factory is FooFactory
273 assert not builder.source_factory is FooFactory
275 def test_source_factory(self):
276 """Test a Builder that creates source nodes of a specified class
280 def FooFactory(source):
283 builder = SCons.Builder.Builder(name = "builder", source_factory = FooFactory)
284 assert not builder.target_factory is FooFactory
285 assert builder.source_factory is FooFactory
287 def test_prefix(self):
288 """Test Builder creation with a specified target prefix
290 Make sure that there is no '.' separator appended.
292 builder = SCons.Builder.Builder(name = "builder", prefix = 'lib.')
293 assert builder.get_prefix(env) == 'lib.'
294 builder = SCons.Builder.Builder(name = "builder", prefix = 'lib')
295 assert builder.get_prefix(env) == 'lib'
296 tgt = builder(env, target = 'tgt1', source = 'src1')
297 assert tgt.path == 'libtgt1', \
298 "Target has unexpected name: %s" % tgt.path
299 tgt = builder(env, target = 'tgt2a tgt2b', source = 'src2')
300 assert tgt.path == 'libtgt2a tgt2b', \
301 "Target has unexpected name: %s" % tgt.path
303 def test_src_suffix(self):
304 """Test Builder creation with a specified source file suffix
306 Make sure that the '.' separator is appended to the
307 beginning if it isn't already present.
309 env = Environment(XSUFFIX = '.x', YSUFFIX = '.y')
311 b1 = SCons.Builder.Builder(name = "builder", src_suffix = '.c')
312 assert b1.src_suffixes(env) == ['.c'], b1.src_suffixes(env)
314 tgt = b1(env, target = 'tgt2', source = 'src2')
315 assert tgt.sources[0].path == 'src2.c', \
316 "Source has unexpected name: %s" % tgt.sources[0].path
318 tgt = b1(env, target = 'tgt3', source = 'src3a src3b')
319 assert len(tgt.sources) == 1
320 assert tgt.sources[0].path == 'src3a src3b.c', \
321 "Unexpected tgt.sources[0] name: %s" % tgt.sources[0].path
323 b2 = SCons.Builder.Builder(name = "b2",
326 assert b2.src_suffixes(env) == ['.2', '.c'], b2.src_suffixes(env)
328 b3 = SCons.Builder.Builder(name = "b3",
329 action = {'.3a' : '', '.3b' : ''})
330 s = b3.src_suffixes(env)
332 assert s == ['.3a', '.3b'], s
334 b4 = SCons.Builder.Builder(name = "b4", src_suffix = '$XSUFFIX')
335 assert b4.src_suffixes(env) == ['.x'], b4.src_suffixes(env)
337 b5 = SCons.Builder.Builder(name = "b5", action = { '.y' : ''})
338 assert b5.src_suffixes(env) == ['.y'], b5.src_suffixes(env)
340 def test_suffix(self):
341 """Test Builder creation with a specified target suffix
343 Make sure that the '.' separator is appended to the
344 beginning if it isn't already present.
346 builder = SCons.Builder.Builder(name = "builder", suffix = '.o')
347 assert builder.get_suffix(env) == '.o', builder.get_suffix(env)
348 builder = SCons.Builder.Builder(name = "builder", suffix = 'o')
349 assert builder.get_suffix(env) == '.o', builder.get_suffix(env)
350 tgt = builder(env, target = 'tgt3', source = 'src3')
351 assert tgt.path == 'tgt3.o', \
352 "Target has unexpected name: %s" % tgt.path
353 tgt = builder(env, target = 'tgt4a tgt4b', source = 'src4')
354 assert tgt.path == 'tgt4a tgt4b.o', \
355 "Target has unexpected name: %s" % tgt.path
357 def test_ListBuilder(self):
358 """Testing ListBuilder class."""
359 def function2(target, source, env, tlist = [outfile, outfile2], **kw):
361 open(str(t), 'w').write("function2\n")
363 if not t in map(str, target):
364 open(t, 'w').write("function2\n")
367 builder = SCons.Builder.Builder(action = function2, name = "function2")
368 tgts = builder(env, target = [outfile, outfile2], source = 'foo')
373 except SCons.Errors.BuildError:
375 c = test.read(outfile, 'r')
376 assert c == "function2\n", c
377 c = test.read(outfile2, 'r')
378 assert c == "function2\n", c
380 sub1_out = test.workpath('sub1', 'out')
381 sub2_out = test.workpath('sub2', 'out')
383 def function3(target, source, env, tlist = [sub1_out, sub2_out]):
385 open(str(t), 'w').write("function3\n")
387 if not t in map(str, target):
388 open(t, 'w').write("function3\n")
391 builder = SCons.Builder.Builder(action = function3, name = "function3")
392 tgts = builder(env, target = [sub1_out, sub2_out], source = 'foo')
397 except SCons.Errors.BuildError:
399 c = test.read(sub1_out, 'r')
400 assert c == "function3\n", c
401 c = test.read(sub2_out, 'r')
402 assert c == "function3\n", c
403 assert os.path.exists(test.workpath('sub1'))
404 assert os.path.exists(test.workpath('sub2'))
406 def test_MultiStepBuilder(self):
407 """Testing MultiStepBuilder class."""
408 builder1 = SCons.Builder.Builder(name = "builder1",
412 builder2 = SCons.Builder.MultiStepBuilder(name = "builder2",
414 src_builder = builder1,
416 tgt = builder2(env, target='baz', source=['test.bar', 'test2.foo', 'test3.txt'])
417 assert str(tgt.sources[0]) == 'test.foo', str(tgt.sources[0])
418 assert str(tgt.sources[0].sources[0]) == 'test.bar', \
419 str(tgt.sources[0].sources[0])
420 assert str(tgt.sources[1]) == 'test2.foo', str(tgt.sources[1])
421 assert str(tgt.sources[2]) == 'test3.txt', str(tgt.sources[2])
423 tgt = builder2(env, 'aaa.bar')
424 assert str(tgt) == 'aaa', str(tgt)
425 assert str(tgt.sources[0]) == 'aaa.foo', str(tgt.sources[0])
426 assert str(tgt.sources[0].sources[0]) == 'aaa.bar', \
427 str(tgt.sources[0].sources[0])
429 builder3 = SCons.Builder.MultiStepBuilder(name = "builder3",
431 src_builder = 'xyzzy',
432 src_suffix = '.xyzzy')
433 assert builder3.get_src_builders(Environment()) == []
435 def test_CompositeBuilder(self):
436 """Testing CompositeBuilder class."""
437 def func_action(target, source, env):
440 builder = SCons.Builder.Builder(name = "builder",
441 action={ '.foo' : func_action,
442 '.bar' : func_action })
444 assert isinstance(builder, SCons.Builder.CompositeBuilder)
445 assert isinstance(builder.action, SCons.Action.CommandGeneratorAction)
446 tgt = builder(env, target='test1', source='test1.foo')
447 assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
448 assert tgt.builder.action is builder.action
449 tgt = builder(env, target='test2', source='test1.bar')
450 assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
451 assert tgt.builder.action is builder.action
453 tgt = builder(env, target='test3', source=['test2.bar', 'test1.foo'])
456 except SCons.Errors.UserError:
458 assert flag, "UserError should be thrown when we build targets with files of different suffixes."
460 foo_bld = SCons.Builder.Builder(name = "foo_bld",
464 assert isinstance(foo_bld, SCons.Builder.BuilderBase)
465 builder = SCons.Builder.Builder(name = "builder",
466 action = { '.foo' : 'foo',
468 src_builder = foo_bld)
469 assert isinstance(builder, SCons.Builder.CompositeBuilder)
470 assert isinstance(builder.action, SCons.Action.CommandGeneratorAction)
472 tgt = builder(env, target='t1', source='t1a.ina t1b.ina')
473 assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
475 tgt = builder(env, target='t2', source='t2a.foo t2b.ina')
476 assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder), tgt.builder.__dict__
478 bar_bld = SCons.Builder.Builder(name = "bar_bld",
482 assert isinstance(bar_bld, SCons.Builder.BuilderBase)
483 builder = SCons.Builder.Builder(name = "builder",
484 action = { '.foo' : 'foo'},
485 src_builder = [foo_bld, bar_bld])
486 assert isinstance(builder, SCons.Builder.CompositeBuilder)
487 assert isinstance(builder.action, SCons.Action.CommandGeneratorAction)
489 builder.add_action('.bar', 'bar')
491 tgt = builder(env, target='t3-foo', source='t3a.foo t3b.ina')
492 assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder)
494 tgt = builder(env, target='t3-bar', source='t3a.bar t3b.inb')
495 assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder)
498 tgt = builder(env, target='t5', source='test5a.foo test5b.inb')
501 except SCons.Errors.UserError:
503 assert flag, "UserError should be thrown when we build targets with files of different suffixes."
506 tgt = builder(env, target='t6', source='test6a.bar test6b.ina')
509 except SCons.Errors.UserError:
511 assert flag, "UserError should be thrown when we build targets with files of different suffixes."
514 tgt = builder(env, target='t4', source='test4a.ina test4b.inb')
517 except SCons.Errors.UserError:
519 assert flag, "UserError should be thrown when we build targets with files of different suffixes."
521 def test_build_scanner(self):
522 """Testing ability to set a target scanner through a builder."""
527 builder = SCons.Builder.Builder(name = "builder", scanner=scn)
528 tgt = builder(env, target='foo2', source='bar')
529 assert tgt.target_scanner == scn, tgt.target_scanner
531 builder1 = SCons.Builder.Builder(name = "builder1",
535 builder2 = SCons.Builder.Builder(name = "builder2",
537 src_builder = builder1,
539 tgt = builder2(env, target='baz2', source='test.bar test2.foo test3.txt')
540 assert tgt.target_scanner == scn, tgt.target_scanner
542 def test_src_scanner(slf):
543 """Testing ability to set a source file scanner through a builder."""
547 return 'TestScannerkey'
548 def instance(self, env):
550 env_scanner = TestScanner()
551 builder = SCons.Builder.Builder(name = "builder", action='action')
552 tgt = builder(env, target='foo.x', source='bar')
554 assert tgt.target_scanner != env_scanner, tgt.target_scanner
555 assert src.source_scanner == env_scanner
557 def test_Builder_Args(self):
558 """Testing passing extra args to a builder."""
559 def buildFunc(target, source, env, s=self):
562 assert env['CC'] == 'mycc'
564 env=Environment(CC='cc')
566 builder = SCons.Builder.Builder(name="builder", action=buildFunc)
567 tgt = builder(env, target='foo', source='bar', foo=1, bar=2, CC='mycc')
569 assert self.foo == 1, self.foo
570 assert self.bar == 2, self.bar
572 def test_emitter(self):
573 """Test emitter functions."""
574 def emit(target, source, env):
575 foo = env.get('foo', 0)
576 bar = env.get('bar', 0)
578 target.append("bar%d"%foo)
581 return ( target, source )
583 builder = SCons.Builder.Builder(name="builder", action='foo',
585 tgt = builder(env, target='foo2', source='bar')
586 assert str(tgt) == 'foo2', str(tgt)
587 assert str(tgt.sources[0]) == 'bar', str(tgt.sources[0])
589 tgt = builder(env, target='foo3', source='bar', foo=1)
590 assert len(tgt) == 2, len(tgt)
591 assert 'foo3' in map(str, tgt), map(str, tgt)
592 assert 'bar1' in map(str, tgt), map(str, tgt)
594 tgt = builder(env, target='foo4', source='bar', bar=1)
595 assert str(tgt) == 'foo4', str(tgt)
596 assert len(tgt.sources) == 2, len(tgt.sources)
597 assert 'baz' in map(str, tgt.sources), map(str, tgt.sources)
598 assert 'bar' in map(str, tgt.sources), map(str, tgt.sources)
600 env2=Environment(FOO=emit)
601 builder2=SCons.Builder.Builder(name="builder2", action='foo',
604 tgt = builder2(env2, target='foo5', source='bar')
605 assert str(tgt) == 'foo5', str(tgt)
606 assert str(tgt.sources[0]) == 'bar', str(tgt.sources[0])
608 tgt = builder2(env2, target='foo6', source='bar', foo=2)
609 assert len(tgt) == 2, len(tgt)
610 assert 'foo6' in map(str, tgt), map(str, tgt)
611 assert 'bar2' in map(str, tgt), map(str, tgt)
613 tgt = builder2(env2, target='foo7', source='bar', bar=1)
614 assert str(tgt) == 'foo7', str(tgt)
615 assert len(tgt.sources) == 2, len(tgt.sources)
616 assert 'baz' in map(str, tgt.sources), map(str, tgt.sources)
617 assert 'bar' in map(str, tgt.sources), map(str, tgt.sources)
619 builder2a=SCons.Builder.Builder(name="builder2", action='foo',
621 assert builder2 == builder2a, repr(builder2.__dict__) + "\n" + repr(builder2a.__dict__)
623 def test_no_target(self):
624 """Test deducing the target from the source."""
626 b = SCons.Builder.Builder(action='foo', suffix='.o')
629 assert str(tgt) == 'aaa.o', str(tgt)
630 assert len(tgt.sources) == 1, map(str, tgt.sources)
631 assert str(tgt.sources[0]) == 'aaa', map(str, tgt.sources)
633 tgt = b(env, 'bbb.c')
634 assert str(tgt) == 'bbb.o', str(tgt)
635 assert len(tgt.sources) == 1, map(str, tgt.sources)
636 assert str(tgt.sources[0]) == 'bbb.c', map(str, tgt.sources)
638 tgt = b(env, 'ccc.x.c')
639 assert str(tgt) == 'ccc.x.o', str(tgt)
640 assert len(tgt.sources) == 1, map(str, tgt.sources)
641 assert str(tgt.sources[0]) == 'ccc.x.c', map(str, tgt.sources)
643 tgt = b(env, ['d0.c', 'd1.c'])
644 assert len(tgt) == 2, map(str, tgt)
645 assert str(tgt[0]) == 'd0.o', map(str, tgt)
646 assert str(tgt[1]) == 'd1.o', map(str, tgt)
647 assert len(tgt[0].sources) == 2, map(str, tgt[0].sources)
648 assert str(tgt[0].sources[0]) == 'd0.c', map(str, tgt[0].sources)
649 assert str(tgt[0].sources[1]) == 'd1.c', map(str, tgt[0].sources)
650 assert len(tgt[1].sources) == 2, map(str, tgt[1].sources)
651 assert str(tgt[1].sources[0]) == 'd0.c', map(str, tgt[1].sources)
652 assert str(tgt[1].sources[1]) == 'd1.c', map(str, tgt[1].sources)
654 tgt = b(env, source='eee')
655 assert str(tgt) == 'eee.o', str(tgt)
656 assert len(tgt.sources) == 1, map(str, tgt.sources)
657 assert str(tgt.sources[0]) == 'eee', map(str, tgt.sources)
659 tgt = b(env, source='fff.c')
660 assert str(tgt) == 'fff.o', str(tgt)
661 assert len(tgt.sources) == 1, map(str, tgt.sources)
662 assert str(tgt.sources[0]) == 'fff.c', map(str, tgt.sources)
664 tgt = b(env, source='ggg.x.c')
665 assert str(tgt) == 'ggg.x.o', str(tgt)
666 assert len(tgt.sources) == 1, map(str, tgt.sources)
667 assert str(tgt.sources[0]) == 'ggg.x.c', map(str, tgt.sources)
669 tgt = b(env, source=['h0.c', 'h1.c'])
670 assert len(tgt) == 2, map(str, tgt)
671 assert str(tgt[0]) == 'h0.o', map(str, tgt)
672 assert str(tgt[1]) == 'h1.o', map(str, tgt)
673 assert len(tgt[0].sources) == 2, map(str, tgt[0].sources)
674 assert str(tgt[0].sources[0]) == 'h0.c', map(str, tgt[0].sources)
675 assert str(tgt[0].sources[1]) == 'h1.c', map(str, tgt[0].sources)
676 assert len(tgt[1].sources) == 2, map(str, tgt[1].sources)
677 assert str(tgt[1].sources[0]) == 'h0.c', map(str, tgt[1].sources)
678 assert str(tgt[1].sources[1]) == 'h1.c', map(str, tgt[1].sources)
680 w = b(env, target='i0.w', source=['i0.x'])
681 y = b(env, target='i1.y', source=['i1.z'])
682 tgt = b(env, source=[w, y])
683 assert len(tgt) == 2, map(str, tgt)
684 assert str(tgt[0]) == 'i0.o'
685 assert str(tgt[1]) == 'i1.o'
686 assert len(tgt[0].sources) == 2, map(str, tgt[0].sources)
687 assert str(tgt[0].sources[0]) == 'i0.w', map(str, tgt[0].sources)
688 assert str(tgt[0].sources[1]) == 'i1.y', map(str, tgt[0].sources)
689 assert len(tgt[1].sources) == 2, map(str, tgt[1].sources)
690 assert str(tgt[1].sources[0]) == 'i0.w', map(str, tgt[1].sources)
691 assert str(tgt[1].sources[1]) == 'i1.y', map(str, tgt[1].sources)
694 if __name__ == "__main__":
695 suite = unittest.makeSuite(BuilderTestCase, 'test_')
696 if not unittest.TextTestRunner().run(suite).wasSuccessful():