File: test_reader.py

package info (click to toggle)
ford 7.0.12-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,000 kB
  • sloc: python: 11,852; f90: 419; javascript: 51; fortran: 45; makefile: 23
file content (223 lines) | stat: -rw-r--r-- 5,941 bytes parent folder | download
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# -*- coding: utf-8 -*-
"""
Created on Tue Mar 17 20:21:05 2020

@author: Peter M. Clausen
"""

import glob
import re

import ford.reader as reader
from ford.reader import _contains_unterminated_string
from ford.settings import ProjectSettings

RE_WHITE = re.compile(r"\s+")


def remove_multiple_white_space(lines):
    return [RE_WHITE.sub(" ", line.strip()) for line in lines]


def test_reader_test_data():
    """Basic regression test"""
    f_files = glob.glob("./test_data/*.f*")
    f_files = [
        f
        for f in f_files
        if "expected" not in f and "bad" not in f  # remove 'expected' and 'bad' files
    ]
    # Set to True to update the 'expected' files
    create_expected = False
    for ff in f_files:
        ee = ff.replace(".f90", "_expected.f90")
        print("\tProcessing: %s \tExpected: %s " % (ff, ee))
        lines = [
            line
            for line in reader.FortranReader(
                ff, docmark="!", predocmark=">", docmark_alt="#", predocmark_alt="<"
            )
        ]
        if create_expected:
            print("WARNING : Writing expected file " + ee)
            with open(ee, "w") as ef:
                for line in lines:
                    print(line)
                    ef.write(line + "\n")
        else:
            with open(ee) as ef:
                lines = remove_multiple_white_space(lines)
                elines = remove_multiple_white_space(ef.readlines())
                assert lines == elines


def test_reader_continuation(copy_fortran_file):
    """Checks that line continuations are handled correctly"""

    data = """\
    program foo
    !! some docs
    integer :: bar = &
    &
    4
    end
    """

    filename = copy_fortran_file(data)

    lines = list(reader.FortranReader(filename, docmark="!"))
    assert lines == ["program foo", "!! some docs", "integer :: bar = 4", "end"]


def test_type(copy_fortran_file):
    """Check that types can be read"""

    data = """\
    program foo
    !! base type
    type :: base
    end type base

    !! derived type
    type, extends(base) :: derived
    end type
    """

    expected = [
        "program foo",
        "!! base type",
        "type :: base",
        "end type base",
        "!! derived type",
        "type, extends(base) :: derived",
        "end type",
    ]

    filename = copy_fortran_file(data)

    lines = list(reader.FortranReader(filename, docmark="!"))
    assert lines == expected


def test_unknown_include(copy_fortran_file):
    """Check that `include "file.h"` ignores unknown files"""

    data = """\
    program test
    include "file.h"
    end program test
    """

    expected = [
        "program test",
        'include "file.h"',
        "end program test",
    ]

    filename = copy_fortran_file(data)

    lines = list(reader.FortranReader(filename, docmark="!"))
    assert lines == expected


def test_unterminated_strings():
    """Check the utility function works"""
    assert _contains_unterminated_string(""" bad "quote """)
    assert _contains_unterminated_string(""" bad 'quote """)
    assert _contains_unterminated_string(""" bad "'quote """)
    assert _contains_unterminated_string(""" bad 'quote" """)
    assert _contains_unterminated_string(""" "multiple" bad "'quote """)
    assert _contains_unterminated_string(""" bad 'quote" """)

    assert not _contains_unterminated_string(""" good "quote" """)
    assert not _contains_unterminated_string(""" good 'quote' """)
    assert not _contains_unterminated_string(""" good "'quote" """)
    assert not _contains_unterminated_string(""" good 'quote"' """)
    assert not _contains_unterminated_string(""" "multiple" good "'quote" """)
    assert not _contains_unterminated_string(""" good 'quote"' """)


def test_multiline_string(copy_fortran_file):
    """Check that we can continue string literals including exclamation
    marks over multiple lines. Issue #320"""

    data = '''\
    program multiline_string
      implicit none
      print*, 'dont''t', " get ""!>quotes!@""", " '""!<wrong!!""' ", "foo&
              &bar! foo&
              &bar"
    end program multiline_string
    '''

    filename = copy_fortran_file(data)
    expected = [
        "program multiline_string",
        "implicit none",
        '''print*, 'dont''t', " get ""!>quotes!@""", " '""!<wrong!!""' ", "foobar! foobar"''',
        "end program multiline_string",
    ]

    lines = list(
        reader.FortranReader(
            filename, docmark="!", predocmark="<", docmark_alt=">", predocmark_alt="@"
        )
    )
    assert lines == expected


def test_preprocessor(copy_fortran_file):
    """Check some basic preprocessing is applied"""

    data = """\
    subroutine SUB_NAME()
    end sub_name SUB_NAME
    """

    filename = copy_fortran_file(data, ".F90")

    lines = "\n".join(
        list(
            reader.FortranReader(
                str(filename), preprocessor=["pcpp"], macros=["SUB_NAME=foo"]
            )
        )
    )
    assert "foo" in lines


def test_preprocessor_warning(copy_fortran_file):
    """Check preprocessing is still done even if there are warnings"""

    data = """\
    #warning something
    subroutine SUB_NAME()
    end sub_name SUB_NAME
    """

    filename = copy_fortran_file(data, ".F90")

    lines = "\n".join(
        list(
            reader.FortranReader(
                str(filename), preprocessor=["pcpp"], macros=["SUB_NAME=foo"]
            )
        )
    )
    assert "foo" in lines


def test_preprocessor_leaves_urls(copy_fortran_file):
    """Check preprocessor leaves urls, issue #611"""

    data = """\
    !! http://www.example.com
    module foo
    end
    """
    filename = copy_fortran_file(data, ".F90")
    preprocessor = ProjectSettings().preprocessor.split()
    lines = "\n".join(
        list(reader.FortranReader(str(filename), preprocessor=preprocessor))
    )
    assert "http://www.example.com" in lines