Failed Conditions
Pull Request — master (#1990)
by Mischa
01:38
created

ManualProcessingTestLinter   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 4
Duplicated Lines 0 %
Metric Value
dl 0
loc 4
rs 10
wmc 1

1 Method

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