The expiration time for new job artifacts in CI/CD pipelines is now 30 days (GitLab default). Previously generated artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

test_toolkit.py 5.47 KB
Newer Older
1
2
#!/usr/bin/python3

3
"""test_toolkit.py - tests of the toolkit-module of DHParser
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22


Author: Eckhart Arnold <arnold@badw.de>

Copyright 2017 Bavarian Academy of Sciences and Humanities

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

Eckhart Arnold's avatar
Eckhart Arnold committed
23
import concurrent.futures
24
import collections.abc
Eckhart Arnold's avatar
Eckhart Arnold committed
25
26
import os
import sys
27

Eckhart Arnold's avatar
Eckhart Arnold committed
28
sys.path.extend(['../', './'])
29

30
from DHParser.toolkit import has_fenced_code, load_if_file, re, \
31
    lstrip_docstring, issubtype, isgenerictype, typing
32
from DHParser.log import log_dir, logging, is_logging
33
34
35


class TestLoggingAndLoading:
36
    filename = "test/tmp/test.py" if os.path.isdir('test') else "tmp/test.py"
37
    dirname = os.path.dirname(filename)
38
39
40
41
    code1 = "x = 46"
    code2 = "def f():\n    return 46"

    def setup(self):
42
43
        if not os.path.exists(self.dirname):
            os.mkdir(self.dirname)
44
45
46
47
48
        with open(self.filename, 'w') as f:
            f.write(self.code2)

    def teardown(self):
        os.remove(self.filename)
49
50
51
52
53
        pycachedir = os.path.join(self.dirname,'__pycache__')
        if os.path.exists(pycachedir):
            for fname in os.listdir(pycachedir):
                os.remove(os.path.join(pycachedir, fname))
            os.rmdir(pycachedir)
54
        os.rmdir(self.dirname)
Eckhart Arnold's avatar
Eckhart Arnold committed
55
56
57
        if os.path.exists("TESTLOGS"):
            os.remove("TESTLOGS/info.txt")
            os.rmdir("TESTLOGS")
58
59
60
61
62
63
64
65
66
67
68
69
70
71

    def test_load_if_file(self):
        # an error should be raised if file expected but not found
        error_raised = False
        try:
            load_if_file('this_is_code_and_not_a_file')
        except FileNotFoundError:
            error_raised = True
        assert error_raised

        # multiline text will never be mistaken for a file
        assert load_if_file('this_is_code_and_not_a_file\n')

        # neither will text that does not look like a file name
72
        s = "this is code * and not a file"
73
74
75
76
77
78
79
80
81
82
83
        assert s == load_if_file(s)

        # not a file and not mistaken for a file
        assert self.code1 == load_if_file(self.code1)

        # not a file and not mistaken for a file either
        assert self.code2 == load_if_file(self.code2)

        # file correctly loaded
        assert self.code2 == load_if_file(self.filename)

84
85
86
87
88
89
90
91
92
    def test_has_fenced_code(self):
        code1="has fenced code block\n~~~ ebnf\nstart = 'start'\n~~~\n"
        code2="no fenced code block ~~~ ebnf\nstart = 'start'\n~~~\n"
        code3="\n~~~ ebnd\nstart = 'start'\n~~"
        assert has_fenced_code(code1)
        assert not has_fenced_code(code2)
        assert not has_fenced_code(code3)


Eckhart Arnold's avatar
Eckhart Arnold committed
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
134
135
    def test_logging(self):
        try:
            log_dir()
            assert False, "Name error should be raised when log_dir() is called outside " \
                          "a logging context."
        except NameError:
            pass
        with logging("TESTLOGS"):
            assert not os.path.exists("TESTSLOGS"), \
                "Log dir should not be created before first use!"
            dirname = log_dir()
            assert dirname == "TESTLOGS"
            assert is_logging(), "is_logging() should return True, if logging is on"
            with logging(False):
                assert not is_logging(), \
                    "is_logging() should return False, if innermost logging context " \
                    "has logging turned off."
            assert is_logging(), "is_logging() should return True after logging off " \
                                 "context has been left"
            assert os.path.exists("TESTLOGS/info.txt"), "an 'info.txt' file should be " \
                "created within a newly created log dir"
        # cleanup
        os.remove("TESTLOGS/info.txt")
        os.rmdir("TESTLOGS")

    def logging_task(self):
        with logging("TESTLOGS"):
            log_dir()
            assert is_logging(), "Logging should be on inside logging context"
        assert not is_logging(), "Logging should be off outside logging context"
        return os.path.exists("TESTLOGS/info.txt")

    def test_logging_multiprocessing(self):
        with concurrent.futures.ProcessPoolExecutor() as ex:
            f1 = ex.submit(self.logging_task)
            f2 = ex.submit(self.logging_task)
            f3 = ex.submit(self.logging_task)
            f4 = ex.submit(self.logging_task)
        assert f1.result()
        assert f2.result()
        assert f3.result()
        assert f4.result()

136

137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
class TestStringHelpers:
    def test_lstrip_docstring(self):
        str1 = """line
        
            indented line
        line
        """
        assert lstrip_docstring(str1) == 'line\n\n    indented line\nline\n'
        str2 = """
            line
            line
                indented line
                    indented indented line"""
        assert lstrip_docstring(str2) == '\nline\nline\n    indented line\n        indented ' \
                                         'indented line'


154
155
class TestTypeSystemSupport:
    def test_issubtype(self):
156
        assert issubtype(typing.List, collections.abc.Sequence)
157
158
159



160
if __name__ == "__main__":
161
    from DHParser.testing import runner
162
    runner("", globals())