tst_FlexibleEBNF_grammar.py 3.72 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python3

"""tst_EBNF_grammar.py - runs the unit tests for the EBNF-grammar
"""

import os
import sys

LOGGING = ''

scriptpath = os.path.dirname(__file__)
dhparserdir = os.path.abspath(os.path.join(scriptpath, '../..'))
if scriptpath not in sys.path:
    sys.path.append(scriptpath)
if dhparserdir not in sys.path:
    sys.path.append(dhparserdir)

try:
di68kap's avatar
di68kap committed
19
20
    from DHParser.configuration import get_config_value, set_config_value, \
        access_presets, set_preset_value, finalize_presets
21
22
23
24
25
26
27
28
29
30
31
    from DHParser import dsl
    import DHParser.log
    from DHParser import testing
    from DHParser.toolkit import is_filename
except ModuleNotFoundError:
    print('Could not import DHParser. Please adjust sys.path in file '
          '"%s" manually' % __file__)
    sys.exit(1)


def recompile_grammar(grammar_src, force):
di68kap's avatar
di68kap committed
32
    grammar_tests_dir = os.path.join(scriptpath, 'tests_grammar')
33
34
35
36
    testing.create_test_templates(grammar_src, grammar_tests_dir)
    DHParser.log.start_logging('LOGS')
    # recompiles Grammar only if it has changed
    saved_syntax_variant = get_config_value('syntax_variant')
Eckhart Arnold's avatar
Eckhart Arnold committed
37
    set_config_value('syntax_variant', 'heuristic')
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
    if not dsl.recompile_grammar(grammar_src, force=force,
            notify=lambda: print('recompiling ' + grammar_src)):
        print('\nErrors while recompiling "%s":' % grammar_src +
              '\n--------------------------------------\n\n')
        if is_filename(grammar_src):
            err_name = grammar_src.replace('.', '_') + '_ERRORS.txt'
        else:
            err_name = 'EBNF_ebnf_ERRORS.txt'
        with open(err_name, encoding='utf-8') as f:
            print(f.read())
        sys.exit(1)
    set_config_value('syntax_variant', saved_syntax_variant)


def run_grammar_tests(glob_pattern, get_grammar, get_transformer):
    DHParser.log.start_logging(LOGGING)
    error_report = testing.grammar_suite(
di68kap's avatar
di68kap committed
55
        os.path.join(scriptpath, 'tests_grammar'),
56
57
58
59
60
        get_grammar, get_transformer,
        fn_patterns=[glob_pattern], report='REPORT', verbose=True)
    return error_report


di68kap's avatar
di68kap committed
61
62
63
64
65
66
67
68
69
def cpu_profile(func):
    import cProfile as profile
    import pstats
    pr = profile.Profile()
    pr.enable()
    result = func()
    pr.disable()
    st = pstats.Stats(pr)
    st.strip_dirs()
70
    st.sort_stats('time').print_stats(80)
di68kap's avatar
di68kap committed
71
72
73
    return result


74
75
if __name__ == '__main__':
    argv = sys.argv[:]
di68kap's avatar
di68kap committed
76
77
78
79
80
81
82
83
84
85
86
    try:
        i = argv.index('--profile')
        del argv[i]
        access_presets()
        set_preset_value('test_parallelization', False)
        finalize_presets()
        print("Profiling test run...")
        profile = True
    except ValueError:
        profile = False
    if len(argv) > 1 and argv[1] == "--debug":
87
        LOGGING = "LOGS"
88
89
90
91
92
93
94
95
96
97
98
99
        del argv[1]
    if (len(argv) >= 2 and (argv[1].endswith('.ebnf') or
        os.path.splitext(argv[1])[1].lower() in testing.TEST_READERS.keys())):
        # if called with a single filename that is either an EBNF file or a known
        # test file type then use the given argument
        arg = argv[1]
    else:
        # otherwise run all tests in the test directory
        arg = '*_test_*.ini'
    if arg.endswith('.ebnf'):
        recompile_grammar(arg, force=True)
    else:
di68kap's avatar
di68kap committed
100
        recompile_grammar(os.path.join(scriptpath, 'FlexibleEBNF.ebnf'),
101
102
                          force=False)
        sys.path.append('.')
di68kap's avatar
di68kap committed
103
        from FlexibleEBNFParser import get_grammar, get_transformer
di68kap's avatar
di68kap committed
104
105
106
107
108
        if profile:
            error_report = cpu_profile(
                lambda : run_grammar_tests(arg, get_grammar, get_transformer))
        else:
            error_report = run_grammar_tests(arg, get_grammar, get_transformer)
109
110
111
112
113
        if error_report:
            print('\n')
            print(error_report)
            sys.exit(1)
        print('ready.\n')