Failed Conditions
Pull Request — master (#1990)
by Mischa
02:15
created

LinterComponentTest

Size/Duplication

Total Lines 447
Duplicated Lines 16.78 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 75
loc 447

23 Methods

Rating   Name   Duplication   Size   Complexity  
A test_repr() 0 9 1
A test_generate_config() 0 18 4
A Handler.process_output() 0 2 1
B test_process_output_corrected() 0 29 3
B test_section_settings_forwarding() 0 34 1
A Handler.create_arguments() 0 3 1
A TestLinter.create_arguments() 0 6 1
C test_decorator_invalid_parameter_types() 0 50 8
B test_check_prerequisites() 0 25 1
A test_decorator_generated_default_interface() 0 4 2
A TestLinter.process_output() 0 3 1
A ManualProcessingTestLinter.process_output() 0 2 1
A test_get_non_optional_settings() 0 19 1
B test_output_stream() 0 40 1
A test_process_output_regex() 0 56 1
A setUp() 0 2 1
A test_metaclass_repr() 0 11 1
A ConfigurationTestLinter.generate_config() 0 3 1
A test_get_executable() 0 3 1
C test_decorator_invalid_states() 39 39 7
C test_decorator_invalid_parameters() 36 36 7
B test_section_settings_defaults_forwarding() 0 42 1
A Handler.generate_config() 0 6 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
import os
2
import sys
3
import unittest
4
from unittest.mock import ANY, Mock
5
6
from coalib.bearlib.abstractions.Linter import linter
7
from coalib.results.Diff import Diff
8
from coalib.results.Result import Result
9
from coalib.results.RESULT_SEVERITY import RESULT_SEVERITY
10
from coalib.settings.Section import Section
11
12
13
def get_testfile_name(name):
14
    """
15
    Gets the full path to a testfile inside ``linter_test_files`` directory.
16
17
    :param name: The filename of the testfile to get the full path for.
18
    :return:     The full path to given testfile name.
19
    """
20
    return os.path.join(os.path.dirname(os.path.realpath(__file__)),
21
                        "linter_test_files",
22
                        name)
23
24
25
class LinterComponentTest(unittest.TestCase):
26
27
    # Using `object` instead of an empty class results in inheritance problems
28
    # inside the linter decorator.
29
    class EmptyTestLinter:
30
        pass
31
32
    class ManualProcessingTestLinter:
33
34
        def process_output(self, *args, **kwargs):
35
            pass
36
37
    def setUp(self):
38
        self.section = Section("TEST_SECTION")
39
40 View Code Duplication
    def test_decorator_invalid_parameters(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
41
        with self.assertRaises(ValueError) as cm:
42
            linter("some-executable", invalid_arg=88, ABC=2000)
43
        self.assertEqual(
44
            str(cm.exception),
45
            "Invalid keyword arguments provided: 'ABC', 'invalid_arg'")
46
47
        with self.assertRaises(ValueError) as cm:
48
            linter("some-executable", diff_severity=RESULT_SEVERITY.MAJOR)
49
        self.assertEqual(str(cm.exception),
50
                         "Invalid keyword arguments provided: 'diff_severity'")
51
52
        with self.assertRaises(ValueError) as cm:
53
            linter("some-executable", diff_message="Custom message")
54
        self.assertEqual(str(cm.exception),
55
                         "Invalid keyword arguments provided: 'diff_message'")
56
57
        with self.assertRaises(ValueError) as cm:
58
            linter("some-executable",
59
                   output_format="corrected",
60
                   output_regex=".*")
61
        self.assertEqual(str(cm.exception),
62
                         "Invalid keyword arguments provided: 'output_regex'")
63
64
        with self.assertRaises(ValueError) as cm:
65
            linter("some-executable",
66
                   output_format="corrected",
67
                   severity_map={})
68
        self.assertEqual(str(cm.exception),
69
                         "Invalid keyword arguments provided: 'severity_map'")
70
71
        with self.assertRaises(ValueError) as cm:
72
            linter("some-executable",
73
                   prerequisite_check_fail_message="some_message")
74
        self.assertEqual(str(cm.exception),
75
                         "Invalid keyword arguments provided: "
76
                         "'prerequisite_check_fail_message'")
77
78 View Code Duplication
    def test_decorator_invalid_states(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
79
        with self.assertRaises(ValueError) as cm:
80
            linter("some-executable", use_stdout=False, use_stderr=False)
81
        self.assertEqual(str(cm.exception),
82
                         "No output streams provided at all.")
83
84
        with self.assertRaises(ValueError) as cm:
85
            linter("some-executable", output_format="INVALID")
86
        self.assertEqual(str(cm.exception),
87
                         "Invalid `output_format` specified.")
88
89
        with self.assertRaises(ValueError) as cm:
90
            linter("some-executable", output_format="regex")
91
        self.assertEqual(
92
            str(cm.exception),
93
            "`output_regex` needed when specified output-format 'regex'.")
94
95
        with self.assertRaises(ValueError) as cm:
96
            linter("some-executable",
97
                   output_format="regex",
98
                   output_regex="",
99
                   severity_map={})
100
        self.assertEqual(
101
            str(cm.exception),
102
            "Provided `severity_map` but named group `severity` is not used "
103
            "in `output_regex`.")
104
105
        with self.assertRaises(ValueError) as cm:
106
            linter("some-executable")(object)
107
        self.assertEqual(
108
            str(cm.exception),
109
            "`process_output` not provided by given class 'object'.")
110
111
        with self.assertRaises(ValueError) as cm:
112
            (linter("some-executable", output_format="regex", output_regex="")
113
             (self.ManualProcessingTestLinter))
114
        self.assertEqual(
115
            str(cm.exception),
116
            "Found `process_output` already defined by class "
117
            "'ManualProcessingTestLinter', but 'regex' output-format is "
118
            "specified.")
119
120
    def test_decorator_generated_default_interface(self):
121
        uut = linter("some-executable")(self.ManualProcessingTestLinter)
122
        with self.assertRaises(NotImplementedError):
123
            uut.create_arguments("filename", "content", None)
124
125
    def test_decorator_invalid_parameter_types(self):
126
        # Provide some invalid severity maps.
127
        with self.assertRaises(TypeError):
128
            linter("some-executable",
129
                   output_format="regex",
130
                   output_regex="(?P<severity>)",
131
                   severity_map=list())
132
133
        with self.assertRaises(TypeError):
134
            linter("some-executable",
135
                   output_format="regex",
136
                   output_regex="(?P<severity>)",
137
                   severity_map={3: 0})
138
139
        with self.assertRaises(TypeError) as cm:
140
            linter("some-executable",
141
                   output_format="regex",
142
                   output_regex="(?P<severity>)",
143
                   severity_map={"critical": "invalid"})
144
        self.assertEqual(str(cm.exception),
145
                         "The value 'invalid' for key 'critical' inside given "
146
                         "severity-map is no valid severity value.")
147
148
        with self.assertRaises(TypeError) as cm:
149
            linter("some-executable",
150
                   output_format="regex",
151
                   output_regex="(?P<severity>)",
152
                   severity_map={"critical-error": 389274234})
153
        self.assertEqual(str(cm.exception),
154
                         "Invalid severity value 389274234 for key "
155
                         "'critical-error' inside given severity-map.")
156
157
        # Other type-error test cases.
158
159
        with self.assertRaises(TypeError):
160
            linter("some-executable",
161
                   output_format="corrected",
162
                   diff_message=list())
163
164
        with self.assertRaises(TypeError) as cm:
165
            linter("some-executable",
166
                   output_format="corrected",
167
                   diff_severity=999888777)
168
        self.assertEqual(str(cm.exception),
169
                         "Invalid value for `diff_severity`: 999888777")
170
171
        with self.assertRaises(TypeError):
172
            linter("some-executable",
173
                   prerequisite_check_command=("command",),
174
                   prerequisite_check_fail_message=382983)
175
176
    def test_get_executable(self):
177
        uut = linter("some-executable")(self.ManualProcessingTestLinter)
178
        self.assertEqual(uut.get_executable(), "some-executable")
179
180
    def test_check_prerequisites(self):
181
        uut = linter(sys.executable)(self.ManualProcessingTestLinter)
182
        self.assertTrue(uut.check_prerequisites())
183
184
        uut = (linter("invalid_nonexisting_programv412")
185
               (self.ManualProcessingTestLinter))
186
        self.assertEqual(uut.check_prerequisites(),
187
                         "'invalid_nonexisting_programv412' is not installed.")
188
189
        uut = (linter(sys.executable,
190
                      prerequisite_check_command=(sys.executable, "--version"))
191
               (self.ManualProcessingTestLinter))
192
        self.assertTrue(uut.check_prerequisites())
193
194
        uut = (linter(sys.executable,
195
                      prerequisite_check_command=("invalid_programv413",))
196
               (self.ManualProcessingTestLinter))
197
        self.assertEqual(uut.check_prerequisites(),
198
                         "Prerequisite check failed.")
199
200
        uut = (linter(sys.executable,
201
                      prerequisite_check_command=("invalid_programv413",),
202
                      prerequisite_check_fail_message="NOPE")
203
               (self.ManualProcessingTestLinter))
204
        self.assertEqual(uut.check_prerequisites(), "NOPE")
205
206
    def test_output_stream(self):
207
        process_output_mock = Mock()
208
209
        class TestLinter:
210
211
            @staticmethod
212
            def process_output(output, filename, file):
213
                process_output_mock(output, filename, file)
214
215
            @staticmethod
216
            def create_arguments(filename, file, config_file):
217
                code = "\n".join(["import sys",
218
                                  "print('hello stdout')",
219
                                  "print('hello stderr', file=sys.stderr)"])
220
                return "-c", code
221
222
        uut = (linter(sys.executable, use_stdout=True)
0 ignored issues
show
Bug introduced by
linter(sys.executable, u...tdout=True)(TestLinter) does not seem to be callable.
Loading history...
223
               (TestLinter)
224
               (self.section, None))
225
        uut.run("", [])
226
227
        process_output_mock.assert_called_once_with("hello stdout\n", "", [])
228
        process_output_mock.reset_mock()
229
230
        uut = (linter(sys.executable, use_stdout=False, use_stderr=True)
0 ignored issues
show
Bug introduced by
linter(sys.executable, u...tderr=True)(TestLinter) does not seem to be callable.
Loading history...
231
               (TestLinter)
232
               (self.section, None))
233
        uut.run("", [])
234
235
        process_output_mock.assert_called_once_with("hello stderr\n", "", [])
236
        process_output_mock.reset_mock()
237
238
        uut = (linter(sys.executable, use_stdout=True, use_stderr=True)
0 ignored issues
show
Bug introduced by
linter(sys.executable, u...tderr=True)(TestLinter) does not seem to be callable.
Loading history...
239
               (TestLinter)
240
               (self.section, None))
241
242
        uut.run("", [])
243
244
        process_output_mock.assert_called_once_with(("hello stdout\n",
245
                                                     "hello stderr\n"), "", [])
246
247
    def test_process_output_corrected(self):
248
        uut = (linter(sys.executable, output_format="corrected")
0 ignored issues
show
Bug introduced by
linter(sys.executable, o...)(self.EmptyTestLinter) does not seem to be callable.
Loading history...
249
               (self.EmptyTestLinter)
250
               (self.section, None))
251
252
        original = [s + "\n" for s in ["void main()  {", "return 09;", "}"]]
253
        fixed = [s + "\n" for s in ["void main()", "{", "return 9;", "}"]]
254
        fixed_string = "".join(fixed)
255
256
        results = list(uut.process_output(fixed_string,
257
                                          "some-file.c",
258
                                          original))
259
260
        diffs = list(Diff.from_string_arrays(original, fixed).split_diff())
261
        expected = [Result.from_values(uut,
262
                                       "Inconsistency found.",
263
                                       "some-file.c",
264
                                       1, None, 2, None,
265
                                       RESULT_SEVERITY.NORMAL,
266
                                       diffs={"some-file.c": diffs[0]})]
267
268
        self.assertEqual(results, expected)
269
270
        # Test when providing a sequence as output.
271
272
        results = list(uut.process_output([fixed_string, fixed_string],
273
                                          "some-file.c",
274
                                          original))
275
        self.assertEqual(results, 2 * expected)
276
277
    def test_process_output_regex(self):
278
        # Also test the case when an unknown severity is matched.
279
        test_output = ("12:4-14:0-Serious issue (error) -> ORIGIN=X\n"
280
                       "0:0-0:1-This is a warning (warning) -> ORIGIN=Y\n"
281
                       "813:77-1024:32-Just a note (info) -> ORIGIN=Z\n"
282
                       "0:0-0:0-Some unknown sev (???) -> ORIGIN=W\n")
283
        regex = (r"(?P<line>\d+):(?P<column>\d+)-"
284
                 r"(?P<end_line>\d+):(?P<end_column>\d+)-"
285
                 r"(?P<message>.*) \((?P<severity>.*)\) -> "
286
                 r"ORIGIN=(?P<origin>.*)")
287
288
        uut = (linter(sys.executable,
0 ignored issues
show
Bug introduced by
linter(sys.executable, o...)(self.EmptyTestLinter) does not seem to be callable.
Loading history...
289
                      output_format="regex",
290
                      output_regex=regex)
291
               (self.EmptyTestLinter)
292
               (self.section, None))
293
        uut.warn = Mock()
294
295
        sample_file = "some-file.xtx"
296
        results = list(uut.process_output(test_output, sample_file, [""]))
297
        expected = [Result.from_values("EmptyTestLinter (X)",
298
                                       "Serious issue",
299
                                       sample_file,
300
                                       12, 4, 14, 0,
301
                                       RESULT_SEVERITY.MAJOR),
302
                    Result.from_values("EmptyTestLinter (Y)",
303
                                       "This is a warning",
304
                                       sample_file,
305
                                       0, 0, 0, 1,
306
                                       RESULT_SEVERITY.NORMAL),
307
                    Result.from_values("EmptyTestLinter (Z)",
308
                                       "Just a note",
309
                                       sample_file,
310
                                       813, 77, 1024, 32,
311
                                       RESULT_SEVERITY.INFO),
312
                    Result.from_values("EmptyTestLinter (W)",
313
                                       "Some unknown sev",
314
                                       sample_file,
315
                                       0, 0, 0, 0,
316
                                       RESULT_SEVERITY.NORMAL)]
317
318
        self.assertEqual(results, expected)
319
        uut.warn.assert_called_once_with(
320
            "'???' not found in severity-map. Assuming "
321
            "`RESULT_SEVERITY.NORMAL`.")
322
323
        # Test when providing a sequence as output.
324
        test_output = ["", "12:4-14:0-Serious issue (error) -> ORIGIN=X\n"]
325
        results = list(uut.process_output(test_output, sample_file, [""]))
326
        expected = [Result.from_values("EmptyTestLinter (X)",
327
                                       "Serious issue",
328
                                       sample_file,
329
                                       12, 4, 14, 0,
330
                                       RESULT_SEVERITY.MAJOR)]
331
332
        self.assertEqual(results, expected)
333
334
    def test_get_non_optional_settings(self):
335
        class Handler(self.ManualProcessingTestLinter):
336
337
            @staticmethod
338
            def create_arguments(filename, file, config_file, param_x: int):
339
                pass
340
341
            @staticmethod
342
            def generate_config(filename, file, superparam):
343
                """
344
                :param superparam: A superparam!
345
                """
346
                return None
347
348
        uut = linter(sys.executable)(Handler)
349
350
        self.assertEqual(uut.get_non_optional_settings(),
351
                         {"param_x": ("No description given.", int),
352
                          "superparam": ("A superparam!", None)})
353
354
    def test_section_settings_forwarding(self):
355
        create_arguments_mock = Mock()
356
        generate_config_mock = Mock()
357
        process_output_mock = Mock()
358
359
        class Handler(self.ManualProcessingTestLinter):
360
361
            @staticmethod
362
            def create_arguments(filename, file, config_file, my_param: int):
363
                create_arguments_mock(filename, file, config_file, my_param)
364
                # Execute python and do nothing.
365
                return "-c", "print('coala!')"
366
367
            @staticmethod
368
            def generate_config(filename, file, my_config_param: int):
369
                generate_config_mock(filename, file, my_config_param)
370
                return None
371
372
            def process_output(self, output, filename, file, makman2: str):
373
                process_output_mock(output, filename, file, makman2)
374
375
        self.section["my_param"] = "109"
376
        self.section["my_config_param"] = "88"
377
        self.section["makman2"] = "is cool"
378
379
        uut = linter(sys.executable)(Handler)(self.section, None)
1 ignored issue
show
Bug introduced by
linter(sys.executable)(Handler) does not seem to be callable.
Loading history...
380
381
        self.assertIsNotNone(list(uut.execute(filename="some_file.cs",
382
                                              file=[])))
383
        create_arguments_mock.assert_called_once_with(
384
            "some_file.cs", [], None, 109)
385
        generate_config_mock.assert_called_once_with("some_file.cs", [], 88)
386
        process_output_mock.assert_called_once_with(
387
            "coala!\n", "some_file.cs", [], "is cool")
388
389
    def test_section_settings_defaults_forwarding(self):
390
        create_arguments_mock = Mock()
391
        generate_config_mock = Mock()
392
        process_output_mock = Mock()
393
394
        class Handler:
395
396
            @staticmethod
397
            def generate_config(filename, file, some_default: str="x"):
398
                generate_config_mock(filename, file, some_default)
399
                return None
400
401
            @staticmethod
402
            def create_arguments(filename, file, config_file, default: int=3):
403
                create_arguments_mock(
404
                    filename, file, config_file, default)
405
                return "-c", "print('hello')"
406
407
            @staticmethod
408
            def process_output(output, filename, file, xxx: int=64):
409
                process_output_mock(output, filename, file, xxx)
410
411
        uut = linter(sys.executable)(Handler)(self.section, None)
1 ignored issue
show
Bug introduced by
linter(sys.executable)(Handler) does not seem to be callable.
Loading history...
412
413
        self.assertIsNotNone(list(uut.execute(filename="abc.py", file=[])))
414
        create_arguments_mock.assert_called_once_with("abc.py", [], None, 3)
415
        generate_config_mock.assert_called_once_with("abc.py", [], "x")
416
        process_output_mock.assert_called_once_with(
417
            "hello\n", "abc.py", [], 64)
418
419
        create_arguments_mock.reset_mock()
420
        generate_config_mock.reset_mock()
421
        process_output_mock.reset_mock()
422
423
        self.section["default"] = "1000"
424
        self.section["some_default"] = "xyz"
425
        self.section["xxx"] = "-50"
426
        self.assertIsNotNone(list(uut.execute(filename="def.py", file=[])))
427
        create_arguments_mock.assert_called_once_with("def.py", [], None, 1000)
428
        generate_config_mock.assert_called_once_with("def.py", [], "xyz")
429
        process_output_mock.assert_called_once_with(
430
            "hello\n", "def.py", [], -50)
431
432
    def test_generate_config(self):
433
        uut = linter("")(self.ManualProcessingTestLinter)
434
        with uut._create_config("filename", []) as config_file:
435
            self.assertIsNone(config_file)
436
437
        class ConfigurationTestLinter(self.ManualProcessingTestLinter):
438
439
            @staticmethod
440
            def generate_config(filename, file, val):
441
                return "config_value = " + str(val)
442
443
        uut = linter("", config_suffix=".xml")(ConfigurationTestLinter)
444
        with uut._create_config("filename", [], val=88) as config_file:
445
            self.assertTrue(os.path.isfile(config_file))
446
            self.assertEqual(config_file[-4:], ".xml")
447
            with open(config_file, mode="r") as fl:
448
                self.assertEqual(fl.read(), "config_value = 88")
449
        self.assertFalse(os.path.isfile(config_file))
450
451
    def test_metaclass_repr(self):
452
        uut = linter("my-tool")(self.ManualProcessingTestLinter)
453
        self.assertEqual(
454
            repr(uut),
455
            "<ManualProcessingTestLinter linter class (wrapping 'my-tool')>")
456
457
        # Test also whether derivatives change the class name accordingly.
458
        class DerivedLinter(uut):
459
            pass
460
        self.assertEqual(repr(DerivedLinter),
461
                         "<DerivedLinter linter class (wrapping 'my-tool')>")
462
463
    def test_repr(self):
464
        uut = (linter(sys.executable)
0 ignored issues
show
Bug introduced by
linter(sys.executable)(s...alProcessingTestLinter) does not seem to be callable.
Loading history...
465
               (self.ManualProcessingTestLinter)
466
               (self.section, None))
467
468
        self.assertEqual(
469
            repr(uut),
470
            "<ManualProcessingTestLinter linter object (wrapping " +
471
            repr(sys.executable) + ")>")
472
473
474
class LinterReallifeTest(unittest.TestCase):
475
476
    def setUp(self):
477
        self.section = Section("REALLIFE_TEST_SECTION")
478
479
        self.test_program_path = get_testfile_name("test_linter.py")
480
        self.test_program_regex = (
481
            r"L(?P<line>\d+)C(?P<column>\d+)-"
482
            r"L(?P<end_line>\d+)C(?P<end_column>\d+):"
483
            r" (?P<message>.*) \| (?P<severity>.+) SEVERITY")
484
        self.test_program_severity_map = {"MAJOR": RESULT_SEVERITY.MAJOR}
485
486
        self.testfile_path = get_testfile_name("test_file.txt")
487
        with open(self.testfile_path, mode="r") as fl:
488
            self.testfile_content = fl.read().splitlines(keepends=True)
489
490
        self.testfile2_path = get_testfile_name("test_file2.txt")
491
        with open(self.testfile2_path, mode="r") as fl:
492
            self.testfile2_content = fl.read().splitlines(keepends=True)
493
494
    def test_nostdin_nostderr_noconfig_nocorrection(self):
495
        create_arguments_mock = Mock()
496
497
        class Handler:
498
499
            @staticmethod
500
            def create_arguments(filename, file, config_file):
501
                create_arguments_mock(filename, file, config_file)
502
                return self.test_program_path, filename
503
504
        uut = (linter(sys.executable,
0 ignored issues
show
Bug introduced by
linter(sys.executable, o..._severity_map)(Handler) does not seem to be callable.
Loading history...
505
                      output_format="regex",
506
                      output_regex=self.test_program_regex,
507
                      severity_map=self.test_program_severity_map)
508
               (Handler)
509
               (self.section, None))
510
511
        results = list(uut.run(self.testfile_path, self.testfile_content))
512
        expected = [Result.from_values(uut,
513
                                       "Invalid char ('0')",
514
                                       self.testfile_path,
515
                                       3, 0, 3, 1,
516
                                       RESULT_SEVERITY.MAJOR),
517
                    Result.from_values(uut,
518
                                       "Invalid char ('.')",
519
                                       self.testfile_path,
520
                                       5, 0, 5, 1,
521
                                       RESULT_SEVERITY.MAJOR),
522
                    Result.from_values(uut,
523
                                       "Invalid char ('p')",
524
                                       self.testfile_path,
525
                                       9, 0, 9, 1,
526
                                       RESULT_SEVERITY.MAJOR)]
527
528
        self.assertEqual(results, expected)
529
        create_arguments_mock.assert_called_once_with(
530
            self.testfile_path, self.testfile_content, None)
531
532
    def test_stdin_stderr_noconfig_nocorrection(self):
533
        create_arguments_mock = Mock()
534
535
        class Handler:
536
537
            @staticmethod
538
            def create_arguments(filename, file, config_file):
539
                create_arguments_mock(filename, file, config_file)
540
                return (self.test_program_path,
541
                        "--use_stderr",
542
                        "--use_stdin",
543
                        filename)
544
545
        uut = (linter(sys.executable,
0 ignored issues
show
Bug introduced by
linter(sys.executable, u..._severity_map)(Handler) does not seem to be callable.
Loading history...
546
                      use_stdin=True,
547
                      use_stdout=False,
548
                      use_stderr=True,
549
                      output_format="regex",
550
                      output_regex=self.test_program_regex,
551
                      severity_map=self.test_program_severity_map)
552
               (Handler)
553
               (self.section, None))
554
555
        results = list(uut.run(self.testfile2_path, self.testfile2_content))
556
        expected = [Result.from_values(uut,
557
                                       "Invalid char ('X')",
558
                                       self.testfile2_path,
559
                                       0, 0, 0, 1,
560
                                       RESULT_SEVERITY.MAJOR),
561
                    Result.from_values(uut,
562
                                       "Invalid char ('i')",
563
                                       self.testfile2_path,
564
                                       4, 0, 4, 1,
565
                                       RESULT_SEVERITY.MAJOR)]
566
567
        self.assertEqual(results, expected)
568
        create_arguments_mock.assert_called_once_with(
569
            self.testfile2_path, self.testfile2_content, None)
570
571
    def test_nostdin_nostderr_noconfig_correction(self):
572
        create_arguments_mock = Mock()
573
574
        class Handler:
575
576
            @staticmethod
577
            def create_arguments(filename, file, config_file):
578
                create_arguments_mock(filename, file, config_file)
579
                return self.test_program_path, "--correct", filename
580
581
        uut = (linter(sys.executable,
0 ignored issues
show
Bug introduced by
linter(sys.executable, o...stom message')(Handler) does not seem to be callable.
Loading history...
582
                      output_format="corrected",
583
                      diff_severity=RESULT_SEVERITY.INFO,
584
                      diff_message="Custom message")
585
               (Handler)
586
               (self.section, None))
587
588
        results = list(uut.run(self.testfile_path, self.testfile_content))
589
590
        expected_correction = [s + "\n"
591
                               for s in ["+", "-", "*", "++", "-", "-", "+"]]
592
593
        diffs = list(Diff.from_string_arrays(
594
            self.testfile_content,
595
            expected_correction).split_diff())
596
597
        expected = [Result.from_values(uut,
598
                                       "Custom message",
599
                                       self.testfile_path,
600
                                       4, None, 4, None,
601
                                       RESULT_SEVERITY.INFO,
602
                                       diffs={self.testfile_path: diffs[0]}),
603
                    Result.from_values(uut,
604
                                       "Custom message",
605
                                       self.testfile_path,
606
                                       6, None, 6, None,
607
                                       RESULT_SEVERITY.INFO,
608
                                       diffs={self.testfile_path: diffs[1]}),
609
                    Result.from_values(uut,
610
                                       "Custom message",
611
                                       self.testfile_path,
612
                                       10, None, 10, None,
613
                                       RESULT_SEVERITY.INFO,
614
                                       diffs={self.testfile_path: diffs[2]})]
615
616
        self.assertEqual(results, expected)
617
        create_arguments_mock.assert_called_once_with(
618
            self.testfile_path, self.testfile_content, None)
619
620
    def test_stdin_stdout_stderr_config_nocorrection(self):
621
        create_arguments_mock = Mock()
622
        generate_config_mock = Mock()
623
624
        class Handler:
625
626
            @staticmethod
627
            def generate_config(filename, file, some_val):
628
                # some_val shall only test the argument delegation from run().
629
                generate_config_mock(filename, file, some_val)
630
                return "\n".join(["use_stdin", "use_stderr"])
631
632
            @staticmethod
633
            def create_arguments(filename, file, config_file, some_val):
634
                create_arguments_mock(filename, file, config_file, some_val)
635
                return self.test_program_path, "--config", config_file
636
637
        uut = (linter(sys.executable,
0 ignored issues
show
Bug introduced by
linter(sys.executable, u..._severity_map)(Handler) does not seem to be callable.
Loading history...
638
                      use_stdin=True,
639
                      use_stderr=True,
640
                      output_format="regex",
641
                      output_regex=self.test_program_regex,
642
                      severity_map=self.test_program_severity_map)
643
               (Handler)
644
               (self.section, None))
645
646
        results = list(uut.run(self.testfile_path,
647
                               self.testfile_content,
648
                               some_val=33))
649
        expected = [Result.from_values(uut,
650
                                       "Invalid char ('0')",
651
                                       self.testfile_path,
652
                                       3, 0, 3, 1,
653
                                       RESULT_SEVERITY.MAJOR),
654
                    Result.from_values(uut,
655
                                       "Invalid char ('.')",
656
                                       self.testfile_path,
657
                                       5, 0, 5, 1,
658
                                       RESULT_SEVERITY.MAJOR),
659
                    Result.from_values(uut,
660
                                       "Invalid char ('p')",
661
                                       self.testfile_path,
662
                                       9, 0, 9, 1,
663
                                       RESULT_SEVERITY.MAJOR)]
664
665
        self.assertEqual(results, expected)
666
        create_arguments_mock.assert_called_once_with(
667
            self.testfile_path, self.testfile_content, ANY, 33)
668
        self.assertIsNotNone(create_arguments_mock.call_args[0][2])
669
        generate_config_mock.assert_called_once_with(
670
            self.testfile_path, self.testfile_content, 33)
671
672
    def test_stdin_stderr_config_correction(self):
673
        create_arguments_mock = Mock()
674
        generate_config_mock = Mock()
675
676
        # `some_value_A` and `some_value_B` are used to test the different
677
        # delegation to `generate_config()` and `create_arguments()`
678
        # accordingly.
679
        class Handler:
680
681
            @staticmethod
682
            def generate_config(filename, file, some_value_A):
683
                generate_config_mock(filename, file, some_value_A)
684
                return "\n".join(["use_stdin", "use_stderr", "correct"])
685
686
            @staticmethod
687
            def create_arguments(filename, file, config_file, some_value_B):
688
                create_arguments_mock(filename, file, config_file,
689
                                      some_value_B)
690
                return self.test_program_path, "--config", config_file
691
692
        uut = (linter(sys.executable,
0 ignored issues
show
Bug introduced by
linter(sys.executable, u...uffix='.conf')(Handler) does not seem to be callable.
Loading history...
693
                      use_stdin=True,
694
                      use_stdout=False,
695
                      use_stderr=True,
696
                      output_format="corrected",
697
                      config_suffix=".conf")
698
               (Handler)
699
               (self.section, None))
700
701
        results = list(uut.run(self.testfile2_path,
702
                               self.testfile2_content,
703
                               some_value_A=124,
704
                               some_value_B=-78))
705
706
        expected_correction = ["+", "/", "/", "-"]
707
        expected_correction = [s + "\n" for s in expected_correction]
708
709
        diffs = list(Diff.from_string_arrays(
710
            self.testfile2_content,
711
            expected_correction).split_diff())
712
713
        expected = [Result.from_values(uut,
714
                                       "Inconsistency found.",
715
                                       self.testfile2_path,
716
                                       1, None, 1, None,
717
                                       RESULT_SEVERITY.NORMAL,
718
                                       diffs={self.testfile2_path: diffs[0]}),
719
                    Result.from_values(uut,
720
                                       "Inconsistency found.",
721
                                       self.testfile2_path,
722
                                       5, None, 5, None,
723
                                       RESULT_SEVERITY.NORMAL,
724
                                       diffs={self.testfile2_path: diffs[1]})]
725
726
        self.assertEqual(results, expected)
727
        create_arguments_mock.assert_called_once_with(
728
            self.testfile2_path, self.testfile2_content, ANY, -78)
729
        self.assertEqual(create_arguments_mock.call_args[0][2][-5:], ".conf")
730
        generate_config_mock.assert_called_once_with(
731
            self.testfile2_path, self.testfile2_content, 124)
732