Completed
Pull Request — master (#1431)
by Abdeali
01:46 queued 13s
created

bears.tests.LocalBearTestHelper.assertLineYieldsResult()   A

Complexity

Conditions 1

Size

Total Lines 19

Duplication

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