File: run_tests.py

package info (click to toggle)
html5-parser 0.4.12%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,748 kB
  • sloc: ansic: 32,397; python: 1,732; makefile: 6
file content (133 lines) | stat: -rw-r--r-- 3,854 bytes parent folder | download | duplicates (2)
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
131
132
133
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: Apache 2.0 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>

from __future__ import absolute_import, division, print_function, unicode_literals

import argparse
import importlib
import os
import sys
import unittest

if 'HTML5_PARSER_DLL_DIR' in os.environ:
    sys.save_dll_dir = os.add_dll_directory(os.environ['HTML5_PARSER_DLL_DIR'])
    print('Added DLL directory', sys.save_dll_dir, 'with contents:',
          os.listdir(os.environ['HTML5_PARSER_DLL_DIR']))
    print('Current sys.path:', sys.path)

self_path = os.path.abspath(__file__)
base = os.path.dirname(self_path)
html5lib_tests_path = os.path.join(base, 'test', 'html5lib-tests')


def itertests(suite):
    stack = [suite]
    while stack:
        suite = stack.pop()
        for test in suite:
            if isinstance(test, unittest.TestSuite):
                stack.append(test)
                continue
            if test.__class__.__name__ == 'ModuleImportFailure':
                raise Exception('Failed to import a test module: %s' % test)
            yield test


def filter_tests(suite, test_ok):
    ans = unittest.TestSuite()
    added = set()
    for test in itertests(suite):
        if test_ok(test) and test not in added:
            ans.addTest(test)
            added.add(test)
    return ans


def filter_tests_by_name(suite, name):
    if not name.startswith('test_'):
        name = 'test_' + name
    if name.endswith('_'):
        def q(test):
            return test._testMethodName.startswith(name)
    else:
        def q(test):
            return test._testMethodName == name

    return filter_tests(suite, q)


def filter_tests_by_module(suite, *names):
    names = frozenset(names)

    def q(test):
        m = test.__class__.__module__.rpartition('.')[-1]
        return m in names

    return filter_tests(suite, q)


def find_tests():
    suites = []
    for f in os.listdir(os.path.join(base, 'test')):
        n, ext = os.path.splitext(f)
        if ext == '.py' and n not in ('__init__', 'html5lib_adapter'):
            m = importlib.import_module('test.' + n)
            suite = unittest.defaultTestLoader.loadTestsFromModule(m)
            suites.append(suite)
    if 'SKIP_HTML5LIB' not in os.environ:
        from test.html5lib_adapter import find_tests
        suites.extend(find_tests())
    return unittest.TestSuite(suites)


def run_memleak_tests():
    tests = find_tests()

    tests = filter_tests_by_name(tests, 'asan_memleak')
    r = unittest.TextTestRunner
    result = r(verbosity=4).run(tests)

    if not result.wasSuccessful():
        raise SystemExit(1)


def main():
    sys.path.insert(0, base)
    if 'MEMLEAK_EXE' in os.environ:
        return run_memleak_tests()
    parser = argparse.ArgumentParser(
        description='''\
Run the specified tests, or all tests if none are specified. Tests
can be specified as either the test method name (without the leading test_)
or a module name with a trailing period.
''')
    parser.add_argument(
        'test_name',
        nargs='*',
        help=(
            'Test name (either a method name or a module name with a trailing period)'
            '. Note that if the name ends with a trailing underscore all tests methods'
            ' whose names start with the specified name are run.'
        )
    )
    args = parser.parse_args()

    tests = find_tests()
    suites = []
    for name in args.test_name:
        if name.endswith('.'):
            suites.append(filter_tests_by_module(tests, name[:-1]))
        else:
            suites.append(filter_tests_by_name(tests, name))
    tests = unittest.TestSuite(suites) if suites else tests

    r = unittest.TextTestRunner
    result = r().run(tests)

    if not result.wasSuccessful():
        raise SystemExit(1)


if __name__ == '__main__':
    main()