File: test_doctest.py

package info (click to toggle)
orange3 3.40.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 15,912 kB
  • sloc: python: 162,745; ansic: 622; makefile: 322; sh: 93; cpp: 77
file content (72 lines) | stat: -rw-r--r-- 2,447 bytes parent folder | download | duplicates (3)
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
import sys
import os
from doctest import DocTestSuite, ELLIPSIS, NORMALIZE_WHITESPACE

SKIP_DIRS = (
    # Skip modules which import and initialize stuff that require QApplication
    'Orange/widgets',
    'Orange/canvas',
    # Skip because we don't want Orange.datasets as a module (yet)
    'Orange/datasets/'
)

if sys.platform == "win32":
    # convert to platform native path component separators
    SKIP_DIRS = tuple(os.path.normpath(p) for p in SKIP_DIRS)


def find_modules(package):
    """Return a recursive list of submodules for a given package"""
    from os import path, walk
    module = path.dirname(getattr(package, '__file__', package))
    parent = path.dirname(module)
    files = (path.join(dir, file)[len(parent) + 1:-3]
             for dir, dirs, files in walk(module)
             for file in files
             if file.endswith('.py'))
    files = (f for f in files if not f.startswith(SKIP_DIRS))
    files = (f.replace(path.sep, '.') for f in files)
    return files


class Context(dict):
    """
    Execution context that retains the changes the tests make. Preferably
    use one per module to obtain nice "literate" modules that "follow along".

    In other words, directly the opposite of:
    https://docs.python.org/3/library/doctest.html#what-s-the-execution-context

    By popular demand:
    http://stackoverflow.com/questions/13106118/object-reuse-in-python-doctest/13106793#13106793
    http://stackoverflow.com/questions/3286658/embedding-test-code-or-data-within-doctest-strings
    """
    def copy(self):
        return self

    def clear(self):
        pass


def suite(package):
    """Assemble test suite for doctests in path (recursively)"""
    from importlib import import_module
    for module in find_modules(package.__file__):
        try:
            module = import_module(module)
            yield DocTestSuite(module,
                               globs=Context(module.__dict__.copy()),
                               optionflags=ELLIPSIS | NORMALIZE_WHITESPACE)
        except ValueError:
            pass  # No doctests in module
        except ImportError:
            import warnings
            warnings.warn('Unimportable module: {}'.format(module))


def load_tests(loader, tests, ignore):
    # This follows the load_tests protocol
    # https://docs.python.org/3/library/unittest.html#load-tests-protocol
    import Orange
    tests.addTests(suite(Orange))
    return tests