1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
"""
Unit tests for the `ciqar.application` module.
"""
from argparse import ArgumentTypeError
from functools import partial
from pathlib import Path
import pytest
from typing import Type
from unittest.mock import Mock, patch
from ciqar.application import CiqarApplication
from ciqar.input.linter.mypy_logfile import MypyLogfileParser
from ciqar.input.linter.pyright_json import PyrightJsonParser
from ciqar.report.generator import ReportGenerator
# TODO: It'd be cool to have a test for the command line interface, i.e. allowed options and
# their syntax, to get a warning when the CLI changes. But I don't have a good idea of how to
# do this, yet.
@patch("ciqar.application.ArgumentParser")
def test_app_description(_: Mock) -> None:
"""
SImple tests for the application name and version properties.
"""
application = CiqarApplication()
assert application.application_name == "Ciqar"
version_strings = application.application_version.split(".")
assert len(version_strings) == 3
major, minor, bug = version_strings
assert major.isdigit()
assert minor.isdigit()
assert bug.isdigit()
@pytest.mark.parametrize("result_url, expected_factory_class, expected_result_path", [
("mypy:/path/to/file.log", MypyLogfileParser, Path("/path/to/file.log")),
("pyright:/path/to/file.json", PyrightJsonParser, Path("/path/to/file.json")),
])
def test__parse_analyzer_result_url__normal_usecase(
result_url: str,
expected_factory_class: Type,
expected_result_path: Path
) -> None:
"""
Tests parsing of analyzer result URLs (as provided on command line).
"""
parser_factory = CiqarApplication._parse_analyzer_result_url(analyzer_result_url=result_url)
expected_factory = partial(expected_factory_class, expected_result_path)
# Returning a "partial" object is not a requirement to test, but the following three checks rely on it.
# So we want a warning if this ever chanegs, because then we need to adapt this testc ase as well.
assert isinstance(parser_factory, partial), "The test requries the factory to be a 'partial' object"
assert parser_factory.func == expected_factory.func
assert parser_factory.args == expected_factory.args
assert parser_factory.keywords == expected_factory.keywords
@pytest.mark.parametrize("invalid_result_url", [
"unknown:/some/file.bin", # Unknown analyzer
"/missing/url/scheme.txt", # Invalid URL - Scheme is missing
"mypy:", # Invalid URL: Path is missing
])
def test__parse_analyzer_result_url__errorcases(invalid_result_url: str) -> None:
"""
Tests the behaviour when the provided result URL is invalid.
"""
with pytest.raises(ArgumentTypeError):
CiqarApplication._parse_analyzer_result_url(analyzer_result_url=invalid_result_url)
@patch("ciqar.application.ArgumentParser")
@patch("ciqar.application.ReportGenerator")
@patch("ciqar.application.SourceFileCollector")
def test_run(_argument_parser_cls_mock: Mock, generator_cls_mock: Mock, _source_collector_cls_mock: Mock) -> None:
"""
Simple test case for the run() method. Makes sure the ReportGenerator is run).
"""
generator_mock = Mock(spec=ReportGenerator)
generator_cls_mock.return_value = generator_mock
app = CiqarApplication()
app.run()
assert generator_mock.generate_report.call_count == 1
|