File: test_Tutorial.py

package info (click to toggle)
python-biopython 1.59-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 32,800 kB
  • sloc: python: 116,625; xml: 39,183; ansic: 8,824; sql: 1,488; makefile: 151
file content (130 lines) | stat: -rw-r--r-- 4,557 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import unittest
import doctest
import os
import sys

if sys.version_info[0] >= 3:
    from lib2to3 import refactor
    rt = refactor.RefactoringTool(refactor.get_fixers_from_package("lib2to3.fixes"))
    assert rt.refactor_docstring(">>> print 2+2\n4\n", "example") == \
           ">>> print(2+2)\n4\n"
    
tutorial = os.path.join(os.path.dirname(sys.argv[0]), "../Doc/Tutorial.tex")
tutorial_base = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../Doc/"))
original_path = os.path.abspath(".")

def _extract(handle):
    line = handle.readline()
    if line != "\\begin{verbatim}\n":
        raise ValueError("Any '%doctest' or '%cont-doctest' line should be followed by '\\begin{verbatim}'")
    lines = []
    while True:
        line = handle.readline()
        if not line:
            if lines:
                print "".join(lines[:30])
                raise ValueError("Didn't find end of test starting: %r", lines[0])
            else:
                raise ValueError("Didn't find end of test!")
        elif line.startswith("\end{verbatim}"):
            break
        else:
            lines.append(line)
    return lines
    
def extract_doctests(latex_filename):
    """Scans LaTeX file and pulls out marked doctests as strings."""
    handle = open(latex_filename, "rU")
    line_number = 0
    in_test = False
    lines = []
    while True:
        line = handle.readline()
        line_number += 1
        if not line:
            #End of file
            break
        elif line.startswith("%cont-doctest"):
            x = _extract(handle)
            lines.extend(x)
            line_number += len(x) + 2
        elif line.startswith("%doctest"):
            if lines:
                if not lines[0].startswith(">>> "):
                    raise ValueError("Should start '>>> ' not %r" % lines[0])
                yield name, "".join(lines), folder
                lines = []
            try:
                folder = line.split(None,1)[1].strip()
            except:
                folder = ""
            name = "test_from_line_%05i" % line_number
            x = _extract(handle)
            lines.extend(x)
            line_number += len(x) + 2
    handle.close()
    if lines:
        if not lines[0].startswith(">>> "):
            raise ValueError("Should start '>>> ' not %r" % lines[0])
        yield name, "".join(lines), folder
    #yield "dummy", ">>> 2 + 2\n5\n"

class TutorialDocTestHolder(object):
    """Python doctests extracted from the Biopython Tutorial."""
    pass


#Create dummy methods on the object purely to hold doctests
for name, example, folder in extract_doctests(tutorial):
    if sys.version_info[0] >= 3:
        example = rt.refactor_docstring(example, name)
    def funct(n, d, f):
        global tutorial_base
        method = lambda x : None
        if f:
            p = os.path.join(tutorial_base, f)
            method.__doc__ = "%s\n\n>>> import os\n>>> os.chdir(%r)\n%s\n" \
                           % (n, p, d)
        else:
            method.__doc__ = "%s\n\n%s\n" % (n, d)
        method._folder = f
        return method
    setattr(TutorialDocTestHolder,
            "doctest_%s" % name.replace(" ","_"),
            funct(name, example, folder))
    del funct


#This is a TestCase class so it is found by run_tests.py
class TutorialTestCase(unittest.TestCase):
    """Python doctests extracted from the Biopython Tutorial."""
    #Single method to be invoked by run_tests.py
    def test_doctests(self):
        """Run tutorial doctests."""
        runner = doctest.DocTestRunner()
        failures = []
        for test in doctest.DocTestFinder().find(TutorialDocTestHolder):
            failed, success = runner.run(test)
            if failed:
                name = test.name
                assert name.startswith("TutorialDocTestHolder.doctest_")
                failures.append(name[30:])
                #raise ValueError("Tutorial doctest %s failed" % test.name[30:])
        if failures:
            raise ValueError("%i Tutorial doctests failed: %s" % \
                             (len(failures), ", ".join(failures)))

    def tearDown(self):
        global original_path
        os.chdir(original_path)


#This is to run the doctests if the script is called directly:
if __name__ == "__main__":
    print "Runing Tutorial doctests..."
    import doctest
    tests = doctest.testmod()
    if tests[0]:
        #Note on Python 2.5+ can use tests.failed rather than tests[0]
        raise RuntimeError("%i/%i tests failed" % tests)
    print "Tests done"