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.
42 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 test.write('act.py', """import os, string, sys
57 f = open(sys.argv[1], 'w')
58 f.write("act.py: '" + string.join(sys.argv[2:], "' '") + "'\\n")
61 f.write("act.py: '" + os.environ[sys.argv[3]] + "'\\n")
65 if os.environ.has_key( 'ACTPY_PIPE' ):
66 sys.stdout.write( 'act.py: stdout: executed act.py\\n' )
67 sys.stderr.write( 'act.py: stderr: executed act.py\\n' )
71 act_py = test.workpath('act.py')
73 outfile = test.workpath('outfile')
74 outfile2 = test.workpath('outfile2')
76 scons_env = SCons.Environment.Environment()
78 # Capture all the stuff the Actions will print,
79 # so it doesn't clutter the output.
80 sys.stdout = StringIO.StringIO()
83 def __init__(self, **kw):
85 self.d['SHELL'] = scons_env['SHELL']
86 self.d['SPAWN'] = scons_env['SPAWN']
87 self.d['PSPAWN'] = scons_env['PSPAWN']
88 self.d['ESCAPE'] = scons_env['ESCAPE']
89 for k, v in kw.items():
92 if not SCons.Util.is_String(s):
97 return self.d.get(s[2:-1], '')
99 return self.d.get(s[1:], '')
102 return self.d.get(s, s)
103 def __getitem__(self, item):
105 def __setitem__(self, item, value):
107 def has_key(self, item):
108 return self.d.has_key(item)
109 def get(self, key, value):
110 return self.d.get(key, value)
112 return self.d.items()
113 def Dictionary(self):
115 def Copy(self, **kw):
117 res.d = SCons.Environment.our_deepcopy(self.d)
118 for k, v in kw.items():
123 for k,v in self.items(): d[k] = v
124 d['TARGETS'] = ['__t1__', '__t2__', '__t3__', '__t4__', '__t5__', '__t6__']
125 d['TARGET'] = d['TARGETS'][0]
126 d['SOURCES'] = ['__s1__', '__s2__', '__s3__', '__s4__', '__s5__', '__s6__']
127 d['SOURCE'] = d['SOURCES'][0]
131 def __init__(self, name):
138 if os.name == 'java':
139 python = os.path.join(sys.prefix, 'jython')
141 python = sys.executable
143 class ActionTestCase(unittest.TestCase):
145 def test_factory(self):
146 """Test the Action factory
152 a1 = SCons.Action.Action(foo)
153 assert isinstance(a1, SCons.Action.FunctionAction), a1
154 assert a1.execfunction == foo, a1.execfunction
156 a2 = SCons.Action.Action("string")
157 assert isinstance(a2, SCons.Action.CommandAction), a2
158 assert a2.cmd_list == "string", a2.cmd_list
160 if hasattr(types, 'UnicodeType'):
161 exec "a3 = SCons.Action.Action(u'string')"
162 exec "assert isinstance(a3, SCons.Action.CommandAction), a3"
164 a4 = SCons.Action.Action(["x", "y", "z", [ "a", "b", "c"]])
165 assert isinstance(a4, SCons.Action.ListAction), a4
166 assert isinstance(a4.list[0], SCons.Action.CommandAction), a4.list[0]
167 assert a4.list[0].cmd_list == "x", a4.list[0].cmd_list
168 assert isinstance(a4.list[1], SCons.Action.CommandAction), a4.list[1]
169 assert a4.list[1].cmd_list == "y", a4.list[1].cmd_list
170 assert isinstance(a4.list[2], SCons.Action.CommandAction), a4.list[2]
171 assert a4.list[2].cmd_list == "z", a4.list[2].cmd_list
172 assert isinstance(a4.list[3], SCons.Action.CommandAction), a4.list[3]
173 assert a4.list[3].cmd_list == [ "a", "b", "c" ], a4.list[3].cmd_list
175 a5 = SCons.Action.Action(1)
176 assert a5 is None, a5
178 a6 = SCons.Action.Action(a1)
181 a7 = SCons.Action.Action([[ "explicit", "command", "line" ]])
182 assert isinstance(a7, SCons.Action.CommandAction), a7
183 assert a7.cmd_list == [ "explicit", "command", "line" ], a7.cmd_list
185 a8 = SCons.Action.Action(["a8"])
186 assert isinstance(a8, SCons.Action.CommandAction), a8
187 assert a8.cmd_list == "a8", a8.cmd_list
189 a9 = SCons.Action.Action("x\ny\nz")
190 assert isinstance(a9, SCons.Action.ListAction), a9
191 assert isinstance(a9.list[0], SCons.Action.CommandAction), a9.list[0]
192 assert a9.list[0].cmd_list == "x", a9.list[0].cmd_list
193 assert isinstance(a9.list[1], SCons.Action.CommandAction), a9.list[1]
194 assert a9.list[1].cmd_list == "y", a9.list[1].cmd_list
195 assert isinstance(a9.list[2], SCons.Action.CommandAction), a9.list[2]
196 assert a9.list[2].cmd_list == "z", a9.list[2].cmd_list
198 a10 = SCons.Action.Action(["x", foo, "z"])
199 assert isinstance(a10, SCons.Action.ListAction), a10
200 assert isinstance(a10.list[0], SCons.Action.CommandAction), a10.list[0]
201 assert a10.list[0].cmd_list == "x", a10.list[0].cmd_list
202 assert isinstance(a10.list[1], SCons.Action.FunctionAction), a10.list[1]
203 assert a10.list[1].execfunction == foo, a10.list[1].execfunction
204 assert isinstance(a10.list[2], SCons.Action.CommandAction), a10.list[2]
205 assert a10.list[2].cmd_list == "z", a10.list[2].cmd_list
207 a11 = SCons.Action.Action(foo, strfunction=bar)
208 assert isinstance(a11, SCons.Action.FunctionAction), a11
209 assert a11.execfunction == foo, a11.execfunction
210 assert a11.strfunction == bar, a11.strfunction
212 class ActionBaseTestCase(unittest.TestCase):
215 """Test Action comparison
217 a1 = SCons.Action.Action("x")
218 a2 = SCons.Action.Action("x")
220 a3 = SCons.Action.Action("y")
225 """Test the show() method
227 save_stdout = sys.stdout
229 save = SCons.Action.print_actions
230 SCons.Action.print_actions = 0
232 sio = StringIO.StringIO()
234 a = SCons.Action.Action("x")
239 SCons.Action.print_actions = 1
241 sio = StringIO.StringIO()
245 assert s == "foobar\n", s
247 SCons.Action.print_actions = save
248 sys.stdout = save_stdout
250 def test_get_actions(self):
251 """Test the get_actions() method
253 a = SCons.Action.Action("x")
258 """Test adding Actions to stuff."""
259 # Adding actions to other Actions or to stuff that can
260 # be converted into an Action should produce a ListAction
261 # containing all the Actions.
264 baz = SCons.Action.CommandGenerator(bar)
265 act1 = SCons.Action.Action('foo bar')
266 act2 = SCons.Action.Action([ 'foo', bar ])
269 assert isinstance(sum, SCons.Action.ListAction), str(sum)
270 assert len(sum.list) == 3, len(sum.list)
271 assert map(lambda x: isinstance(x, SCons.Action.ActionBase),
272 sum.list) == [ 1, 1, 1 ]
275 assert isinstance(sum, SCons.Action.ListAction), str(sum)
276 assert len(sum.list) == 2, len(sum.list)
279 assert isinstance(sum, SCons.Action.ListAction), str(sum)
280 assert len(sum.list) == 4, len(sum.list)
282 # Should also be able to add command generators to each other
285 assert isinstance(sum, SCons.Action.ListAction), str(sum)
286 assert len(sum.list) == 2, len(sum.list)
289 assert isinstance(sum, SCons.Action.ListAction), str(sum)
290 assert len(sum.list) == 2, len(sum.list)
293 assert isinstance(sum, SCons.Action.ListAction), str(sum)
294 assert len(sum.list) == 3, len(sum.list)
296 # Also should be able to add Actions to anything that can
297 # be converted into an action.
299 assert isinstance(sum, SCons.Action.ListAction), str(sum)
300 assert len(sum.list) == 2, len(sum.list)
301 assert isinstance(sum.list[1], SCons.Action.FunctionAction)
303 sum = 'foo bar' + act2
304 assert isinstance(sum, SCons.Action.ListAction), str(sum)
305 assert len(sum.list) == 3, len(sum.list)
306 assert isinstance(sum.list[0], SCons.Action.CommandAction)
308 sum = [ 'foo', 'bar' ] + act1
309 assert isinstance(sum, SCons.Action.ListAction), str(sum)
310 assert len(sum.list) == 3, sum.list
311 assert isinstance(sum.list[0], SCons.Action.CommandAction)
312 assert isinstance(sum.list[1], SCons.Action.CommandAction)
314 sum = act2 + [ baz, bar ]
315 assert isinstance(sum, SCons.Action.ListAction), str(sum)
316 assert len(sum.list) == 4, len(sum.list)
317 assert isinstance(sum.list[2], SCons.Action.CommandGeneratorAction)
318 assert isinstance(sum.list[3], SCons.Action.FunctionAction)
325 assert 0, "Should have thrown a TypeError adding to an int."
332 assert 0, "Should have thrown a TypeError adding to an int."
334 class CommandActionTestCase(unittest.TestCase):
337 """Test creation of a command Action
339 a = SCons.Action.CommandAction(["xyzzy"])
340 assert a.cmd_list == [ "xyzzy" ], a.cmd_list
342 def test_strfunction(self):
343 """Test fetching the string representation of command Actions
346 act = SCons.Action.CommandAction('xyzzy $TARGET $SOURCE')
347 s = act.strfunction([], [], Environment())
348 assert s == ['xyzzy'], s
349 s = act.strfunction([DummyNode('target')], [DummyNode('source')], Environment())
350 assert s == ['xyzzy target source'], s
351 s = act.strfunction([DummyNode('t1'), DummyNode('t2')],
352 [DummyNode('s1'), DummyNode('s2')], Environment())
353 assert s == ['xyzzy t1 s1'], s
355 act = SCons.Action.CommandAction('xyzzy $TARGETS $SOURCES')
356 s = act.strfunction([], [], Environment())
357 assert s == ['xyzzy'], s
358 s = act.strfunction([DummyNode('target')], [DummyNode('source')], Environment())
359 assert s == ['xyzzy target source'], s
360 s = act.strfunction([DummyNode('t1'), DummyNode('t2')],
361 [DummyNode('s1'), DummyNode('s2')], Environment())
362 assert s == ['xyzzy t1 t2 s1 s2'], s
364 act = SCons.Action.CommandAction(['xyzzy',
365 '$TARGET', '$SOURCE',
366 '$TARGETS', '$SOURCES'])
367 s = act.strfunction([], [], Environment())
368 assert s == ['xyzzy'], s
369 s = act.strfunction([DummyNode('target')], [DummyNode('source')], Environment())
370 assert s == ['xyzzy target source target source'], s
371 s = act.strfunction([DummyNode('t1'), DummyNode('t2')],
372 [DummyNode('s1'), DummyNode('s2')], Environment())
373 assert s == ['xyzzy t1 s1 t1 t2 s1 s2'], s
375 def test_execute(self):
376 """Test execution of command Actions
381 except AttributeError:
384 cmd1 = r'%s %s %s xyzzy' % (python, act_py, outfile)
386 act = SCons.Action.CommandAction(cmd1)
387 r = act([], [], env.Copy())
389 c = test.read(outfile, 'r')
390 assert c == "act.py: 'xyzzy'\n", c
392 cmd2 = r'%s %s %s $TARGET' % (python, act_py, outfile)
394 act = SCons.Action.CommandAction(cmd2)
395 r = act('foo', [], env.Copy())
397 c = test.read(outfile, 'r')
398 assert c == "act.py: 'foo'\n", c
400 cmd3 = r'%s %s %s ${TARGETS}' % (python, act_py, outfile)
402 act = SCons.Action.CommandAction(cmd3)
403 r = act(['aaa', 'bbb'], [], env.Copy())
405 c = test.read(outfile, 'r')
406 assert c == "act.py: 'aaa' 'bbb'\n", c
408 cmd4 = r'%s %s %s $SOURCES' % (python, act_py, outfile)
410 act = SCons.Action.CommandAction(cmd4)
411 r = act([], [DummyNode('one'), DummyNode('two')], env.Copy())
413 c = test.read(outfile, 'r')
414 assert c == "act.py: 'one' 'two'\n", c
416 cmd4 = r'%s %s %s ${SOURCES[:2]}' % (python, act_py, outfile)
418 act = SCons.Action.CommandAction(cmd4)
420 source = [DummyNode('three'),
425 c = test.read(outfile, 'r')
426 assert c == "act.py: 'three' 'four'\n", c
428 cmd5 = r'%s %s %s $TARGET XYZZY' % (python, act_py, outfile)
430 act = SCons.Action.CommandAction(cmd5)
432 if scons_env.has_key('ENV'):
433 env5['ENV'] = scons_env['ENV']
434 PATH = scons_env['ENV'].get('PATH', '')
439 env5['ENV']['XYZZY'] = 'xyzzy'
440 r = act(target = 'out5', source = [], env = env5)
442 act = SCons.Action.CommandAction(cmd5)
443 r = act(target = DummyNode('out5'),
445 env = env.Copy(ENV = {'XYZZY' : 'xyzzy',
448 c = test.read(outfile, 'r')
449 assert c == "act.py: 'out5' 'XYZZY'\nact.py: 'xyzzy'\n", c
452 def __init__(self, str):
459 cmd6 = r'%s %s %s ${TARGETS[1]} $TARGET ${SOURCES[:2]}' % (python, act_py, outfile)
461 act = SCons.Action.CommandAction(cmd6)
462 r = act(target = [Obj('111'), Obj('222')],
463 source = [Obj('333'), Obj('444'), Obj('555')],
466 c = test.read(outfile, 'r')
467 assert c == "act.py: '222' '111' '333' '444'\n", c
469 cmd7 = '%s %s %s one\n\n%s %s %s two' % (python, act_py, outfile,
470 python, act_py, outfile)
471 expect7 = '%s %s %s one\n%s %s %s two\n' % (python, act_py, outfile,
472 python, act_py, outfile)
474 act = SCons.Action.CommandAction(cmd7)
480 show_string = show_string + string + "\n"
483 r = act([], [], env.Copy())
485 assert show_string == expect7, show_string
488 # NT treats execs of directories and non-executable files
489 # as "file not found" errors
490 expect_nonexistent = 1
491 expect_nonexecutable = 1
492 elif sys.platform == 'cygwin':
493 expect_nonexistent = 127
494 expect_nonexecutable = 127
496 expect_nonexistent = 127
497 expect_nonexecutable = 126
499 # Test that a nonexistent command returns 127
500 act = SCons.Action.CommandAction(python + "_XyZzY_")
501 r = act([], [], env.Copy(out = outfile))
502 assert r == expect_nonexistent, "r == %d" % r
504 # Test that trying to execute a directory returns 126
505 dir, tail = os.path.split(python)
506 act = SCons.Action.CommandAction(dir)
507 r = act([], [], env.Copy(out = outfile))
508 assert r == expect_nonexecutable, "r == %d" % r
510 # Test that trying to execute a non-executable file returns 126
511 act = SCons.Action.CommandAction(outfile)
512 r = act([], [], env.Copy(out = outfile))
513 assert r == expect_nonexecutable, "r == %d" % r
516 def test_pipe_execute(self):
517 """Test capturing piped output from an action
519 pipe_file = open( test.workpath('pipe.out'), "w" )
520 self.env = Environment(ENV = {'ACTPY_PIPE' : '1'}, PIPE_BUILD = 1,
521 PSTDOUT = pipe_file, PSTDERR = pipe_file)
522 # everything should also work when piping output
524 self.env['PSTDOUT'].close()
525 pipe_out = test.read( test.workpath('pipe.out') )
526 if sys.platform == 'win32':
530 found = re.findall( "act.py: stdout: executed act.py%s\nact.py: stderr: executed act.py%s\n" % (cr, cr), pipe_out )
531 assert len(found) == 8, found
533 def test_set_handler(self):
534 """Test setting the command handler...
540 def func(sh, escape, cmd, args, env, test=t):
544 def escape_func(cmd):
545 return '**' + cmd + '**'
548 def __init__(self, x):
552 def is_literal(self):
556 SCons.Action.SetCommandHandler(func)
557 except SCons.Errors.UserError:
560 assert 0, "should have gotten user error"
562 a = SCons.Action.CommandAction(["xyzzy"])
563 a([], [], Environment(SPAWN = func))
564 assert t.executed == [ 'xyzzy' ]
566 a = SCons.Action.CommandAction(["xyzzy"])
567 a([], [], Environment(SPAWN = func, SHELL = 'fake shell'))
568 assert t.executed == [ 'xyzzy' ]
569 assert t.shell == 'fake shell'
571 a = SCons.Action.CommandAction([ LiteralStr("xyzzy") ])
572 a([], [], Environment(SPAWN = func, ESCAPE = escape_func))
573 assert t.executed == [ '**xyzzy**' ], t.executed
575 def test_get_raw_contents(self):
576 """Test fetching the contents of a command Action
578 def CmdGen(target, source, env, for_signature):
581 (env["foo"], env["bar"])
583 # The number 1 is there to make sure all args get converted to strings.
584 a = SCons.Action.CommandAction(["|", "$(", "$foo", "|", "$bar",
585 "$)", "|", "$baz", 1])
586 c = a.get_raw_contents(target=[], source=[],
587 env=Environment(foo = 'FFF', bar = 'BBB',
589 assert c == "| $( FFF | BBB $) | FFF BBB 1", c
591 # We've discusssed using the real target and source names in a
592 # CommandAction's signature contents. This would have have the
593 # advantage of recompiling when a file's name changes (keeping
594 # debug info current), but it would currently break repository
595 # logic that will change the file name based on whether the
596 # files come from a repository or locally. If we ever move to
597 # that scheme, then all of the '__t1__' and '__s6__' file names
598 # in the asserts below would change to 't1' and 's6' and the
600 t = map(DummyNode, ['t1', 't2', 't3', 't4', 't5', 't6'])
601 s = map(DummyNode, ['s1', 's2', 's3', 's4', 's5', 's6'])
604 a = SCons.Action.CommandAction(["$TARGET"])
605 c = a.get_raw_contents(target=t, source=s, env=env)
608 a = SCons.Action.CommandAction(["$TARGETS"])
609 c = a.get_raw_contents(target=t, source=s, env=env)
610 assert c == "t1 t2 t3 t4 t5 t6", c
612 a = SCons.Action.CommandAction(["${TARGETS[2]}"])
613 c = a.get_raw_contents(target=t, source=s, env=env)
616 a = SCons.Action.CommandAction(["${TARGETS[3:5]}"])
617 c = a.get_raw_contents(target=t, source=s, env=env)
618 assert c == "t4 t5", c
620 a = SCons.Action.CommandAction(["$SOURCE"])
621 c = a.get_raw_contents(target=t, source=s, env=env)
624 a = SCons.Action.CommandAction(["$SOURCES"])
625 c = a.get_raw_contents(target=t, source=s, env=env)
626 assert c == "s1 s2 s3 s4 s5 s6", c
628 a = SCons.Action.CommandAction(["${SOURCES[2]}"])
629 c = a.get_raw_contents(target=t, source=s, env=env)
632 a = SCons.Action.CommandAction(["${SOURCES[3:5]}"])
633 c = a.get_raw_contents(target=t, source=s, env=env)
634 assert c == "s4 s5", c
636 def test_get_contents(self):
637 """Test fetching the contents of a command Action
639 def CmdGen(target, source, env, for_signature):
642 (env["foo"], env["bar"])
644 # The number 1 is there to make sure all args get converted to strings.
645 a = SCons.Action.CommandAction(["|", "$(", "$foo", "|", "$bar",
646 "$)", "|", "$baz", 1])
647 c = a.get_contents(target=[], source=[],
648 env=Environment(foo = 'FFF', bar = 'BBB',
650 assert c == "| | FFF BBB 1", c
652 # We've discusssed using the real target and source names in a
653 # CommandAction's signature contents. This would have have the
654 # advantage of recompiling when a file's name changes (keeping
655 # debug info current), but it would currently break repository
656 # logic that will change the file name based on whether the
657 # files come from a repository or locally. If we ever move to
658 # that scheme, then all of the '__t1__' and '__s6__' file names
659 # in the asserts below would change to 't1' and 's6' and the
661 t = map(DummyNode, ['t1', 't2', 't3', 't4', 't5', 't6'])
662 s = map(DummyNode, ['s1', 's2', 's3', 's4', 's5', 's6'])
665 a = SCons.Action.CommandAction(["$TARGET"])
666 c = a.get_contents(target=t, source=s, env=env)
669 a = SCons.Action.CommandAction(["$TARGETS"])
670 c = a.get_contents(target=t, source=s, env=env)
671 assert c == "t1 t2 t3 t4 t5 t6", c
673 a = SCons.Action.CommandAction(["${TARGETS[2]}"])
674 c = a.get_contents(target=t, source=s, env=env)
677 a = SCons.Action.CommandAction(["${TARGETS[3:5]}"])
678 c = a.get_contents(target=t, source=s, env=env)
679 assert c == "t4 t5", c
681 a = SCons.Action.CommandAction(["$SOURCE"])
682 c = a.get_contents(target=t, source=s, env=env)
685 a = SCons.Action.CommandAction(["$SOURCES"])
686 c = a.get_contents(target=t, source=s, env=env)
687 assert c == "s1 s2 s3 s4 s5 s6", c
689 a = SCons.Action.CommandAction(["${SOURCES[2]}"])
690 c = a.get_contents(target=t, source=s, env=env)
693 a = SCons.Action.CommandAction(["${SOURCES[3:5]}"])
694 c = a.get_contents(target=t, source=s, env=env)
695 assert c == "s4 s5", c
697 class CommandGeneratorActionTestCase(unittest.TestCase):
700 """Test creation of a command generator Action
702 def f(target, source, env):
704 a = SCons.Action.CommandGeneratorAction(f)
705 assert a.generator == f
707 def test_execute(self):
708 """Test executing a command generator Action
711 def f(target, source, env, for_signature, self=self):
714 s = env.subst("$FOO")
715 assert s == 'foo baz\nbar ack', s
717 def func_action(target, source, env, self=self):
719 s = env.subst('$foo')
722 def f2(target, source, env, for_signature, f=func_action):
724 def ch(sh, escape, cmd, args, env, self=self):
726 self.args.append(args)
728 a = SCons.Action.CommandGeneratorAction(f)
732 a([], [], env=Environment(FOO = 'foo baz\nbar ack',
735 assert self.dummy == 1, self.dummy
736 assert self.cmd == ['foo', 'bar'], self.cmd
737 assert self.args == [[ 'foo', 'baz' ], [ 'bar', 'ack' ]], self.args
739 b = SCons.Action.CommandGeneratorAction(f2)
741 b(target=[], source=[], env=Environment(foo = 'bar',
743 assert self.dummy==2, self.dummy
747 def __init__(self, t):
750 self.t.rfile_called = 1
752 def f3(target, source, env, for_signature):
754 c = SCons.Action.CommandGeneratorAction(f3)
755 c(target=[], source=DummyFile(self), env=Environment())
756 assert self.rfile_called
758 def test_get_contents(self):
759 """Test fetching the contents of a command generator Action
761 def f(target, source, env, for_signature):
764 assert for_signature, for_signature
765 return [["guux", foo, "$(", "$ignore", "$)", bar,
766 '${test("$( foo $bar $)")}' ]]
769 assert mystr == "$( foo $bar $)", mystr
772 a = SCons.Action.CommandGeneratorAction(f)
773 c = a.get_contents(target=[], source=[],
774 env=Environment(foo = 'FFF', bar = 'BBB',
775 ignore = 'foo', test=test))
776 assert c == "guux FFF BBB test", c
779 class FunctionActionTestCase(unittest.TestCase):
782 """Test creation of a function Action
793 a = SCons.Action.FunctionAction(func1)
794 assert a.execfunction == func1, a.execfunction
795 assert isinstance(a.strfunction, types.FunctionType)
797 a = SCons.Action.FunctionAction(func2, strfunction=func3)
798 assert a.execfunction == func2, a.execfunction
799 assert a.strfunction == func3, a.strfunction
801 a = SCons.Action.FunctionAction(func3, func4)
802 assert a.execfunction == func3, a.execfunction
803 assert a.strfunction == func4, a.strfunction
805 a = SCons.Action.FunctionAction(func4, None)
806 assert a.execfunction == func4, a.execfunction
807 assert a.strfunction is None, a.strfunction
809 def test_execute(self):
810 """Test executing a function Action
813 def f(target, source, env):
818 assert env.subst("$BAR") == 'foo bar', env.subst("$BAR")
820 a = SCons.Action.FunctionAction(f)
821 a(target=1, source=2, env=Environment(BAR = 'foo bar',
823 assert self.inc == 1, self.inc
824 assert self.source == [2], self.source
825 assert self.target == [1], self.target
829 def function1(target, source, env):
833 open(t, 'w').write("function1\n")
836 act = SCons.Action.FunctionAction(function1)
839 r = act(target = [outfile, outfile2], source=[], env=Environment())
840 except SCons.Errors.BuildError:
844 c = test.read(outfile, 'r')
845 assert c == "function1\n", c
846 c = test.read(outfile2, 'r')
847 assert c == "function1\n", c
850 def __init__(self, target, source, env):
851 open(env['out'], 'w').write("class1a\n")
853 act = SCons.Action.FunctionAction(class1a)
854 r = act([], [], Environment(out = outfile))
855 assert r.__class__ == class1a
856 c = test.read(outfile, 'r')
857 assert c == "class1a\n", c
860 def __call__(self, target, source, env):
861 open(env['out'], 'w').write("class1b\n")
864 act = SCons.Action.FunctionAction(class1b())
865 r = act([], [], Environment(out = outfile))
867 c = test.read(outfile, 'r')
868 assert c == "class1b\n", c
870 def build_it(target, source, env, self=self):
873 def string_it(target, source, env, self=self):
876 act = SCons.Action.FunctionAction(build_it, string_it)
877 r = act([], [], Environment())
880 assert self.string_it
882 def test_get_contents(self):
883 """Test fetching the contents of a function Action
885 a = SCons.Action.FunctionAction(Func)
886 c = a.get_contents(target=[], source=[], env=Environment())
887 assert c == "\177\036\000\177\037\000d\000\000S", repr(c)
889 a = SCons.Action.FunctionAction(Func, varlist=['XYZ'])
890 c = a.get_contents(target=[], source=[], env=Environment())
891 assert c == "\177\036\000\177\037\000d\000\000S", repr(c)
892 c = a.get_contents(target=[], source=[], env=Environment(XYZ = 'foo'))
893 assert c == "\177\036\000\177\037\000d\000\000Sfoo", repr(c)
895 class ListActionTestCase(unittest.TestCase):
898 """Test creation of a list of subsidiary Actions
902 a = SCons.Action.ListAction(["x", func, ["y", "z"]])
903 assert isinstance(a.list[0], SCons.Action.CommandAction)
904 assert isinstance(a.list[1], SCons.Action.FunctionAction)
905 assert isinstance(a.list[2], SCons.Action.ListAction)
906 assert a.list[2].list[0].cmd_list == 'y'
908 def test_get_actions(self):
909 """Test the get_actions() method for ListActions
911 a = SCons.Action.ListAction(["x", "y"])
913 assert len(l) == 2, l
914 assert isinstance(l[0], SCons.Action.CommandAction), l[0]
915 g = l[0].get_actions()
916 assert g == [l[0]], g
917 assert isinstance(l[1], SCons.Action.CommandAction), l[1]
918 g = l[1].get_actions()
919 assert g == [l[1]], g
921 def test_execute(self):
922 """Test executing a list of subsidiary Actions
925 def f(target,source,env):
928 a = SCons.Action.ListAction([f, f, f])
929 a([], [], Environment(s = self))
930 assert self.inc == 3, self.inc
932 cmd2 = r'%s %s %s syzygy' % (python, act_py, outfile)
934 def function2(target, source, env):
935 open(env['out'], 'a').write("function2\n")
939 def __call__(self, target, source, env):
940 open(env['out'], 'a').write("class2a\n")
944 def __init__(self, target, source, env):
945 open(env['out'], 'a').write("class2b\n")
946 act = SCons.Action.ListAction([cmd2, function2, class2a(), class2b])
947 r = act([], [], Environment(out = outfile))
948 assert r.__class__ == class2b
949 c = test.read(outfile, 'r')
950 assert c == "act.py: 'syzygy'\nfunction2\nclass2a\nclass2b\n", c
952 def test_get_contents(self):
953 """Test fetching the contents of a list of subsidiary Actions
956 def gen(target, source, env, for_signature):
960 a = SCons.Action.ListAction(["x",
961 SCons.Action.CommandGenerator(gen),
963 c = a.get_contents(target=[], source=[], env=Environment(s = self))
964 assert self.foo==1, self.foo
967 class LazyActionTestCase(unittest.TestCase):
969 """Test creation of a lazy-evaluation Action
971 # Environment variable references should create a special
972 # type of CommandGeneratorAction that lazily evaluates the
974 a9 = SCons.Action.Action('$FOO')
975 assert isinstance(a9, SCons.Action.CommandGeneratorAction), a9
976 assert a9.generator.var == 'FOO', a9.generator.var
978 a10 = SCons.Action.Action('${FOO}')
979 assert isinstance(a9, SCons.Action.CommandGeneratorAction), a10
980 assert a10.generator.var == 'FOO', a10.generator.var
982 def test_execute(self):
983 """Test executing a lazy-evaluation Action
985 def f(target, source, env):
989 a = SCons.Action.Action('$BAR')
990 a([], [], env=Environment(BAR = f, s = self))
991 assert self.test == 1, self.test
993 def test_get_contents(self):
994 """Test fetching the contents of a lazy-evaluation Action
996 a = SCons.Action.Action("${FOO}")
997 c = a.get_contents(target=[], source=[],
998 env = Environment(FOO = [["This", "is", "$(", "$a", "$)", "test"]]))
999 assert c == "This is test", c
1002 if __name__ == "__main__":
1003 suite = unittest.TestSuite()
1004 tclasses = [ ActionTestCase,
1006 CommandActionTestCase,
1007 CommandGeneratorActionTestCase,
1008 FunctionActionTestCase,
1010 LazyActionTestCase ]
1011 for tclass in tclasses:
1012 names = unittest.getTestCaseNames(tclass, 'test_')
1013 suite.addTests(map(tclass, names))
1014 if not unittest.TextTestRunner().run(suite).wasSuccessful():