Coverage for tests / unit / utils / summary / test_safe_cast.py: 100%
30 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 _safe_cast function in summary_tables module.
3Tests cover type conversion with fallbacks for int and float values,
4and error handling for invalid inputs.
5"""
7from __future__ import annotations
9from typing import Any
10from unittest.mock import patch
12import pytest
13from assertpy import assert_that
15from lintro.utils.summary_tables import _safe_cast
17# =============================================================================
18# Tests for _safe_cast function
19# =============================================================================
22@pytest.mark.parametrize(
23 ("value", "converter", "default", "expected"),
24 [
25 ("42", int, 0, 42),
26 ("100", int, -1, 100),
27 ("0", int, 99, 0),
28 ],
29 ids=["basic-int", "with-different-default", "zero-value"],
30)
31def test_safe_cast_successful_int_cast(
32 value: str,
33 converter: type,
34 default: int,
35 expected: int,
36) -> None:
37 """Cast string to int successfully with various inputs.
39 Args:
40 value: String value to cast.
41 converter: Value converter function.
42 default: Default value.
43 expected: Expected result after casting.
44 """
45 summary = {"count": value}
46 with patch("lintro.utils.summary_tables.get_summary_value", return_value=value):
47 result = _safe_cast(summary, "count", default, converter)
48 assert_that(result).is_equal_to(expected)
51@pytest.mark.parametrize(
52 ("value", "default", "expected"),
53 [
54 ("1.5", 0.0, 1.5),
55 ("3.14159", 0.0, 3.14159),
56 ("0.0", 1.0, 0.0),
57 ],
58 ids=["basic-float", "pi-value", "zero-float"],
59)
60def test_safe_cast_successful_float_cast(
61 value: str,
62 default: float,
63 expected: float,
64) -> None:
65 """Cast string to float successfully with various inputs.
67 Args:
68 value: String value to cast.
69 default: Default value.
70 expected: Expected result after casting.
71 """
72 summary = {"duration": value}
73 with patch("lintro.utils.summary_tables.get_summary_value", return_value=value):
74 result = _safe_cast(summary, "duration", default, float)
75 assert_that(result).is_equal_to(expected)
78@pytest.mark.parametrize(
79 ("value", "default"),
80 [
81 ("not_a_number", -1),
82 ("abc", 0),
83 ("12.34.56", 100),
84 ],
85 ids=["text-value", "letters-only", "malformed-number"],
86)
87def test_safe_cast_returns_default_on_value_error(value: str, default: int) -> None:
88 """Return default when value cannot be converted due to ValueError.
90 Args:
91 value: Value to test.
92 default: Default value to return.
93 """
94 summary = {"count": value}
95 with patch("lintro.utils.summary_tables.get_summary_value", return_value=value):
96 result = _safe_cast(summary, "count", default, int)
97 assert_that(result).is_equal_to(default)
100@pytest.mark.parametrize(
101 ("value", "default"),
102 [
103 (None, 0),
104 (None, -1),
105 (None, 999),
106 ],
107 ids=["default-zero", "default-negative", "default-large"],
108)
109def test_safe_cast_returns_default_on_type_error(value: Any, default: int) -> None:
110 """Return default when value causes TypeError during conversion.
112 Args:
113 value: Value that causes TypeError.
114 default: Default value to return.
115 """
116 summary = {"count": value}
117 with patch("lintro.utils.summary_tables.get_summary_value", return_value=value):
118 result = _safe_cast(summary, "count", default, int)
119 assert_that(result).is_equal_to(default)