Merged clarifications requested by Ben Finney
[be.git] / test.py
1 # Copyright (C) 2005-2010 Aaron Bentley and Panometrics, Inc.
2 #                         Marien Zwart <marienz@gentoo.org>
3 #                         W. Trevor King <wking@drexel.edu>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
19 import doctest
20 import os
21 import os.path
22 import sys
23 import unittest
24
25 import libbe
26 libbe.TESTING = True
27 from libbe.util.tree import Tree
28 from libbe.util.plugin import import_by_name
29
30 def python_tree(root_path='libbe', root_modname='libbe'):
31     tree = Tree()
32     tree.path = root_path
33     tree.parent = None
34     stack = [tree]
35     while len(stack) > 0:
36         f = stack.pop(0)
37         if f.path.endswith('.py'):
38             f.name = os.path.basename(f.path)[:-len('.py')]
39         elif os.path.isdir(f.path) \
40                 and os.path.exists(os.path.join(f.path, '__init__.py')):
41             f.name = os.path.basename(f.path)
42             f.is_module = True
43             for child in os.listdir(f.path):
44                 if child == '__init__.py':
45                     continue
46                 c = Tree()
47                 c.path = os.path.join(f.path, child)
48                 c.parent = f
49                 stack.append(c)
50         else:
51             continue
52         if f.parent == None:
53             f.modname = root_modname
54         else:
55             f.modname = f.parent.modname + '.' + f.name
56             f.parent.append(f)
57     return tree
58
59 def add_module_tests(suite, modname):
60     try:
61         mod = import_by_name(modname)
62     except ValueError, e:
63         print >> sys.stderr, 'Failed to import "%s"' % (modname)
64         raise e
65     if hasattr(mod, 'suite'):
66         s = mod.suite
67     else:
68         s = unittest.TestLoader().loadTestsFromModule(mod)
69         try:
70             sdoc = doctest.DocTestSuite(mod)
71             suite.addTest(sdoc)
72         except ValueError:
73             pass
74     suite.addTest(s)
75
76 if __name__ == '__main__':
77     import optparse
78     parser = optparse.OptionParser(usage='%prog [options] [modules ...]',
79                                    description=
80 """When called without optional module names, run the test suites for
81 *all* modules.  This may raise lots of errors if you haven't installed
82 one of the versioning control systems.
83
84 When called with module name arguments, only run the test suites from
85 those modules and their submodules.  For example::
86
87     $ python test.py libbe.bugdir libbe.storage
88 """)
89     parser.add_option('-q', '--quiet', action='store_true', default=False,
90                       help='Run unittests in quiet mode (verbosity 1).')
91     options,args = parser.parse_args()
92
93     verbosity = 2
94     if options.quiet == True:
95         verbosity = 1
96
97     suite = unittest.TestSuite()
98     tree = python_tree()
99     if len(args) == 0:
100         for node in tree.traverse():
101             add_module_tests(suite, node.modname)
102     else:
103         added = []
104         for modname in args:
105             for node in tree.traverse():
106                 if node.modname == modname:
107                     for n in node.traverse():
108                         if n.modname not in added:
109                             add_module_tests(suite, n.modname)
110                             added.append(n.modname)
111                     break
112     
113     result = unittest.TextTestRunner(verbosity=verbosity).run(suite)
114     
115     numErrors = len(result.errors)
116     numFailures = len(result.failures)
117     numBad = numErrors + numFailures
118     if numBad > 126:
119         numBad = 1
120     sys.exit(numBad)