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__"
45 def _actionAppend(a1, a2):
47 for curr_a in [a1, a2]:
48 if isinstance(curr_a, MyAction):
50 elif isinstance(curr_a, MyListAction):
51 all.extend(curr_a.list)
52 elif type(curr_a) == type([1,2]):
55 raise 'Cannot Combine Actions'
56 return MyListAction(all)
59 def __add__(self, other):
60 return _actionAppend(self, other)
62 def __radd__(self, other):
63 return _actionAppend(other, self)
65 class MyAction(MyActionBase):
69 def __call__(self, target, source, env, errfunc):
70 global built_it, built_target, built_source, built_args, built_order
75 built_order = built_order + 1
76 self.order = built_order
79 class MyListAction(MyActionBase):
80 def __init__(self, list):
82 def __call__(self, target, source, env, errfunc):
84 A(target, source, env, errfunc)
86 class MyNonGlobalAction(MyActionBase):
90 self.built_target = None
91 self.built_source = None
93 def __call__(self, target, source, env, errfunc):
94 # Okay, so not ENTIRELY non-global...
97 self.built_target = target
98 self.built_source = source
100 built_order = built_order + 1
101 self.order = built_order
105 def __init__(self, **kw):
107 self._dict.update(kw)
108 def __getitem__(self, key):
109 return self._dict[key]
110 def Dictionary(self, *args):
112 def Override(self, overrides):
113 d = self._dict.copy()
115 return apply(Environment, (), d)
116 def _update(self, dict):
117 self._dict.update(dict)
118 def get_calculator(self):
119 return SCons.Sig.default_calc
120 def get_scanner(self, scanner_key):
121 return self._dict['SCANNERS'][0]
124 def __init__(self, env=None, is_explicit=1):
125 if env is None: env = Environment()
128 self.action = MyAction()
129 self.source_factory = MyNode
130 self.is_explicit = is_explicit
131 def targets(self, t):
133 def get_actions(self):
135 def get_contents(self, target, source, env):
138 class NoneBuilder(Builder):
139 def execute(self, target, source, env):
140 Builder.execute(self, target, source, env)
143 class ListBuilder(Builder):
144 def __init__(self, *nodes):
145 Builder.__init__(self)
147 def execute(self, target, source, env):
148 if hasattr(self, 'status'):
152 target = self.nodes[0]
153 self.status = Builder.execute(self, target, source, env)
156 def execute(self, target, source, env):
160 def execute(self, target, source, env):
161 raise SCons.Errors.BuildError
163 class ExceptBuilder2:
164 def execute(self, target, source, env):
169 def __call__(self, node):
171 return node.found_includes
172 def select(self, node):
175 class MyNode(SCons.Node.Node):
176 """The base Node class contains a number of do-nothing methods that
177 we expect to be overridden by real, functional Node subclasses. So
178 simulate a real, functional Node subclass.
180 def __init__(self, name):
181 SCons.Node.Node.__init__(self)
183 self.found_includes = []
186 def get_found_includes(self, env, scanner, target):
190 def __init__(self, val):
193 def __init__(self, val):
195 def signature(self, args):
197 def collect(self, args):
198 return reduce(lambda x, y: x+y, args, self.val)
203 class NodeTestCase(unittest.TestCase):
205 def test_build(self):
206 """Test building a node
208 global built_it, built_order
210 # Make sure it doesn't blow up if no builder is set.
213 assert built_it == None
214 node.build(extra_kw_argument = 1)
215 assert built_it == None
218 node.builder_set(Builder())
219 node.env_set(Environment())
221 node.sources = ["yyy", "zzz"]
224 assert built_target == [node], built_target
225 assert built_source == ["yyy", "zzz"], built_source
229 node.builder_set(NoneBuilder())
230 node.env_set(Environment())
232 node.sources = ["rrr", "sss"]
233 node.builder.overrides = { "foo" : 1, "bar" : 2 }
236 assert built_target == [node], built_target
237 assert built_source == ["rrr", "sss"], built_source
238 assert built_args["foo"] == 1, built_args
239 assert built_args["bar"] == 2, built_args
243 lb = ListBuilder(fff, ggg)
251 fff.sources = ["hhh", "iii"]
252 ggg.sources = ["hhh", "iii"]
253 # [Charles C. 1/7/2002] Uhhh, why are there no asserts here?
254 # [SK, 15 May 2003] I dunno, let's add some...
258 assert built_target == [fff], built_target
259 assert built_source == ["hhh", "iii"], built_source
263 assert built_target == [ggg], built_target
264 assert built_source == ["hhh", "iii"], built_source
270 # NOTE: No env_set()! We should pull the environment from the builder.
271 b.env = Environment()
272 b.overrides = { "on" : 3, "off" : 4 }
276 assert built_target[0] == jjj, built_target[0]
277 assert built_source == [], built_source
278 assert built_args["on"] == 3, built_args
279 assert built_args["off"] == 4, built_args
284 node.builder_set(Builder())
285 node.env_set(Environment())
286 node.sources = ["yyy", "zzz"]
287 pre1 = MyNonGlobalAction()
288 pre2 = MyNonGlobalAction()
289 post1 = MyNonGlobalAction()
290 post2 = MyNonGlobalAction()
291 node.add_pre_action(pre1)
292 node.add_pre_action(pre2)
293 node.add_post_action(post1)
294 node.add_post_action(post2)
299 assert post1.built_it
300 assert post2.built_it
301 assert pre1.order == 1, pre1.order
302 assert pre2.order == 2, pre1.order
303 # The action of the builder itself is order 3...
304 assert post1.order == 4, pre1.order
305 assert post2.order == 5, pre1.order
307 for act in [ pre1, pre2, post1, post2 ]:
308 assert type(act.built_target[0]) == type(MyNode("bar")), type(act.built_target[0])
309 assert str(act.built_target[0]) == "xxx", str(act.built_target[0])
310 assert act.built_source == ["yyy", "zzz"], act.built_source
312 def test_get_executor(self):
313 """Test the reset_executor() method"""
314 n = SCons.Node.Node()
318 except AttributeError:
321 self.fail("did not catch expected AttributeError")
328 n = SCons.Node.Node()
329 n.builder_set(Builder())
331 assert x.env == 'env1', x.env
333 n = SCons.Node.Node()
334 n.builder_set(Builder())
337 assert x.env == 'env2', x.env
339 def test_set_executor(self):
340 """Test the reset_executor() method"""
341 n = SCons.Node.Node()
343 assert n.executor == 1, n.executor
345 def test_reset_executor(self):
346 """Test the reset_executor() method"""
347 n = SCons.Node.Node()
349 assert n.executor == 1, n.executor
351 assert not hasattr(n, 'executor'), "unexpected executor attribute"
353 def test_built(self):
354 """Test the built() method"""
355 class SubNode(SCons.Node.Node):
361 assert n.cleared, n.cleared
363 def test_retrieve_from_cache(self):
364 """Test the base retrieve_from_cache() method"""
365 n = SCons.Node.Node()
366 r = n.retrieve_from_cache()
369 def test_visited(self):
370 """Test the base visited() method
372 Just make sure it's there and we can call it.
374 n = SCons.Node.Node()
377 def test_depends_on(self):
378 """Test the depends_on() method
380 parent = SCons.Node.Node()
381 child = SCons.Node.Node()
382 parent.add_dependency([child])
383 assert parent.depends_on([child])
385 def test_builder_set(self):
386 """Test setting a Node's Builder
388 node = SCons.Node.Node()
391 assert node.builder == b
393 def test_has_builder(self):
394 """Test the has_builder() method
396 n1 = SCons.Node.Node()
397 assert n1.has_builder() == 0
398 n1.builder_set(Builder())
399 assert n1.has_builder() == 1
401 def test_has_explicit_builder(self):
402 """Test the has_explicit_builder() method
404 n1 = SCons.Node.Node()
405 assert not n1.has_explicit_builder()
406 n1.builder_set(Builder(is_explicit=1))
407 assert n1.has_explicit_builder()
408 n1.builder_set(Builder(is_explicit=None))
409 assert not n1.has_explicit_builder()
411 def test_get_builder(self):
412 """Test the get_builder() method"""
413 n1 = SCons.Node.Node()
416 b = n1.get_builder(777)
421 b = n1.get_builder(999)
424 def test_multiple_side_effect_has_builder(self):
425 """Test the multiple_side_effect_has_builder() method
427 n1 = SCons.Node.Node()
428 assert n1.multiple_side_effect_has_builder() == 0
429 n1.builder_set(Builder())
430 assert n1.multiple_side_effect_has_builder() == 1
432 def test_is_derived(self):
433 """Test the is_derived() method
435 n1 = SCons.Node.Node()
436 n2 = SCons.Node.Node()
437 n3 = SCons.Node.Node()
439 n2.builder_set(Builder())
442 assert n1.is_derived() == 0
443 assert n2.is_derived() == 1
444 assert n3.is_derived() == 1
446 def test_alter_targets(self):
447 """Test the alter_targets() method
449 n = SCons.Node.Node()
450 t, m = n.alter_targets()
454 def test_current(self):
455 """Test the default current() method
457 node = SCons.Node.Node()
458 assert node.current() is None
460 def test_children_are_up_to_date(self):
461 """Test the children_are_up_to_date() method used by subclasses
463 n1 = SCons.Node.Node()
464 n2 = SCons.Node.Node()
466 calc = Calculator(111)
469 assert n1.children_are_up_to_date(calc), "expected up to date"
470 n2.set_state(SCons.Node.executed)
471 assert not n1.children_are_up_to_date(calc), "expected not up to date"
472 n2.set_state(SCons.Node.up_to_date)
473 assert n1.children_are_up_to_date(calc), "expected up to date"
475 assert not n1.children_are_up_to_date(calc), "expected not up to date"
477 def test_env_set(self):
478 """Test setting a Node's Environment
480 node = SCons.Node.Node()
485 def test_get_actions(self):
486 """Test fetching a Node's action list
488 node = SCons.Node.Node()
489 node.builder_set(Builder())
490 a = node.builder.get_actions()
491 assert isinstance(a[0], MyAction), a[0]
493 def test_calc_bsig(self):
494 """Test generic build signature calculation
496 node = SCons.Node.Node()
497 result = node.calc_bsig(Calculator(222))
498 assert result == 222, result
499 result = node.calc_bsig(Calculator(333))
500 assert result == 222, result
502 def test_calc_csig(self):
503 """Test generic content signature calculation
505 node = SCons.Node.Node()
506 result = node.calc_csig(Calculator(444))
507 assert result == 444, result
508 result = node.calc_csig(Calculator(555))
509 assert result == 444, result
511 def test_gen_binfo(self):
512 """Test generating a build information structure
514 node = SCons.Node.Node()
515 binfo = node.gen_binfo(Calculator(666))
516 assert isinstance(binfo, SCons.Node.BuildInfo), binfo
517 assert hasattr(binfo, 'bsources')
518 assert hasattr(binfo, 'bsourcesigs')
519 assert hasattr(binfo, 'bdepends')
520 assert hasattr(binfo, 'bdependsigs')
521 assert hasattr(binfo, 'bimplicit')
522 assert hasattr(binfo, 'bimplicitsigs')
523 assert binfo.bsig == 666, binfo.bsig
525 def test_explain(self):
526 """Test explaining why a Node must be rebuilt
528 node = SCons.Node.Node()
529 node.exists = lambda: None
530 node.__str__ = lambda: 'xyzzy'
531 result = node.explain()
532 assert result == "building `xyzzy' because it doesn't exist\n", result
534 node = SCons.Node.Node()
535 result = node.explain()
536 assert result == None, result
542 node.get_stored_info = Null_BInfo
543 node.__str__ = lambda: 'null_binfo'
544 result = node.explain()
545 assert result == "Cannot explain why `null_binfo' is being rebuilt: No previous build information found\n", result
547 # XXX additional tests for the guts of the functionality some day
549 def test_del_binfo(self):
550 """Test deleting the build information from a Node
552 node = SCons.Node.Node()
555 assert not hasattr(node, 'binfo'), node
557 def test_store_info(self):
558 """Test calling the method to store build information
562 node = SCons.Node.Node()
563 node.store_info(Entry())
565 def test_get_stored_info(self):
566 """Test calling the method to fetch stored build information
568 node = SCons.Node.Node()
569 result = node.get_stored_info()
570 assert result is None, result
572 def test_set_always_build(self):
573 """Test setting a Node's always_build value
575 node = SCons.Node.Node()
576 node.set_always_build()
577 assert node.always_build
578 node.set_always_build(3)
579 assert node.always_build == 3
581 def test_set_precious(self):
582 """Test setting a Node's precious value
584 node = SCons.Node.Node()
588 assert node.precious == 7
590 def test_exists(self):
591 """Test evaluating whether a Node exists.
593 node = SCons.Node.Node()
597 def test_exists(self):
598 """Test evaluating whether a Node exists locally or in a repository.
600 node = SCons.Node.Node()
604 class MyNode(SCons.Node.Node):
612 def test_prepare(self):
613 """Test preparing a node to be built
615 node = SCons.Node.Node()
617 n1 = SCons.Node.Node()
618 n1.builder_set(Builder())
620 node.implicit_dict = {}
621 node._add_child(node.implicit, node.implicit_dict, [n1])
623 node.prepare() # should not throw an exception
625 n2 = SCons.Node.Node()
628 node.implicit_dict = {}
629 node._add_child(node.implicit, node.implicit_dict, [n2])
631 node.prepare() # should not throw an exception
633 n3 = SCons.Node.Node()
635 node.implicit_dict = {}
636 node._add_child(node.implicit, node.implicit_dict, [n3])
638 node.prepare() # should not throw an exception
640 class MyNode(SCons.Node.Node):
645 node.implicit_dict = {}
646 node._add_child(node.implicit, node.implicit_dict, [n4])
650 except SCons.Errors.StopError:
652 assert exc_caught, "did not catch expected StopError"
654 def test_add_dependency(self):
655 """Test adding dependencies to a Node's list.
657 node = SCons.Node.Node()
658 assert node.depends == []
660 zero = SCons.Node.Node()
662 one = SCons.Node.Node()
663 two = SCons.Node.Node()
664 three = SCons.Node.Node()
665 four = SCons.Node.Node()
666 five = SCons.Node.Node()
667 six = SCons.Node.Node()
669 node.add_dependency(zero)
670 assert node.depends == [zero]
671 node.add_dependency([one])
672 assert node.depends == [zero, one]
673 node.add_dependency([two, three])
674 assert node.depends == [zero, one, two, three]
675 node.add_dependency([three, four, one])
676 assert node.depends == [zero, one, two, three, four]
679 node.add_depends([[five, six]])
683 raise "did not catch expected exception"
684 assert node.depends == [zero, one, two, three, four]
687 def test_add_source(self):
688 """Test adding sources to a Node's list.
690 node = SCons.Node.Node()
691 assert node.sources == []
693 zero = SCons.Node.Node()
694 one = SCons.Node.Node()
695 two = SCons.Node.Node()
696 three = SCons.Node.Node()
697 four = SCons.Node.Node()
698 five = SCons.Node.Node()
699 six = SCons.Node.Node()
701 node.add_source(zero)
702 assert node.sources == [zero]
703 node.add_source([one])
704 assert node.sources == [zero, one]
705 node.add_source([two, three])
706 assert node.sources == [zero, one, two, three]
707 node.add_source([three, four, one])
708 assert node.sources == [zero, one, two, three, four]
711 node.add_source([[five, six]])
715 raise "did not catch expected exception"
716 assert node.sources == [zero, one, two, three, four]
718 def test_add_ignore(self):
719 """Test adding files whose dependencies should be ignored.
721 node = SCons.Node.Node()
722 assert node.ignore == []
724 zero = SCons.Node.Node()
725 one = SCons.Node.Node()
726 two = SCons.Node.Node()
727 three = SCons.Node.Node()
728 four = SCons.Node.Node()
729 five = SCons.Node.Node()
730 six = SCons.Node.Node()
732 node.add_ignore(zero)
733 assert node.ignore == [zero]
734 node.add_ignore([one])
735 assert node.ignore == [zero, one]
736 node.add_ignore([two, three])
737 assert node.ignore == [zero, one, two, three]
738 node.add_ignore([three, four, one])
739 assert node.ignore == [zero, one, two, three, four]
742 node.add_ignore([[five, six]])
746 raise "did not catch expected exception"
747 assert node.ignore == [zero, one, two, three, four]
749 def test_get_found_includes(self):
750 """Test the default get_found_includes() method
752 node = SCons.Node.Node()
753 target = SCons.Node.Node()
755 deps = node.get_found_includes(e, None, target)
756 assert deps == [], deps
758 def test_get_implicit_deps(self):
759 """Test get_implicit_deps()
762 target = MyNode("ttt")
765 # No scanner at all returns []
766 deps = node.get_implicit_deps(env, None, target)
767 assert deps == [], deps
771 node.found_includes = [d]
773 # Simple return of the found includes
774 deps = node.get_implicit_deps(env, s, target)
775 assert deps == [d], deps
777 # No "recursive" attribute on scanner doesn't recurse
779 d.found_includes = [e]
780 deps = node.get_implicit_deps(env, s, target)
781 assert deps == [d], map(str, deps)
783 # Explicit "recursive" attribute on scanner doesn't recurse
785 deps = node.get_implicit_deps(env, s, target)
786 assert deps == [d], map(str, deps)
788 # Explicit "recursive" attribute on scanner which does recurse
790 deps = node.get_implicit_deps(env, s, target)
791 assert deps == [d, e], map(str, deps)
793 # Recursive scanning eliminates duplicates
795 d.found_includes = [e, f]
796 e.found_includes = [f]
797 deps = node.get_implicit_deps(env, s, target)
798 assert deps == [d, e, f], map(str, deps)
800 def test_get_source_scanner(self):
801 """Test fetching the source scanner for a Node
803 target = SCons.Node.Node()
804 source = SCons.Node.Node()
805 s = target.get_source_scanner(source, None)
812 class Builder1(Builder):
813 def __call__(self, source):
814 r = SCons.Node.Node()
817 class Builder2(Builder1):
818 def __init__(self, scanner):
819 self.source_scanner = scanner
821 builder = Builder2(ts1)
823 targets = builder([source])
824 s = targets[0].get_source_scanner(source, None)
827 target.builder_set(Builder2(ts1))
828 target.builder.source_scanner = ts2
829 s = target.get_source_scanner(source, None)
832 builder = Builder1(env=Environment(SCANNERS = [ts3]))
834 targets = builder([source])
836 s = targets[0].get_source_scanner(source, builder.env)
841 """Test Scanner functionality
844 node.builder = Builder()
845 node.env_set(Environment())
849 node.found_includes = [d]
851 node.builder.target_scanner = s
852 assert node.implicit is None
856 assert node.implicit == [d], node.implicit
858 # Check that scanning a node with some stored implicit
859 # dependencies resets internal attributes appropriately
860 # if the stored dependencies need recalculation.
861 class StoredNode(MyNode):
862 def get_stored_implicit(self):
863 return ['implicit1', 'implicit2']
866 def current(self, node, sig):
868 def bsig(self, node):
873 save_default_calc = SCons.Sig.default_calc
874 save_implicit_cache = SCons.Node.implicit_cache
875 save_implicit_deps_changed = SCons.Node.implicit_deps_changed
876 save_implicit_deps_unchanged = SCons.Node.implicit_deps_unchanged
877 SCons.Sig.default_calc = NotCurrent()
878 SCons.Node.implicit_cache = 1
879 SCons.Node.implicit_deps_changed = None
880 SCons.Node.implicit_deps_unchanged = None
882 sn = StoredNode("eee")
883 sn._children = ['fake']
884 sn.builder_set(Builder())
885 sn.builder.target_scanner = s
889 assert sn.implicit == [], sn.implicit
890 assert sn._children == [], sn._children
893 SCons.Sig.default_calc = save_default_calc
894 SCons.Node.implicit_cache = save_implicit_cache
895 SCons.Node.implicit_deps_changed = save_implicit_deps_changed
896 SCons.Node.implicit_deps_unchanged = save_implicit_deps_unchanged
898 def test_scanner_key(self):
899 """Test that a scanner_key() method exists"""
900 assert SCons.Node.Node().scanner_key() == None
902 def test_children(self):
903 """Test fetching the non-ignored "children" of a Node.
905 node = SCons.Node.Node()
906 n1 = SCons.Node.Node()
907 n2 = SCons.Node.Node()
908 n3 = SCons.Node.Node()
909 n4 = SCons.Node.Node()
910 n5 = SCons.Node.Node()
911 n6 = SCons.Node.Node()
912 n7 = SCons.Node.Node()
913 n8 = SCons.Node.Node()
914 n9 = SCons.Node.Node()
915 n10 = SCons.Node.Node()
916 n11 = SCons.Node.Node()
917 n12 = SCons.Node.Node()
919 node.add_source([n1, n2, n3])
920 node.add_dependency([n4, n5, n6])
922 node.implicit_dict = {}
923 node._add_child(node.implicit, node.implicit_dict, [n7, n8, n9])
924 node._add_child(node.implicit, node.implicit_dict, [n10, n11, n12])
925 node.add_ignore([n2, n5, n8, n11])
927 kids = node.children()
928 for kid in [n1, n3, n4, n6, n7, n9, n10, n12]:
929 assert kid in kids, kid
930 for kid in [n2, n5, n8, n11]:
931 assert not kid in kids, kid
933 def test_all_children(self):
934 """Test fetching all the "children" of a Node.
936 node = SCons.Node.Node()
937 n1 = SCons.Node.Node()
938 n2 = SCons.Node.Node()
939 n3 = SCons.Node.Node()
940 n4 = SCons.Node.Node()
941 n5 = SCons.Node.Node()
942 n6 = SCons.Node.Node()
943 n7 = SCons.Node.Node()
944 n8 = SCons.Node.Node()
945 n9 = SCons.Node.Node()
946 n10 = SCons.Node.Node()
947 n11 = SCons.Node.Node()
948 n12 = SCons.Node.Node()
950 node.add_source([n1, n2, n3])
951 node.add_dependency([n4, n5, n6])
953 node.implicit_dict = {}
954 node._add_child(node.implicit, node.implicit_dict, [n7, n8, n9])
955 node._add_child(node.implicit, node.implicit_dict, [n10, n11, n12])
956 node.add_ignore([n2, n5, n8, n11])
958 kids = node.all_children()
959 for kid in [n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12]:
960 assert kid in kids, kid
962 def test_state(self):
963 """Test setting and getting the state of a node
965 node = SCons.Node.Node()
966 assert node.get_state() == None
967 node.set_state(SCons.Node.executing)
968 assert node.get_state() == SCons.Node.executing
969 assert SCons.Node.pending < SCons.Node.executing
970 assert SCons.Node.executing < SCons.Node.up_to_date
971 assert SCons.Node.up_to_date < SCons.Node.executed
972 assert SCons.Node.executed < SCons.Node.failed
974 def test_walker(self):
975 """Test walking a Node tree.
980 nw = SCons.Node.Walker(n1)
981 assert not nw.is_done()
982 assert nw.next().name == "n1"
984 assert nw.next() == None
988 n1.add_source([n2, n3])
990 nw = SCons.Node.Walker(n1)
992 assert n.name == "n2", n.name
994 assert n.name == "n3", n.name
996 assert n.name == "n1", n.name
1004 n2.add_source([n4, n5])
1005 n3.add_dependency([n6, n7])
1007 nw = SCons.Node.Walker(n1)
1008 assert nw.next().name == "n4"
1009 assert nw.next().name == "n5"
1010 assert nw.history.has_key(n2)
1011 assert nw.next().name == "n2"
1012 assert nw.next().name == "n6"
1013 assert nw.next().name == "n7"
1014 assert nw.history.has_key(n3)
1015 assert nw.next().name == "n3"
1016 assert nw.history.has_key(n1)
1017 assert nw.next().name == "n1"
1018 assert nw.next() == None
1021 n8.add_dependency([n3])
1022 n7.add_dependency([n8])
1024 def cycle(node, stack):
1025 global cycle_detected
1028 global cycle_detected
1030 nw = SCons.Node.Walker(n3, cycle_func = cycle)
1032 assert n.name == "n6", n.name
1034 assert n.name == "n8", n.name
1035 assert cycle_detected
1036 cycle_detected = None
1038 assert n.name == "n7", n.name
1040 assert nw.next() == None
1042 def test_abspath(self):
1043 """Test the get_abspath() method."""
1045 assert n.get_abspath() == str(n), n.get_abspath()
1047 def test_for_signature(self):
1048 """Test the for_signature() method."""
1050 assert n.for_signature() == str(n), n.get_abspath()
1052 def test_get_string(self):
1053 """Test the get_string() method."""
1054 class TestNode(MyNode):
1055 def __init__(self, name, sig):
1056 MyNode.__init__(self, name)
1059 def for_signature(self):
1062 n = TestNode("foo", "bar")
1063 assert n.get_string(0) == "foo", n.get_string(0)
1064 assert n.get_string(1) == "bar", n.get_string(1)
1066 def test_literal(self):
1067 """Test the is_literal() function."""
1069 assert n.is_literal()
1071 def test_Annotate(self):
1072 """Test using an interface-specific Annotate function."""
1073 def my_annotate(node, self=self):
1074 node.annotation = self.node_string
1076 save_Annotate = SCons.Node.Annotate
1077 SCons.Node.Annotate = my_annotate
1080 self.node_string = '#1'
1081 n = SCons.Node.Node()
1082 assert n.annotation == '#1', n.annotation
1084 self.node_string = '#2'
1085 n = SCons.Node.Node()
1086 assert n.annotation == '#2', n.annotation
1088 SCons.Node.Annotate = save_Annotate
1090 def test_clear(self):
1091 """Test clearing all cached state information."""
1092 n = SCons.Node.Node()
1096 n.includes = 'testincludes'
1097 n.found_include = {'testkey':'testvalue'}
1098 n.implicit = 'testimplicit'
1099 n.waiting_parents = ['foo', 'bar']
1103 assert n.get_state() is None, n.get_state()
1104 assert not hasattr(n, 'binfo'), n.bsig
1105 assert n.includes is None, n.includes
1106 assert n.found_includes == {}, n.found_includes
1107 assert n.implicit is None, n.implicit
1108 assert n.waiting_parents == [], n.waiting_parents
1110 def test_get_subst_proxy(self):
1111 """Test the get_subst_proxy method."""
1114 assert n.get_subst_proxy() == n, n.get_subst_proxy()
1116 def test_new_binfo(self):
1117 """Test the new_binfo() method"""
1118 n = SCons.Node.Node()
1119 result = n.new_binfo()
1120 assert isinstance(result, SCons.Node.BuildInfo), result
1122 def test_get_suffix(self):
1123 """Test the base Node get_suffix() method"""
1124 n = SCons.Node.Node()
1128 def test_generate_build_dict(self):
1129 """Test the base Node generate_build_dict() method"""
1130 n = SCons.Node.Node()
1131 dict = n.generate_build_dict()
1132 assert dict == {}, dict
1134 def test_postprocess(self):
1135 """Test calling the base Node postprocess() method"""
1136 n = SCons.Node.Node()
1139 def test_add_to_waiting_parents(self):
1140 """Test the add_to_waiting_parents() method"""
1141 n1 = SCons.Node.Node()
1142 n2 = SCons.Node.Node()
1143 assert n1.waiting_parents == [], n1.waiting_parents
1144 n1.add_to_waiting_parents(n2)
1145 assert n1.waiting_parents == [n2], n1.waiting_parents
1147 def test_call_for_all_waiting_parents(self):
1148 """Test the call_for_all_waiting_parents() method"""
1149 n1 = SCons.Node.Node()
1150 n2 = SCons.Node.Node()
1151 n1.add_to_waiting_parents(n2)
1153 def func(node, result=result):
1155 n1.call_for_all_waiting_parents(func)
1156 assert result == [n1, n2], result
1158 class NodeListTestCase(unittest.TestCase):
1159 def test___str__(self):
1164 nl = SCons.Node.NodeList([n3, n2, n1])
1167 ul = UserList.UserList([2])
1171 # An older version of Python (*cough* 1.5.2 *cough*)
1172 # that doesn't allow UserList objects to extend lists.
1176 assert s == "['n3', 'n2', 'n1']", s
1179 r = re.sub('at (0x)?[0-9A-Fa-f]+', 'at 0x', repr(nl))
1180 l = string.join(["<__main__.MyNode instance at 0x>"]*3, ", ")
1181 assert r == '[%s]' % l, r
1185 if __name__ == "__main__":
1186 suite = unittest.TestSuite()
1187 tclasses = [ NodeTestCase,
1189 for tclass in tclasses:
1190 names = unittest.getTestCaseNames(tclass, 'test_')
1191 suite.addTests(map(tclass, names))
1192 if not unittest.TextTestRunner().run(suite).wasSuccessful():