Coverage for tests / unit / utils / test_native_parsers.py: 100%
49 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""Unit tests for native_parsers.py error handling."""
3from __future__ import annotations
5from pathlib import Path
6from unittest.mock import mock_open, patch
8from assertpy import assert_that
10from lintro.utils.native_parsers import _load_json_config, _load_native_tool_config
12# =============================================================================
13# _load_json_config - Error Handling
14# =============================================================================
17def test_load_json_config_parse_error_logs_warning(tmp_path: Path) -> None:
18 """Verify JSON parse error logs warning with details.
20 Args:
21 tmp_path: Pytest temporary directory fixture.
22 """
23 config_file = tmp_path / "bad.json"
24 config_file.write_text("{ invalid json }")
26 with patch("lintro.utils.native_parsers.logger") as mock_logger:
27 result = _load_json_config(config_file)
29 assert_that(result).is_equal_to({})
30 mock_logger.warning.assert_called_once()
31 warning_msg = mock_logger.warning.call_args[0][0]
32 assert_that(warning_msg).contains("Failed to parse JSON config")
33 assert_that(warning_msg).contains(str(config_file))
36def test_load_json_config_file_not_found_logs_debug(tmp_path: Path) -> None:
37 """Verify missing file logs debug message.
39 Args:
40 tmp_path: Pytest temporary directory fixture.
41 """
42 missing_file = tmp_path / "missing.json"
44 with patch("lintro.utils.native_parsers.logger") as mock_logger:
45 result = _load_json_config(missing_file)
47 assert_that(result).is_equal_to({})
48 mock_logger.debug.assert_called_once()
49 debug_msg = mock_logger.debug.call_args[0][0]
50 assert_that(debug_msg).contains("Config file not found")
53def test_load_json_config_valid_returns_dict(tmp_path: Path) -> None:
54 """Verify valid JSON returns parsed dict.
56 Args:
57 tmp_path: Pytest temporary directory fixture.
58 """
59 config_file = tmp_path / "valid.json"
60 config_file.write_text('{"key": "value"}')
62 result = _load_json_config(config_file)
64 assert_that(result).is_equal_to({"key": "value"})
67def test_load_json_config_non_dict_returns_empty(tmp_path: Path) -> None:
68 """Verify non-dict JSON returns empty dict.
70 Args:
71 tmp_path: Pytest temporary directory fixture.
72 """
73 config_file = tmp_path / "array.json"
74 config_file.write_text('["item1", "item2"]')
76 result = _load_json_config(config_file)
78 assert_that(result).is_equal_to({})
81# =============================================================================
82# _load_native_tool_config - YAML Parse Errors (yamllint)
83# =============================================================================
86def test_load_yamllint_config_yaml_error_logs_warning() -> None:
87 """Verify YAML parse error for yamllint config logs warning."""
88 with (
89 patch("lintro.utils.native_parsers.Path.exists", return_value=True),
90 patch(
91 "builtins.open",
92 mock_open(read_data="invalid: yaml: content: ["),
93 ),
94 patch("lintro.utils.native_parsers.yaml") as mock_yaml,
95 patch("lintro.utils.native_parsers.logger") as mock_logger,
96 ):
97 # Make yaml.YAMLError available for isinstance check
98 mock_yaml.YAMLError = type("YAMLError", (Exception,), {})
99 mock_yaml.safe_load.side_effect = mock_yaml.YAMLError("bad yaml")
101 result = _load_native_tool_config("yamllint")
103 assert_that(result).is_equal_to({})
104 mock_logger.warning.assert_called()
107def test_load_yamllint_config_os_error_returns_empty() -> None:
108 """Verify OS error reading yamllint config returns empty dict."""
109 with (
110 patch("lintro.utils.native_parsers.Path.exists", return_value=True),
111 patch("builtins.open", side_effect=OSError("Permission denied")),
112 patch("lintro.utils.native_parsers.yaml") as mock_yaml,
113 ):
114 mock_yaml.YAMLError = type("YAMLError", (Exception,), {})
116 result = _load_native_tool_config("yamllint")
118 # OS errors should return empty dict gracefully
119 assert_that(result).is_equal_to({})
122# =============================================================================
123# _load_native_tool_config - Markdownlint Parse Errors
124# =============================================================================
127def test_load_markdownlint_missing_config_returns_empty() -> None:
128 """Verify missing markdownlint config returns empty dict."""
129 with patch("lintro.utils.native_parsers.Path.exists", return_value=False):
130 result = _load_native_tool_config("markdownlint")
131 assert_that(result).is_equal_to({})