source: pyyaml/trunk/tests3/test_appliance.py @ 328

Revision 328, 4.9 KB checked in by xi, 5 years ago (diff)

Added basic support for Python 3 (Thanks idadesub(at)users(dot)sourceforge(dot)net).

RevLine 
[39]1
[322]2import sys, os, os.path, types, traceback, pprint
[39]3
[328]4DATA = 'tests3/data'
[51]5
[322]6def find_test_functions(collections):
7    if not isinstance(collections, list):
8        collections = [collections]
9    functions = []
10    for collection in collections:
11        if not isinstance(collection, dict):
12            collection = vars(collection)
[328]13        for key in sorted(collection):
[322]14            value = collection[key]
15            if isinstance(value, types.FunctionType) and hasattr(value, 'unittest'):
16                functions.append(value)
17    return functions
[39]18
[322]19def find_test_filenames(directory):
20    filenames = {}
21    for filename in os.listdir(directory):
22        if os.path.isfile(os.path.join(directory, filename)):
23            base, ext = os.path.splitext(filename)
24            filenames.setdefault(base, []).append(ext)
[328]25    filenames = sorted(filenames.items())
[322]26    return filenames
[39]27
[322]28def parse_arguments(args):
29    if args is None:
30        args = sys.argv[1:]
31    verbose = False
32    if '-v' in args:
33        verbose = True
34        args.remove('-v')
35    if '--verbose' in args:
36        verbose = True
37    if 'YAML_TEST_VERBOSE' in os.environ:
38        verbose = True
39    include_functions = []
40    if args:
41        include_functions.append(args.pop(0))
42    if 'YAML_TEST_FUNCTIONS' in os.environ:
43        include_functions.extend(os.environ['YAML_TEST_FUNCTIONS'].split())
44    include_filenames = []
45    include_filenames.extend(args)
46    if 'YAML_TEST_FILENAMES' in os.environ:
47        include_filenames.extend(os.environ['YAML_TEST_FILENAMES'].split())
48    return include_functions, include_filenames, verbose
[39]49
[322]50def execute(function, filenames, verbose):
[328]51    name = function.__name__
[322]52    if verbose:
53        sys.stdout.write('='*75+'\n')
[325]54        sys.stdout.write('%s(%s)...\n' % (name, ', '.join(filenames)))
[322]55    try:
56        function(verbose=verbose, *filenames)
[328]57    except Exception as exc:
[322]58        info = sys.exc_info()
59        if isinstance(exc, AssertionError):
60            kind = 'FAILURE'
[43]61        else:
[322]62            kind = 'ERROR'
63        if verbose:
64            traceback.print_exc(limit=1, file=sys.stdout)
65        else:
66            sys.stdout.write(kind[0])
67            sys.stdout.flush()
68    else:
69        kind = 'SUCCESS'
70        info = None
71        if not verbose:
72            sys.stdout.write('.')
73    sys.stdout.flush()
[325]74    return (name, filenames, kind, info)
[43]75
[322]76def display(results, verbose):
77    if results and not verbose:
78        sys.stdout.write('\n')
79    total = len(results)
80    failures = 0
81    errors = 0
[325]82    for name, filenames, kind, info in results:
[322]83        if kind == 'SUCCESS':
84            continue
85        if kind == 'FAILURE':
86            failures += 1
87        if kind == 'ERROR':
88            errors += 1
89        sys.stdout.write('='*75+'\n')
[325]90        sys.stdout.write('%s(%s): %s\n' % (name, ', '.join(filenames), kind))
[322]91        if kind == 'ERROR':
92            traceback.print_exception(file=sys.stdout, *info)
[51]93        else:
[322]94            sys.stdout.write('Traceback (most recent call last):\n')
95            traceback.print_tb(info[2], file=sys.stdout)
96            sys.stdout.write('%s: see below\n' % info[0].__name__)
97            sys.stdout.write('~'*75+'\n')
98            for arg in info[1].args:
[325]99                pprint.pprint(arg, stream=sys.stdout)
[322]100        for filename in filenames:
101            sys.stdout.write('-'*75+'\n')
102            sys.stdout.write('%s:\n' % filename)
[328]103            data = open(filename, 'r', errors='replace').read()
[322]104            sys.stdout.write(data)
105            if data and data[-1] != '\n':
106                sys.stdout.write('\n')
107    sys.stdout.write('='*75+'\n')
108    sys.stdout.write('TESTS: %s\n' % total)
109    if failures:
110        sys.stdout.write('FAILURES: %s\n' % failures)
111    if errors:
112        sys.stdout.write('ERRORS: %s\n' % errors)
[43]113
[322]114def run(collections, args=None):
115    test_functions = find_test_functions(collections)
116    test_filenames = find_test_filenames(DATA)
117    include_functions, include_filenames, verbose = parse_arguments(args)
118    results = []
119    for function in test_functions:
[328]120        if include_functions and function.__name__ not in include_functions:
[322]121            continue
122        if function.unittest:
123            for base, exts in test_filenames:
124                if include_filenames and base not in include_filenames:
125                    continue
126                filenames = []
127                for ext in function.unittest:
128                    if ext not in exts:
129                        break
130                    filenames.append(os.path.join(DATA, base+ext))
[43]131                else:
[322]132                    skip_exts = getattr(function, 'skip', [])
133                    for skip_ext in skip_exts:
134                        if skip_ext in exts:
135                            break
136                    else:
137                        result = execute(function, filenames, verbose)
138                        results.append(result)
[43]139        else:
[322]140            result = execute(function, [], verbose)
141            results.append(result)
142    display(results, verbose=verbose)
[43]143
Note: See TracBrowser for help on using the repository browser.