~testdoc-dev/testdoc/trunk.git

« back to all changes in this revision

Viewing changes to testdoc/__init__.py

  • Committer: jml@canonical.com
  • Date: 2007-03-25 09:47:54 UTC
  • Revision ID: git-v1:efaa91a66979f582c7692974477fb9b0716ba2d7
First draft after a day of hacking on a crazy python test -> doc tool.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import inspect
 
2
import re
 
3
 
 
4
from twisted.trial.runner import TestLoader
 
5
 
 
6
def split_name(name):
 
7
    bits = name.split('_')
 
8
    if len(bits) > 2:
 
9
        return bits
 
10
    return list(gen_split_name(name))
 
11
    names = []
 
12
    for word in bits:
 
13
        names.extend(
 
14
            [bit.lower() for bit in wordRE.findall(word) if len(bit) != 0])
 
15
    return names
 
16
 
 
17
 
 
18
def gen_split_name(name,
 
19
                   wordRE=re.compile(
 
20
                       r'[0-9]+|[A-Z]?(?:(?:[A-Z](?![a-z]))+|[a-z]*)')):
 
21
    for word in name.split('_'):
 
22
        for bit in wordRE.findall(word):
 
23
            if len(bit) == 0:
 
24
                continue
 
25
            if len(bit) > 1 and bit.upper() == bit:
 
26
                yield bit
 
27
            else:
 
28
                yield bit.lower()
 
29
 
 
30
 
 
31
def get_lineno(obj):
 
32
    return inspect.getsourcelines(obj)[1]
 
33
 
 
34
 
 
35
def find_tests(finder, module):
 
36
    loader = TestLoader()
 
37
    finder.gotModule(module)
 
38
    classes = sorted(loader.findTestClasses(module), key=get_lineno)
 
39
    for testCaseClass in classes:
 
40
        finder.gotTestClass(testCaseClass)
 
41
        methods = [getattr(testCaseClass, 'test%s' % name)
 
42
                   for name in loader.getTestCaseNames(testCaseClass)]
 
43
        for method in sorted(methods, key=get_lineno):
 
44
            finder.gotTest(method)
 
45
 
 
46
 
 
47
class Documenter(object):
 
48
 
 
49
    def __init__(self, formatter):
 
50
        self.formatter = formatter
 
51
 
 
52
    def titleCase(self, words):
 
53
        titled = []
 
54
        for word in words:
 
55
            if word.lower() in ['in', 'a', 'the', 'of']:
 
56
                titled.append(word.lower())
 
57
            elif word.upper() == word:
 
58
                titled.append(word)
 
59
            else:
 
60
                titled.append(word.capitalize())
 
61
        titled = ' '.join(titled)
 
62
        return titled[0].upper() + titled[1:]
 
63
 
 
64
    def getDocs(self, obj):
 
65
        doc = inspect.getdoc(obj)
 
66
        if doc is None:
 
67
            doc = inspect.getcomments(obj)
 
68
        return doc
 
69
 
 
70
    def gotModule(self, module):
 
71
        self.formatter.title(module.__name__)
 
72
        docs = self.getDocs(module)
 
73
        if docs is not None:
 
74
            self.formatter.paragraph(docs)
 
75
 
 
76
    def gotTestClass(self, klass):
 
77
        self.formatter.section(self.titleCase(
 
78
                [bit for bit in split_name(klass.__name__) if bit != 'test']))
 
79
        docs = self.getDocs(klass)
 
80
        if docs is not None:
 
81
            self.formatter.paragraph(docs)
 
82
 
 
83
    def gotTest(self, method):
 
84
        self.formatter.subsection(
 
85
            self.titleCase(split_name(method.__name__)[1:]))
 
86
        docs = self.getDocs(method)
 
87
        if docs is not None:
 
88
            self.formatter.paragraph(docs)
 
89
 
 
90
 
 
91
class WikiFormatter(object):
 
92
    def __init__(self, stream):
 
93
        self.stream = stream
 
94
 
 
95
    def writeln(self, line):
 
96
        self.stream.write('%s\n' % (line,))
 
97
 
 
98
    def title(self, name):
 
99
        self.writeln('= %s =\n' % (name,))
 
100
 
 
101
    def section(self, name):
 
102
        self.writeln('== %s ==\n' % (name,))
 
103
 
 
104
    def subsection(self, name):
 
105
        self.writeln('=== %s ===\n' % (name,))
 
106
 
 
107
    def paragraph(self, text):
 
108
        self.writeln('%s\n' % (text.strip(),))
 
109
 
 
110
 
 
111
if __name__ == '__main__':
 
112
    import sys
 
113
    from twisted.python.reflect import namedAny
 
114
    formatter = WikiFormatter(sys.stdout)
 
115
    documenter = Documenter(formatter)
 
116
    find_tests(documenter, namedAny(sys.argv[1]))