-
Notifications
You must be signed in to change notification settings - Fork 380
Expand file tree
/
Copy pathtest_conversions.py
More file actions
209 lines (179 loc) · 6.47 KB
/
test_conversions.py
File metadata and controls
209 lines (179 loc) · 6.47 KB
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
from __future__ import annotations
from datetime import date, datetime
import pytest
from sqlmesh.utils.conversions import ensure_bool, make_serializable, try_str_to_bool
class TestTryStrToBool:
"""Tests for the try_str_to_bool function."""
@pytest.mark.parametrize(
"input_val,expected",
[
("true", True),
("True", True),
("TRUE", True),
("TrUe", True),
("false", False),
("False", False),
("FALSE", False),
("FaLsE", False),
],
)
def test_boolean_strings(self, input_val: str, expected: bool) -> None:
"""Strings 'true' and 'false' (case-insensitive) convert to bool."""
assert try_str_to_bool(input_val) is expected
@pytest.mark.parametrize(
"input_val",
[
"yes",
"no",
"1",
"0",
"",
"truthy",
"falsey",
"t",
"f",
"on",
"off",
],
)
def test_non_boolean_strings_pass_through(self, input_val: str) -> None:
"""Non-boolean strings are returned unchanged."""
assert try_str_to_bool(input_val) == input_val
def test_return_type_for_true(self) -> None:
"""Returns actual bool True, not truthy value."""
result = try_str_to_bool("true")
assert result is True
assert isinstance(result, bool)
def test_return_type_for_false(self) -> None:
"""Returns actual bool False, not falsey value."""
result = try_str_to_bool("false")
assert result is False
assert isinstance(result, bool)
class TestEnsureBool:
"""Tests for the ensure_bool function."""
def test_bool_true_passthrough(self) -> None:
"""Boolean True passes through unchanged."""
assert ensure_bool(True) is True
def test_bool_false_passthrough(self) -> None:
"""Boolean False passes through unchanged."""
assert ensure_bool(False) is False
@pytest.mark.parametrize(
"input_val,expected",
[
("true", True),
("True", True),
("false", False),
("False", False),
],
)
def test_boolean_strings(self, input_val: str, expected: bool) -> None:
"""String 'true'/'false' converts to corresponding bool."""
assert ensure_bool(input_val) is expected
@pytest.mark.parametrize(
"input_val,expected",
[
("yes", True), # Non-empty string is truthy
("no", True), # Non-empty string is truthy
("", False), # Empty string is falsey
("0", True), # String "0" is truthy (non-empty)
],
)
def test_other_strings_use_bool_conversion(self, input_val: str, expected: bool) -> None:
"""Non-boolean strings fall back to bool() conversion."""
assert ensure_bool(input_val) is expected
@pytest.mark.parametrize(
"input_val,expected",
[
(1, True),
(0, False),
(-1, True),
(100, True),
],
)
def test_integers(self, input_val: int, expected: bool) -> None:
"""Integers convert via bool() - 0 is False, others True."""
assert ensure_bool(input_val) is expected
@pytest.mark.parametrize(
"input_val,expected",
[
(1.0, True),
(0.0, False),
(-0.5, True),
],
)
def test_floats(self, input_val: float, expected: bool) -> None:
"""Floats convert via bool() - 0.0 is False, others True."""
assert ensure_bool(input_val) is expected
@pytest.mark.parametrize(
"input_val,expected",
[
([], False),
([1], True),
({}, False),
({"a": 1}, True),
(None, False),
],
)
def test_other_types(self, input_val: object, expected: bool) -> None:
"""Other types convert via bool()."""
assert ensure_bool(input_val) is expected
class TestMakeSerializable:
"""Tests for the make_serializable function."""
def test_date_to_isoformat(self) -> None:
"""date objects convert to ISO format string."""
d = date(2024, 1, 15)
assert make_serializable(d) == "2024-01-15"
def test_datetime_to_isoformat(self) -> None:
"""datetime objects convert to ISO format string."""
dt = datetime(2024, 1, 15, 10, 30, 45)
assert make_serializable(dt) == "2024-01-15T10:30:45"
def test_datetime_with_microseconds(self) -> None:
"""datetime with microseconds preserves precision."""
dt = datetime(2024, 1, 15, 10, 30, 45, 123456)
assert make_serializable(dt) == "2024-01-15T10:30:45.123456"
def test_dict_recursive(self) -> None:
"""Dictionaries are processed recursively."""
obj = {"date": date(2024, 1, 15), "name": "test"}
result = make_serializable(obj)
assert result == {"date": "2024-01-15", "name": "test"}
def test_list_recursive(self) -> None:
"""Lists are processed recursively."""
obj = [date(2024, 1, 15), "test", 123]
result = make_serializable(obj)
assert result == ["2024-01-15", "test", 123]
def test_nested_structure(self) -> None:
"""Deeply nested structures are fully processed."""
obj = {
"dates": [date(2024, 1, 1), date(2024, 12, 31)],
"nested": {"inner": {"dt": datetime(2024, 6, 15, 12, 0, 0)}},
}
result = make_serializable(obj)
assert result == {
"dates": ["2024-01-01", "2024-12-31"],
"nested": {"inner": {"dt": "2024-06-15T12:00:00"}},
}
@pytest.mark.parametrize(
"input_val",
[
"string",
123,
45.67,
True,
False,
None,
],
)
def test_primitives_unchanged(self, input_val: object) -> None:
"""Primitive types pass through unchanged."""
assert make_serializable(input_val) == input_val
def test_empty_dict(self) -> None:
"""Empty dict returns empty dict."""
assert make_serializable({}) == {}
def test_empty_list(self) -> None:
"""Empty list returns empty list."""
assert make_serializable([]) == []
def test_dict_keys_unchanged(self) -> None:
"""Dictionary keys are not modified."""
obj = {"key_with_date": date(2024, 1, 1)}
result = make_serializable(obj)
assert "key_with_date" in result