Support building (sub)directories.
[scons.git] / src / engine / SCons / Node / NodeTests.py
1 #
2 # Copyright (c) 2001 Steven Knight
3 #
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:
11 #
12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software.
14 #
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.
22 #
23
24 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
25
26 import os
27 import sys
28 import unittest
29
30 import SCons.Errors
31 import SCons.Node
32
33
34
35 built_it = None
36
37 class Builder:
38     def execute(self, **kw):
39         global built_it
40         built_it = 1
41         return 0
42
43 class FailBuilder:
44     def execute(self, **kw):
45         return 1
46
47 class Environment:
48     def Dictionary(self, *args):
49         pass
50
51
52
53 class NodeTestCase(unittest.TestCase):
54
55     def test_BuildException(self):
56         """Test throwing an exception on build failure.
57         """
58         node = SCons.Node.Node()
59         node.builder_set(FailBuilder())
60         node.env_set(Environment())
61         try:
62             node.build()
63         except SCons.Errors.BuildError:
64             pass
65         else:
66             raise TestFailed, "did not catch expected BuildError"
67
68     def test_build(self):
69         """Test building a node
70         """
71         # Make sure it doesn't blow up if no builder is set.
72         node = SCons.Node.Node()
73         node.build()
74         assert built_it == None
75
76         node = SCons.Node.Node()
77         node.builder_set(Builder())
78         node.env_set(Environment())
79         node.path = "xxx"       # XXX FAKE SUBCLASS ATTRIBUTE
80         node.sources = "yyy"    # XXX FAKE SUBCLASS ATTRIBUTE
81         node.build()
82         assert built_it
83
84     def test_builder_set(self):
85         """Test setting a Node's Builder
86         """
87         node = SCons.Node.Node()
88         b = Builder()
89         node.builder_set(b)
90         assert node.builder == b
91
92     def test_current(self):
93         """Test the default current() method
94         """
95         node = SCons.Node.Node()
96         assert node.current() is None
97
98     def test_env_set(self):
99         """Test setting a Node's Environment
100         """
101         node = SCons.Node.Node()
102         e = Environment()
103         node.env_set(e)
104         assert node.env == e
105
106     def test_has_signature(self):
107         """Test whether or not a node has a signature
108         """
109         node = SCons.Node.Node()
110         assert not node.has_signature()
111         node.set_signature('xxx')
112         assert node.has_signature()
113
114     def test_set_signature(self):
115         """Test setting a Node's signature
116         """
117         node = SCons.Node.Node()
118         node.set_signature('yyy')
119         assert node.signature == 'yyy'
120
121     def test_get_signature(self):
122         """Test fetching a Node's signature
123         """
124         node = SCons.Node.Node()
125         node.set_signature('zzz')
126         assert node.get_signature() == 'zzz'
127
128     def test_add_dependency(self):
129         """Test adding dependencies to a Node's list.
130         """
131         node = SCons.Node.Node()
132         assert node.depends == []
133
134         zero = SCons.Node.Node()
135         try:
136             node.add_dependency(zero)
137         except TypeError:
138             pass
139         else:
140             assert 0
141
142         one = SCons.Node.Node()
143         two = SCons.Node.Node()
144         three = SCons.Node.Node()
145         four = SCons.Node.Node()
146
147         node.add_dependency([one])
148         assert node.depends == [one]
149         node.add_dependency([two, three])
150         assert node.depends == [one, two, three]
151         node.add_dependency([three, four, one])
152         assert node.depends == [one, two, three, four]
153
154         assert zero.get_parents() == []
155         assert one.get_parents() == [node]
156         assert two.get_parents() == [node]
157         assert three.get_parents() == [node]
158         assert four.get_parents() == [node]
159
160
161     def test_add_source(self):
162         """Test adding sources to a Node's list.
163         """
164         node = SCons.Node.Node()
165         assert node.sources == []
166
167         zero = SCons.Node.Node()
168         try:
169             node.add_source(zero)
170         except TypeError:
171             pass
172         else:
173             assert 0
174
175         one = SCons.Node.Node()
176         two = SCons.Node.Node()
177         three = SCons.Node.Node()
178         four = SCons.Node.Node()
179
180         node.add_source([one])
181         assert node.sources == [one]
182         node.add_source([two, three])
183         assert node.sources == [one, two, three]
184         node.add_source([three, four, one])
185         assert node.sources == [one, two, three, four]
186
187         assert zero.get_parents() == []
188         assert one.get_parents() == [node]
189         assert two.get_parents() == [node]
190         assert three.get_parents() == [node]
191         assert four.get_parents() == [node]
192
193     def test_children(self):
194         """Test fetching the "children" of a Node.
195         """
196         node = SCons.Node.Node()
197         one = SCons.Node.Node()
198         two = SCons.Node.Node()
199         three = SCons.Node.Node()
200         four = SCons.Node.Node()
201         five = SCons.Node.Node()
202         six = SCons.Node.Node()
203
204         node.add_source([one, two, three])
205         node.add_dependency([four, five, six])
206         kids = node.children()
207         assert len(kids) == 6
208         assert one in kids
209         assert two in kids
210         assert three in kids
211         assert four in kids
212         assert five in kids
213         assert six in kids
214
215     def test_add_parent(self):
216         """Test adding parents to a Node."""
217         node = SCons.Node.Node()
218         parent = SCons.Node.Node()
219         node._add_parent(parent)
220         assert node.get_parents() == [parent]
221         node._add_parent(parent)
222         assert node.get_parents() == [parent]
223
224     def test_state(self):
225         """Test setting and getting the state of a node
226         """
227         node = SCons.Node.Node()
228         assert node.get_state() == None
229         node.set_state(SCons.Node.executing)
230         assert node.get_state() == SCons.Node.executing
231         assert SCons.Node.pending < SCons.Node.executing
232         assert SCons.Node.executing < SCons.Node.up_to_date
233         assert SCons.Node.up_to_date < SCons.Node.executed
234         assert SCons.Node.executed < SCons.Node.failed
235
236     def test_walker(self):
237         """Test walking a Node tree.
238         """
239
240         class MyNode(SCons.Node.Node):
241             def __init__(self, name):
242                 SCons.Node.Node.__init__(self)
243                 self.name = name
244
245         n1 = MyNode("n1")
246
247         nw = SCons.Node.Walker(n1)
248         assert not nw.is_done()
249         assert nw.next().name ==  "n1"
250         assert nw.is_done()
251         assert nw.next() == None
252
253         n2 = MyNode("n2")
254         n3 = MyNode("n3")
255         n1.add_source([n2, n3])
256
257         nw = SCons.Node.Walker(n1)
258         assert nw.next().name ==  "n2"
259         assert nw.next().name ==  "n3"
260         assert nw.next().name ==  "n1"
261         assert nw.next() == None
262
263         n4 = MyNode("n4")
264         n5 = MyNode("n5")
265         n6 = MyNode("n6")
266         n7 = MyNode("n7")
267         n2.add_source([n4, n5])
268         n3.add_dependency([n6, n7])
269
270         nw = SCons.Node.Walker(n1)
271         assert nw.next().name ==  "n4"
272         assert nw.next().name ==  "n5"
273         assert nw.next().name ==  "n2"
274         assert nw.next().name ==  "n6"
275         assert nw.next().name ==  "n7"
276         assert nw.next().name ==  "n3"
277         assert nw.next().name ==  "n1"
278         assert nw.next() == None
279
280     def test_children_are_executed(self):
281         n1 = SCons.Node.Node()
282         n2 = SCons.Node.Node()
283         n3 = SCons.Node.Node()
284         n4 = SCons.Node.Node()
285
286         n4.add_source([n3])
287         n3.add_source([n1, n2])
288
289         assert not n4.children_are_executed()
290         assert not n3.children_are_executed()
291         assert n2.children_are_executed()
292         assert n1.children_are_executed()
293
294         n1.set_state(SCons.Node.executed)
295         assert not n4.children_are_executed()
296         assert not n3.children_are_executed()
297         assert n2.children_are_executed()
298         assert n1.children_are_executed()
299
300         n2.set_state(SCons.Node.executed)
301         assert not n4.children_are_executed()
302         assert n3.children_are_executed()
303         assert n2.children_are_executed()
304         assert n1.children_are_executed()
305
306         n3.set_state(SCons.Node.executed)
307         assert n4.children_are_executed()
308         assert n3.children_are_executed()
309         assert n2.children_are_executed()
310         assert n1.children_are_executed()
311
312
313
314
315 if __name__ == "__main__":
316     suite = unittest.makeSuite(NodeTestCase, 'test_')
317     if not unittest.TextTestRunner().run(suite).wasSuccessful():
318         sys.exit(1)