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__"
33 from UserDict import UserDict
39 from SCons.Util import *
46 self.buffer = self.buffer + str
48 class dictifyTestCase(unittest.TestCase):
49 def test_dictify(self):
50 """Test the dictify() function"""
51 r = SCons.Util.dictify(['a', 'b', 'c'], [1, 2, 3])
52 assert r == {'a':1, 'b':2, 'c':3}, r
55 SCons.Util.dictify(['a'], [1], r)
56 SCons.Util.dictify(['b'], [2], r)
57 SCons.Util.dictify(['c'], [3], r)
58 assert r == {'a':1, 'b':2, 'c':3}, r
60 class UtilTestCase(unittest.TestCase):
61 def test_splitext(self):
62 assert splitext('foo') == ('foo','')
63 assert splitext('foo.bar') == ('foo','.bar')
64 assert splitext(os.path.join('foo.bar', 'blat')) == (os.path.join('foo.bar', 'blat'),'')
67 def __init__(self, name, children=[]):
68 self.children = children
77 def has_builder(self):
79 def has_explicit_builder(self):
81 def side_effect(self):
85 def always_build(self):
87 def is_up_to_date(self):
92 def tree_case_1(self):
93 """Fixture for the render_tree() and print_tree() tests."""
94 windows_h = self.Node("windows.h")
95 stdlib_h = self.Node("stdlib.h")
96 stdio_h = self.Node("stdio.h")
97 bar_c = self.Node("bar.c", [stdlib_h, windows_h])
98 bar_o = self.Node("bar.o", [bar_c])
99 foo_c = self.Node("foo.c", [stdio_h])
100 foo_o = self.Node("foo.o", [foo_c])
101 foo = self.Node("foo", [foo_o, bar_o])
114 lines = expect.split('\n')[:-1]
115 lines = ['[E BSPACN ]'+l for l in lines]
116 withtags = '\n'.join(lines) + '\n'
118 return foo, expect, withtags
120 def tree_case_2(self, prune=1):
121 """Fixture for the render_tree() and print_tree() tests."""
123 stdlib_h = self.Node("stdlib.h")
124 bar_h = self.Node('bar.h', [stdlib_h])
125 blat_h = self.Node('blat.h', [stdlib_h])
126 blat_c = self.Node('blat.c', [blat_h, bar_h])
127 blat_o = self.Node('blat.o', [blat_c])
139 expect = expect.replace('[', '')
140 expect = expect.replace(']', '')
142 lines = expect.split('\n')[:-1]
143 lines = ['[E BSPACN ]'+l for l in lines]
144 withtags = '\n'.join(lines) + '\n'
146 return blat_o, expect, withtags
148 def test_render_tree(self):
149 """Test the render_tree() function"""
150 def get_children(node):
153 node, expect, withtags = self.tree_case_1()
154 actual = render_tree(node, get_children)
155 assert expect == actual, (expect, actual)
157 node, expect, withtags = self.tree_case_2()
158 actual = render_tree(node, get_children, 1)
159 assert expect == actual, (expect, actual)
161 def test_print_tree(self):
162 """Test the print_tree() function"""
163 def get_children(node):
166 save_stdout = sys.stdout
169 node, expect, withtags = self.tree_case_1()
171 sys.stdout = StringIO.StringIO()
172 print_tree(node, get_children)
173 actual = sys.stdout.getvalue()
174 assert expect == actual, (expect, actual)
176 sys.stdout = StringIO.StringIO()
177 print_tree(node, get_children, showtags=1)
178 actual = sys.stdout.getvalue()
179 assert withtags == actual, (withtags, actual)
181 node, expect, withtags = self.tree_case_2(prune=0)
183 sys.stdout = StringIO.StringIO()
184 print_tree(node, get_children, 1)
185 actual = sys.stdout.getvalue()
186 assert expect == actual, (expect, actual)
188 sys.stdout = StringIO.StringIO()
189 # The following call should work here:
190 # print_tree(node, get_children, 1, showtags=1)
191 # For some reason I don't understand, though, *this*
192 # time that we call print_tree, the visited dictionary
193 # is still populated with the values from the last call!
194 # I can't see why this would be, short of a bug in Python,
195 # and rather than continue banging my head against the
196 # brick wall for a *test*, we're going to going with
197 # the cheap, easy workaround:
198 print_tree(node, get_children, 1, showtags=1, visited={})
199 actual = sys.stdout.getvalue()
200 assert withtags == actual, (withtags, actual)
202 sys.stdout = save_stdout
204 def test_is_Dict(self):
206 assert is_Dict(UserDict())
213 assert is_Dict(mydict({}))
214 assert not is_Dict([])
215 assert not is_Dict(())
216 assert not is_Dict("")
217 if hasattr(types, 'UnicodeType'):
218 exec "assert not is_Dict(u'')"
220 def test_is_List(self):
223 assert is_List(UserList.UserList())
230 assert is_List(mylist([]))
231 assert not is_List(())
232 assert not is_List({})
233 assert not is_List("")
234 if hasattr(types, 'UnicodeType'):
235 exec "assert not is_List(u'')"
237 def test_is_String(self):
239 if hasattr(types, 'UnicodeType'):
240 exec "assert is_String(u'')"
246 assert is_String(UserString.UserString(''))
253 assert is_String(mystr(''))
254 assert not is_String({})
255 assert not is_String([])
256 assert not is_String(())
258 def test_is_Tuple(self):
261 class mytuple(tuple):
266 assert is_Tuple(mytuple(()))
267 assert not is_Tuple([])
268 assert not is_Tuple({})
269 assert not is_Tuple("")
270 if hasattr(types, 'UnicodeType'):
271 exec "assert not is_Tuple(u'')"
273 def test_to_String(self):
274 """Test the to_String() method."""
275 assert to_String(1) == "1", to_String(1)
276 assert to_String([ 1, 2, 3]) == str([1, 2, 3]), to_String([1,2,3])
277 assert to_String("foo") == "foo", to_String("foo")
282 s1=UserString.UserString('blah')
283 assert to_String(s1) == s1, s1
284 assert to_String(s1) == 'blah', s1
286 class Derived(UserString.UserString):
289 assert to_String(s2) == s2, s2
290 assert to_String(s2) == 'foo', s2
292 if hasattr(types, 'UnicodeType'):
293 s3=UserString.UserString(unicode('bar'))
294 assert to_String(s3) == s3, s3
295 assert to_String(s3) == unicode('bar'), s3
296 assert type(to_String(s3)) is types.UnicodeType, \
301 if hasattr(types, 'UnicodeType'):
303 assert to_String(s4) == unicode('baz'), to_String(s4)
304 assert type(to_String(s4)) is types.UnicodeType, \
307 def test_WhereIs(self):
308 test = TestCmd.TestCmd(workdir = '')
310 sub1_xxx_exe = test.workpath('sub1', 'xxx.exe')
311 sub2_xxx_exe = test.workpath('sub2', 'xxx.exe')
312 sub3_xxx_exe = test.workpath('sub3', 'xxx.exe')
313 sub4_xxx_exe = test.workpath('sub4', 'xxx.exe')
315 test.subdir('subdir', 'sub1', 'sub2', 'sub3', 'sub4')
317 if sys.platform != 'win32':
318 test.write(sub1_xxx_exe, "\n")
320 os.mkdir(sub2_xxx_exe)
322 test.write(sub3_xxx_exe, "\n")
323 os.chmod(sub3_xxx_exe, 0777)
325 test.write(sub4_xxx_exe, "\n")
326 os.chmod(sub4_xxx_exe, 0777)
328 env_path = os.environ['PATH']
331 pathdirs_1234 = [ test.workpath('sub1'),
332 test.workpath('sub2'),
333 test.workpath('sub3'),
334 test.workpath('sub4'),
335 ] + env_path.split(os.pathsep)
337 pathdirs_1243 = [ test.workpath('sub1'),
338 test.workpath('sub2'),
339 test.workpath('sub4'),
340 test.workpath('sub3'),
341 ] + env_path.split(os.pathsep)
343 os.environ['PATH'] = os.pathsep.join(pathdirs_1234)
344 wi = WhereIs('xxx.exe')
345 assert wi == test.workpath(sub3_xxx_exe), wi
346 wi = WhereIs('xxx.exe', pathdirs_1243)
347 assert wi == test.workpath(sub4_xxx_exe), wi
348 wi = WhereIs('xxx.exe', os.pathsep.join(pathdirs_1243))
349 assert wi == test.workpath(sub4_xxx_exe), wi
351 wi = WhereIs('xxx.exe',reject = sub3_xxx_exe)
352 assert wi == test.workpath(sub4_xxx_exe), wi
353 wi = WhereIs('xxx.exe', pathdirs_1243, reject = sub3_xxx_exe)
354 assert wi == test.workpath(sub4_xxx_exe), wi
356 os.environ['PATH'] = os.pathsep.join(pathdirs_1243)
357 wi = WhereIs('xxx.exe')
358 assert wi == test.workpath(sub4_xxx_exe), wi
359 wi = WhereIs('xxx.exe', pathdirs_1234)
360 assert wi == test.workpath(sub3_xxx_exe), wi
361 wi = WhereIs('xxx.exe', os.pathsep.join(pathdirs_1234))
362 assert wi == test.workpath(sub3_xxx_exe), wi
364 if sys.platform == 'win32':
365 wi = WhereIs('xxx', pathext = '')
366 assert wi is None, wi
368 wi = WhereIs('xxx', pathext = '.exe')
369 assert wi == test.workpath(sub4_xxx_exe), wi
371 wi = WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
372 assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
374 # Test that we return a normalized path even when
375 # the path contains forward slashes.
376 forward_slash = test.workpath('') + '/sub3'
377 wi = WhereIs('xxx', path = forward_slash, pathext = '.EXE')
378 assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
380 del os.environ['PATH']
381 wi = WhereIs('xxx.exe')
382 assert wi is None, wi
385 os.environ['PATH'] = env_path
387 def test_get_env_var(self):
388 """Testing get_environment_var()."""
389 assert get_environment_var("$FOO") == "FOO", get_environment_var("$FOO")
390 assert get_environment_var("${BAR}") == "BAR", get_environment_var("${BAR}")
391 assert get_environment_var("$FOO_BAR1234") == "FOO_BAR1234", get_environment_var("$FOO_BAR1234")
392 assert get_environment_var("${BAR_FOO1234}") == "BAR_FOO1234", get_environment_var("${BAR_FOO1234}")
393 assert get_environment_var("${BAR}FOO") == None, get_environment_var("${BAR}FOO")
394 assert get_environment_var("$BAR ") == None, get_environment_var("$BAR ")
395 assert get_environment_var("FOO$BAR") == None, get_environment_var("FOO$BAR")
396 assert get_environment_var("$FOO[0]") == None, get_environment_var("$FOO[0]")
397 assert get_environment_var("${some('complex expression')}") == None, get_environment_var("${some('complex expression')}")
399 def test_Proxy(self):
400 """Test generic Proxy class."""
410 class ProxyTest(Proxy):
416 assert p.foo() == 1, p.foo()
417 assert p.bar() == 4, p.bar()
418 assert p.baz == 3, p.baz
423 assert p.baz == 5, p.baz
424 assert p.get() == s, p.get()
426 def test_display(self):
427 old_stdout = sys.stdout
428 sys.stdout = OutBuffer()
434 display("line4\n", append_newline=0)
436 display("dont print1")
437 display("dont print2\n", append_newline=0)
439 assert sys.stdout.buffer == "line1\nline3\nline4\n"
440 sys.stdout = old_stdout
442 def test_get_native_path(self):
443 """Test the get_native_path() function."""
445 filename = tempfile.mktemp()
446 str = '1234567890 ' + filename
448 open(filename, 'w').write(str)
449 assert open(get_native_path(filename)).read() == str
456 def test_PrependPath(self):
457 """Test prepending to a path"""
458 p1 = r'C:\dir\num\one;C:\dir\num\two'
459 p2 = r'C:\mydir\num\one;C:\mydir\num\two'
460 # have to include the pathsep here so that the test will work on UNIX too.
461 p1 = PrependPath(p1,r'C:\dir\num\two',sep = ';')
462 p1 = PrependPath(p1,r'C:\dir\num\three',sep = ';')
463 p2 = PrependPath(p2,r'C:\mydir\num\three',sep = ';')
464 p2 = PrependPath(p2,r'C:\mydir\num\one',sep = ';')
465 assert(p1 == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
466 assert(p2 == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
468 def test_AppendPath(self):
469 """Test appending to a path."""
470 p1 = r'C:\dir\num\one;C:\dir\num\two'
471 p2 = r'C:\mydir\num\one;C:\mydir\num\two'
472 # have to include the pathsep here so that the test will work on UNIX too.
473 p1 = AppendPath(p1,r'C:\dir\num\two',sep = ';')
474 p1 = AppendPath(p1,r'C:\dir\num\three',sep = ';')
475 p2 = AppendPath(p2,r'C:\mydir\num\three',sep = ';')
476 p2 = AppendPath(p2,r'C:\mydir\num\one',sep = ';')
477 assert(p1 == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
478 assert(p2 == r'C:\mydir\num\two;C:\mydir\num\three;C:\mydir\num\one')
480 def test_PrependPathPreserveOld(self):
481 """Test prepending to a path while preserving old paths"""
482 p1 = r'C:\dir\num\one;C:\dir\num\two'
483 # have to include the pathsep here so that the test will work on UNIX too.
484 p1 = PrependPath(p1,r'C:\dir\num\two',sep = ';', delete_existing=0)
485 p1 = PrependPath(p1,r'C:\dir\num\three',sep = ';')
486 assert(p1 == r'C:\dir\num\three;C:\dir\num\one;C:\dir\num\two')
488 def test_AppendPathPreserveOld(self):
489 """Test appending to a path while preserving old paths"""
490 p1 = r'C:\dir\num\one;C:\dir\num\two'
491 # have to include the pathsep here so that the test will work on UNIX too.
492 p1 = AppendPath(p1,r'C:\dir\num\one',sep = ';', delete_existing=0)
493 p1 = AppendPath(p1,r'C:\dir\num\three',sep = ';')
494 assert(p1 == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
496 def test_CLVar(self):
497 """Test the command-line construction variable class"""
498 f = SCons.Util.CLVar('a b')
501 assert isinstance(r, SCons.Util.CLVar), type(r)
502 assert r.data == ['a', 'b', 'c', 'd'], r.data
503 assert str(r) == 'a b c d', str(r)
506 assert isinstance(r, SCons.Util.CLVar), type(r)
507 assert r.data == ['a', 'b', 'c', 'd'], r.data
508 assert str(r) == 'a b c d', str(r)
511 assert isinstance(r, SCons.Util.CLVar), type(r)
512 assert r.data == ['a', 'b', 'c d'], r.data
513 assert str(r) == 'a b c d', str(r)
516 assert isinstance(r, SCons.Util.CLVar), type(r)
517 assert r.data == ['a', 'b', ' c d'], r.data
518 assert str(r) == 'a b c d', str(r)
521 assert isinstance(r, SCons.Util.CLVar), type(r)
522 assert r.data == ['a', 'b', 'c', 'd'], r.data
523 assert str(r) == 'a b c d', str(r)
526 assert isinstance(r, SCons.Util.CLVar), type(r)
527 assert r.data == ['a', 'b', ' c', 'd'], r.data
528 assert str(r) == 'a b c d', str(r)
530 f = SCons.Util.CLVar(['a b'])
533 assert isinstance(r, SCons.Util.CLVar), type(r)
534 assert r.data == ['a b', 'c', 'd'], r.data
535 assert str(r) == 'a b c d', str(r)
538 assert isinstance(r, SCons.Util.CLVar), type(r)
539 assert r.data == ['a b', 'c', 'd'], r.data
540 assert str(r) == 'a b c d', str(r)
543 assert isinstance(r, SCons.Util.CLVar), type(r)
544 assert r.data == ['a b', 'c d'], r.data
545 assert str(r) == 'a b c d', str(r)
548 assert isinstance(r, SCons.Util.CLVar), type(r)
549 assert r.data == ['a b', ' c d'], r.data
550 assert str(r) == 'a b c d', str(r)
553 assert isinstance(r, SCons.Util.CLVar), type(r)
554 assert r.data == ['a b', 'c', 'd'], r.data
555 assert str(r) == 'a b c d', str(r)
558 assert isinstance(r, SCons.Util.CLVar), type(r)
559 assert r.data == ['a b', ' c', 'd'], r.data
560 assert str(r) == 'a b c d', str(r)
562 f = SCons.Util.CLVar(['a', 'b'])
565 assert isinstance(r, SCons.Util.CLVar), type(r)
566 assert r.data == ['a', 'b', 'c', 'd'], r.data
567 assert str(r) == 'a b c d', str(r)
570 assert isinstance(r, SCons.Util.CLVar), type(r)
571 assert r.data == ['a', 'b', 'c', 'd'], r.data
572 assert str(r) == 'a b c d', str(r)
575 assert isinstance(r, SCons.Util.CLVar), type(r)
576 assert r.data == ['a', 'b', 'c d'], r.data
577 assert str(r) == 'a b c d', str(r)
580 assert isinstance(r, SCons.Util.CLVar), type(r)
581 assert r.data == ['a', 'b', ' c d'], r.data
582 assert str(r) == 'a b c d', str(r)
585 assert isinstance(r, SCons.Util.CLVar), type(r)
586 assert r.data == ['a', 'b', 'c', 'd'], r.data
587 assert str(r) == 'a b c d', str(r)
590 assert isinstance(r, SCons.Util.CLVar), type(r)
591 assert r.data == ['a', 'b', ' c', 'd'], r.data
592 assert str(r) == 'a b c d', str(r)
594 def test_Selector(self):
595 """Test the Selector class"""
598 def __init__(self, name):
600 self.suffix = os.path.splitext(name)[1]
605 s = Selector({'a' : 'AAA', 'b' : 'BBB'})
606 assert s['a'] == 'AAA', s['a']
607 assert s['b'] == 'BBB', s['b']
613 assert exc_caught, "should have caught a KeyError"
615 assert s['c'] == 'CCC', s['c']
617 class DummyEnv(UserDict):
618 def subst(self, key):
625 s = Selector({'.d' : 'DDD', '.e' : 'EEE'})
627 assert ret is None, ret
628 ret = s(env, [MyNode('foo.d')])
629 assert ret == 'DDD', ret
630 ret = s(env, [MyNode('bar.e')])
631 assert ret == 'EEE', ret
632 ret = s(env, [MyNode('bar.x')])
633 assert ret is None, ret
635 ret = s(env, [MyNode('bar.x')])
636 assert ret == 'XXX', ret
638 env = DummyEnv({'FSUFF' : '.f', 'GSUFF' : '.g'})
640 s = Selector({'$FSUFF' : 'FFF', '$GSUFF' : 'GGG'})
641 ret = s(env, [MyNode('foo.f')])
642 assert ret == 'FFF', ret
643 ret = s(env, [MyNode('bar.g')])
644 assert ret == 'GGG', ret
646 def test_adjustixes(self):
647 """Test the adjustixes() function"""
648 r = adjustixes('file', 'pre-', '-suf')
649 assert r == 'pre-file-suf', r
650 r = adjustixes('pre-file', 'pre-', '-suf')
651 assert r == 'pre-file-suf', r
652 r = adjustixes('file-suf', 'pre-', '-suf')
653 assert r == 'pre-file-suf', r
654 r = adjustixes('pre-file-suf', 'pre-', '-suf')
655 assert r == 'pre-file-suf', r
656 r = adjustixes('pre-file.xxx', 'pre-', '-suf')
657 assert r == 'pre-file.xxx', r
658 r = adjustixes('dir/file', 'pre-', '-suf')
659 assert r == os.path.join('dir', 'pre-file-suf'), r
661 def test_containsAny(self):
662 """Test the containsAny() function"""
663 assert containsAny('*.py', '*?[]')
664 assert not containsAny('file.txt', '*?[]')
666 def test_containsAll(self):
667 """Test the containsAll() function"""
668 assert containsAll('43221', '123')
669 assert not containsAll('134', '123')
671 def test_containsOnly(self):
672 """Test the containsOnly() function"""
673 assert containsOnly('.83', '0123456789.')
674 assert not containsOnly('43221', '123')
676 def test_LogicalLines(self):
677 """Test the LogicalLines class"""
678 fobj = StringIO.StringIO(r"""
688 lines = LogicalLines(fobj).readlines()
693 'bling bling \\ bling\n',
697 def test_intern(self):
698 s1 = silent_intern("spam")
699 # Python 1.5 and 3.x do not have a unicode() built-in
700 if sys.version[0] == '2':
701 s2 = silent_intern(unicode("unicode spam"))
702 s3 = silent_intern(42)
703 s4 = silent_intern("spam")
704 assert id(s1) == id(s4)
707 class MD5TestCase(unittest.TestCase):
709 def test_collect(self):
710 """Test collecting a list of signatures into a new signature value
712 s = list(map(MD5signature, ('111', '222', '333')))
714 assert '698d51a19d8a121ce581499d7b701668' == MD5collect(s[0:1])
715 assert '8980c988edc2c78cc43ccb718c06efd5' == MD5collect(s[0:2])
716 assert '53fd88c84ff8a285eb6e0a687e55b8c7' == MD5collect(s)
718 def test_MD5signature(self):
719 """Test generating a signature"""
720 s = MD5signature('111')
721 assert '698d51a19d8a121ce581499d7b701668' == s, s
723 s = MD5signature('222')
724 assert 'bcbe3365e6ac95ea2c0343a2395834dd' == s, s
726 class NodeListTestCase(unittest.TestCase):
727 def test_simple_attributes(self):
728 """Test simple attributes of a NodeList class"""
730 def __init__(self, name, child=None):
734 t1 = TestClass('t1', TestClass('t1child'))
735 t2 = TestClass('t2', TestClass('t2child'))
738 nl = NodeList([t1, t2, t3])
739 assert nl.bar == [ 't1', 't2', 't3' ], nl.bar
740 assert nl[0:2].child.bar == [ 't1child', 't2child' ], \
743 def test_callable_attributes(self):
744 """Test callable attributes of a NodeList class"""
746 def __init__(self, name, child=None):
750 return self.bar + "foo"
754 t1 = TestClass('t1', TestClass('t1child'))
755 t2 = TestClass('t2', TestClass('t2child'))
758 nl = NodeList([t1, t2, t3])
759 assert nl.foo() == [ 't1foo', 't2foo', 't3foo' ], nl.foo()
760 assert nl.bar == [ 't1', 't2', 't3' ], nl.bar
761 assert nl.getself().bar == [ 't1', 't2', 't3' ], nl.getself().bar
762 assert nl[0:2].child.foo() == [ 't1childfoo', 't2childfoo' ], \
764 assert nl[0:2].child.bar == [ 't1child', 't2child' ], \
768 """Test a null NodeList"""
773 raise Exception, "should not enter this loop"
776 class flattenTestCase(unittest.TestCase):
778 def test_scalar(self):
779 """Test flattening a scalar"""
780 result = flatten('xyz')
781 assert result == ['xyz'], result
783 if __name__ == "__main__":
784 suite = unittest.TestSuite()
785 tclasses = [ dictifyTestCase,
791 for tclass in tclasses:
792 names = unittest.getTestCaseNames(tclass, 'test_')
793 suite.addTests(list(map(tclass, names)))
794 if not unittest.TextTestRunner().run(suite).wasSuccessful():
799 # indent-tabs-mode:nil
801 # vim: set expandtab tabstop=4 shiftwidth=4: