|
2 | 2 |
|
3 | 3 | import dataclasses |
4 | 4 | from http import HTTPStatus |
5 | | -from unittest.mock import patch |
| 5 | +from unittest.mock import MagicMock, patch |
6 | 6 |
|
7 | 7 | import httpx2 |
8 | 8 | import msgspec |
@@ -196,3 +196,37 @@ def test_msgspec_still_accepts_native_containers(model: type) -> None: |
196 | 196 | plain builtin element types. |
197 | 197 | """ |
198 | 198 | assert MsgspecDecoder().can_decode(model) is True |
| 199 | + |
| 200 | + |
| 201 | +def test_msgspec_can_decode_result_is_cached() -> None: |
| 202 | + """Repeat can_decode calls reuse a cached verdict, not the per-dispatch probe.""" |
| 203 | + decoder = MsgspecDecoder() |
| 204 | + with patch( |
| 205 | + "httpware.decoders.msgspec.msgspec.inspect.type_info", |
| 206 | + wraps=msgspec.inspect.type_info, |
| 207 | + ) as spy: |
| 208 | + assert decoder.can_decode(_Item) is True |
| 209 | + assert decoder.can_decode(_Item) is True |
| 210 | + assert spy.call_count == 1 |
| 211 | + assert decoder._can_decode_results[_Item] is True # noqa: SLF001 |
| 212 | + |
| 213 | + |
| 214 | +def test_msgspec_can_decode_caches_negative_verdict() -> None: |
| 215 | + """A rejection is cached too, so repeat probes don't repeat the walk.""" |
| 216 | + decoder = MsgspecDecoder() |
| 217 | + with patch( |
| 218 | + "httpware.decoders.msgspec.msgspec.inspect.type_info", |
| 219 | + wraps=msgspec.inspect.type_info, |
| 220 | + ) as spy: |
| 221 | + assert decoder.can_decode(_PydanticUser) is False |
| 222 | + assert decoder.can_decode(_PydanticUser) is False |
| 223 | + assert spy.call_count == 1 |
| 224 | + assert decoder._can_decode_results[_PydanticUser] is False # noqa: SLF001 |
| 225 | + |
| 226 | + |
| 227 | +def test_msgspec_can_decode_unhashable_model_does_not_raise() -> None: |
| 228 | + """An unhashable model falls back to a fresh probe instead of raising from the cache.""" |
| 229 | + decoder = MsgspecDecoder() |
| 230 | + decoder._can_decode_results = MagicMock() # noqa: SLF001 |
| 231 | + decoder._can_decode_results.get.side_effect = TypeError("unhashable type") # noqa: SLF001 |
| 232 | + assert decoder.can_decode(_Item) is True |
0 commit comments