Completed
Pull Request — master (#1162)
by Mischa
01:44
created

coalib.tests.output.ConsoleInteractionTest   D

Complexity

Total Complexity 58

Size/Duplication

Total Lines 488
Duplicated Lines 0 %
Metric Value
dl 0
loc 488
rs 4.8387
wmc 58

21 Methods

Rating   Name   Duplication   Size   Complexity  
B test_print_results_multiple_ranges() 0 30 4
A test_print_bears_no_needed_settings() 0 15 2
A test_print_results_project_wide() 0 12 2
A test_print_results_empty() 0 4 2
A test_print_results_missing_file() 0 19 2
A setUp() 0 12 3
A test_print_bears() 0 17 2
B test_show_bears() 0 23 4
A test_print_results_missing_line() 0 21 3
A test_print_bears_empty() 0 9 3
B test_require_settings() 0 24 2
A test_nothing_done() 0 6 2
A test_print_section_beginning() 0 4 2
B test_print_result_auto_apply() 0 59 4
D test_print_result() 0 90 8
A test_print_bears_no_settings() 0 12 2
A test_print_bears_no_sections() 0 11 2
A test_print_bears_no_optional_settings() 0 13 2
B test_print_results_for_file() 0 40 3
B test_print_results_sorting() 0 32 2
A test_print_results_without_line() 0 14 2

How to fix   Complexity   

Complex Class

Complex classes like coalib.tests.output.ConsoleInteractionTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import tempfile
2
import unittest
3
import sys
4
import os
5
from collections import OrderedDict
6
from pyprint.NullPrinter import NullPrinter
7
from pyprint.ConsolePrinter import ConsolePrinter
8
9
sys.path.insert(0, ".")
10
from coalib.results.result_actions.ResultAction import ResultAction
11
from coalib.results.Result import Result
12
from coalib.results.SourceRange import SourceRange
13
from coalib.results.Diff import Diff
14
from coalib.settings.Section import Section
15
from coalib.settings.Setting import Setting
16
from coalib.misc.ContextManagers import (simulate_console_inputs,
17
                                         retrieve_stdout)
18
from coalib.output.ConsoleInteraction import (CLI_ACTIONS,
19
                                              nothing_done,
20
                                              acquire_settings,
21
                                              print_bears,
22
                                              get_action_info,
23
                                              print_result,
24
                                              print_section_beginning,
25
                                              print_results,
26
                                              show_bears,
27
                                              print_results_formatted)
28
from coalib.output.printers.LogPrinter import LogPrinter
29
from coalib.output.printers.StringPrinter import StringPrinter
30
from coalib.results.result_actions.ApplyPatchAction import ApplyPatchAction
31
from coalib.results.result_actions.OpenEditorAction import OpenEditorAction
32
from coalib.bears.Bear import Bear
33
from bears.general.KeywordBear import KeywordBear
34
from bears.general.LineLengthBear import LineLengthBear
35
36
37
STR_GET_VAL_FOR_SETTING = ("Please enter a value for the setting \"{}\" ({}) "
38
                           "needed by {}: ")
39
STR_LINE_DOESNT_EXIST = ("The line belonging to the following result "
40
                         "cannot be printed because it refers to a line "
41
                         "that doesn't seem to exist in the given file.")
42
STR_PROJECT_WIDE = "Project wide:"
43
44
45
class TestAction(ResultAction):
46
    def apply(self, result, original_file_dict, file_diff_dict, param):
47
        pass
48
49
50
class RaisingAction(ResultAction):
51
    def apply(self, *args):
52
        raise AssertionError
53
54
55
class TestBear(Bear):
56
    def run(self, setting1, setting2: int=None):
57
        """
58
        Test bear Description.
59
60
        :param setting1: Required Setting.
61
        :param setting2: Optional Setting.
62
        """
63
        return None
64
65
66
class TestBear2(Bear):
67
    def run(self, setting1):
68
        """
69
        Test bear 2 description.
70
71
        :param setting1: Required Setting.
72
        """
73
        return None
74
75
class SomeBear(Bear):
76
    def run(self):
77
        """
78
        Some Description.
79
        """
80
        return None
81
82
83
class SomeOtherBear(Bear):
84
    def run(self, setting: int=None):
85
        """
86
        This is a Bear.
87
        :param setting: This is an optional setting.
88
        """
89
        setting = 1
90
        return None
91
92
93
class SomeglobalBear(Bear):
94
    def run(self):
95
        """
96
        Some Description.
97
        """
98
        return None
99
100
101
class ConsoleInteractionTest(unittest.TestCase):
102
    def setUp(self):
103
        self.log_printer = LogPrinter(ConsolePrinter(print_colored=False))
104
        self.console_printer = ConsolePrinter(print_colored=False)
105
        self.file_diff_dict = {}
106
        self.local_bears = OrderedDict([("default", [KeywordBear]),
107
                                        ("test", [LineLengthBear,
108
                                                  KeywordBear])])
109
        self.global_bears = OrderedDict([("default", [SomeglobalBear]),
110
                                         ("test", [SomeglobalBear])])
111
112
        OpenEditorAction.is_applicable = staticmethod(lambda *args: False)
113
        ApplyPatchAction.is_applicable = staticmethod(lambda *args: False)
114
115
    def test_require_settings(self):
116
        self.assertRaises(TypeError, acquire_settings, self.log_printer, 0)
117
        self.assertEqual(acquire_settings(self.log_printer, {0: 0}), {})
118
119
        with simulate_console_inputs(0, 1, 2) as generator:
120
            self.assertEqual(acquire_settings(self.log_printer,
121
                                              {"setting": ["help text",
122
                                                           "SomeBear"]}),
123
                             {"setting": 0})
124
125
            self.assertEqual(acquire_settings(self.log_printer,
126
                                              {"setting": ["help text",
127
                                                           "SomeBear",
128
                                                           "AnotherBear"]}),
129
                             {"setting": 1})
130
131
            self.assertEqual(acquire_settings(self.log_printer,
132
                                              {"setting": ["help text",
133
                                                           "SomeBear",
134
                                                           "AnotherBear",
135
                                                           "YetAnotherBear"]}),
136
                             {"setting": 2})
137
138
            self.assertEqual(generator.last_input, 2)
139
140
    def test_print_result(self):
141
        print_result(self.console_printer,
142
                     self.log_printer,
143
                     None,
144
                     self.file_diff_dict,
145
                     "illegal value",
146
                     {})
147
148
        with simulate_console_inputs(0):
149
            print_result(self.console_printer,
150
                         self.log_printer,
151
                         None,
152
                         self.file_diff_dict,
153
                         Result("origin", "msg", diffs={}),
154
                         {})
155
156
        (testfile, testfile_path) = tempfile.mkstemp()
157
        os.close(testfile)
158
        file_dict = {
159
            testfile_path: ["1\n", "2\n", "3\n"],
160
            "f_b": ["1", "2", "3"]
161
        }
162
        diff = Diff(file_dict[testfile_path])
163
        diff.delete_line(2)
164
        diff.change_line(3, "3\n", "3_changed\n")
165
166
        with simulate_console_inputs(1), self.assertRaises(ValueError):
167
            ApplyPatchAction.is_applicable = staticmethod(lambda *args: True)
168
            print_result(self.console_printer,
169
                         self.log_printer,
170
                         None,
171
                         self.file_diff_dict,
172
                         Result("origin", "msg", diffs={testfile_path: diff}),
173
                         file_dict)
174
175
        # Interaction must be closed by the user with `0` if it's not a param
176
        with simulate_console_inputs("INVALID",
177
                                     -1,
178
                                     1,
179
                                     0,
180
                                     3) as input_generator:
181
            curr_section = Section("")
182
            print_section_beginning(self.console_printer, curr_section)
183
            print_result(self.console_printer,
184
                         self.log_printer,
185
                         curr_section,
186
                         self.file_diff_dict,
187
                         Result("origin", "msg", diffs={testfile_path: diff}),
188
                         file_dict)
189
            self.assertEqual(input_generator.last_input, 3)
190
191
            self.file_diff_dict.clear()
192
193
            with open(testfile_path) as f:
194
                self.assertEqual(f.readlines(), ["1\n", "3_changed\n"])
195
196
            os.remove(testfile_path)
197
            os.remove(testfile_path + ".orig")
198
199
            name, section = get_action_info(curr_section,
200
                                            TestAction().get_metadata())
201
            self.assertEqual(input_generator.last_input, 4)
202
            self.assertEqual(str(section), " {param : '3'}")
203
            self.assertEqual(name, "TestAction")
204
205
        # Check if the user is asked for the parameter only the first time.
206
        # Use OpenEditorAction that needs this parameter (editor command).
207
        with simulate_console_inputs(1, "test_editor", 0, 1, 0) as generator:
208
            OpenEditorAction.is_applicable = staticmethod(lambda *args: True)
209
210
            patch_result = Result("origin", "msg", diffs={testfile_path: diff})
211
            patch_result.file = "f_b"
212
213
            print_result(self.console_printer,
214
                         self.log_printer,
215
                         curr_section,
216
                         self.file_diff_dict,
217
                         patch_result,
218
                         file_dict)
219
            # choose action, choose editor, choose no action (-1 -> 2)
220
            self.assertEqual(generator.last_input, 2)
221
222
            # It shoudn't ask for parameter again
223
            print_result(self.console_printer,
224
                         self.log_printer,
225
                         curr_section,
226
                         self.file_diff_dict,
227
                         patch_result,
228
                         file_dict)
229
            self.assertEqual(generator.last_input, 4)
230
231
    def test_print_result_auto_apply(self):
232
        section = Section("X")
233
        section.append(Setting("default_actions",
234
                               "SuperBear: InvalidACTION, XBear: ABC, "
235
                                   "UltraBear: ApplyPatchAction"))
236
        with retrieve_stdout() as stdout:
237
            print_result(self.console_printer,
238
                         self.log_printer,
239
                         section,
240
                         self.file_diff_dict,
241
                         Result("origin", "msg", diffs={}),
242
                         {})
243
            console_content = stdout.getvalue()
244
            self.assertIn("Selected default action 'InvalidACTION' for bear "
245
                              "'SuperBear' does not exist.",
246
                          console_content)
247
            self.assertIn("Selected default action 'ABC' for bear 'XBear' "
248
                              "does not exist.",
249
                          console_content)
250
            self.assertIn("Selected default action 'ApplyPatchAction' for "
251
                              "bear 'UltraBear' is not applicable.",
252
                          console_content)
253
254
        CLI_ACTIONS.append(TestAction())
255
256
        section = Section("A")
257
        section.append(Setting("default_actions",
258
                               "MyBear: TestAction"))
259
        with retrieve_stdout() as stdout:
260
            print_result(self.console_printer,
261
                         self.log_printer,
262
                         section,
263
                         self.file_diff_dict,
264
                         Result("MyBear", "msg", diffs={}),
265
                         {})
266
            self.assertNotIn("Selected default action 'TestAction' for bear "
267
                                 "'MyBear' does not exist or is not "
268
                                 "applicable.",
269
                             stdout.getvalue())
270
271
        CLI_ACTIONS.pop()
272
273
        CLI_ACTIONS.append(RaisingAction())
274
275
        section = Section("B")
276
        section.append(Setting("default_actions",
277
                               "MySuperBear: RaisingAction"))
278
279
        with retrieve_stdout() as stdout:
280
            print_result(self.console_printer,
281
                         self.log_printer,
282
                         section,
283
                         self.file_diff_dict,
284
                         Result("MySuperBear", "msg", diffs={}),
285
                         {})
286
            self.assertIn("Failed to execute action RaisingAction.",
287
                          stdout.getvalue())
288
289
        CLI_ACTIONS.pop()
290
291
    def test_print_section_beginning(self):
292
        with retrieve_stdout() as stdout:
293
            print_section_beginning(self.console_printer, Section("name"))
294
            self.assertEqual(stdout.getvalue(), "Executing section name...\n")
295
296
    def test_nothing_done(self):
297
        with retrieve_stdout() as stdout:
298
            nothing_done(self.log_printer)
299
            self.assertIn("No existent section was targeted or enabled. "
300
                          "Nothing to do.\n",
301
                          stdout.getvalue())
302
303
    def test_print_results_empty(self):
304
        with retrieve_stdout() as stdout:
305
            print_results(self.log_printer, Section(""), [], {}, {})
306
            self.assertEqual(stdout.getvalue(), "")
307
308
    def test_print_results_project_wide(self):
309
        with retrieve_stdout() as stdout:
310
            print_results(self.log_printer,
311
                          Section(""),
312
                          [Result("origin", "message")],
313
                          {},
314
                          {},
315
                          color=False)
316
            self.assertEqual(
317
                "\n{}\n|    | [NORMAL] origin:\n|    | message"
318
                "\n".format(STR_PROJECT_WIDE),
319
                stdout.getvalue())
320
321
    def test_print_results_for_file(self):
322
        with retrieve_stdout() as stdout:
323
            print_results(
324
                self.log_printer,
325
                Section(""),
326
                [Result.from_values("SpaceConsistencyBear",
327
                                    "Trailing whitespace found",
328
                                    file="proj/white",
329
                                    line=2)],
330
                {"proj/white": ["test line\n", "line 2\n", "line 3\n"]},
331
                {},
332
                color=False)
333
            self.assertEqual("""\nproj/white
334
|   2| line 2
335
|    | [NORMAL] SpaceConsistencyBear:
336
|    | Trailing whitespace found
337
""",
338
                         stdout.getvalue())
339
340
        with retrieve_stdout() as stdout:
341
            print_results(
342
                self.log_printer,
343
                Section(""),
344
                [Result.from_values("SpaceConsistencyBear",
345
                                    "Trailing whitespace found",
346
                                    file="proj/white",
347
                                    line=5)],
348
                {"proj/white": ["test line\n",
349
                                "line 2\n",
350
                                "line 3\n",
351
                                "line 4\n",
352
                                "line 5\n"]},
353
                {},
354
                color=False)
355
            self.assertEqual("""\nproj/white
356
|   5| line 5
357
|    | [NORMAL] SpaceConsistencyBear:
358
|    | Trailing whitespace found
359
""",
360
                             stdout.getvalue())
361
362
    def test_print_results_sorting(self):
363
        with retrieve_stdout() as stdout:
364
            print_results(self.log_printer,
365
                          Section(""),
366
                          [Result.from_values("SpaceConsistencyBear",
367
                                              "Trailing whitespace found",
368
                                              file="file",
369
                                              line=5),
370
                           Result.from_values("SpaceConsistencyBear",
371
                                              "Trailing whitespace found",
372
                                              file="file",
373
                                              line=2)],
374
                          {"file": ["test line\n",
375
                                    "line 2\n",
376
                                    "line 3\n",
377
                                    "line 4\n",
378
                                    "line 5\n"]},
379
                          {},
380
                          color=False)
381
382
            self.assertEqual("""
383
file
384
|   2| line 2
385
|    | [NORMAL] SpaceConsistencyBear:
386
|    | Trailing whitespace found
387
388
file
389
|   5| line 5
390
|    | [NORMAL] SpaceConsistencyBear:
391
|    | Trailing whitespace found
392
""",
393
                             stdout.getvalue())
394
395
    def test_print_results_multiple_ranges(self):
396
        affected_code = (SourceRange.from_values("some_file", 5, end_line=7),
397
                         SourceRange.from_values("another_file", 1, 3, 1, 5),
398
                         SourceRange.from_values("another_file", 3, 3, 3, 5))
399
        with retrieve_stdout() as stdout:
400
            print_results(
401
                self.log_printer,
402
                Section(""),
403
                [Result("ClangCloneDetectionBear",
404
                        "Clone Found",
405
                        affected_code)],
406
                {"some_file": ["line "+str(i+1)+"\n" for i in range(10)],
407
                 "another_file": ["line "+str(i+1)+"\n" for i in range(10)]},
408
                {},
409
                color=False)
410
            self.assertEqual("""
411
another_file
412
|   1| line 1
413
414
another_file
415
|   3| line 3
416
417
some_file
418
|   5| line 5
419
|   6| line 6
420
|   7| line 7
421
|    | [NORMAL] ClangCloneDetectionBear:
422
|    | Clone Found
423
""",
424
                         stdout.getvalue())
425
426
    def test_print_results_missing_file(self):
427
        self.log_printer = LogPrinter(NullPrinter())
428
        with retrieve_stdout() as stdout:
429
            print_results(
430
                self.log_printer,
431
                Section(""),
432
                [Result("t", "msg"),
433
                 Result.from_values("t", "msg", file="file", line=5)],
434
                {},
435
                {},
436
                color=False)
437
            self.assertEqual("\n" + STR_PROJECT_WIDE + "\n"
438
                             "|    | [NORMAL] t:\n"
439
                             "|    | msg\n"
440
                             # Second results file isn't there, no context is
441
                             # printed, only a warning log message which we
442
                             # don't catch
443
                             "|    | [NORMAL] t:\n"
444
                             "|    | msg\n", stdout.getvalue())
445
446
    def test_print_results_missing_line(self):
447
        with retrieve_stdout() as stdout:
448
            print_results(
449
                self.log_printer,
450
                Section(""),
451
                [Result.from_values("t", "msg", file="file", line=5),
452
                 Result.from_values("t", "msg", file="file", line=6)],
453
                {"file": ["line " + str(i+1) for i in range(5)]},
454
                {},
455
                color=False)
456
            self.assertEqual("\n"
457
                             "file\n"
458
                             "|   5| line 5\n"
459
                             "|    | [NORMAL] t:\n"
460
                             "|    | msg\n"
461
                             "\n"
462
                             "file\n"
463
                             "|    | {}\n"
464
                             "|    | [NORMAL] t:\n"
465
                             "|    | msg\n".format(STR_LINE_DOESNT_EXIST),
466
                             stdout.getvalue())
467
468
    def test_print_results_without_line(self):
469
        with retrieve_stdout() as stdout:
470
            print_results(
471
                self.log_printer,
472
                Section(""),
473
                [Result.from_values("t", "msg", file="file")],
474
                {"file": []},
475
                {},
476
                color=False)
477
            self.assertEqual(
478
                "\nfile\n"
479
                "|    | [NORMAL] t:\n"
480
                "|    | msg\n",
481
                stdout.getvalue())
482
483
    def test_print_bears_empty(self):
484
        with retrieve_stdout() as stdout:
485
            bears = {}
486
            print_bears(self.log_printer.printer, bears, True)
487
            self.assertEqual("No bears to show.\n", stdout.getvalue())
488
        with retrieve_stdout() as stdout:
489
            bears = {}
490
            print_bears(self.log_printer.printer, bears, False)
491
            self.assertEqual("No bears to show.\n", stdout.getvalue())
492
493
    def test_print_bears(self):
494
        with retrieve_stdout() as stdout:
495
            bears = {TestBear: ["default", "docs"]}
496
            print_bears(self.log_printer.printer, bears, False)
497
            expected_string = "TestBear:\n"
498
            expected_string += "  Test bear Description.\n\n"
499
            expected_string += "  Used in:\n"
500
            expected_string += "   * default\n"
501
            expected_string += "   * docs\n\n"
502
            expected_string += "  Needed Settings:\n"
503
            expected_string += "   * setting1: Required Setting.\n\n"
504
            expected_string += "  Optional Settings:\n"
505
            expected_string += "   * setting2: Optional Setting. ("
506
            expected_string += "Optional, defaults to 'None'."
507
            expected_string += ")\n\n"
508
509
            self.assertEqual(expected_string, stdout.getvalue())
510
511
    def test_print_bears_no_settings(self):
512
        with retrieve_stdout() as stdout:
513
            bears = {SomeBear: ["default"]}
514
            print_bears(self.log_printer.printer, bears, False)
515
            expected_string = "SomeBear:\n"
516
            expected_string += "  Some Description.\n\n"
517
            expected_string += "  Used in:\n"
518
            expected_string += "   * default\n\n"
519
            expected_string += "  No needed settings.\n\n"
520
            expected_string += "  No optional settings.\n\n"
521
522
            self.assertEqual(expected_string, stdout.getvalue())
523
524
    def test_print_bears_no_needed_settings(self):
525
        with retrieve_stdout() as stdout:
526
            bears = {SomeOtherBear: ["test"]}
527
            print_bears(self.log_printer.printer, bears, False)
528
            expected_string = "SomeOtherBear:\n"
529
            expected_string += "  This is a Bear.\n\n"
530
            expected_string += "  Used in:\n"
531
            expected_string += "   * test\n\n"
532
            expected_string += "  No needed settings.\n\n"
533
            expected_string += "  Optional Settings:\n"
534
            expected_string += "   * setting: This is an optional setting. ("
535
            expected_string += "Optional, defaults to 'None'."
536
            expected_string += ")\n\n"
537
538
            self.assertEqual(expected_string, stdout.getvalue())
539
540
    def test_print_bears_no_optional_settings(self):
541
        with retrieve_stdout() as stdout:
542
            bears = {TestBear2: ["test"]}
543
            print_bears(self.log_printer.printer, bears, False)
544
            expected_string = "TestBear2:\n"
545
            expected_string += "  Test bear 2 description.\n\n"
546
            expected_string += "  Used in:\n"
547
            expected_string += "   * test\n\n"
548
            expected_string += "  Needed Settings:\n"
549
            expected_string += "   * setting1: Required Setting.\n\n"
550
            expected_string += "  No optional settings.\n\n"
551
552
            self.assertEqual(expected_string, stdout.getvalue())
553
554
    def test_print_bears_no_sections(self):
555
        with retrieve_stdout() as stdout:
556
            bears = {SomeBear: []}
557
            print_bears(self.log_printer.printer, bears, False)
558
            expected_string = "SomeBear:\n"
559
            expected_string += "  Some Description.\n\n"
560
            expected_string += "  No sections.\n\n"
561
            expected_string += "  No needed settings.\n\n"
562
            expected_string += "  No optional settings.\n\n"
563
564
            self.assertEqual(expected_string, stdout.getvalue())
565
566
    def test_show_bears(self):
567
        with retrieve_stdout() as stdout:
568
            bears = {KeywordBear: ['default', 'test'],
569
                     LineLengthBear: ['test'],
570
                     SomeglobalBear: ['default', 'test']}
571
            print_bears(self.log_printer.printer, bears, False)
572
            expected_string = stdout.getvalue()
573
        self.maxDiff = None
574
        with retrieve_stdout() as stdout:
575
            show_bears(self.local_bears,
576
                       self.global_bears,
577
                       False,
578
                       self.log_printer.printer)
579
            self.assertEqual(expected_string, stdout.getvalue())
580
581
        with retrieve_stdout() as stdout:
582
            show_bears(self.local_bears,
583
                       self.global_bears,
584
                       True,
585
                       self.log_printer.printer)
586
            self.assertEqual(" * KeywordBear\n"
587
                             " * LineLengthBear\n"
588
                             " * SomeglobalBear\n", stdout.getvalue())
589
590
591
# Own test because this is easy and not tied to the rest
592
class PrintFormattedResultsTest(unittest.TestCase):
593
    def setUp(self):
594
        self.printer = StringPrinter()
595
        self.logger = LogPrinter(self.printer)
596
        self.section = Section("t")
597
598
    def test_default_format(self):
599
        expected_string = ("id:-?[0-9]+:origin:1:file:None:from_line:None:"
600
                           "from_column:None:to_line:None:to_column:None:"
601
                           "severity:1:msg:2\n")
602
        with retrieve_stdout() as stdout:
603
            print_results_formatted(self.logger,
604
                                    self.section,
605
                                    [Result("1", "2")],
606
                                    None,
607
                                    None)
608
            self.assertRegex(stdout.getvalue(), expected_string)
609
610
    def test_multiple_ranges(self):
611
        expected_string = (
612
            "id:-?[0-9]+:origin:1:file:another_file:from_line:5:"
613
            "from_column:3:to_line:5:to_column:5:"
614
            "severity:1:msg:2\n"
615
            "id:-?[0-9]+:origin:1:file:some_file:from_line:5:"
616
            "from_column:None:to_line:7:to_column:None:"
617
            "severity:1:msg:2\n")
618
        affected_code = (SourceRange.from_values("some_file", 5, end_line=7),
619
                         SourceRange.from_values("another_file", 5, 3, 5, 5))
620
        with retrieve_stdout() as stdout:
621
            print_results_formatted(self.logger,
622
                                    self.section,
623
                                    [Result("1", "2", affected_code)],
624
                                    None,
625
                                    None)
626
            self.assertRegex(stdout.getvalue(), expected_string)
627
628
    def test_bad_format(self):
629
        self.section.append(Setting("format_str", "{nonexistant}"))
630
        print_results_formatted(self.logger,
631
                                self.section,
632
                                [Result("1", "2")],
633
                                None,
634
                                None)
635
        self.assertRegex(self.printer.string, ".*Unable to print.*")
636
637
    def test_good_format(self):
638
        self.section.append(Setting("format_str", "{origin}"))
639
        with retrieve_stdout() as stdout:
640
            print_results_formatted(self.logger,
641
                                    self.section,
642
                                    [Result("1", "2")],
643
                                    None,
644
                                    None)
645
            self.assertEqual(stdout.getvalue(), "1\n")
646
647
    def test_empty_list(self):
648
        self.section.append(Setting("format_str", "{origin}"))
649
        # Shouldn't attempt to format the string None and will fail badly if
650
        # its done wrong.
651
        print_results_formatted(None,
652
                                self.section,
653
                                [],
654
                                None,
655
                                None,
656
                                None)
657
658
659
if __name__ == '__main__':
660
    unittest.main(verbosity=2)
661