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

test_section_settings_forwarding()   B

Complexity

Conditions 1

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
dl 0
loc 34
rs 8.8571

1 Method

Rating   Name   Duplication   Size   Complexity  
A Handler.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
            def process_output(self, output, filename, file):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
210
                process_output_mock(output, filename, file)
211
212
            @staticmethod
213
            def create_arguments(filename, file, config_file):
214
                code = "\n".join(["import sys",
215
                                  "print('hello stdout')",
216
                                  "print('hello stderr', file=sys.stderr)"])
217
                return "-c", code
218
219
        uut = (Linter(sys.executable, use_stdout=True)
220
               (TestLinter)
221
               (self.section, None))
222
        uut.run("", [])
223
224
        process_output_mock.assert_called_once_with("hello stdout\n", "", [])
225
        process_output_mock.reset_mock()
226
227
        uut = (Linter(sys.executable, use_stdout=False, use_stderr=True)
228
               (TestLinter)
229
               (self.section, None))
230
        uut.run("", [])
231
232
        process_output_mock.assert_called_once_with("hello stderr\n", "", [])
233
        process_output_mock.reset_mock()
234
235
        uut = (Linter(sys.executable, use_stdout=True, use_stderr=True)
236
               (TestLinter)
237
               (self.section, None))
238
239
        uut.run("", [])
240
241
        process_output_mock.assert_called_once_with(("hello stdout\n",
242
                                                     "hello stderr\n"), "", [])
243
244
    def test_execute_command(self):
245
        test_program_path = get_testfile_name("stdout_stderr.py")
246
        uut = Linter(sys.executable)(self.ManualProcessingTestLinter)
247
248
        # The test program puts out the stdin content (only the first line) to
249
        # stdout and the arguments passed to stderr.
250
        stdout, stderr = uut._execute_command(
251
            [test_program_path, "some_argument"],
252
            stdin="display content")
253
254
        self.assertEqual(stdout, "display content\n")
255
        self.assertEqual(stderr, "['some_argument']\n")
256
257
    def test_process_output_corrected(self):
258
        uut = (Linter(sys.executable, output_format="corrected")
259
               (self.EmptyTestLinter)
260
               (self.section, None))
261
262
        original = [s + "\n" for s in ["void main()  {", "return 09;", "}"]]
263
        fixed = [s + "\n" for s in ["void main()", "{", "return 9;", "}"]]
264
        fixed_string = "".join(fixed)
265
266
        results = list(uut.process_output(fixed_string,
267
                                          "some-file.c",
268
                                          original))
269
270
        diffs = list(Diff.from_string_arrays(original, fixed).split_diff())
271
        expected = [Result.from_values(uut,
272
                                       "Inconsistency found.",
273
                                       "some-file.c",
274
                                       1, None, 2, None,
275
                                       RESULT_SEVERITY.NORMAL,
276
                                       diffs={"some-file.c": diffs[0]})]
277
278
        self.assertEqual(results, expected)
279
280
        # Test when providing a sequence as output.
281
282
        results = list(uut.process_output([fixed_string, fixed_string],
283
                                          "some-file.c",
284
                                          original))
285
        self.assertEqual(results, 2 * expected)
286
287
    def test_process_output_regex(self):
288
        # Also test the case when an unknown severity is matched.
289
        test_output = ("12:4-14:0-Serious issue (error) -> ORIGIN=X\n"
290
                       "0:0-0:1-This is a warning (warning) -> ORIGIN=Y\n"
291
                       "813:77-1024:32-Just a note (info) -> ORIGIN=Z\n"
292
                       "0:0-0:0-Some unknown sev (???) -> ORIGIN=W\n")
293
        regex = (r"(?P<line>\d+):(?P<column>\d+)-"
294
                 r"(?P<end_line>\d+):(?P<end_column>\d+)-"
295
                 r"(?P<message>.*) \((?P<severity>.*)\) -> "
296
                 r"ORIGIN=(?P<origin>.*)")
297
298
        uut = (Linter(sys.executable,
299
                      output_format="regex",
300
                      output_regex=regex)
301
               (self.EmptyTestLinter)
302
               (self.section, None))
303
        uut.warn = Mock()
304
305
        sample_file = "some-file.xtx"
306
        results = list(uut.process_output(test_output, sample_file, [""]))
307
        expected = [Result.from_values("EmptyTestLinter (X)",
308
                                       "Serious issue",
309
                                       sample_file,
310
                                       12, 4, 14, 0,
311
                                       RESULT_SEVERITY.MAJOR),
312
                    Result.from_values("EmptyTestLinter (Y)",
313
                                       "This is a warning",
314
                                       sample_file,
315
                                       0, 0, 0, 1,
316
                                       RESULT_SEVERITY.NORMAL),
317
                    Result.from_values("EmptyTestLinter (Z)",
318
                                       "Just a note",
319
                                       sample_file,
320
                                       813, 77, 1024, 32,
321
                                       RESULT_SEVERITY.INFO),
322
                    Result.from_values("EmptyTestLinter (W)",
323
                                       "Some unknown sev",
324
                                       sample_file,
325
                                       0, 0, 0, 0,
326
                                       RESULT_SEVERITY.NORMAL)]
327
328
        self.assertEqual(results, expected)
329
        uut.warn.assert_called_once_with(
330
            "No correspondence for '???' found in given severity map. "
331
            "Assuming `RESULT_SEVERITY.NORMAL`.")
332
333
        # Test when providing a sequence as output.
334
        test_output = ["", "12:4-14:0-Serious issue (error) -> ORIGIN=X\n"]
335
        results = list(uut.process_output(test_output, sample_file, [""]))
336
        expected = [Result.from_values("EmptyTestLinter (X)",
337
                                       "Serious issue",
338
                                       sample_file,
339
                                       12, 4, 14, 0,
340
                                       RESULT_SEVERITY.MAJOR)]
341
342
        self.assertEqual(results, expected)
343
344
    def test_get_non_optional_settings(self):
345
        class Handler(self.ManualProcessingTestLinter):
346
347
            @staticmethod
348
            def create_arguments(filename, file, config_file, param_x: int):
349
                pass
350
351
            @staticmethod
352
            def generate_config(filename, file, superparam):
353
                """
354
                :param superparam: A superparam!
355
                """
356
                return None
357
358
        uut = Linter(sys.executable)(Handler)
359
360
        self.assertEqual(uut.get_non_optional_settings(),
361
                         {"param_x": ("No description given.", int),
362
                          "superparam": ("A superparam!", None)})
363
364
    def test_section_settings_forwarding(self):
365
        create_arguments_mock = Mock()
366
        generate_config_mock = Mock()
367
        process_output_mock = Mock()
368
369
        class Handler(self.ManualProcessingTestLinter):
370
371
            @staticmethod
372
            def create_arguments(filename, file, config_file, my_param: int):
373
                create_arguments_mock(filename, file, config_file, my_param)
374
                # Execute python and do nothing.
375
                return "-c", "print('coala!')"
376
377
            @staticmethod
378
            def generate_config(filename, file, my_config_param: int):
379
                generate_config_mock(filename, file, my_config_param)
380
                return None
381
382
            def process_output(self, output, filename, file, makman2: str):
383
                process_output_mock(output, filename, file, makman2)
384
385
        self.section["my_param"] = "109"
386
        self.section["my_config_param"] = "88"
387
        self.section["makman2"] = "is cool"
388
389
        uut = Linter(sys.executable)(Handler)(self.section, None)
390
391
        self.assertIsNotNone(list(uut.execute(filename="some_file.cs",
392
                                              file=[])))
393
        create_arguments_mock.assert_called_once_with(
394
            "some_file.cs", [], None, 109)
395
        generate_config_mock.assert_called_once_with("some_file.cs", [], 88)
396
        process_output_mock.assert_called_once_with(
397
            "coala!\n", "some_file.cs", [], "is cool")
398
399
    def test_section_settings_defaults_forwarding(self):
400
        create_arguments_mock = Mock()
401
        generate_config_mock = Mock()
402
        process_output_mock = Mock()
403
404
        class Handler:
405
406
            @staticmethod
407
            def generate_config(filename, file, some_default: str="x"):
408
                generate_config_mock(filename, file, some_default)
409
                return None
410
411
            @staticmethod
412
            def create_arguments(filename, file, config_file, default: int=3):
413
                create_arguments_mock(
414
                    filename, file, config_file, default)
415
                return "-c", "print('hello')"
416
417
            def process_output(self, output, filename, file, xxx: int=64):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
418
                process_output_mock(output, filename, file, xxx)
419
420
        uut = Linter(sys.executable)(Handler)(self.section, None)
421
422
        self.assertIsNotNone(list(uut.execute(filename="abc.py", file=[])))
423
        create_arguments_mock.assert_called_once_with("abc.py", [], None, 3)
424
        generate_config_mock.assert_called_once_with("abc.py", [], "x")
425
        process_output_mock.assert_called_once_with(
426
            "hello\n", "abc.py", [], 64)
427
428
        create_arguments_mock.reset_mock()
429
        generate_config_mock.reset_mock()
430
        process_output_mock.reset_mock()
431
432
        self.section["default"] = "1000"
433
        self.section["some_default"] = "xyz"
434
        self.section["xxx"] = "-50"
435
        self.assertIsNotNone(list(uut.execute(filename="def.py", file=[])))
436
        create_arguments_mock.assert_called_once_with("def.py", [], None, 1000)
437
        generate_config_mock.assert_called_once_with("def.py", [], "xyz")
438
        process_output_mock.assert_called_once_with(
439
            "hello\n", "def.py", [], -50)
440
441
    def test_generate_config(self):
442
        uut = Linter("")(self.ManualProcessingTestLinter)
443
        with uut._create_config("filename", []) as config_file:
444
            self.assertIsNone(config_file)
445
446
        class ConfigurationTestLinter(self.ManualProcessingTestLinter):
447
448
            @staticmethod
449
            def generate_config(filename, file, val):
450
                return "config_value = " + str(val)
451
452
        uut = Linter("", config_suffix=".xml")(ConfigurationTestLinter)
453
        with uut._create_config("filename", [], val=88) as config_file:
454
            self.assertTrue(os.path.isfile(config_file))
455
            self.assertEqual(config_file[-4:], ".xml")
456
            with open(config_file, mode="r") as fl:
457
                self.assertEqual(fl.read(), "config_value = 88")
458
        self.assertFalse(os.path.isfile(config_file))
459
460
461
class LinterReallifeTest(unittest.TestCase):
462
463
    def setUp(self):
464
        self.section = Section("REALLIFE_TEST_SECTION")
465
466
        self.test_program_path = get_testfile_name("test_linter.py")
467
        self.test_program_regex = (
468
            r"L(?P<line>\d+)C(?P<column>\d+)-"
469
            r"L(?P<end_line>\d+)C(?P<end_column>\d+):"
470
            r" (?P<message>.*) \| (?P<severity>.+) SEVERITY")
471
        self.test_program_severity_map = {"MAJOR": RESULT_SEVERITY.MAJOR}
472
473
        self.testfile_path = get_testfile_name("test_file.txt")
474
        with open(self.testfile_path, mode="r") as fl:
475
            self.testfile_content = fl.read().splitlines(keepends=True)
476
477
        self.testfile2_path = get_testfile_name("test_file2.txt")
478
        with open(self.testfile2_path, mode="r") as fl:
479
            self.testfile2_content = fl.read().splitlines(keepends=True)
480
481
    def test_nostdin_nostderr_noconfig_nocorrection(self):
482
        create_arguments_mock = Mock()
483
484
        class Handler:
485
486
            @staticmethod
487
            def create_arguments(filename, file, config_file):
488
                create_arguments_mock(filename, file, config_file)
489
                return self.test_program_path, filename
490
491
        uut = (Linter(sys.executable,
492
                      output_format="regex",
493
                      output_regex=self.test_program_regex,
494
                      severity_map=self.test_program_severity_map)
495
               (Handler)
496
               (self.section, None))
497
498
        results = list(uut.run(self.testfile_path, self.testfile_content))
499
        expected = [Result.from_values(uut,
500
                                       "Invalid char ('0')",
501
                                       self.testfile_path,
502
                                       3, 0, 3, 1,
503
                                       RESULT_SEVERITY.MAJOR),
504
                    Result.from_values(uut,
505
                                       "Invalid char ('.')",
506
                                       self.testfile_path,
507
                                       5, 0, 5, 1,
508
                                       RESULT_SEVERITY.MAJOR),
509
                    Result.from_values(uut,
510
                                       "Invalid char ('p')",
511
                                       self.testfile_path,
512
                                       9, 0, 9, 1,
513
                                       RESULT_SEVERITY.MAJOR)]
514
515
        self.assertEqual(results, expected)
516
        create_arguments_mock.assert_called_once_with(
517
            self.testfile_path, self.testfile_content, None)
518
519
    def test_stdin_stderr_noconfig_nocorrection(self):
520
        create_arguments_mock = Mock()
521
522
        class Handler:
523
524
            @staticmethod
525
            def create_arguments(filename, file, config_file):
526
                create_arguments_mock(filename, file, config_file)
527
                return (self.test_program_path,
528
                        "--use_stderr",
529
                        "--use_stdin",
530
                        filename)
531
532
        uut = (Linter(sys.executable,
533
                      use_stdin=True,
534
                      use_stdout=False,
535
                      use_stderr=True,
536
                      output_format="regex",
537
                      output_regex=self.test_program_regex,
538
                      severity_map=self.test_program_severity_map)
539
               (Handler)
540
               (self.section, None))
541
542
        results = list(uut.run(self.testfile2_path, self.testfile2_content))
543
        expected = [Result.from_values(uut,
544
                                       "Invalid char ('X')",
545
                                       self.testfile2_path,
546
                                       0, 0, 0, 1,
547
                                       RESULT_SEVERITY.MAJOR),
548
                    Result.from_values(uut,
549
                                       "Invalid char ('i')",
550
                                       self.testfile2_path,
551
                                       4, 0, 4, 1,
552
                                       RESULT_SEVERITY.MAJOR)]
553
554
        self.assertEqual(results, expected)
555
        create_arguments_mock.assert_called_once_with(
556
            self.testfile2_path, self.testfile2_content, None)
557
558
    def test_nostdin_nostderr_noconfig_correction(self):
559
        create_arguments_mock = Mock()
560
561
        class Handler:
562
563
            @staticmethod
564
            def create_arguments(filename, file, config_file):
565
                create_arguments_mock(filename, file, config_file)
566
                return self.test_program_path, "--correct", filename
567
568
        uut = (Linter(sys.executable,
569
                      output_format="corrected",
570
                      diff_severity=RESULT_SEVERITY.INFO,
571
                      diff_message="Custom message")
572
               (Handler)
573
               (self.section, None))
574
575
        results = list(uut.run(self.testfile_path, self.testfile_content))
576
577
        expected_correction = [s + "\n"
578
                               for s in ["+", "-", "*", "++", "-", "-", "+"]]
579
580
        diffs = list(Diff.from_string_arrays(
581
            self.testfile_content,
582
            expected_correction).split_diff())
583
584
        expected = [Result.from_values(uut,
585
                                       "Custom message",
586
                                       self.testfile_path,
587
                                       4, None, 4, None,
588
                                       RESULT_SEVERITY.INFO,
589
                                       diffs={self.testfile_path: diffs[0]}),
590
                    Result.from_values(uut,
591
                                       "Custom message",
592
                                       self.testfile_path,
593
                                       6, None, 6, None,
594
                                       RESULT_SEVERITY.INFO,
595
                                       diffs={self.testfile_path: diffs[1]}),
596
                    Result.from_values(uut,
597
                                       "Custom message",
598
                                       self.testfile_path,
599
                                       10, None, 10, None,
600
                                       RESULT_SEVERITY.INFO,
601
                                       diffs={self.testfile_path: diffs[2]})]
602
603
        self.assertEqual(results, expected)
604
        create_arguments_mock.assert_called_once_with(
605
            self.testfile_path, self.testfile_content, None)
606
607
    def test_stdin_stdout_stderr_config_nocorrection(self):
608
        create_arguments_mock = Mock()
609
        generate_config_mock = Mock()
610
611
        class Handler:
612
613
            @staticmethod
614
            def generate_config(filename, file, some_val):
615
                # some_val shall only test the argument delegation from run().
616
                generate_config_mock(filename, file, some_val)
617
                return "\n".join(["use_stdin", "use_stderr"])
618
619
            @staticmethod
620
            def create_arguments(filename, file, config_file, some_val):
621
                create_arguments_mock(filename, file, config_file, some_val)
622
                return self.test_program_path, "--config", config_file
623
624
        uut = (Linter(sys.executable,
625
                      use_stdin=True,
626
                      use_stderr=True,
627
                      output_format="regex",
628
                      output_regex=self.test_program_regex,
629
                      severity_map=self.test_program_severity_map)
630
               (Handler)
631
               (self.section, None))
632
633
        results = list(uut.run(self.testfile_path,
634
                               self.testfile_content,
635
                               some_val=33))
636
        expected = [Result.from_values(uut,
637
                                       "Invalid char ('0')",
638
                                       self.testfile_path,
639
                                       3, 0, 3, 1,
640
                                       RESULT_SEVERITY.MAJOR),
641
                    Result.from_values(uut,
642
                                       "Invalid char ('.')",
643
                                       self.testfile_path,
644
                                       5, 0, 5, 1,
645
                                       RESULT_SEVERITY.MAJOR),
646
                    Result.from_values(uut,
647
                                       "Invalid char ('p')",
648
                                       self.testfile_path,
649
                                       9, 0, 9, 1,
650
                                       RESULT_SEVERITY.MAJOR)]
651
652
        self.assertEqual(results, expected)
653
        create_arguments_mock.assert_called_once_with(
654
            self.testfile_path, self.testfile_content, ANY, 33)
655
        self.assertIsNotNone(create_arguments_mock.call_args[0][2])
656
        generate_config_mock.assert_called_once_with(
657
            self.testfile_path, self.testfile_content, 33)
658
659
    def test_stdin_stderr_config_correction(self):
660
        create_arguments_mock = Mock()
661
        generate_config_mock = Mock()
662
663
        # `some_value_A` and `some_value_B` are used to test the different
664
        # delegation to `generate_config()` and `create_arguments()`
665
        # accordingly.
666
        class Handler:
667
668
            @staticmethod
669
            def generate_config(filename, file, some_value_A):
670
                generate_config_mock(filename, file, some_value_A)
671
                return "\n".join(["use_stdin", "use_stderr", "correct"])
672
673
            @staticmethod
674
            def create_arguments(filename, file, config_file, some_value_B):
675
                create_arguments_mock(filename, file, config_file,
676
                                      some_value_B)
677
                return self.test_program_path, "--config", config_file
678
679
        uut = (Linter(sys.executable,
680
                      use_stdin=True,
681
                      use_stdout=False,
682
                      use_stderr=True,
683
                      output_format="corrected",
684
                      config_suffix=".conf")
685
               (Handler)
686
               (self.section, None))
687
688
        results = list(uut.run(self.testfile2_path,
689
                               self.testfile2_content,
690
                               some_value_A=124,
691
                               some_value_B=-78))
692
693
        expected_correction = ["+", "/", "/", "-"]
694
        expected_correction = [s + "\n" for s in expected_correction]
695
696
        diffs = list(Diff.from_string_arrays(
697
            self.testfile2_content,
698
            expected_correction).split_diff())
699
700
        expected = [Result.from_values(uut,
701
                                       "Inconsistency found.",
702
                                       self.testfile2_path,
703
                                       1, None, 1, None,
704
                                       RESULT_SEVERITY.NORMAL,
705
                                       diffs={self.testfile2_path: diffs[0]}),
706
                    Result.from_values(uut,
707
                                       "Inconsistency found.",
708
                                       self.testfile2_path,
709
                                       5, None, 5, None,
710
                                       RESULT_SEVERITY.NORMAL,
711
                                       diffs={self.testfile2_path: diffs[1]})]
712
713
        self.assertEqual(results, expected)
714
        create_arguments_mock.assert_called_once_with(
715
            self.testfile2_path, self.testfile2_content, ANY, -78)
716
        self.assertEqual(create_arguments_mock.call_args[0][2][-5:], ".conf")
717
        generate_config_mock.assert_called_once_with(
718
            self.testfile2_path, self.testfile2_content, 124)
719