Failed Conditions
Pull Request — master (#1431)
by Abdeali
01:33
created

bears.tests.LocalBearTest.setUp()   A

Complexity

Conditions 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 2
dl 0
loc 5
rs 9.4285
1
from contextlib import contextmanager
2
from queue import Queue
3
import unittest
4
5
from coalib.bears.LocalBear import LocalBear
6
from coalib.results.Result import Result
7
from coalib.settings.Section import Section
8
from coalib.settings.Setting import Setting
9
from bears.tests.BearTestHelper import generate_skip_decorator
10
11
12
@contextmanager
13
def prepare_file(lines, filename, force_linebreaks, create_tempfile):
14
    """
15
    Can creates a temporary file (if filename is None) with the lines.
16
    Can also add a trailing newline to each line specified if needed.
17
18
    :param lines:            The lines from the file. (list of strings)
19
    :param filename:         The filename to be prepared.
20
                              - If it is None, A new tempfile will be created
21
                                (if create_tempfile is True).
22
                              - If it is a string, use it as the filename.
23
                              - If it is a dictionary, it is passed as kwargs
24
                                to NamedTemporaryFile.
25
    :param force_linebreaks: Whether to append newlines at each line if needed.
26
    :param create_tempfile:  Whether to save lines in tempfile if needed.
27
    """
28
    if force_linebreaks:
29
        for i, line in enumerate(lines):
30
            lines[i] = line if line.endswith("\n") else line + "\n"
31
32
    if not create_tempfile and filename is None:
33
        filename = "dummy_file_name"
34
35
    if not isinstance(filename, str) and create_tempfile:
36
        tempfile_kwargs = {} if filename is None else filename
37
        with NamedTemporaryFile(**tempfile_kwargs) as file:
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'NamedTemporaryFile'
Loading history...
38
            file.write(bytes("".join(lines), 'UTF-8'))
39
            yield lines, file.name
40
    else:
41
        yield lines, filename
42
43
44
class LocalBearTestHelper(unittest.TestCase):  # pragma: no cover
45
    """
46
    This is a helper class for simplification of testing of local bears.
47
48
    Please note that all abstraction will prepare the lines so you don't need
49
    to do that if you use them.
50
51
    If you miss some methods, get in contact with us, we'll be happy to help!
52
    """
53
54
    def check_validity(self,
55
                       local_bear,
56
                       lines,
57
                       filename="default",
58
                       valid=True,
59
                       force_linebreaks=True,
60
                       create_tempfile=True):
61
        """
62
        Asserts that a check of the given lines with the given local bear
63
        either yields or does not yield any results.
64
65
        :param local_bear:       The local bear to check with.
66
        :param lines:            The lines to check. (string if single line
67
                                                      or List of strings)
68
        :param filename:         The filename, if it matters.
69
        :param valid:            Whether the lines are valid or not.
70
        :param force_linebreaks: Whether to append newlines at each line
71
                                 if needed. (Bears expect a \\n for every line)
72
        :param create_tempfile:  Whether to save lines in tempfile if needed.
73
        """
74
        if isinstance(lines, str):
75
            lines = [lines]
76
77
        assert isinstance(self, unittest.TestCase)
78
        self.assertIsInstance(local_bear,
79
                              LocalBear,
80
                              msg="The given bear is not a local bear.")
81
        self.assertIsInstance(lines,
82
                              list,
83
                              msg="The given lines are not a list.")
84
85
        with prepare_file(lines, filename, force_linebreaks, create_tempfile) \
86
                as (lines, filename):
87
88
            bear_output = list(local_bear.execute(filename, lines))
89
90
            if valid:
91
                msg = ("The local bear '{}' yields a result although it "
92
                       "shouldn't.".format(local_bear.__class__.__name__))
93
                self.assertEqual(bear_output, [], msg=msg)
94
            else:
95
                msg = ("The local bear '{}' yields no result although it "
96
                       "should.".format(local_bear.__class__.__name__))
97
                self.assertNotEqual(len(bear_output), 0, msg=msg)
98
99
    def check_results(self,
100
                      local_bear,
101
                      lines,
102
                      results,
103
                      filename="default",
104
                      check_order=False,
105
                      force_linebreaks=True,
106
                      create_tempfile=True):
107
        """
108
        Asserts that a check of the given lines with the given local bear does
109
        yield exactly the given results.
110
111
        :param local_bear:       The local bear to check with.
112
        :param lines:            The lines to check. (string if single line
113
                                                      or List of strings)
114
        :param results:          The expected result or list of results.
115
        :param filename:         The filename, if it matters.
116
        :param force_linebreaks: Whether to append newlines at each line
117
                                 if needed. (Bears expect a \\n for every line)
118
        :param create_tempfile:  Whether to save lines in tempfile if needed.
119
        """
120
        if isinstance(lines, str):
121
            lines = [lines]
122
        if isinstance(results, Result):
123
            results = [results]
124
125
        assert isinstance(self, unittest.TestCase)
126
        self.assertIsInstance(local_bear,
127
                              LocalBear,
128
                              msg="The given bear is not a local bear.")
129
        self.assertIsInstance(lines,
130
                              list,
131
                              msg="The given lines are not a list.")
132
        self.assertIsInstance(results,
133
                              list,
134
                              msg="The given results are not a list.")
135
136
        with prepare_file(lines, filename, force_linebreaks, create_tempfile) \
137
                as (lines, filename):
138
139
            msg = ("The local bear '{}' doesn't yield the right results. Or the"
140
                   " order may be wrong.".format(local_bear.__class__.__name__))
141
            bear_output = list(local_bear.execute(filename, lines))
142
143
            if not check_order:
144
                self.assertEqual(sorted(bear_output), sorted(results), msg=msg)
145
            else:
146
                self.assertEqual(bear_output, results, msg=msg)
147
148
149
def verify_local_bear(bear,
150
                      valid_files,
151
                      invalid_files,
152
                      filename='default',
153
                      settings={},
154
                      force_linebreaks=True,
155
                      create_tempfile=True):
156
    """
157
    Generates a test for a local bear by checking the given valid and invalid
158
    file contents. Simply use it on your module level like:
159
160
    YourTestName = verify_local_bear(YourBear, (['valid line'],),
161
                                     (['invalid line'],))
162
163
    :param bear:             The Bear class to test.
164
    :param valid_files:      An iterable of files as a string list that won't
165
                             yield results.
166
    :param invalid_files:    An iterable of files as a string list that must
167
                             yield results.
168
    :param filename:         The filename to use for valid and invalid files.
169
    :param settings:         A dictionary of keys and values (both string) from
170
                             which settings will be created that will be made
171
                             available for the tested bear.
172
    :param force_linebreaks: Whether to append newlines at each line
173
                             if needed. (Bears expect a \\n for every line)
174
    :param create_tempfile:  Whether to save lines in tempfile if needed.
175
    :return:                 A unittest.TestCase object.
176
    """
177
    @generate_skip_decorator(bear)
178
    class LocalBearTest(LocalBearTestHelper):
179
180
        def setUp(self):
181
            self.section = Section('name')
182
            self.uut = bear(self.section, Queue())
183
            for name, value in settings.items():
184
                self.section.append(Setting(name, value))
185
186
        def test_valid_files(self):
187
            for file in valid_files:
188
                self.check_validity(self.uut,
189
                                    file,
190
                                    filename,
191
                                    valid=True,
192
                                    force_linebreaks=force_linebreaks,
193
                                    create_tempfile=create_tempfile)
194
195
        def test_invalid_files(self):
196
            for file in invalid_files:
197
                self.check_validity(self.uut,
198
                                    file,
199
                                    filename,
200
                                    valid=False,
201
                                    force_linebreaks=force_linebreaks,
202
                                    create_tempfile=create_tempfile)
203
204
    return LocalBearTest
205