Pyright Code Quality Report

File Listing for test/ciqar/test_application.py

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